X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Ftime.c;h=478c41f3d1410070e3bea1ddd922f1fd5eab70e1;hb=14d0ba44433f0f828aff710184fd3c597ab73999;hp=449afcd94b0ac810464a4399821b0d298ab5a5f1;hpb=d0b4559f2936f6d9f06be0f7c3c51527a480ec0d;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/time.c b/KernelLand/Kernel/time.c index 449afcd9..478c41f3 100644 --- a/KernelLand/Kernel/time.c +++ b/KernelLand/Kernel/time.c @@ -74,20 +74,21 @@ void Timer_CallbackThread(void *Unused) */ void Timer_CallTimers() { + // Tick the random number generator every time timers are checked + rand(); + SHORTLOCK(&gTimers_ListLock); + LOG("gTimers = %p (%lli ms)", gTimers, (gTimers ? gTimers->FiresAfter : 0)); while( gTimers && gTimers->FiresAfter < now() ) { + ASSERT( gTimers != gTimers->Next ); // Get timer from list tTimer *timer = gTimers; - - ASSERT( gTimers != gTimers->Next ); gTimers = gTimers->Next; // Perform event if( timer->Callback ) { LOG("Callback schedule %p", timer); - // PROBLEM! Possibly causes rescheudle during interrupt -// Mutex_Acquire( &timer->Lock ); // Released once the callback fires Workqueue_AddWork(&gTimers_CallbackQueue, timer); } else { @@ -117,7 +118,8 @@ tTimer *Time_CreateTimer(int Delta, tTimerCallback *Callback, void *Argument) */ void Time_ScheduleTimer(tTimer *Timer, int Delta) { - tTimer *t, *p; + tTimer *t; + tTimer **prev_next; // Sanity checks if( !Timer ) return ; @@ -134,9 +136,10 @@ void Time_ScheduleTimer(tTimer *Timer, int Delta) // Add into list (sorted) SHORTLOCK(&gTimers_ListLock); // Mutex_Release( &Timer->Lock ); // Prevent deadlocks - for( p = (tTimer*)&gTimers, t = gTimers; t; p = t, t = t->Next ) + for( prev_next = &gTimers, t = gTimers; t; prev_next = &t->Next, t = t->Next ) { - ASSERT( p != t ); ASSERT( CheckMem(t, sizeof(tTimer)) ); + ASSERT( prev_next != &t->Next ); + ASSERT( CheckMem(t, sizeof(tTimer)) ); if( t == Timer ) { LOG("Double schedule - increasing delta"); @@ -147,9 +150,9 @@ void Time_ScheduleTimer(tTimer *Timer, int Delta) if( t->FiresAfter > Timer->FiresAfter ) break; } Timer->Next = t; - p->Next = Timer; + *prev_next = Timer; Timer->bActive = 1; - LOG(" %p %p %p", p, Timer, t); + LOG(" prev_next=%p Timer=%p next=%p", prev_next, Timer, t); SHORTREL(&gTimers_ListLock); } @@ -158,17 +161,19 @@ void Time_ScheduleTimer(tTimer *Timer, int Delta) */ void Time_RemoveTimer(tTimer *Timer) { - tTimer *t, *p; + tTimer *t; + tTimer **prev_next; if( !Timer ) return ; SHORTLOCK(&gTimers_ListLock); - for( p = (tTimer*)&gTimers, t = gTimers; t; p = t, t = t->Next ) + for( prev_next = &gTimers, t = gTimers; t; prev_next = &t->Next, t = t->Next ) { - ASSERT( p != t ); ASSERT( CheckMem(t, sizeof(tTimer)) ); + ASSERT( prev_next != &t->Next ); + ASSERT( CheckMem(t, sizeof(tTimer)) ); if( t == Timer ) { - p->Next = t->Next; + *prev_next = t->Next; break ; } } @@ -206,6 +211,7 @@ void Time_InitTimer(tTimer *Timer, tTimerCallback *Callback, void *Argument) Timer->Argument = Argument; // memset( &Timer->Lock, 0, sizeof(Timer->Lock) ); Timer->bActive = 0; + LOG("Initialised timer %p (cb=%p,arg=%p)", Timer, Callback, Argument); } /** @@ -226,15 +232,23 @@ void Time_FreeTimer(tTimer *Timer) LOG("%p deallocated %p", __builtin_return_address(0), Timer); } +void Time_ScheduleEvent(int Delay) +{ + tTimer *t = &Proc_GetCurThread()->ThreadTimer; + Time_RemoveTimer(t); + Time_InitTimer(t, NULL, NULL); + Time_ScheduleTimer(t, Delay); +} + /** * \fn void Time_Delay(int Delay) * \brief Delay for a small ammount of time */ void Time_Delay(int Delay) { - tTimer *t = &Proc_GetCurThread()->ThreadTimer; - Time_InitTimer(t, NULL, NULL); - Time_ScheduleTimer(t, Delay); + LOG("(%i)", Delay); + Threads_ClearEvent(THREAD_EVENT_TIMER); + Time_ScheduleEvent(Delay); Threads_WaitEvents(THREAD_EVENT_TIMER); }