FreeCalypso > hg > freecalypso-sw
comparison gsm-fw/gpf/osl/os_tim_fl.c @ 482:9d80090a9e0c
os_tim_{fl,ir}.c: timer list concurrency interlocks redesigned
to something sensible
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sun, 29 Jun 2014 07:37:22 +0000 |
parents | 5639b4fa8672 |
children |
comparison
equal
deleted
inserted
replaced
481:5639b4fa8672 | 482:9d80090a9e0c |
---|---|
1 /* | 1 /* |
2 * This C module is a reconstruction based on the disassembly of | 2 * This C module is a reconstruction based on the disassembly of |
3 * os_tim.obj in frame_na7_db_fl.lib from the Leonardo package. | 3 * os_tim.obj in frame_na7_db_fl.lib from the Leonardo package, |
4 * subsequently reworked by Space Falcon. | |
4 */ | 5 */ |
5 | 6 |
6 /* set of included headers from COFF symtab: */ | 7 /* set of included headers from COFF symtab: */ |
7 #include <stdio.h> | 8 #include <stdio.h> |
8 #include "gpfconf.h" /* FreeCalypso addition */ | 9 #include "gpfconf.h" /* FreeCalypso addition */ |
23 extern void timer_error(int err); | 24 extern void timer_error(int err); |
24 | 25 |
25 unsigned os_time_to_tick_multiplier = TIME_TO_TICK_TDMA_FRAME_MULTIPLIER; | 26 unsigned os_time_to_tick_multiplier = TIME_TO_TICK_TDMA_FRAME_MULTIPLIER; |
26 unsigned os_tick_to_time_multiplier = TICK_TO_TIME_TDMA_FRAME_MULTIPLIER; | 27 unsigned os_tick_to_time_multiplier = TICK_TO_TIME_TDMA_FRAME_MULTIPLIER; |
27 | 28 |
28 unsigned t_start_ticks; | 29 unsigned volatile t_start_ticks; |
29 T_OS_TIMER_TABLE_ENTRY * volatile t_running; | 30 T_OS_TIMER_TABLE_ENTRY *t_running; |
30 int used_timers; | 31 int used_timers; |
31 int next_t_handle; | 32 int next_t_handle; |
32 int volatile t_list_access; | 33 int volatile t_list_access; |
33 int max_used_timers; | 34 int max_used_timers; |
34 NU_SEMAPHORE TimSemCB; | 35 NU_SEMAPHORE TimSemCB; |
35 NU_TIMER os_timer_cb; | 36 NU_TIMER os_timer_cb; |
37 | |
38 #define BARRIER asm volatile ("": : :"memory") | |
36 | 39 |
37 GLOBAL LONG | 40 GLOBAL LONG |
38 os_set_tick(int os_system_tick) | 41 os_set_tick(int os_system_tick) |
39 { | 42 { |
40 switch (os_system_tick) { | 43 switch (os_system_tick) { |
115 | 118 |
116 GLOBAL LONG | 119 GLOBAL LONG |
117 os_QueryTimer(OS_HANDLE TaskHandle, OS_HANDLE TimerHandle, | 120 os_QueryTimer(OS_HANDLE TaskHandle, OS_HANDLE TimerHandle, |
118 OS_TIME *RemainingTime) | 121 OS_TIME *RemainingTime) |
119 { | 122 { |
120 T_OS_TIMER_TABLE_ENTRY *timer, *t_r0, *t_r3; | 123 T_OS_TIMER_TABLE_ENTRY *timer, *t_iter; |
121 OS_TICK c_ticks, r_ticks, e_ticks; | 124 OS_TICK c_ticks, r_ticks, e_ticks; |
122 STATUS sts; | 125 STATUS sts; |
123 | 126 |
124 t_list_access = 1; | 127 if (TimerHandle > MaxSimultaneousTimer) |
125 if (TimerHandle > MaxSimultaneousTimer) { | 128 return(OS_ERROR); |
126 error_out: t_list_access = 0; | 129 sts = NU_Obtain_Semaphore(&TimSemCB, NU_SUSPEND); |
130 timer = &TimerTable[TimerHandle].entry; | |
131 if (timer->status == TMR_FREE) { | |
132 if (sts == NU_SUCCESS) | |
133 NU_Release_Semaphore(&TimSemCB); | |
127 return(OS_ERROR); | 134 return(OS_ERROR); |
128 } | 135 } |
129 timer = &TimerTable[TimerHandle].entry; | 136 t_list_access = 1; |
130 if (!timer->status) | 137 BARRIER; |
131 goto error_out; | 138 if (!t_running) { |
132 sts = NU_Obtain_Semaphore(&TimSemCB, NU_SUSPEND); | 139 r_ticks = 0; |
133 if (sts != NU_SUCCESS) | 140 goto out; |
134 timer_error(15); | 141 } |
135 c_ticks = NU_Retrieve_Clock(); | 142 c_ticks = NU_Retrieve_Clock(); |
136 e_ticks = c_ticks - t_start_ticks; | 143 e_ticks = c_ticks - t_start_ticks; |
137 t_r0 = t_running; | 144 t_iter = t_running; |
138 *RemainingTime = 0; | 145 if (t_iter->r_ticks >= e_ticks) |
139 t_r3 = t_running; | 146 r_ticks = t_iter->r_ticks - e_ticks; |
140 if (t_r0 == t_r3) | |
141 r_ticks = t_r0->r_ticks - e_ticks; | |
142 else | 147 else |
143 r_ticks = t_r0->r_ticks; | 148 r_ticks = 0; |
144 while (t_r0 != timer) { | 149 while (t_iter != timer) { |
145 t_r0 = t_r0->next; | 150 t_iter = t_iter->next; |
146 if (t_r0 == t_r3) | 151 if (t_iter == t_running) { |
152 r_ticks = 0; | |
147 goto out; | 153 goto out; |
148 r_ticks += t_r0->r_ticks; | 154 } |
155 r_ticks += t_iter->r_ticks; | |
149 } | 156 } |
157 out: BARRIER; | |
158 t_list_access = 0; | |
159 if (sts == NU_SUCCESS) | |
160 NU_Release_Semaphore(&TimSemCB); | |
150 *RemainingTime = SYSTEM_TICKS_TO_TIME(r_ticks); | 161 *RemainingTime = SYSTEM_TICKS_TO_TIME(r_ticks); |
151 out: if (sts == NU_SUCCESS) | |
152 NU_Release_Semaphore(&TimSemCB); | |
153 t_list_access = 0; | |
154 return(OS_OK); | 162 return(OS_OK); |
155 } | 163 } |
156 | 164 |
157 GLOBAL LONG | 165 GLOBAL LONG |
158 os_InactivityTicks(int *next_event, OS_TICK *next_event_ticks) | 166 os_InactivityTicks(int *next_event, OS_TICK *next_event_ticks) |