1 /*************************************************************************** 2 * Copyright (c) 2024 Microsoft Corporation 3 * 4 * This program and the accompanying materials are made available under the 5 * terms of the MIT License which is available at 6 * https://opensource.org/licenses/MIT. 7 * 8 * SPDX-License-Identifier: MIT 9 **************************************************************************/ 10 11 12 /**************************************************************************/ 13 /**************************************************************************/ 14 /** */ 15 /** ThreadX Component */ 16 /** */ 17 /** Timer */ 18 /** */ 19 /**************************************************************************/ 20 /**************************************************************************/ 21 22 #define TX_SOURCE_CODE 23 24 #ifndef TX_NO_TIMER 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 /* 05-19-2020 William E. Lamie Initial Version 6.0 */ 72 /* 09-30-2020 Scott Larson Modified comment(s), and */ 73 /* opt out of function when */ 74 /* TX_NO_TIMER is defined, */ 75 /* resulting in version 6.1 */ 76 /* */ 77 /**************************************************************************/ _tx_timer_system_activate(TX_TIMER_INTERNAL * timer_ptr)78VOID _tx_timer_system_activate(TX_TIMER_INTERNAL *timer_ptr) 79 { 80 81 TX_TIMER_INTERNAL **timer_list; 82 TX_TIMER_INTERNAL *next_timer; 83 TX_TIMER_INTERNAL *previous_timer; 84 ULONG delta; 85 ULONG remaining_ticks; 86 ULONG expiration_time; 87 88 89 /* Pickup the remaining ticks. */ 90 remaining_ticks = timer_ptr -> tx_timer_internal_remaining_ticks; 91 92 /* Determine if there is a timer to activate. */ 93 if (remaining_ticks != ((ULONG) 0)) 94 { 95 96 /* Determine if the timer is set to wait forever. */ 97 if (remaining_ticks != TX_WAIT_FOREVER) 98 { 99 100 /* Valid timer activate request. */ 101 102 /* Determine if the timer still needs activation. */ 103 if (timer_ptr -> tx_timer_internal_list_head == TX_NULL) 104 { 105 106 /* Activate the timer. */ 107 108 /* Calculate the amount of time remaining for the timer. */ 109 if (remaining_ticks > TX_TIMER_ENTRIES) 110 { 111 112 /* Set expiration time to the maximum number of entries. */ 113 expiration_time = TX_TIMER_ENTRIES - ((ULONG) 1); 114 } 115 else 116 { 117 118 /* Timer value fits in the timer entries. */ 119 120 /* Set the expiration time. */ 121 expiration_time = (remaining_ticks - ((ULONG) 1)); 122 } 123 124 /* At this point, we are ready to put the timer on one of 125 the timer lists. */ 126 127 /* Calculate the proper place for the timer. */ 128 timer_list = TX_TIMER_POINTER_ADD(_tx_timer_current_ptr, expiration_time); 129 if (TX_TIMER_INDIRECT_TO_VOID_POINTER_CONVERT(timer_list) >= TX_TIMER_INDIRECT_TO_VOID_POINTER_CONVERT(_tx_timer_list_end)) 130 { 131 132 /* Wrap from the beginning of the list. */ 133 delta = TX_TIMER_POINTER_DIF(timer_list, _tx_timer_list_end); 134 timer_list = TX_TIMER_POINTER_ADD(_tx_timer_list_start, delta); 135 } 136 137 /* Now put the timer on this list. */ 138 if ((*timer_list) == TX_NULL) 139 { 140 141 /* This list is NULL, just put the new timer on it. */ 142 143 /* Setup the links in this timer. */ 144 timer_ptr -> tx_timer_internal_active_next = timer_ptr; 145 timer_ptr -> tx_timer_internal_active_previous = timer_ptr; 146 147 /* Setup the list head pointer. */ 148 *timer_list = timer_ptr; 149 } 150 else 151 { 152 153 /* This list is not NULL, add current timer to the end. */ 154 next_timer = *timer_list; 155 previous_timer = next_timer -> tx_timer_internal_active_previous; 156 previous_timer -> tx_timer_internal_active_next = timer_ptr; 157 next_timer -> tx_timer_internal_active_previous = timer_ptr; 158 timer_ptr -> tx_timer_internal_active_next = next_timer; 159 timer_ptr -> tx_timer_internal_active_previous = previous_timer; 160 } 161 162 /* Setup list head pointer. */ 163 timer_ptr -> tx_timer_internal_list_head = timer_list; 164 } 165 } 166 } 167 } 168 169 #endif 170