Information Technology Reference
In-Depth Information
voidthread_yield()
{
//Makestacklooksimilartotheinterruptcase(e.g.,Fig. ?? )
pusheflags; //Pushprocessorexecutionflagsontostack
pushLABEL; //PushaddressofLABELinstruction(below)
//insteadofcurrentinstructionpointer.Inx86
//thepushedaddressneedstoincludeboththe
//codesegment(cs)andprogramcounter(eip).
pushad; //Pushgeneralpurposeregisters
//Copythecurrentthread'ssavedstatetoTCBdatastructure
memcopy(&(currentThread->TCB.savedRegisters),stackPointer,STATE_SIZE);
//ChooseanotherTCBfromthereadylist
chosenTCB=readyList->getNextThread();
//
//Restorestateofthechosenthread
//
//First,setstackpointertopointtoareaofTCBdatastructure
//thatstoresthesavedstate.Then,restoretherestofthe
//stateasifwewerejustpoppingitoffthestack.
stackPointer=&(chosenTCB->savedRegisters);
popad; //Popotherthread'sgeneralpurposeregisters
iret; //Popotherthread'sinstructionpointerandexecutionflags
//Thislineisneverexecuted!
assert(0);
//Whencallingthreadisresumed,itwillstarthere
LABEL:
return;
}
Figure4.12: Pseudo-code for threadyield() for in-kernel threads on x86
architecture.
3. Restore the state. Restore the next ready thread's registers so that it
can resume running where it left off.
As you can see, these steps are quite similar to the steps for an interrupt-
and exception-triggered thread context switch. This is no accident!
Example: threadyield() on x86. To make this software-based approach
concrete, Figure 4.12 shows pseudo-code for a simple implementation of
threadyield() for in-kernel threads for the x86 hardware architecture. A
thread calls threadyield() to voluntarily relinquish the processor to another
thread. The calling thread's registers are copied to its TCB on the ready queue,
and that thread resumes running later, when the scheduler chooses it.
In this code, the calling thread first saves its state to its stack. In our pseudo-
code we take care to ensure the stack we construct here looks like the one con-
structed when an interrupt triggers the context switch (Figure ?? on page ??).
So, we first push the x86 eflags register, which includes the mode bit (user v.
kernel) and a flag indicating whether interrupts are masked or enabled.
 
Search WWH ::




Custom Search