zoukankan      html  css  js  c++  java
  • MIT 6.828 JOS/XV6 LAB4-partC

    这一部分要实现抢占式调度和进程间通信

    前面的调度是进程资源放弃CPU,但是实际中没有进程会这样做的,而为了不让某一进程耗尽CPU资源,需要抢占式调度,也就需要硬件定时

    但是外部硬件定时在Bootloader的时候就关闭了,至今都没有开启

    而JOS采取的策略是,在内核中的时候,外部中断是始终关闭的,而在用户态的时候,需要开启中断

    所以首先需要求改IDT,但是我在之前把256个都弄好了

    所以现在只需要在进入用户态的时候,保证外部中断是使能的就可以了,为了做到这一点,可以在每个进程初始化的时候就将外部中断使能位置位

    在kern/env.c的env_alloc中

    clip_image001

    现在虽然中断使能已经打开,在用户态进程运行的时候,外部中断会产生并进入内核,但是现在还没有能处理这类中断

    所以需要修改trap_dispatch,在发生外部定时中断的时候,调用调度器,调度另外一个可运行的进程

    clip_image002

    在跑make run-spin的时候,总是遇到bug,发现父进程调用sys_env_destroy没能把子进程杀死

    找了半天,发现传入sys_env_destroy的参数是子进程的进程id,而在内核的系统调用sys_env_destroy中,却莫名其妙的变成了父进程的进程id,最后发现是syscall函数写错了

    clip_image003

    这一句的参数应该是a1,我却写成了curenv->env_id

    这个问题显然是自lab3就有的,但是到现在才发现是错的,而且之前一直没有出错。。。

    实现IPC

    IPC是计算机系统中非常重要的一部分,而JOS选择了一种看起来挺别扭的方法来实现

    两个进程需要通信的话,一方要发起recv,然后阻塞,直到有一个进程调用send向正在接受的进程发送了信息,阻塞的进程才会被唤醒

    而JOS中,可以允许传递两种信息,一是一个32位整数,另外一个就是传递页的映射,在这个过程中,接收方和发送方将同时映射到一个相同的物理页,此时也就实现了内存共享

    然后将这两个功能实现在了同一个系统调用中

    首先看内核中的sys_ipc_recv函数。当一个进程试图去接收信息的时候,应该将自己标记为正在接收信息,而且为了不浪费CPU资源,应该同时标记自己为ENV_NOT_RUNNABLE,只有当有进程向自己发了信息之后,才会重新恢复可运行

    clip_image004

    将自己标记为不可运行之后,调用调度器运行其他进程

    而内核中的sys_ipc_try_send的实现则相对来说麻烦很多,因为有很多的检测项,包括权限是否符合要求,要传送的页有没有,能不能将这一页映射到对方页表中去等等

    clip_image005

    如果srcva是在UTOP之下,那么说明是要共享内存,那就首先要在发送方的页表中找到srcva对应的页表项,然后在接收方给定的虚地址处插入这个页表项

    接收完成之后,重新将当前进程设置为可运行,同时把env_ipc_recving设置为0,以防止其他的进程再发送,覆盖掉当前的内容

    以上的两个函数都是系统调用,而在用户态下的函数调用需要另外实现

    clip_image006

    clip_image007

    至此,整个lab4就实现完成了,好累。。。

  • 相关阅读:
    HDU
    【JZOJ1252】【洛谷P5194】天平【搜索】
    【JZOJ1252】【洛谷P5194】天平【搜索】
    【JZOJ3896】战争游戏【割点】
    【JZOJ3896】战争游戏【割点】
    【JZOJ3895】数字对【ST表】
    【JZOJ3895】数字对【ST表】
    【JZOJ3894】改造二叉树【树】【LIS】
    【JZOJ3894】改造二叉树【树】【LIS】
    【洛谷P4014】【网络流24题】分配问题【费用流】
  • 原文地址:https://www.cnblogs.com/bdhmwz/p/5105352.html
Copyright © 2011-2022 走看看