一、写在前面
在上一节中我们分析了List、ListElement和Thread三个类的数据成员和函数的执行过程,本节将继续分析thread包下的代码,重点在于理解scheduler和switch两个类的代码.
二、源码分析
1、调度器:Scheduler
class Scheduler {
public:
Scheduler(); // Initialize list of ready threads
~Scheduler(); // De-allocate ready list
void ReadyToRun(Thread* thread); // Thread can be dispatched.
Thread* FindNextToRun(); // Dequeue first thread on the ready
// list, if any, and return thread.
void Run(Thread* nextThread); // Cause nextThread to start running
void Print(); // Print contents of ready list
private:
List *readyList; // queue of threads that are ready to run,
// but not running
};
描述调度器的头文件scheduler.h中定义了Scheduler类的函数与数据成员,Scheduler唯一的数据成员是一个链表指针,该链表用于存放就绪的线程以供其进行调度.其中就绪的线程是指线程创建完毕并调用了Fork函数后或进程运行中调用了Yield函数后.
下面对Scheduler的函数进行简要的介绍:
- ReadyToRun:接收一个线程的指针,用于构造一个ListElement并将其存入就绪队列
- FindNextToRun:返回就绪队列中的首个ListElement中的数据成员(即指向某进程的指针)
- Run:接收一个线程的指针,剥夺当前线程的处理机并使该线程立刻执行
Scheduler::Scheduler()
{
readyList = new List;
}
Scheduler::~Scheduler()
{
delete readyList;
}
void
Scheduler::ReadyToRun (Thread *thread)
{
DEBUG('t', "Putting thread %s on ready list.\n", thread->getName());
thread->setStatus(READY);
readyList->Append((void *)thread);
}
Thread *
Scheduler::FindNextToRun ()
{
return (Thread *)readyList->Remove();
}
void
Scheduler::Run (Thread *nextThread)
{
Thread *oldThread = currentThread;
#ifdef USER_PROGRAM // ignore until running user programs
if (currentThread->space != NULL) { // if this thread is a user program,
currentThread->SaveUserState(); // save the user's CPU registers
currentThread->space->SaveState();
}
#endif
oldThread->CheckOverflow(); // check if the old thread
// had an undetected stack overflow
curren