hw5 cpu alarm
目标
这次hw向xv6添加一个功能,以便在进程使用CPU时,定时提醒进程.这对计算敏感的进程很有帮助,限制他们CPU的使用时间,也让进程在计算的同时执行一些周期性任务.更通用来说来说,我们将实现1个用户级别的中断异常处理.
在这里会用到上次系统调用的实现机制.即增加1个alarm(interval, handler)
系统调用.当1个应用调用alarm(n, fn)
时,那么每隔n个CPU时钟节拍,内核将使应用调用fn
函数.当fn
函数返回时,应用从调用地址重新开始执行.
测试程序alarmtest.c
1 |
|
其调用alarm(10, periodic)
, 使得内核每隔10个tick调用一次periodic
.输出形式如下:1
2
3
4
5
6
7
8
9
10
11
12
13$alarmtest
alarmtest starting
.....alarm!
....alarm!
.....alarm!
......alarm!
.....alarm!
....alarm!
....alarm!
......alarm!
.....alarm!
...alarm!
...$
实现
实现步骤:
1.参照hw3 system call,按照添加系统调用的方式添加用户态调用程序、系统调用号和系统调用程序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 //user.h
int alarm(int ticks, void(*hander)());
//usys.S
SYSCALL(alarm)
//Makefile UPROGS:
_alarmtest\
//syscall.h
//syscall.c
extern int sys_alarm(void);
//syscall.c syscalls[]
[SYS_alarm] sys_alarm,
//sysproc.c
int
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
1
2
3
4 //struct proc
int alarmticks;
int curalarmticks;
void (*alarmhander)();
3.在
trap.c
中处理时钟中断添加handler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 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){ // tick到达了周期
proc->curalarmtick = 0;
//将eip压栈
tf->esp -= 4;
*((uint *)(tf->esp)) = tf->eip;
// 拷贝alarmhandler给eip,准备执行
tf->eip =(uint) proc->alarmhandler;
}
}
lapiceoi();
break;
`