一直认为线程的上下文保存与恢复是个神秘的过程,今天仔细阅读Nachos Study Book后,发现其理解起来也不是非常困难.
Nachos中线程的上下文环境,被定义在Thread.h中,上下文数据主要包括线程栈顶执行、线程下一条代执行执行地址、以及调用过程中用到的各个寄存器的值。这些数据的定义必须按指定位置,因为Nachos在线程切换时,会按预先指定的顺序操作线程上下文内存和寄存器。线程切换的上下文保存于恢复放在了Switch.h和Switch.s中,在Switch.h中定义了各个变量在线程上下文内存空间内的偏移地址(因为在此已经固定了变量的偏移地址,因此在线程中定义的变量顺序不能改变).具体的代码如下:
其中定义了SP即StackTop Point的编译地址为0,因此Thread必须将StackPoint作为第一个变量进行定义.接着定义了线程执行过程中的各个变量便宜地址,其中PC为线程下一条指令的便宜地址。
在Switch.s中,Nachos为各个寄存器定义了名称,代码如下:
其中将4号寄存器命名为a0,用来存放上一个线程的地址,将5号寄存器命名为a1,用来存放即将要执行的线程地址.将29号寄存器命名为sp用来存储栈顶指针、将31号寄存器命名为ra用来存放进行返回地址。
定义完这些数据后,下面我们来看具体的上下文保存于恢复方法:
上述代码主要涉及两条指令分别是sw和lw。sw的意思是将寄存器的内容,写到制定的内存空间中,lw的功能是从指定的内存空间中加载数据到寄存器中。上述代码的前半部分是将寄存器的内容,写到以a0为基址并指定偏移的内存中。后半部分是将基址为a1并指定偏移的内存数据加载到寄存器中,最后调用j ra执行即将执行的线程的下一条指令,从而切换到下一个线程中,进行执行。