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 #ifndef TX_NO_TIMER
26 
27 /* Include necessary system files.  */
28 
29 #include "tx_api.h"
30 #include "tx_timer.h"
31 
32 
33 /**************************************************************************/
34 /*                                                                        */
35 /*  FUNCTION                                               RELEASE        */
36 /*                                                                        */
37 /*    _tx_timer_system_activate                           PORTABLE C      */
38 /*                                                           6.1          */
39 /*  AUTHOR                                                                */
40 /*                                                                        */
41 /*    William E. Lamie, Microsoft Corporation                             */
42 /*                                                                        */
43 /*  DESCRIPTION                                                           */
44 /*                                                                        */
45 /*    This function places the specified internal timer in the proper     */
46 /*    place in the timer expiration list.  If the timer is already active */
47 /*    this function does nothing.                                         */
48 /*                                                                        */
49 /*  INPUT                                                                 */
50 /*                                                                        */
51 /*    timer_ptr                         Pointer to timer control block    */
52 /*                                                                        */
53 /*  OUTPUT                                                                */
54 /*                                                                        */
55 /*    TX_SUCCESS                        Always returns success            */
56 /*                                                                        */
57 /*  CALLS                                                                 */
58 /*                                                                        */
59 /*    None                                                                */
60 /*                                                                        */
61 /*  CALLED BY                                                             */
62 /*                                                                        */
63 /*    _tx_thread_system_suspend         Thread suspend function           */
64 /*    _tx_thread_system_ni_suspend      Non-interruptable suspend thread  */
65 /*    _tx_timer_thread_entry            Timer thread processing           */
66 /*    _tx_timer_activate                Application timer activate        */
67 /*                                                                        */
68 /*  RELEASE HISTORY                                                       */
69 /*                                                                        */
70 /*    DATE              NAME                      DESCRIPTION             */
71 /*                                                                        */
72 /*  05-19-2020     William E. Lamie         Initial Version 6.0           */
73 /*  09-30-2020     Scott Larson             Modified comment(s), and      */
74 /*                                            opt out of function when    */
75 /*                                            TX_NO_TIMER is defined,     */
76 /*                                            resulting in version 6.1    */
77 /*                                                                        */
78 /**************************************************************************/
_tx_timer_system_activate(TX_TIMER_INTERNAL * timer_ptr)79 VOID  _tx_timer_system_activate(TX_TIMER_INTERNAL *timer_ptr)
80 {
81 
82 TX_TIMER_INTERNAL           **timer_list;
83 TX_TIMER_INTERNAL           *next_timer;
84 TX_TIMER_INTERNAL           *previous_timer;
85 ULONG                       delta;
86 ULONG                       remaining_ticks;
87 ULONG                       expiration_time;
88 
89 
90     /* Pickup the remaining ticks.  */
91     remaining_ticks =  timer_ptr -> tx_timer_internal_remaining_ticks;
92 
93     /* Determine if there is a timer to activate.  */
94     if (remaining_ticks != ((ULONG) 0))
95     {
96 
97         /* Determine if the timer is set to wait forever.  */
98         if (remaining_ticks != TX_WAIT_FOREVER)
99         {
100 
101             /* Valid timer activate request.  */
102 
103             /* Determine if the timer still needs activation.  */
104             if (timer_ptr -> tx_timer_internal_list_head == TX_NULL)
105             {
106 
107                 /* Activate the timer.  */
108 
109                 /* Calculate the amount of time remaining for the timer.  */
110                 if (remaining_ticks > TX_TIMER_ENTRIES)
111                 {
112 
113                     /* Set expiration time to the maximum number of entries.  */
114                     expiration_time =  TX_TIMER_ENTRIES - ((ULONG) 1);
115                 }
116                 else
117                 {
118 
119                     /* Timer value fits in the timer entries.  */
120 
121                     /* Set the expiration time.  */
122                     expiration_time =  (remaining_ticks - ((ULONG) 1));
123                 }
124 
125                 /* At this point, we are ready to put the timer on one of
126                    the timer lists.  */
127 
128                 /* Calculate the proper place for the timer.  */
129                 timer_list =  TX_TIMER_POINTER_ADD(_tx_timer_current_ptr, expiration_time);
130                 if (TX_TIMER_INDIRECT_TO_VOID_POINTER_CONVERT(timer_list) >= TX_TIMER_INDIRECT_TO_VOID_POINTER_CONVERT(_tx_timer_list_end))
131                 {
132 
133                     /* Wrap from the beginning of the list.  */
134                     delta =  TX_TIMER_POINTER_DIF(timer_list, _tx_timer_list_end);
135                     timer_list =  TX_TIMER_POINTER_ADD(_tx_timer_list_start, delta);
136                 }
137 
138                 /* Now put the timer on this list.  */
139                 if ((*timer_list) == TX_NULL)
140                 {
141 
142                     /* This list is NULL, just put the new timer on it.  */
143 
144                     /* Setup the links in this timer.  */
145                     timer_ptr -> tx_timer_internal_active_next =      timer_ptr;
146                     timer_ptr -> tx_timer_internal_active_previous =  timer_ptr;
147 
148                     /* Setup the list head pointer.  */
149                     *timer_list =  timer_ptr;
150                 }
151                 else
152                 {
153 
154                     /* This list is not NULL, add current timer to the end. */
155                     next_timer =                                        *timer_list;
156                     previous_timer =                                    next_timer -> tx_timer_internal_active_previous;
157                     previous_timer -> tx_timer_internal_active_next =   timer_ptr;
158                     next_timer -> tx_timer_internal_active_previous =   timer_ptr;
159                     timer_ptr -> tx_timer_internal_active_next =        next_timer;
160                     timer_ptr -> tx_timer_internal_active_previous =    previous_timer;
161                 }
162 
163                 /* Setup list head pointer.  */
164                 timer_ptr -> tx_timer_internal_list_head =  timer_list;
165             }
166         }
167     }
168 }
169 
170 #endif
171