1 /**************************************************************************/
2 /*                                                                        */
3 /*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4 /*                                                                        */
5 /*       This software is licensed under the Microsoft Software License   */
6 /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7 /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8 /*       and in the root directory of this software.                      */
9 /*                                                                        */
10 /**************************************************************************/
11 
12 
13 /**************************************************************************/
14 /**************************************************************************/
15 /**                                                                       */
16 /** ThreadX Component                                                     */
17 /**                                                                       */
18 /**   Timer                                                               */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 #define TX_SOURCE_CODE
24 
25 
26 /* Include necessary system files.  */
27 
28 #include "tx_api.h"
29 #include "tx_timer.h"
30 
31 
32 /**************************************************************************/
33 /*                                                                        */
34 /*  FUNCTION                                               RELEASE        */
35 /*                                                                        */
36 /*    _tx_timer_system_activate                           PORTABLE C      */
37 /*                                                           6.1          */
38 /*  AUTHOR                                                                */
39 /*                                                                        */
40 /*    William E. Lamie, Microsoft Corporation                             */
41 /*                                                                        */
42 /*  DESCRIPTION                                                           */
43 /*                                                                        */
44 /*    This function places the specified internal timer in the proper     */
45 /*    place in the timer expiration list.  If the timer is already active */
46 /*    this function does nothing.                                         */
47 /*                                                                        */
48 /*  INPUT                                                                 */
49 /*                                                                        */
50 /*    timer_ptr                         Pointer to timer control block    */
51 /*                                                                        */
52 /*  OUTPUT                                                                */
53 /*                                                                        */
54 /*    TX_SUCCESS                        Always returns success            */
55 /*                                                                        */
56 /*  CALLS                                                                 */
57 /*                                                                        */
58 /*    None                                                                */
59 /*                                                                        */
60 /*  CALLED BY                                                             */
61 /*                                                                        */
62 /*    _tx_thread_system_suspend         Thread suspend function           */
63 /*    _tx_thread_system_ni_suspend      Non-interruptable suspend thread  */
64 /*    _tx_timer_thread_entry            Timer thread processing           */
65 /*    _tx_timer_activate                Application timer activate        */
66 /*                                                                        */
67 /*  RELEASE HISTORY                                                       */
68 /*                                                                        */
69 /*    DATE              NAME                      DESCRIPTION             */
70 /*                                                                        */
71 /*  09-30-2020     William E. Lamie         Initial Version 6.1           */
72 /*                                                                        */
73 /**************************************************************************/
_tx_timer_system_activate(TX_TIMER_INTERNAL * timer_ptr)74 VOID  _tx_timer_system_activate(TX_TIMER_INTERNAL *timer_ptr)
75 {
76 
77 TX_TIMER_INTERNAL           **timer_list;
78 TX_TIMER_INTERNAL           *next_timer;
79 TX_TIMER_INTERNAL           *previous_timer;
80 ULONG                       delta;
81 ULONG                       remaining_ticks;
82 ULONG                       expiration_time;
83 
84 
85     /* Pickup the remaining ticks.  */
86     remaining_ticks =  timer_ptr -> tx_timer_internal_remaining_ticks;
87 
88     /* Determine if there is a timer to activate.  */
89     if (remaining_ticks != ((ULONG) 0))
90     {
91 
92         /* Determine if the timer is set to wait forever.  */
93         if (remaining_ticks != TX_WAIT_FOREVER)
94         {
95 
96             /* Valid timer activate request.  */
97 
98             /* Determine if the timer still needs activation.  */
99             if (timer_ptr -> tx_timer_internal_list_head == TX_NULL)
100             {
101 
102                 /* Activate the timer.  */
103 
104                 /* Calculate the amount of time remaining for the timer.  */
105                 if (remaining_ticks > TX_TIMER_ENTRIES)
106                 {
107 
108                     /* Set expiration time to the maximum number of entries.  */
109                     expiration_time =  TX_TIMER_ENTRIES - ((ULONG) 1);
110                 }
111                 else
112                 {
113 
114                     /* Timer value fits in the timer entries.  */
115 
116                     /* Set the expiration time.  */
117                     expiration_time =  (remaining_ticks - ((ULONG) 1));
118                 }
119 
120                 /* At this point, we are ready to put the timer on one of
121                    the timer lists.  */
122 
123                 /* Calculate the proper place for the timer.  */
124                 timer_list =  TX_TIMER_POINTER_ADD(_tx_timer_current_ptr, expiration_time);
125                 if (TX_TIMER_INDIRECT_TO_VOID_POINTER_CONVERT(timer_list) >= TX_TIMER_INDIRECT_TO_VOID_POINTER_CONVERT(_tx_timer_list_end))
126                 {
127 
128                     /* Wrap from the beginning of the list.  */
129                     delta =  TX_TIMER_POINTER_DIF(timer_list, _tx_timer_list_end);
130                     timer_list =  TX_TIMER_POINTER_ADD(_tx_timer_list_start, delta);
131                 }
132 
133                 /* Now put the timer on this list.  */
134                 if ((*timer_list) == TX_NULL)
135                 {
136 
137                     /* This list is NULL, just put the new timer on it.  */
138 
139                     /* Setup the links in this timer.  */
140                     timer_ptr -> tx_timer_internal_active_next =      timer_ptr;
141                     timer_ptr -> tx_timer_internal_active_previous =  timer_ptr;
142 
143                     /* Setup the list head pointer.  */
144                     *timer_list =  timer_ptr;
145                 }
146                 else
147                 {
148 
149                     /* This list is not NULL, add current timer to the end. */
150                     next_timer =                                        *timer_list;
151                     previous_timer =                                    next_timer -> tx_timer_internal_active_previous;
152                     previous_timer -> tx_timer_internal_active_next =   timer_ptr;
153                     next_timer -> tx_timer_internal_active_previous =   timer_ptr;
154                     timer_ptr -> tx_timer_internal_active_next =        next_timer;
155                     timer_ptr -> tx_timer_internal_active_previous =    previous_timer;
156                 }
157 
158                 /* Setup list head pointer.  */
159                 timer_ptr -> tx_timer_internal_list_head =  timer_list;
160             }
161         }
162     }
163 }
164 
165