免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
1234下一页
最近访问板块 发新帖
查看: 12723 | 回复: 37
打印 上一主题 下一主题

关于switch_to()这个函数的疑惑 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-04-17 19:48 |只看该作者 |倒序浏览
在看switch_to()这个函数的时候,有点疑惑,就是为什么第三个参数last要指向刚刚被切换掉的那个进程呢?
这样有什么用吗? 反正这个进程暂时就不用了,指向它有什么微妙之处吗?
谢谢.

论坛徽章:
0
2 [报告]
发表于 2007-04-17 19:59 |只看该作者

回复 #1 scutan 的帖子

哦.好像在调用中是这样的switch_to(prev, next, prev);
最后一个参数的作用是在调用了之后将第三个参数保存第一个参数的值,因此即使第一个参数的值改变了仍然可以通过第三个参数将这个值返回到调用switch_to()的函数中.
不知我这样分析是正确的吗? 望大家指教指教.

论坛徽章:
0
3 [报告]
发表于 2007-04-17 20:54 |只看该作者
你看的是2.4.0版吗?switch_to是宏,不是函数。23行的__switch_to才是函数,并且是个fast_call函数,这种函数的参数不在堆栈中,而在寄存器中。其中第一个参数在eax中,指向将被调离的进程。第二个参数在edx中,指向将被调入的进程。至于为何还要把被调离进程的PCB指针放入ebx,我就不清楚了,但应该不是你说的那个原因

论坛徽章:
0
4 [报告]
发表于 2007-04-17 21:04 |只看该作者

回复 #3 gta 的帖子

我开始说错了, 是宏, 不是函数.
好像这个宏在最开始进去的时候执行
movl prev, %eax
然后就去执行一系列的事情.到了最后再执行一次
movl %eax, last
将最开始保存的prev的值又传递给了last.
而last与prev在调用的时候是相同的, 所以其实prev在执行之后也是不变的. 不知是这样的吗?

论坛徽章:
0
5 [报告]
发表于 2007-04-17 21:35 |只看该作者
不是,switch_to执行完后,prev已不在指向原进程,而是指向新换入的进程。因为堆栈已被切换了

论坛徽章:
0
6 [报告]
发表于 2007-04-17 21:55 |只看该作者

回复 #5 gta 的帖子

switch_to()函数是这样被调用的
switch(prev, next, prev);
你的意思是说在执行完之后前一个prev的值已经变了. 而后一个prev的值没有变?
还是指这两个prev的值都变了?
还是前一个没变而后一个变了?

movl prev, %eax
movl %eax, last
是这样执行的吗: 即, prev先将值传给%eax, %eax然后变化了, 然后再将这个变化了的%eax传给last.

最后这个context_switch()返回的是prev这个指针. 那么这个指针在调用switch_to()之前和之后变化了吗?
对汇编不是太熟悉.见笑了. 望指教.
谢谢!

论坛徽章:
0
7 [报告]
发表于 2007-04-19 21:16 |只看该作者
在switch_to里面引用prev时,是从寄存器中取值,因此switch_to中的prev指向原进程的pcb。退出switch_to后,引用prev时,是从堆栈取值,而堆栈已在switch_to的20行被切换了,故此时的prev指向新换入的进程

论坛徽章:
16
2015亚冠之吉达阿赫利
日期:2015-08-17 11:21:462015年迎新春徽章
日期:2015-03-04 09:58:11酉鸡
日期:2014-12-07 09:06:19水瓶座
日期:2014-11-04 14:23:29天秤座
日期:2014-03-02 08:57:52双鱼座
日期:2014-02-22 13:07:56午马
日期:2014-02-14 11:08:18双鱼座
日期:2014-02-13 11:09:37卯兔
日期:2014-02-06 15:10:34子鼠
日期:2014-01-20 14:48:19戌狗
日期:2013-12-19 09:37:46射手座
日期:2013-12-19 09:33:47
8 [报告]
发表于 2011-10-17 08:52 |只看该作者
查看了一些资料,大家一致认为最后的prev指向的是之前的那个进程,但7楼的说法谁能解释下,eax是在新进程的堆栈中吗?

论坛徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技术图书徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44双子座
日期:2013-12-27 12:32:29双子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
9 [报告]
发表于 2011-10-17 09:00 |只看该作者
这个问题我以前思考过,发出来望大家指教:
        5. swtich_to(prev, next, last)宏与函数schedule()切换进程:
                1). prev为将要换出的进程描述符的地址,而当切换进程后prev进程恢复执行,prev被复用为last
                2). next为将要切换至的进程描述符的地址
                3). 均为prev进程的schedule()函数的局部变量

        movl prev, %eax                // prev保存在eax,即(%eax)代表prev->
        movl next, %edx                // next保存在edx,即(%edx)代表next->
       
        pushfl                        // 在prev的内核栈上保存了prev进程的eflags寄存器的值
        pushl %ebp                // 在prev的内核栈上保存了prev进程的ebp寄存器的值

        movl %esp,484(%eax)        // 将prev进程的esp寄存器值保存在了prev->thread.esp域(484为该域的offset)
        movl 484(%edx), %esp        // 将next->thread.esp域装载入了esp寄存器,从现在开始push,pop使用的将是next进程的内核栈

        movl $1f, 480(%eax)        // 将下次prev进程恢复执行的指令位置(prev->thread.eip域,480为该域offset)设置为标号1位置,请注意和下面2条指令对比起来思考
        pushl 480(%edx)                // 将next进程恢复执行的指令位置(next->thread.eip域)压入next进程的内核栈

        jmp _ _switch_to        // 直接跳转到__switch_to函数,请注意该函数返回时,返回地址为刚push的next->thread.eip,
                                // 即返回后就恢复next进程的执行(绝大多数是标号1位置),即next进程被切换时保存的恢复执行位置
1:
        popl %ebp                // 这里即是prev以后恢复执行的起始位置,也是(绝大部分情况)next进程从__switch_to函数返回后的位置.开始恢复以前压入的ebp
        popfl                        // 恢复eflags寄存器,请注意看第3,4条指令,是保存与恢复的对应

        movl %eax,last                // 将eax的值即prev保存到last

        // 针对最后条指令进行特别说明:此时运行的是next进程,典型的为在schedule()函数中
        // 局部变量prev与next(next进程中schedule()函数中的局部变量,为区分,暂且叫做prev_1与next_1)和prev,next将不是同一组值
        // 而是以前保存在next进程中的内核栈中的局部变量,现在为了和刚切换出的进程即prev相联系,将prev_1的值更新为prev(eax寄存器的值)
        // 即最后指令中的movl %eax,last中的last,由于schedule()函数中复用prev_1局部变量,因此switch_to宏将prev输出到了prev_1
        // 也就是说last是prev_1.(所以在汇编指令中看到的应该是movl %eax,prev_1)

论坛徽章:
0
10 [报告]
发表于 2011-10-17 09:09 |只看该作者
回复 9# asuka2001


    A->B  进程A进入睡眠。。。
    B->C
    C->A 进程A醒过来继续执行,这时在某些cpu上需要对上一个进程(C)做一些情理工作finish_task_switch

所以要获得C的信息。last参数就是这个作用。具体怎么传得看我的文档。

process-schedule.rar

106.04 KB, 下载次数: 437

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP