免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3481 | 回复: 12

Linux进程调度的上下文保存问题 [复制链接]

论坛徽章:
0
发表于 2008-10-22 22:41 |显示全部楼层
进程调度的代码:
asmlinkage void __sched schedule(void)
{
     。。。。。。
   prev = context_switch(rq, prev, next);
    。。。。。。
}

static inline
task_t * context_switch(runqueue_t *rq, task_t *prev, task_t *next)
{
    。。。。。。
    /* Here we just switch the register state and the stack. */
    switch_to(prev, next, prev);

    return prev;
}

#define switch_to(prev,next,last) do {                                        \
        unsigned long esi,edi;                                                \
        asm volatile("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"                                        \
                     :"=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)

switch_to宏执行切换到另一个进程的处理。linux书上说执行切换的进程的普通寄存器保存在内核栈上。
switch_to宏有用到ebp\esi\edi\dx\,因此在context_switch调用switch_to前应该会保存这些寄存器的值。那么在从switch_to返回后调用return prev前会恢复这些寄存器的值,这样switch_to做的进程切换不会影响这些寄存器的值。
我的问题是ebx\ecx寄存器得值怎么恢复?难道ebx\ecx只能在函数内部使用吗?

论坛徽章:
0
发表于 2008-10-23 19:42 |显示全部楼层

回复 #1 biger410 的帖子

自己顶,望高手指点。

论坛徽章:
0
发表于 2008-10-23 21:00 |显示全部楼层
ebx\ecx寄存器 这个应该是压入了堆栈,执行完后弹出这些值。

论坛徽章:
0
发表于 2008-10-23 21:12 |显示全部楼层

回复 #3 可可熊 的帖子

编译器应该是函数用到那个寄存器才保存那个寄存器的吧,没用到的也保存很浪费效率。现在是context_switch没办法知道从switch_to切出去在切回来,是否有修改这两个寄存器的值。既然无法知道自然也就不保存了吧。

论坛徽章:
0
发表于 2008-10-23 21:17 |显示全部楼层

回复 #4 biger410 的帖子

gcc比较“聪明”,可以从上面的内联汇编中确定是否需要保存寄存器的值。

论坛徽章:
0
发表于 2008-10-23 22:46 |显示全部楼层
内联的汇编中没有那两个寄存器!

论坛徽章:
0
发表于 2008-10-23 22:49 |显示全部楼层
unsigned long esi,edi;           
这里定义成C变量了

论坛徽章:
0
发表于 2008-10-24 09:03 |显示全部楼层
反汇编看看编译后的代码是怎样?

论坛徽章:
0
发表于 2008-10-24 15:17 |显示全部楼层

回复 #8 qtdszws 的帖子

这里已经是汇编了。。

论坛徽章:
0
发表于 2008-10-26 20:38 |显示全部楼层
这个问题搞清楚了。如下:
ecx为调用者保存寄存器,在schedule调用context_switch的时候,如果必要肯定会保存ecx的值。而ebx为被调用者保存寄存器,因此context_switch肯定在
进入函数的时候会保存。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP