内核级线程需要进入内核中,即在内核态跑,又在用户态跑:
需要使用两套栈。
用户栈和内核栈之间的关联:
具体工作流程:
五段论伪代码实现
用内核栈实现核心级线程切换
main() //main后面一行代码地址压入栈
{
A(); //B地址压入栈 跳到A地址执行
B();
}
A()
{
fork(); //mov %eax, __NR_fork
//int 0x80 ;0x80的中断处理函数是__system_call
//mov res, %eax
//__system_call:
// push %ds .. %fs ;刚进入内核态,要保存用户态的现场 SS:SP CS:IP
// pushl %edx ... ;诸多寄存器
// call sys_fork ;通过表table找到sys_fork
// pushl %eax
// movl __current, %eax ;PCB --> eax
// cmpl $0,state(%eax) ;PCB中的state是否为0
// jne reschedule ;不是0就切换 (非0意味着阻塞了,必须切换) 第2~4段
// cmpl $0,counter(%eax);PCB中counter(时间片)是否为0,如果时间片为0必须切换
// je reschedule
// ret_from_sys_call ;从中断返回 第五段
//reschedule:
// pushl $ret_from_sys_call
// jmp _schedule ;(C函数)
//void shedule(void) ;(C函数)
//{
// switch_to(next);
//}
//ret_from_sys_call: ;从中断返回 第五段
// popl %eax
// pop %fs
// iret
}