当前位置: 首页 > news >正文

站长基地gif网站素材深圳宝安区好不好

站长基地gif网站素材,深圳宝安区好不好,怎样申请自己的网址,怎样建免费个人网站首发公号#xff1a;Rand_cs 本文讲述 xv6 中的一些细节流程#xff0c;还有对之前文中遗留的问题做一些补充说明#xff0c;主要有以下几个问题#xff1a; 一次完整的磁盘中断流程进入调度器后的详细流程sched 函数中的条件判断scheduler 函数中为什么要周期性关中断 …首发公号Rand_cs 本文讲述 xv6 中的一些细节流程还有对之前文中遗留的问题做一些补充说明主要有以下几个问题 一次完整的磁盘中断流程进入调度器后的详细流程sched 函数中的条件判断scheduler 函数中为什么要周期性关中断 一次完整的磁盘流程 此节讲述完整的磁盘读写流程读写的流程总体差不多这里以读为例子先看“流程图”看代码时的笔记图 readint $T_SYSCALLsys_readfilereadreadibreadbgetiderwidestart还是从 A 进程的用户态 read 函数开始 A 进程用户态调用 read 读取磁盘上的数据read 通过 INT 0x80 软件中断通过中断门进入内核此时会关中断NOTE 这里我以中断门来实现系统调用为例会关中断xv6 源代码是以陷阱门实现系统调用不会关中断期间多次取锁放锁进行了多次 pushcli 和 popcli但总是成对存在所以目前总体还是处于 0 次 puchcli 状态如果磁盘数据没有缓存调用 iderw 来读写磁盘 A 进程内核态iderw 函数 acquire(idelock)获取磁盘锁pushclicpu.IF 01 次pushcli 状态调用 idestart将要读写的命令扇区号等信息写进磁盘端口以此来请求磁盘操作。写磁盘端口是通过 out 指令实现的。向磁盘发送命令后磁盘就会工作磁盘完成工作后就会向 cpu 发送中断信号。A 进程调用 sleep 等待磁盘操作完成。在 sleep 函数中获取 ptable.lock释放 idelock然后调用 sched 让出 by the way这里补充说明 sched 函数中的条件检查之前的文章都一笔带过了 void sched(void) //让出CPU重新调度 {int intena;struct proc *p myproc();if(!holding(ptable.lock)) // 必须持有 ptable.lockpanic(sched ptable.lock);if(mycpu()-ncli ! 1) // 1 次 pushcli 状态panic(sched locks);if(p-state RUNNING) // 只可能是 SLEEPING、RUNNABLE、ZOMBIE 三种状态之一panic(sched running);if(readeflags()FL_IF) // 此时肯定处于关中断状态(通过中断门进入内核会关中断1次pushcli状态也应该对应关中断状态)panic(sched interruptible);intena mycpu()-intena;swtch(p-context, mycpu()-scheduler);mycpu()-intena intena; }sched 函数中有 4 个条件检查 xv6 是个多 CPU 多任务系统在 sched 任务调度的时候需要持有 ptable.lock不然进程的上下文会发生紊乱举个简单的例子A 时间片到了先将 A 的状态设置为 RUNNABLE然后调用 sched 让出 CPU如果此时没有持有 ptable.lock那么 A 进程便可能在另一个 CPU 上被调度那么便出现一个进程在两 CPU 上运行的情况Error在 sched 函数中应当只有 1 次 pushcli 状态这个条件检查感觉有点难以理解。从实践看代码确实不管从哪条路径到达 sched 函数都应该只有 1 次 pushcli这是获取 ptable.lock 的锁造成的。从个人理解上说sched 是为了调度进程是要从 A 进程到 B 进程那么 A 进程的开关中断(pushcli popcli 次数)不应该带入 B 进程除了一种情况——调度那就是 A 进程获取 ptable.lock 但是要在 B 进程中释放 ptable.lock。所以 sched 中应当只有 1 次 pushcli在真正切换进程上下文之前会首先修改旧进程的状态在 xv6 中是 SLEEPING、RUNNABLE、ZOMBIE 三种之一在 sched 中理应处于关中断状态如果是通过中断门进入内核的那么本身就处于关中断。如果是通过陷阱门进入内核那么有 1 次 pushcli也会处于关中断状态 回到磁盘中断当 A 进程调用 sched 切换到 B 进程这里假如 B 进程最初是因为时间片到了调用 yield-sched-swtch 主动让出 CPU 的则 B 进程的流程如下 回到 B 进程 sched 函数中的 swtch 下一条指令处然后释放 ptable.lock此时 cpu.IF 00 次 pushcli 状态cpu.IF 0 仍然处于关中断状态 是因为 A 进程通过中断门进入内核关中断造成的B 进程经过一些列指令后最后执行 iret 返回 B 进程的用户态此时会开中断NOTE这里我们假设 CPU 内部逻辑每条指令执行后都会检查是否有中断发生如果有中断发生且开中断的情况下则去处理中断。再假设此前的磁盘操作已完成已经向 CPU 发生了中断信号。但是在此之前 CPU 一直没有去处理中断是因为在此之前一直处于关中断状态。NowCPU 处于开中断状态继续执行 B 进程的指令开中断后的第一条指令执行完成后检查是否有中断发生发现有磁盘中断那么中断 B 进程通过中断门进入内核(该过程关中断)执行磁盘中断处理程序也就是执行 insl 指令从 0x1f0 端口将磁盘数据读取到内存然后唤醒等待该磁盘事件的进程在我们的例子当中就是 A 进程中断执行完成iret 返回 B 进程用户态(该过程开中断)继续执行 B 进程的指令时钟中断 B 进程再次通过中断门进入内核(关中断)发现 B 进程的时间片到了那么调用 yield-sched-swtch 重新调度进程这里假设调度到 A 进程 回到 A 进程的内核态准确来说回到 iderw-sleep-sched-swtch 的下一条指令 A 进程执行 release(ptable.lock)、acquire(idelock)、release(idelock)此时状态 cpu.IF 00 次 pushcli将磁盘中断获取的数据 cp 到 A 进程内核态A 进程层层返回最后 iret 返回 A 进程用户态(开中断) 系统启动进入调度器后的流程 mainuserinit //准备好 initcode 进程mpmainscheduler // 进入调度器调度器上下文 第一次进入 schedulerfor 循环找到 RUNNABLE 进程目前就只有一个 initcode 进程为 RUNNABLE 进程找到并切换上下文到 initcode 进程 initcode 进程上下文 执行 forkret 函数因为是第一次执行会首先执行 iinit 来初始化根文件系统执行 readsb 从磁盘中读取超级块数据期间会使用 iderw 读写磁盘具体流程见第一小节。总之initcode 进程会调用 sleep 函数让出 CPU 来等待磁盘操作在 sleep-sched-swtch 中再次切换上下文到 调度器上下文 调度器上下文 切换到内核页表然后遍历任务队列寻找 RUNNABLE 进程但是目前只有一个且处于 SLEEPING 状态的进程所以这里调度器会轮询空转直到磁盘中断处理完成initcode 进程被唤醒。再次切换上下文到 initcode 进程 initcode 进程上下文 回到 forkret-iinit-readsb-bread-iderw-sleep-sched-swtch 的下一条指令处然后层层返回到 forkret再执行 initlog 恢复日志这里会涉及到两次磁盘读写道理同上不再赘述第 4 次调度到 initcode 进程后forkret 函数执行完毕再执行 trapret 函数其中包含了 iret 指令至此回到用户态开始执行 initcode 进程的逻辑 by the way again这里解释为什么在 scheduler 函数中需要周期性的开中断 void scheduler(void) {for(;;){sti(); // 周期性开中断for(p ptable.proc; p ptable.proc[NPROC]; p){ //循环找一个RUNNABLE进程...}} }进入调度器上下文有两条路径 系统刚启动进入 schedulersched 函数中 swtch 上下文到调度器 回想前面说的 sched 函数在它切换到新进程并返回用户态之前理应都处于关中断的状态。而一直处于关中断且没有开中断的话会引发死循环。 举个例子假设没有周期性的开中断也就是 scheduler 代码长这样的话 void scheduler(void) {for(;;){// 遍历进程列表寻找 RUNNABLE 进程for(p ptable.proc; p ptable.proc[NPROC]; p){...}} }假如当前系统只有一个进程shell进程它需要等待键盘输入而被阻塞(stateSLEEPING)内层循环是找不到 RUNNABLE 进程的便回到外层循环外层循环现在相当于什么也不做便又再次进入内层循环。如此下来死循环。 而加入周期性的开中断后CPU 便会响应中断。当有键盘输入时中断当前的调度上下文而进入中断上下文执行键盘中断处理程序唤醒 shell 进程中断处理完成后再回到调度上下文。此时内层循环便能找到一个 RUNNABLE 进程然后切换到它的上下文执行。 本文就先补充这么多吧这补充系列的文章是之前做了关于 xv6、nemu 的项目将 xv6 启动到 nemu 上这需要对很多地方细扣对 xv6 的理解又增加了一些分享出来。 停更这么久啊一直再忙工作学习新的东西时间不是很多当然也有懒的原因后面慢慢克服回归吧。OK那有什么问题欢迎来讨论交流。 首发公号Rand_cs
http://www.w-s-a.com/news/869086/

相关文章:

  • 企业网站首页学生做的网站成品
  • 网站开发 架构设计企业信息管理系统的组成不包括
  • 网站维护模式网页传奇游戏平台排行
  • 企业网站改自适应蛋糕方案网站建设
  • 网站开发技术职责网站升级中html
  • 天网网站建设百度权重高的网站
  • 明年做哪些网站致富网站站长 感受
  • 东莞营销网站建设优化怎么做微信网站推广
  • 网站建设一个多少钱php网站服务器怎么来
  • 引流用的电影网站怎么做2012服务器如何做网站
  • 什么网站可以做推广广州安全信息教育平台
  • 网站开发具备的相关知识wordpress简约文字主题
  • asp网站伪静态文件下载seo外包公司哪家好
  • 淘宝客网站根目录怎么建个废品网站
  • 网站备案更改需要多久百度免费网站空间
  • 外发加工是否有专门的网站wordpress主页 摘要
  • 企业网站优化系统浙江建设信息港证书查询
  • 很多年前的51网站如何做跨境电商需要哪些条件
  • 网站建设中 请稍后访问互联网营销设计
  • 软文网站名称用户浏览网站的方式
  • 大兴模版网站搭建哪家好网站建设与管理管理课程
  • 四川成都网站制作微信广告平台推广
  • 网站价格网页制作网站开发实训步骤
  • cms 导航网站鹤壁做网站价格
  • 微信营销软件免费版郑州关键词优化费用
  • 邢台专业做网站哪家好临沂网站建设中企动力
  • 建设网站是主营成本吗wordpress 后台
  • 猎头可以做单的网站企业网站建设
  • 建小程序需要网站吗在putty上怎样安装wordpress
  • 天津智能网站建设找哪家WordPress相册插件pro