/**
* @author Kevin Klues <klueska@cs.stanford.edu>
*/
-
+
module TinyThreadSchedulerP {
provides {
interface ThreadScheduler;
//Thread queue for keeping track of threads waiting to run
thread_queue_t ready_queue;
- 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);
}
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
- num_runnable_threads--;
- post timerTask();
+ #ifdef TOSTHREADS_TIMER_OPTIMIZATION
+ num_runnable_threads--;
+ post alarmTask();
+ #endif
sleepWhileIdle();
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--;
- post timerTask();
- for(i=0; i<TOSTHREAD_MAX_NUM_THREADS; i++) {
- if(call BitArrayUtils.getBit(t->joinedOnMe, i))
- call ThreadScheduler.wakeupThread(i);
- }
- signal ThreadCleanup.cleanup[t->id]();
- }
+ void stop(thread_t* t) {
+ t->state = TOSTHREAD_STATE_INACTIVE;
+ num_runnable_threads--;
+ wakeupJoined(t);
+ #ifdef TOSTHREADS_TIMER_OPTIMIZATION
+ post alarmTask();
+ #else
+ if(num_runnable_threads == 1)
+ call PreemptionAlarm.stop();
+ #endif
+ signal ThreadCleanup.cleanup[t->id]();
+ }
/* This executes and cleans up a thread
*/
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);
- num_runnable_threads++;
- post timerTask();
return SUCCESS;
}
}
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;
}
t->state = TOSTHREAD_STATE_READY;
if(t != tos_thread) {
call ThreadQueue.enqueue(&ready_queue, call ThreadInfo.get[id]());
- atomic num_runnable_threads++;
- post timerTask();
+ #ifdef TOSTHREADS_TIMER_OPTIMIZATION
+ atomic num_runnable_threads++;
+ post alarmTask();
+ #endif
}
return SUCCESS;
}
return NULL;
}
}
-