- 论坛徽章:
- 1
|
本帖最后由 seufy88 于 2017-01-01 11:00 编辑
第一个问题,已解决。- #define switch_to(prev,next,last) do { \
- asm volatile("pushl %%esi\n\t" \
- "pushl %%edi\n\t" \
- "pushl %%ebp\n\t" \
- "movl %%esp,%0\n\t" /* save ESP */ \
- "movl %3,%%esp\n\t" /* restore ESP */ \
- "movl $1f,%1\n\t" /* save EIP */ \
- "pushl %4\n\t" /* restore EIP */ \
- "jmp __switch_to\n" \
- "1:\t" \
- "popl %%ebp\n\t" \
- "popl %%edi\n\t" \
- "popl %%esi\n\t" \
- :"=m" (prev->thread.esp),"=m" (prev->thread.eip), \
- "=b" (last) \
- :"m" (next->thread.esp),"m" (next->thread.eip), \
- "a" (prev), "d" (next), \
- "b" (prev)); \
- } while (0)
复制代码 进程A切换到进程B,在内核栈从A变成B后,该嵌入汇编最后会将EBX寄存器的内容赋值给LAST变量,而EBX又是输入寄存器,在整个SWITCH过程中并不改,一直存放着PREV的内容,注意这里的PREV是进程A的内核栈上的内容。也就是进程A的current
在执行完SWITCH的最后,将EBX赋值给LAST变量,而由于内核栈已经切换到B,这里的LAST变量虽然也是栈上的局部变量,但已经是进程B栈上的了。
所以切换到B后,对B来讲PREV局部变量中已经是存放着上一个被切过来的进程A的TAKS_struct了。接着调用schedule_tail,传入RREV,将进程A的has_cpu清0,让进程A将来可以再次被调度。
|
|