switch_to 宏

static inline

task_t * context_switch(runqueue_t *rq, task_t *prev, task_t *next)

{

struct mm_struct *mm = next->mm;

struct mm_struct *oldmm = prev->active_mm;

 

if (unlikely(!mm)) {

next->active_mm = oldmm;

atomic_inc(&oldmm->mm_count);

enter_lazy_tlb(oldmm, next);

} else

switch_mm(oldmm, mm, next);

 

if (unlikely(!prev->mm)) {

prev->active_mm = NULL;

WARN_ON(rq->prev_mm);

rq->prev_mm = oldmm;

}

 

/* Here we just switch the register state and the stack. */

switch_to(prev, next, prev);

 

return prev;

}

 

可以看出进程切换

1.内存地址空间切换

2.register ,内核栈的切换

 

 

 

 

#define switch_to(prev,next,last) do { /

unsigned long esi,edi; /

asm volatile("pushfl/n/t" /

    "pushl %%ebp/n/t" /

    "movl %%esp,%0/n/t" /* save ESP */ /

    "movl %5,%%esp/n/t" /* restore ESP */ /

    "movl $1f,%1/n/t" /* save EIP */ /

    "pushl %6/n/t" /* restore EIP */ /

    "jmp __switch_to/n" /

    "1:/t" /

    "popl %%ebp/n/t" /

    "popfl" /

    :"=m" (prev->thread.esp),"=m" (prev->thread.eip), /

     "=a" (last),"=S" (esi),"=D" (edi) /

    :"m" (next->thread.esp),"m" (next->thread.eip), /

     "2" (prev), "d" (next)); /

} while (0)

1.将 eflags 压栈

2.将 内核栈地址压栈

3.指令指针压栈

切换前 将 prev 局部变量(内核栈内) 写 eax

切换后将 prev 赋值为 eax;

   c: prev =c,next =a;

   a: prev =a,next =b

切换后 

   a: prev =c,next=b

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值