MIT6.828 HW5 CPU alarm

来源:互联网 发布:淘宝灰色退款思路 编辑:程序博客网 时间:2024/06/03 20:26

  在这次练习中,我们将为xv6增加1个特性支持周期性发警告给进程。这对计算敏感的进程很有帮助,限制他们CPU的使用时间,也让进程在计算的同时执行一些周期性任务。更通用地来说,我们将实现1个用户级别的中断异常处理。在这里会用到上次系统调用的实现机制。
  增加1个alarm(interval, handler)系统调用。当1个应用调用alarm(n, fn)时,那么每隔n个CPU时钟节拍,内核将使应用调用fn函数。当fn函数返回时,应用从调用处重新开始执行。
  用户测试的用户程序:

#include "types.h"#include "stat.h"#include "user.h"void periodic();intmain(int argc, char *argv[]){  int i;  printf(1, "alarmtest starting\n");  alarm(10, periodic);  for(i = 0; i < 50*500000; i++){    if((i++ % 500000) == 0)      write(2, ".", 1);  }  exit();}voidperiodic(){  printf(1, "alarm!\n");}

  期望的输出:(形式一致即可)

$ alarmtestalarmtest starting.....alarm!....alarm!.....alarm!......alarm!.....alarm!....alarm!....alarm!......alarm!.....alarm!...alarm!...$ 

  实现思路:
  1、按照添加系统调用的方式添加用户态调用程序、系统调用号和系统调用程序

//user.hint alarm(int ticks, void(*hander)());//usys.SSYSCALL(alarm)//Makefile    UPROGS:_alarmtest\ //syscall.h#define SYS_alarm 23//syscall.cextern int sys_alarm(void);//syscall.c syscalls[][SYS_alarm]   sys_alarm,//sysproc.cint    sys_alarm(void)    {      int ticks;      void (*handler)();      if(argint(0, &ticks) < 0)        return -1;      if(argptr(1, (char**)&handler, 1) < 0)        return -1;      proc->alarmticks = ticks;      proc->alarmhandler = handler;      return 0;    }

  2、在proc.c的proc结构体中添加变量记录总ticks、当前ticks和对应的handler

//struct procint alarmticks;int curalarmticks;void (*alarmhander)();
3、在trap.c中处理时钟中断添加handler
case T_IRQ0 + IRQ_TIMER:    if(cpu->id == 0){       acquire(&tickslock);       ticks++;      wakeup(&ticks);      release(&tickslock);    }      if(proc && (tf->cs & 3) == 3){        proc->curalarmtick++;        if(proc->alarmticks == proc->curalarmtick){  // 到达了周期          proc->curalarmtick = 0;    //下面两句将eip压栈          tf->esp -= 4;              *((uint *)(tf->esp)) = tf->eip;    // 将alarmhandler复制给eip,准备执行          tf->eip =(uint) proc->alarmhandler;        }      }    lapiceoi();    break;

  challenge部分:
  1、保存调用者的寄存器,当调用结束时恢复。由于调用的是无参数函数,故此只要保存EIP(返回地址)即可。
  2、防止重叠进入handler函数,即handler未处理完不该再调用handler,具体可以通过再添加1个变量表示是否已经进入handler。
  3、检查tf->esp的有效性,因为在调用handler时涉及对用户栈的操作,检查tf->esp所在页的有效性和权限。

  至此,本次HW就到此了。

0 0
原创粉丝点击