13e12c5d1SDavid du Colombier #include "u.h" 23e12c5d1SDavid du Colombier #include "../port/lib.h" 33e12c5d1SDavid du Colombier #include "mem.h" 43e12c5d1SDavid du Colombier #include "dat.h" 53e12c5d1SDavid du Colombier #include "fns.h" 63e12c5d1SDavid du Colombier 74b348146SDavid du Colombier static Alarms alarms; 84b348146SDavid du Colombier static Rendez alarmr; 93e12c5d1SDavid du Colombier 103e12c5d1SDavid du Colombier void alarmkproc(void *)117dd7cddfSDavid du Colombieralarmkproc(void*) 123e12c5d1SDavid du Colombier { 133e12c5d1SDavid du Colombier Proc *rp; 143e12c5d1SDavid du Colombier ulong now; 153e12c5d1SDavid du Colombier 163e12c5d1SDavid du Colombier for(;;){ 173e12c5d1SDavid du Colombier now = MACHP(0)->ticks; 183e12c5d1SDavid du Colombier qlock(&alarms); 19*6bbfed0dSDavid du Colombier /* 20*6bbfed0dSDavid du Colombier * the odd test of now vs. rp->alarm is to cope with 21*6bbfed0dSDavid du Colombier * now wrapping around. 22*6bbfed0dSDavid du Colombier */ 23*6bbfed0dSDavid du Colombier while((rp = alarms.head) && (long)(now - rp->alarm) >= 0){ 243e12c5d1SDavid du Colombier if(rp->alarm != 0L){ 257dd7cddfSDavid du Colombier if(canqlock(&rp->debug)){ 263e12c5d1SDavid du Colombier if(!waserror()){ 273e12c5d1SDavid du Colombier postnote(rp, 0, "alarm", NUser); 283e12c5d1SDavid du Colombier poperror(); 293e12c5d1SDavid du Colombier } 303e12c5d1SDavid du Colombier qunlock(&rp->debug); 313e12c5d1SDavid du Colombier rp->alarm = 0L; 327dd7cddfSDavid du Colombier }else 337dd7cddfSDavid du Colombier break; 343e12c5d1SDavid du Colombier } 353e12c5d1SDavid du Colombier alarms.head = rp->palarm; 363e12c5d1SDavid du Colombier } 373e12c5d1SDavid du Colombier qunlock(&alarms); 383e12c5d1SDavid du Colombier 393e12c5d1SDavid du Colombier sleep(&alarmr, return0, 0); 403e12c5d1SDavid du Colombier } 413e12c5d1SDavid du Colombier } 423e12c5d1SDavid du Colombier 433e12c5d1SDavid du Colombier /* 443e12c5d1SDavid du Colombier * called every clock tick 453e12c5d1SDavid du Colombier */ 463e12c5d1SDavid du Colombier void checkalarms(void)473e12c5d1SDavid du Colombiercheckalarms(void) 483e12c5d1SDavid du Colombier { 493e12c5d1SDavid du Colombier Proc *p; 503e12c5d1SDavid du Colombier ulong now; 513e12c5d1SDavid du Colombier 523e12c5d1SDavid du Colombier p = alarms.head; 533e12c5d1SDavid du Colombier now = MACHP(0)->ticks; 543e12c5d1SDavid du Colombier 55*6bbfed0dSDavid du Colombier if(p && (long)(now - p->alarm) >= 0) 563e12c5d1SDavid du Colombier wakeup(&alarmr); 573e12c5d1SDavid du Colombier } 583e12c5d1SDavid du Colombier 593e12c5d1SDavid du Colombier ulong procalarm(ulong time)603e12c5d1SDavid du Colombierprocalarm(ulong time) 613e12c5d1SDavid du Colombier { 627dd7cddfSDavid du Colombier Proc **l, *f; 633e12c5d1SDavid du Colombier ulong when, old; 643e12c5d1SDavid du Colombier 657dd7cddfSDavid du Colombier if(up->alarm) 663ff48bf5SDavid du Colombier old = tk2ms(up->alarm - MACHP(0)->ticks); 67219b2ee8SDavid du Colombier else 68219b2ee8SDavid du Colombier old = 0; 693e12c5d1SDavid du Colombier if(time == 0) { 707dd7cddfSDavid du Colombier up->alarm = 0; 713e12c5d1SDavid du Colombier return old; 723e12c5d1SDavid du Colombier } 739a747e4fSDavid du Colombier when = ms2tk(time)+MACHP(0)->ticks; 74*6bbfed0dSDavid du Colombier if(when == 0) /* ticks have wrapped to 0? */ 75*6bbfed0dSDavid du Colombier when = 1; /* distinguish a wrapped alarm from no alarm */ 763e12c5d1SDavid du Colombier 773e12c5d1SDavid du Colombier qlock(&alarms); 783e12c5d1SDavid du Colombier l = &alarms.head; 793e12c5d1SDavid du Colombier for(f = *l; f; f = f->palarm) { 807dd7cddfSDavid du Colombier if(up == f){ 813e12c5d1SDavid du Colombier *l = f->palarm; 823e12c5d1SDavid du Colombier break; 833e12c5d1SDavid du Colombier } 843e12c5d1SDavid du Colombier l = &f->palarm; 853e12c5d1SDavid du Colombier } 863e12c5d1SDavid du Colombier 877dd7cddfSDavid du Colombier up->palarm = 0; 883e12c5d1SDavid du Colombier if(alarms.head) { 893e12c5d1SDavid du Colombier l = &alarms.head; 903e12c5d1SDavid du Colombier for(f = *l; f; f = f->palarm) { 91*6bbfed0dSDavid du Colombier if((long)(f->alarm - when) >= 0) { 927dd7cddfSDavid du Colombier up->palarm = f; 937dd7cddfSDavid du Colombier *l = up; 943e12c5d1SDavid du Colombier goto done; 953e12c5d1SDavid du Colombier } 963e12c5d1SDavid du Colombier l = &f->palarm; 973e12c5d1SDavid du Colombier } 987dd7cddfSDavid du Colombier *l = up; 993e12c5d1SDavid du Colombier } 1003e12c5d1SDavid du Colombier else 1017dd7cddfSDavid du Colombier alarms.head = up; 1023e12c5d1SDavid du Colombier done: 1037dd7cddfSDavid du Colombier up->alarm = when; 1043e12c5d1SDavid du Colombier qunlock(&alarms); 1053e12c5d1SDavid du Colombier 1063e12c5d1SDavid du Colombier return old; 1073e12c5d1SDavid du Colombier } 108