首先來看一下要求和實現效果:
我們要增加一個系統調用 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
參考資料: