1 #include "u.h" 2 #include "lib.h" 3 #include "dat.h" 4 #include "fns.h" 5 #include "error.h" 6 7 void sleep(Rendez * r,int (* f)(void *),void * arg)8sleep(Rendez *r, int (*f)(void*), void *arg) 9 { 10 int s; 11 12 s = splhi(); 13 14 lock(&r->lk); 15 lock(&up->rlock); 16 if(r->p){ 17 print("double sleep %lud %lud\n", r->p->pid, up->pid); 18 dumpstack(); 19 } 20 21 /* 22 * Wakeup only knows there may be something to do by testing 23 * r->p in order to get something to lock on. 24 * Flush that information out to memory in case the sleep is 25 * committed. 26 */ 27 r->p = up; 28 29 if((*f)(arg) || up->notepending){ 30 /* 31 * if condition happened or a note is pending 32 * never mind 33 */ 34 r->p = nil; 35 unlock(&up->rlock); 36 unlock(&r->lk); 37 } else { 38 /* 39 * now we are committed to 40 * change state and call scheduler 41 */ 42 up->state = Wakeme; 43 up->r = r; 44 45 /* statistics */ 46 /* m->cs++; */ 47 48 unlock(&up->rlock); 49 unlock(&r->lk); 50 51 procsleep(); 52 } 53 54 if(up->notepending) { 55 up->notepending = 0; 56 splx(s); 57 error(Eintr); 58 } 59 60 splx(s); 61 } 62 63 Proc* wakeup(Rendez * r)64wakeup(Rendez *r) 65 { 66 Proc *p; 67 int s; 68 69 s = splhi(); 70 71 lock(&r->lk); 72 p = r->p; 73 74 if(p != nil){ 75 lock(&p->rlock); 76 if(p->state != Wakeme || p->r != r) 77 panic("wakeup: state"); 78 r->p = nil; 79 p->r = nil; 80 p->state = Running; 81 procwakeup(p); 82 unlock(&p->rlock); 83 } 84 unlock(&r->lk); 85 86 splx(s); 87 88 return p; 89 } 90 91