【歸檔】[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中斷檢測

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