ref: b7cd7074c00f15df5b30eee0e0a1b216839646ad
dir: /kern/rendez.c/
#include "u.h" #include "lib.h" #include "dat.h" #include "fns.h" #include "error.h" void sleep(Rendez *r, int (*f)(void*), void *arg) { int s; s = splhi(); lock(&r->lk); lock(&up->rlock); if(r->p){ print("double sleep %lud %lud\n", r->p->pid, up->pid); dumpstack(); } /* * Wakeup only knows there may be something to do by testing * r->p in order to get something to lock on. * Flush that information out to memory in case the sleep is * committed. */ r->p = up; if((*f)(arg) || up->notepending){ /* * if condition happened or a note is pending * never mind */ r->p = nil; unlock(&up->rlock); unlock(&r->lk); } else { /* * now we are committed to * change state and call scheduler */ up->state = Wakeme; up->r = r; /* statistics */ /* m->cs++; */ unlock(&up->rlock); unlock(&r->lk); procsleep(); } if(up->notepending) { up->notepending = 0; splx(s); error(Eintr); } splx(s); } Proc* wakeup(Rendez *r) { Proc *p; int s; s = splhi(); lock(&r->lk); p = r->p; if(p != nil){ lock(&p->rlock); if(p->state != Wakeme || p->r != r) panic("wakeup: state"); r->p = nil; p->r = nil; p->state = Running; procwakeup(p); unlock(&p->rlock); } unlock(&r->lk); splx(s); return p; }