FreeCalypso > hg > freecalypso-sw
diff 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 |
line wrap: on
line diff
--- a/gsm-fw/gpf/osl/os_tim_fl.c Sun Jun 29 04:06:24 2014 +0000 +++ b/gsm-fw/gpf/osl/os_tim_fl.c Sun Jun 29 07:37:22 2014 +0000 @@ -1,6 +1,7 @@ /* * This C module is a reconstruction based on the disassembly of - * os_tim.obj in frame_na7_db_fl.lib from the Leonardo package. + * os_tim.obj in frame_na7_db_fl.lib from the Leonardo package, + * subsequently reworked by Space Falcon. */ /* set of included headers from COFF symtab: */ @@ -25,8 +26,8 @@ unsigned os_time_to_tick_multiplier = TIME_TO_TICK_TDMA_FRAME_MULTIPLIER; unsigned os_tick_to_time_multiplier = TICK_TO_TIME_TDMA_FRAME_MULTIPLIER; -unsigned t_start_ticks; -T_OS_TIMER_TABLE_ENTRY * volatile t_running; +unsigned volatile t_start_ticks; +T_OS_TIMER_TABLE_ENTRY *t_running; int used_timers; int next_t_handle; int volatile t_list_access; @@ -34,6 +35,8 @@ NU_SEMAPHORE TimSemCB; NU_TIMER os_timer_cb; +#define BARRIER asm volatile ("": : :"memory") + GLOBAL LONG os_set_tick(int os_system_tick) { @@ -117,40 +120,45 @@ os_QueryTimer(OS_HANDLE TaskHandle, OS_HANDLE TimerHandle, OS_TIME *RemainingTime) { - T_OS_TIMER_TABLE_ENTRY *timer, *t_r0, *t_r3; + T_OS_TIMER_TABLE_ENTRY *timer, *t_iter; OS_TICK c_ticks, r_ticks, e_ticks; STATUS sts; - t_list_access = 1; - if (TimerHandle > MaxSimultaneousTimer) { -error_out: t_list_access = 0; + if (TimerHandle > MaxSimultaneousTimer) + return(OS_ERROR); + sts = NU_Obtain_Semaphore(&TimSemCB, NU_SUSPEND); + timer = &TimerTable[TimerHandle].entry; + if (timer->status == TMR_FREE) { + if (sts == NU_SUCCESS) + NU_Release_Semaphore(&TimSemCB); return(OS_ERROR); } - timer = &TimerTable[TimerHandle].entry; - if (!timer->status) - goto error_out; - sts = NU_Obtain_Semaphore(&TimSemCB, NU_SUSPEND); - if (sts != NU_SUCCESS) - timer_error(15); + t_list_access = 1; + BARRIER; + if (!t_running) { + r_ticks = 0; + goto out; + } c_ticks = NU_Retrieve_Clock(); e_ticks = c_ticks - t_start_ticks; - t_r0 = t_running; - *RemainingTime = 0; - t_r3 = t_running; - if (t_r0 == t_r3) - r_ticks = t_r0->r_ticks - e_ticks; + t_iter = t_running; + if (t_iter->r_ticks >= e_ticks) + r_ticks = t_iter->r_ticks - e_ticks; else - r_ticks = t_r0->r_ticks; - while (t_r0 != timer) { - t_r0 = t_r0->next; - if (t_r0 == t_r3) + r_ticks = 0; + while (t_iter != timer) { + t_iter = t_iter->next; + if (t_iter == t_running) { + r_ticks = 0; goto out; - r_ticks += t_r0->r_ticks; + } + r_ticks += t_iter->r_ticks; } +out: BARRIER; + t_list_access = 0; + if (sts == NU_SUCCESS) + NU_Release_Semaphore(&TimSemCB); *RemainingTime = SYSTEM_TICKS_TO_TIME(r_ticks); -out: if (sts == NU_SUCCESS) - NU_Release_Semaphore(&TimSemCB); - t_list_access = 0; return(OS_OK); }