X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=tos%2Flib%2Ftosthreads%2Fsystem%2FTinyThreadSchedulerP.nc;h=8466a9821513ef86e4987f450682b956b9b1322d;hb=f50b3e1320b358f1686b7fd440dc125e3c24c327;hp=45e63e703c06584e640a0fd52b74a34e185397d2;hpb=55a96adbb332e819532c8deb33505315eb275197;p=tinyos-2.x.git diff --git a/tos/lib/tosthreads/system/TinyThreadSchedulerP.nc b/tos/lib/tosthreads/system/TinyThreadSchedulerP.nc index 45e63e70..8466a982 100644 --- a/tos/lib/tosthreads/system/TinyThreadSchedulerP.nc +++ b/tos/lib/tosthreads/system/TinyThreadSchedulerP.nc @@ -32,7 +32,7 @@ /** * @author Kevin Klues */ - + module TinyThreadSchedulerP { provides { interface ThreadScheduler; @@ -61,16 +61,14 @@ implementation { //Thread queue for keeping track of threads waiting to run thread_queue_t ready_queue; -#ifdef TOSTHREADS_TIMER_OPTIMIZATION - void task timerTask() { + void task alarmTask() { uint8_t temp; atomic temp = num_runnable_threads; if(temp <= 1) call PreemptionAlarm.stop(); - if(temp > 1) + else if(temp > 1) call PreemptionAlarm.startOneShot(TOSTHREAD_PREEMPTION_PERIOD); } -#endif /* switch_threads() * This routine swaps the stack and allows a thread to run. @@ -140,30 +138,46 @@ implementation { void suspend(thread_t* thread) { //if there are no active threads, put the MCU to sleep //Then wakeup the TinyOS thread whenever the MCU wakes up again - #ifdef TOSTHREADS_TIMER_OPTIMIZATION + #ifdef TOSTHREADS_TIMER_OPTIMIZATION num_runnable_threads--; - post timerTask(); + post alarmTask(); #endif sleepWhileIdle(); interrupt(thread); } + void wakeupJoined(thread_t* t) { + int i,j,k; + k = 0; + for(i=0; ijoinedOnMe); i++) { + if(t->joinedOnMe[i] == 0) { + k+=8; + continue; + } + for(j=0; j<8; j++) { + if(t->joinedOnMe[i] & 0x1) + call ThreadScheduler.wakeupThread(k); + t->joinedOnMe[i] >>= 1; + k++; + } + } + } + /* stop * This routine stops a thread by putting it into the inactive state * and decrementing any necessary variables used to keep track of * threads by the thread scheduler. */ void stop(thread_t* t) { - int i; t->state = TOSTHREAD_STATE_INACTIVE; - #ifdef TOSTHREADS_TIMER_OPTIMIZATION - num_runnable_threads--; - post timerTask(); + num_runnable_threads--; + wakeupJoined(t); + #ifdef TOSTHREADS_TIMER_OPTIMIZATION + post alarmTask(); + #else + if(num_runnable_threads == 1) + call PreemptionAlarm.stop(); #endif - for(i=0; ijoinedOnMe, i)) - call ThreadScheduler.wakeupThread(i); - } signal ThreadCleanup.cleanup[t->id](); } @@ -209,12 +223,15 @@ implementation { atomic { thread_t* t = (call ThreadInfo.get[id]()); if(t->state == TOSTHREAD_STATE_INACTIVE) { + num_runnable_threads++; + #ifdef TOSTHREADS_TIMER_OPTIMIZATION + post alarmTask(); + #else + if(num_runnable_threads == 2) + call PreemptionAlarm.startOneShot(TOSTHREAD_PREEMPTION_PERIOD); + #endif t->state = TOSTHREAD_STATE_READY; call ThreadQueue.enqueue(&ready_queue, t); - #ifdef TOSTHREADS_TIMER_OPTIMIZATION - num_runnable_threads++; - post timerTask(); - #endif return SUCCESS; } } @@ -248,7 +265,8 @@ implementation { atomic { if(current_thread->state == TOSTHREAD_STATE_ACTIVE) { current_thread->state = TOSTHREAD_STATE_READY; - call ThreadQueue.enqueue(&ready_queue, current_thread); + if(current_thread != tos_thread) + call ThreadQueue.enqueue(&ready_queue, current_thread); interrupt(current_thread); return SUCCESS; } @@ -274,13 +292,13 @@ implementation { thread_t* t = call ThreadInfo.get[id](); if((t->state) == TOSTHREAD_STATE_SUSPENDED) { t->state = TOSTHREAD_STATE_READY; - if(t != tos_thread) { - call ThreadQueue.enqueue(&ready_queue, call ThreadInfo.get[id]()); - #ifdef TOSTHREADS_TIMER_OPTIMIZATION - atomic num_runnable_threads++; - post timerTask(); - #endif - } + if(t != tos_thread) { + call ThreadQueue.enqueue(&ready_queue, call ThreadInfo.get[id]()); + #ifdef TOSTHREADS_TIMER_OPTIMIZATION + atomic num_runnable_threads++; + post alarmTask(); + #endif + } return SUCCESS; } return FAIL; @@ -311,4 +329,3 @@ implementation { return NULL; } } -