【归档】[OS] Xv6 CPU Alarm

首先来看一下要求和实现效果:

我们要增加一个系统调用 alarm(interval, handler) ,使CPU定时提醒进程。这对那些计算绑定的应用程序有用,这样可以监控他们消耗了多少CPU时间,或者是在计算的过程中可以做一些其他的事情。

添加测试命令

新建一个文件 alarmtest.c 并将一下代码写在里面:

#include "types.h"
#include "stat.h"
#include "user.h"

void periodic();

int main(int argc, char *argv[])
{
    int i;
    printf(1, "alarmtest starting\n");
    alarm(10, periodic);
    for (i = 0; i < 250 * 500000; i++)
    {
        if ((i % 250000) == 0)
            write(2, ".", 1);
    }
    exit();
}

void periodic()
{
    printf(1, "alarm!\n");
}

在所有的修改都完成后,运行 alarmtest 这个命令会有如下的输出结果(形式类似):

$ alarmtest
alarmtest starting
.....alarm!
....alarm!
.....alarm!
......alarm!
.....alarm!
....alarm!
....alarm!
......alarm!
.....alarm!
...alarm!
...$ 

为了将 alarmtest.c 编译成Xv6的用户程序,需要修改 Makefile ,在 UPROGS 中加入下面这一行:

_alarmtest\

添加系统调用

user.h 中添加:

int alarm(int ticks, void(*hander)());

usys.S 中添加:

SYSCALL(alarm)

syscall.h 中添加:

#define SYS_alarm  23

syscall.c 中添加:

...
  
extern int sys_alarm(void);

...
  
//static int (*syscalls[])(void) = {
        ...
        [SYS_alarm] sys_alarm,
//};

proc.h 的结构体 proc 中添加:

  int alarmticks;
  int curalarmticks;
  void (*alarmhandler)();

sysproc.c 中添加:

// cpu alarm
int
sys_alarm(void)
{
  int ticks;
  void (*handler)();

  if(argint(0, &ticks) < 0)
    return -1;
  if(argptr(1, (char**)&handler, 1) < 0)
    return -1;
  myproc()->alarmticks = ticks;
  myproc()->alarmhandler = handler;
  return 0;
}

以上,系统调用 alarm 就添加完成了。

下面,要添加中断处理:

中断处理

打开文件 trap.c ,在函数 void trap(struct trapframe *tf){} 中修改 case T_IRQ0 + IRQ_TIMER

  case T_IRQ0 + IRQ_TIMER:
    if(cpuid() == 0){
      acquire(&tickslock);
      ticks++;
      wakeup(&ticks);
      release(&tickslock);
    }
    if(myproc() && (tf->cs & 3) == 3){
        myproc()->curalarmticks++;
        if(myproc()->alarmticks == myproc()->curalarmticks){  // 到达了周期
            myproc()->curalarmticks = 0;

          //下面两句将eip压栈
          tf->esp -= 4;    
          *((uint *)(tf->esp)) = tf->eip;
          // 将alarmhandler复制给eip,准备执行
          tf->eip =(uint) myproc()->alarmhandler;
        }
      }
    lapiceoi();
    break;

至此,所有修改都已经完成了。

在Ubuntu下编译运行:

$ make CPUS=1 qemu-nox

其中, CPUS=1 是为了将执行速度变慢,以观察系统中断的执行

运行Xv6后,输入命令:

$ alarmtest

输出结果如下:

alarmtest starting
.....................................alarm!
...................................alarm!
...........................................alarm!
...........................................alarm!
..........................................alarm!
....................................alarm!
.....................................alarm!
.............................alarm!
...............................alarm!
.................................alarm!
...................................alarm!
..............................alarm!
.................................alarm!
..................................alarm!
..$ 

Bingo

参考资料:

Homework: xv6 CPU alarm

MIT6.828 HW5 CPU alarm

xv6之添加alarm CPU中断检测

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章