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 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
| #define SYS_alarm 24
int alarm(int ticks, void (*handler)());
SYSCALL(alarm)
extern int sys_alarm(void); [SYS_alarm] sys_alarm, [SYS_alarm] "alarm",
int alarmticks; int alarmticksleft; void (*alarmhandler)(); int alarm_in_handler; uint alarm_eip; struct trapframe *alarm_tf;
p->alarmticks = 0; p->alarmticksleft = 0; p->alarmhandler = 0; p->alarm_in_handler = 0; p->alarm_eip = 0; p->alarm_tf = 0; np->alarmticks = curproc->alarmticks; np->alarmticksleft = curproc->alarmticksleft; np->alarmhandler = curproc->alarmhandler; np->alarm_in_handler = 0; np->alarm_eip = 0; np->alarm_tf = 0;
int sys_alarm(void) { int ticks; void (*handler)(); if(argint(0, &ticks) < 0) return -1; if(argptr(1, (char**)&handler, 1) < 0) return -1; cprintf("sys_alarm: ticks=%d, handler=%x\n", ticks, (uint)handler);
curproc->alarmticks = ticks; curproc->alarmticksleft = ticks; curproc->alarmhandler = handler; curproc->alarm_in_handler = 0; curproc->alarm_eip = 0; return 0; }
if(myproc() != 0 && (tf->cs & 3) == 3){ struct proc *p = myproc(); if(p->alarmticks > 0 && p->alarm_in_handler == 0){ p->alarmticksleft--; if(p->alarmticksleft == 0){ p->alarmticksleft = p->alarmticks; p->alarm_in_handler = 1; if(p->alarm_tf == 0){ p->alarm_tf = (struct trapframe*)kalloc(); if(p->alarm_tf == 0){ panic("alarm: kalloc failed"); } } memmove(p->alarm_tf, tf, sizeof(struct trapframe));
p->alarm_eip = tf->eip; tf->eip = (uint)p->alarmhandler; } } } struct proc *p = myproc(); if(p != 0 && p->alarm_in_handler == 1 && p->alarm_eip != 0){ if(tf->eip != (uint)p->alarmhandler){ if(p->alarm_tf != 0){ memmove(tf, p->alarm_tf, sizeof(struct trapframe)); tf->eip = p->alarm_eip; kfree((char*)p->alarm_tf); p->alarm_tf = 0; } else { tf->eip = p->alarm_eip; } p->alarm_eip = 0; p->alarm_in_handler = 0; } }
|