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);
 }