• linux 内核的 switch_to原理


    switch_to:这是一个宏,有三个参数prev,next,last

    局部变量prev,next:指向进程描述符的内存地址

    首先明确的是:last和prev是同一个,用last只是为了理解方便,完全可以用两个参数prev,next。因为last就是prev

    switch_to宏用于进程切换,给定了前一个进程结构体指针prev,以及需要切换到的进程结构体指针next,从prev切换到next.
    但是,实际上,switch_to宏有三个参数,除了上面说的两个参数之外,还有一个last参数.而且使用switch_to宏的时候传入的prev和last都是同一个值,比如会这么调用这个宏:
    switch_to(prev,next,prev).

    这是为什么呢?

    考虑一种场景,进程A切换到进程B,因为每个进程的空间是不同的,所以在切换之前,进程A的空间里prev=A,next=B,last=A.
    一段时间之后,需要切换回到进程A,假设当前进程是C,那么对于C而言prev=C,next=A,last=C.

    对比前后两种场景:
    进程A切换前:prev=A,next=B,last=A
    进程C切换前:prev=C,next=A,last=C

    这时开始从进程C切换到进程A,注意到在切换之前switch_to宏将prev存放到了eax寄存器中,也就是在进程C切换到进程A之前,eax=C
    切换之后,很显然,来到了进程A的空间,因此prev,next,last指针要回到进程A被切换出去之前的指向,因此prev=A,next=B,last=A,而eax的数据保持不变(这是在eax的内容覆盖A进程的堆栈的prev之前的情况)
    在switch_to宏返回之前,将eax寄存器的数据存放到last中,因此,last=eax=C,其实也就是prev=C

       注意,在宏里面,出现last的地方实质上就是prev。

       当从C转回A的时候,A怎么知道它的上一个进程是哪一个呢?
        为了使你好理解,现在做如下假设:
        加入没有last这个参数,那么switch变成:switch_to(prev, next);
         这时候返回A进程后,prev指向它自己,next指向B,那么如何知道A的上一个进程是谁呢?就是不能够获取C的描述符。
        这时候我们加上last,switch_to(prev, next, prev);,最后一个参数是一个输出参数,那么当switch_to执行完毕后,prev就会变成进程C的描述符。
        这是通过movl %eax, last来实现的。
        关键的一点来了,为什么这个eax存的是C的描述符呢,这是由于在从C->A中的时候,movl prev, %eax,这个prev就是C。

       我个人认为这样做是为了便于理解,不然的话,switch_to(prev, next);也可以实现上述功能,直接把prev这个参数即当输入参数,又当输出参数就可以了。

  • 相关阅读:
    完全背包笔记
    渗透测试之信息收集常用网站
    结对项目-四则运算"软件"之升级版
    第三次作业:个人项目-小学四则运算“软件”之初版
    分布式版本控制系统Git的安装与使用
    第一次作业:准备
    爬虫综合大作业
    爬取全部校园新闻
    理解爬虫原理
    中文词频统计与词云生成
  • 原文地址:https://www.cnblogs.com/kkshaq/p/4433351.html
Copyright © 2020-2023  润新知