/* * uthread_switch() * * This is where all the magic is. Wait until there is a runnable thread, and * then switch to it using uthread_swapcontext(). Make sure you pick the * highest priority runnable thread to switch to. Also don't forget to take * care of setting the ON_CPU thread state and the current thread. Note that * it is okay to switch back to the calling thread if it is the highest * priority runnable thread. * * Every time uthread_switch() is called, uthread_idle() should be called at * least once. In addition, when there are no runnable threads, you should * repeatedly call uthread_idle() until there are runnable threads. Threads * with numerically higher priorities run first. For example, a thread with * priority 8 will run before one with priority 3. * */ void uthread_switch(void) { //we change the location of //the first thread: it might be put in runnable queue //or it might be just switched uthread_t * old_thr = ut_curthr; //check the state if( old_thr -> ut_state == UT_RUNNABLE){ //called by uthread_yield uthread_add_to_runnable_queue(old_thr); } else{ //wont add to the runnable queue } uthread_idle(); while(1){ //get the next runnable thread. //from highest priority queue to low priority queue int i = UTH_MAXPRIO; /* for(; i >= 0; i --){ printf("%d:%d\n", i, runq_table[i].tq_size); } i = UTH_MAXPRIO; */ uthread_t* next_thread = NULL; for(; i >= 0; i --){ if( !utqueue_empty(&runq_table[i])){ //printf("%d:%d\n", i, runq_table[i].tq_size); next_thread = utqueue_dequeue(&runq_table[i]); break; } } if(next_thread != NULL){ //switch! next_thread->ut_state = UT_ON_CPU; ut_curthr = next_thread; uthread_swapcontext(& old_thr -> ut_ctx, &ut_curthr -> ut_ctx); return; } //no runnable threads //TODO: Rewrtie uthread_idle else{ uthread_idle(); } } }
/* * uthread_switch() * * Wait until there is a runnable thread, and then switch to it using * uthread_swapcontext(). * */ void uthread_switch(void) { int i = 0; while (1) { uthread_idle(); for(i = UTH_MAXPRIO; i >= 0; i--) { if (!utqueue_empty(&runq_table[i])) { uthread_t* backup = ut_curthr; uthread_t* new_thread = utqueue_dequeue(&runq_table[i]); assert(new_thread->ut_state == UT_RUNNABLE); assert(new_thread->ut_link.l_prev == NULL && new_thread->ut_link.l_next == NULL); /* Swap the new thread */ ut_curthr = new_thread; ut_curthr->ut_state = UT_ON_CPU; /* Swap context */ uthread_swapcontext(&backup->ut_ctx, &ut_curthr->ut_ctx); return; } } } }