/**
* @author Kevin Klues <klueska@cs.stanford.edu>
*/
-
+
module TinyThreadSchedulerP {
provides {
interface ThreadScheduler;
while(TRUE) {
bool mt;
atomic mt = (call ThreadQueue.isEmpty(&ready_queue) == TRUE);
- if(!mt) break;
+ if(!mt || tos_thread->state == TOSTHREAD_STATE_READY) break;
call McuSleep.sleep();
}
}
*/
void scheduleNextThread() {
if(tos_thread->state == TOSTHREAD_STATE_READY)
- current_thread = call ThreadQueue.remove(&ready_queue, tos_thread);
+ current_thread = tos_thread;
else
current_thread = call ThreadQueue.dequeue(&ready_queue);
interrupt(thread);
}
+ void wakeupJoined(thread_t* t) {
+ int i,j,k;
+ k = 0;
+ for(i=0; i<sizeof(t->joinedOnMe); i++) {
+ 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;
num_runnable_threads--;
- for(i=0; i<TOSTHREAD_MAX_NUM_THREADS; i++) {
- if(call BitArrayUtils.getBit(t->joinedOnMe, i))
- call ThreadScheduler.wakeupThread(i);
- }
+ wakeupJoined(t);
#ifdef TOSTHREADS_TIMER_OPTIMIZATION
post alarmTask();
#else
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;
}
thread_t* t = call ThreadInfo.get[id]();
if((t->state) == TOSTHREAD_STATE_SUSPENDED) {
t->state = TOSTHREAD_STATE_READY;
- call ThreadQueue.enqueue(&ready_queue, call ThreadInfo.get[id]());
- #ifdef TOSTHREADS_TIMER_OPTIMIZATION
- atomic num_runnable_threads++;
- post alarmTask();
- #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;