19ef1f84bSDavid du Colombier #include "u.h" 29ef1f84bSDavid du Colombier #include "../port/lib.h" 39ef1f84bSDavid du Colombier #include "mem.h" 49ef1f84bSDavid du Colombier #include "dat.h" 59ef1f84bSDavid du Colombier #include "fns.h" 69ef1f84bSDavid du Colombier 79ef1f84bSDavid du Colombier static Alarms alarms; 89ef1f84bSDavid du Colombier static Rendez alarmr; 99ef1f84bSDavid du Colombier 109ef1f84bSDavid du Colombier void alarmkproc(void *)119ef1f84bSDavid du Colombieralarmkproc(void*) 129ef1f84bSDavid du Colombier { 139ef1f84bSDavid du Colombier Proc *rp; 149ef1f84bSDavid du Colombier ulong now; 159ef1f84bSDavid du Colombier 169ef1f84bSDavid du Colombier for(;;){ 179ef1f84bSDavid du Colombier now = sys->ticks; 189ef1f84bSDavid du Colombier qlock(&alarms); 19*406c76faSDavid du Colombier /* 20*406c76faSDavid du Colombier * the odd test of now vs. rp->alarm is to cope with 21*406c76faSDavid du Colombier * now wrapping around. 22*406c76faSDavid du Colombier */ 23*406c76faSDavid du Colombier while((rp = alarms.head) && (long)(now - rp->alarm) >= 0){ 249ef1f84bSDavid du Colombier if(rp->alarm != 0L){ 259ef1f84bSDavid du Colombier if(canqlock(&rp->debug)){ 269ef1f84bSDavid du Colombier if(!waserror()){ 279ef1f84bSDavid du Colombier postnote(rp, 0, "alarm", NUser); 289ef1f84bSDavid du Colombier poperror(); 299ef1f84bSDavid du Colombier } 309ef1f84bSDavid du Colombier qunlock(&rp->debug); 319ef1f84bSDavid du Colombier rp->alarm = 0L; 329ef1f84bSDavid du Colombier }else 339ef1f84bSDavid du Colombier break; 349ef1f84bSDavid du Colombier } 359ef1f84bSDavid du Colombier alarms.head = rp->palarm; 369ef1f84bSDavid du Colombier } 379ef1f84bSDavid du Colombier qunlock(&alarms); 389ef1f84bSDavid du Colombier 399ef1f84bSDavid du Colombier sleep(&alarmr, return0, 0); 409ef1f84bSDavid du Colombier } 419ef1f84bSDavid du Colombier } 429ef1f84bSDavid du Colombier 439ef1f84bSDavid du Colombier /* 449ef1f84bSDavid du Colombier * called every clock tick 459ef1f84bSDavid du Colombier */ 469ef1f84bSDavid du Colombier void checkalarms(void)479ef1f84bSDavid du Colombiercheckalarms(void) 489ef1f84bSDavid du Colombier { 499ef1f84bSDavid du Colombier Proc *p; 509ef1f84bSDavid du Colombier ulong now; 519ef1f84bSDavid du Colombier 529ef1f84bSDavid du Colombier p = alarms.head; 539ef1f84bSDavid du Colombier now = sys->ticks; 549ef1f84bSDavid du Colombier 55*406c76faSDavid du Colombier if(p && (long)(now - p->alarm) >= 0) 569ef1f84bSDavid du Colombier wakeup(&alarmr); 579ef1f84bSDavid du Colombier } 589ef1f84bSDavid du Colombier 599ef1f84bSDavid du Colombier ulong procalarm(ulong time)609ef1f84bSDavid du Colombierprocalarm(ulong time) 619ef1f84bSDavid du Colombier { 629ef1f84bSDavid du Colombier Proc **l, *f; 639ef1f84bSDavid du Colombier ulong when, old; 649ef1f84bSDavid du Colombier 659ef1f84bSDavid du Colombier if(up->alarm) 669ef1f84bSDavid du Colombier old = tk2ms(up->alarm - sys->ticks); 679ef1f84bSDavid du Colombier else 689ef1f84bSDavid du Colombier old = 0; 699ef1f84bSDavid du Colombier if(time == 0) { 709ef1f84bSDavid du Colombier up->alarm = 0; 719ef1f84bSDavid du Colombier return old; 729ef1f84bSDavid du Colombier } 739ef1f84bSDavid du Colombier when = ms2tk(time)+sys->ticks; 74*406c76faSDavid du Colombier if(when == 0) /* ticks have wrapped to 0? */ 75*406c76faSDavid du Colombier when = 1; /* distinguish a wrapped alarm from no alarm */ 769ef1f84bSDavid du Colombier 779ef1f84bSDavid du Colombier qlock(&alarms); 789ef1f84bSDavid du Colombier l = &alarms.head; 799ef1f84bSDavid du Colombier for(f = *l; f; f = f->palarm) { 809ef1f84bSDavid du Colombier if(up == f){ 819ef1f84bSDavid du Colombier *l = f->palarm; 829ef1f84bSDavid du Colombier break; 839ef1f84bSDavid du Colombier } 849ef1f84bSDavid du Colombier l = &f->palarm; 859ef1f84bSDavid du Colombier } 869ef1f84bSDavid du Colombier 879ef1f84bSDavid du Colombier up->palarm = 0; 889ef1f84bSDavid du Colombier if(alarms.head) { 899ef1f84bSDavid du Colombier l = &alarms.head; 909ef1f84bSDavid du Colombier for(f = *l; f; f = f->palarm) { 91*406c76faSDavid du Colombier if((long)(f->alarm - when) >= 0) { 929ef1f84bSDavid du Colombier up->palarm = f; 939ef1f84bSDavid du Colombier *l = up; 949ef1f84bSDavid du Colombier goto done; 959ef1f84bSDavid du Colombier } 969ef1f84bSDavid du Colombier l = &f->palarm; 979ef1f84bSDavid du Colombier } 989ef1f84bSDavid du Colombier *l = up; 999ef1f84bSDavid du Colombier } 1009ef1f84bSDavid du Colombier else 1019ef1f84bSDavid du Colombier alarms.head = up; 1029ef1f84bSDavid du Colombier done: 1039ef1f84bSDavid du Colombier up->alarm = when; 1049ef1f84bSDavid du Colombier qunlock(&alarms); 1059ef1f84bSDavid du Colombier 1069ef1f84bSDavid du Colombier return old; 1079ef1f84bSDavid du Colombier } 108