1 #include "u.h" 2 #include "../port/lib.h" 3 #include "mem.h" 4 #include "dat.h" 5 #include "fns.h" 6 7 static Alarms alarms; 8 static Rendez alarmr; 9 10 void alarmkproc(void *)11alarmkproc(void*) 12 { 13 Proc *rp; 14 ulong now; 15 16 for(;;){ 17 now = MACHP(0)->ticks; 18 qlock(&alarms); 19 /* 20 * the odd test of now vs. rp->alarm is to cope with 21 * now wrapping around. 22 */ 23 while((rp = alarms.head) && (long)(now - rp->alarm) >= 0){ 24 if(rp->alarm != 0L){ 25 if(canqlock(&rp->debug)){ 26 if(!waserror()){ 27 postnote(rp, 0, "alarm", NUser); 28 poperror(); 29 } 30 qunlock(&rp->debug); 31 rp->alarm = 0L; 32 }else 33 break; 34 } 35 alarms.head = rp->palarm; 36 } 37 qunlock(&alarms); 38 39 sleep(&alarmr, return0, 0); 40 } 41 } 42 43 /* 44 * called every clock tick 45 */ 46 void checkalarms(void)47checkalarms(void) 48 { 49 Proc *p; 50 ulong now; 51 52 p = alarms.head; 53 now = MACHP(0)->ticks; 54 55 if(p && (long)(now - p->alarm) >= 0) 56 wakeup(&alarmr); 57 } 58 59 ulong procalarm(ulong time)60procalarm(ulong time) 61 { 62 Proc **l, *f; 63 ulong when, old; 64 65 if(up->alarm) 66 old = tk2ms(up->alarm - MACHP(0)->ticks); 67 else 68 old = 0; 69 if(time == 0) { 70 up->alarm = 0; 71 return old; 72 } 73 when = ms2tk(time)+MACHP(0)->ticks; 74 if(when == 0) /* ticks have wrapped to 0? */ 75 when = 1; /* distinguish a wrapped alarm from no alarm */ 76 77 qlock(&alarms); 78 l = &alarms.head; 79 for(f = *l; f; f = f->palarm) { 80 if(up == f){ 81 *l = f->palarm; 82 break; 83 } 84 l = &f->palarm; 85 } 86 87 up->palarm = 0; 88 if(alarms.head) { 89 l = &alarms.head; 90 for(f = *l; f; f = f->palarm) { 91 if((long)(f->alarm - when) >= 0) { 92 up->palarm = f; 93 *l = up; 94 goto done; 95 } 96 l = &f->palarm; 97 } 98 *l = up; 99 } 100 else 101 alarms.head = up; 102 done: 103 up->alarm = when; 104 qunlock(&alarms); 105 106 return old; 107 } 108