zoukankan      html  css  js  c++  java
  • 2020-2021-1 20209309闫兆森 《Linux内核原理与分析》第三周作业

    实验过程

    make

    粘贴代码

    修改代码

    make通过

    运行

    代码分析

    1. 启动进程0的关键代码:
    asm volatile(
        "movl %1,%%esp
    	" 	/* set task[pid].thread.sp to rsp */
        "pushl %1
    	" 	        /* push rbp */
        "pushl %0
    	" 	        /* push task[pid].thread.ip */
        "ret
    	" 	            /* pop task[pid].thread.ip to rip */
        : 
        : "c" (task[pid].thread.ip),"d" (task[pid].thread.sp)
    );
    

    由于这里是单线程的进程所以在调度的时候,实际是对单个线程环境维护(线程是调度的基本单位),也就是一个栈空间的sp与一个代码段的ip,在启动的时候该线程的栈空间是空的,所以对应之前的栈顶就是对应的栈底,并且栈顶等于栈底,而要想让其运行则需要将ip寄存器修改为对应线程的thread.ip,这里使用的是ret的方式,先将ip入栈之后ret设置。

    1. 进程调度的关键代码
    asm volatile(	
        "pushl %%ebp
    	"       /* save rbp of prev */
        "movl %%esp,%0
    	"     /* save rsp of prev */
        "movl %2,%%esp
    	"     /* restore  rsp of next */
        "movl $1f,%1
    	"       /* save rip of prev */	
        "pushl %3
    	" 
        "ret
    	" 	            /* restore  rip of next */
        "1:	"                  /* next process start here */
        "popl %%ebp
    	"
        : "=m" (prev->thread.sp),"=m" (prev->thread.ip)
        : "m" (next->thread.sp),"m" (next->thread.ip)
    ); 
    

    虽然是进程调度,但是实际处理的还是线程,将正在运行的线程数据保存,包括对栈底的保存(直接入栈),对栈顶的保存(存入对应的结构体),对ip的保存,这里区分了线程运行的状态,每一个运行过的线程都给了一个统一的标号点1,之后就是新运行线程环境的设置,对应设置其栈顶,使用ret的方式设置其ip位置,栈为空栈底等于栈底,并且这里每个线程都独享一个字符数组作为栈,每个栈底ebp对应在数组中的偏置位置是相同的。

    1. 小结

    这里虽然模拟了单线程进程的调度,实际在多线程进程中的调度也大致相同,都是对线程运行的环境进行一个维护,相同进程的线程之间的调度可以在同一个进程控制块内进行调整,不同进程之间的线程调度则需要进行跨进程的调度,需要去维护多个进程控制块的信息,同进程线程共享进程资源,所以其与不同进程的线程的调度相比而言要复杂一些,但是其大致的流程也都类似。

  • 相关阅读:
    前缀和-长度最小的子数组
    找到字符串中所有的字母异位词
    区间列表的交集
    比较含退格的字符串
    [转] ios数组基本用法和排序
    [转] 【iOS基础知识】之判断NSString是否为整数、浮点数
    解决resignFirstResponder或者endEditing无效的办法
    iOS 根据文字字数动态确定Label宽高
    [转] iOS开发-搜索栏UISearchBar和UISearchController
    UIActionSheet的最后一项点击失效
  • 原文地址:https://www.cnblogs.com/yanzs/p/13873844.html
Copyright © 2011-2022 走看看