盘算机构成原理(39): 分时之四——示例:定时器中缀处理
底下例子是定时器中缀处理步骤的事情办法,目标是使用定时器中缀来更新纪录在利用体系中的如今时间TOD(current Time of Day)数据值。
假定:定时器每1/60秒触发一次。
要求:
- 用户形式的使用步骤在有定时器中缀的情况下可以正常实行,无需举行任何特别处理。
- 定时器中缀会定期中缀使用步骤的运转,经过利用体系的中缀处理步骤来处理定时器中缀事变,处理完成后,规复实行用户形式的使用步骤。
- 假如用户步骤必要拜候TOD,它会向利用体系里的该步骤发射得当的办事哀求。
- 利用体系中的时钟处理步骤代码以少数的汇编言语开头和完毕(保存和规复形态的代码),在正中,汇编代码举行C历程调用以实践处理中缀。
中缀处理步骤代码如下(用C言语编写)
long TimeOfDay;
struct Mstate{ int Regs[31];} UserMstate;
/* Execute 60 times/Sec */
Clock_handler() {
TimeOfDay = TimeOfDay + 1;
if ( TimeOfDay % QUANTUM == 0) Scheduler();
}
在上述代码中,我们找到了TOD数据值的声明TimeOfDay,已暂且保存的历程形态UserMstate ,另有效于增长TOD值的C历程Clock_handler()。
定时器中缀处理步骤代码(用汇编编写)
定时器中缀在地点0x80000008实行BR()指令,该指令跳转到实践地点Clock_h处的中缀处理步骤代码。
Clock_h:
ST (r0, UserMstate) // save interrupted App State
ST (r1, UserMstate+4)
ST (r2, UserMstate+8)
...
ST (r31, UserMstate+30*4)
LD (KStack, SP) // use KERNEL SP
BR (Clock_handler, lp) // call Handler
LD (UserMstate, r0) // restore interrupted App State
LD (UserMstate+4, r1)
LD (UserMstate+8, r2)
...
LD (UserMstate+30*4,r31)
SUBC (XP, 4, XP) // set interrupted App breakpoint
JMP (XP) // return interrupted App
上述代码
- 起首保存被中缀的用户形式下的历程形态,将CPU存放器R0~R31 的值保存到数据布局UserMState中,由于存放器R31的值一直为0,以是保存不保存无所谓
- 设置内核形式堆栈指针后,汇编言语调用C历程Clock_handler()处理繁复的事情
- 完成历程调用后,将保存的历程形态重新加载到CPU存放器
- 设置被中缀的断点指针XP XP-4
- 经过JMP(XP)前往被中缀的使用步骤。
简便的分时调治器
在定时器中缀处理步骤代码中调用了C历程Clock_handler() 。
C历程Clock_handler()中:
每中缀一次,TOD值加1。
另有一个利用体系的例程(routine) Scheduler()调用。在中缀处理中,假如我们想每2次定时器中缀调用一次例程 ,我们将常量QUANTUM设置为2。
例程Scheduler()是举行分时的场合。一个简便的分时调治器代码如下:
struct Mstate{ int Regs[31];} UserMstate;
struct PCB { // Process Control Block
struct Mstate state; // Process State
struct Context PageMap; // MMU state for Process
int DPYNum; // Console number (and other I/O state)
} ProcTbl[N] // one per process
int Cur; // index of "Active" process
Scheduler() {
ProcTbl[Cur].state = User; // Save Cur state
Cur = (Cur + 1)%N; // Increase mod N
User = ProcTbl[Cur].state; // Install state for next user
LoadUserContext(ProcTbl[Cur].PageMap); // Install context
}
上述代码中:
- UserMstate以前在中缀处理步骤中举行了保存。
- 接着界说了一系列历程控制块PCB(Process Control Block)的数据布局,在体系中的每个历程1个PCB。如今正在实行其他历程时,PCB会保存该历程的完备形态——这是历程形态的长时存储。它包含了 的抄本、MMU形态以及历程的I/O活动干系的种种形态(这里用了一个数字表现,该数字指示了历程毗连了哪个假造用户界面控制台。
- 变量Cur为如今活动历程的索引,为如今正在运转的历程提供历程表ProcTbl的索引.
- 最初是完因素时共享调治器Scheduler()的十分简便的代码。每当调用例程时,它就开头将如今的历程形态保存,接着递增到下一个历程,%N是在N个用户历程中循环,规复下一个历程的CPU形态,MMU形态(上下文)。