// User-level semaphore implementation: // try to do the operations in user space on u, // but when it's time to block, fall back on the kernel semaphore k. // This is the same algorithm used in Plan 9. void usemacquire(Usema *s) { if((int32)xadd(&s->u, -1) < 0) { if(s->k == 0) initsema(&s->k); mach_semacquire(s->k); } }
int32 runtime·semasleep(int64 ns) { int32 v; if(m->profilehz > 0) runtime·setprof(false); v = runtime·mach_semacquire(m->waitsema, ns); if(m->profilehz > 0) runtime·setprof(true); return v; }
void lock(Lock *l) { if(m->locks < 0) throw("lock count"); m->locks++; if(xadd(&l->key, 1) > 1) { // someone else has it; wait // Allocate semaphore if needed. if(l->sema == 0) initsema(&l->sema); mach_semacquire(l->sema); } }