1
0
mirror of https://github.com/golang/go synced 2024-11-22 08:04:39 -07:00

runtime: wait to allocate mach semaphores backing Locks until needed

need better management of mach semaphores eventually
but this avoids allocating them for uncontended Locks.

R=r
CC=agl1, golang-dev
https://golang.org/cl/190079
This commit is contained in:
Russ Cox 2010-01-19 21:14:15 -08:00
parent b2beb8abf0
commit 0365b989a4

View File

@ -60,13 +60,13 @@ lock(Lock *l)
throw("lock count"); throw("lock count");
m->locks++; m->locks++;
if(xadd(&l->key, 1) > 1) { // someone else has it; wait
// Allocate semaphore if needed. // Allocate semaphore if needed.
if(l->sema == 0) if(l->sema == 0)
initsema(&l->sema); initsema(&l->sema);
if(xadd(&l->key, 1) > 1) // someone else has it; wait
mach_semacquire(l->sema); mach_semacquire(l->sema);
} }
}
void void
unlock(Lock *l) unlock(Lock *l)
@ -75,9 +75,13 @@ unlock(Lock *l)
if(m->locks < 0) if(m->locks < 0)
throw("lock count"); throw("lock count");
if(xadd(&l->key, -1) > 0) // someone else is waiting if(xadd(&l->key, -1) > 0) { // someone else is waiting
// Allocate semaphore if needed.
if(l->sema == 0)
initsema(&l->sema);
mach_semrelease(l->sema); mach_semrelease(l->sema);
} }
}
// User-level semaphore implementation: // User-level semaphore implementation:
@ -87,16 +91,22 @@ unlock(Lock *l)
void void
usemacquire(Usema *s) usemacquire(Usema *s)
{ {
if((int32)xadd(&s->u, -1) < 0) if((int32)xadd(&s->u, -1) < 0) {
if(s->k == 0)
initsema(&s->k);
mach_semacquire(s->k); mach_semacquire(s->k);
} }
}
void void
usemrelease(Usema *s) usemrelease(Usema *s)
{ {
if((int32)xadd(&s->u, 1) <= 0) if((int32)xadd(&s->u, 1) <= 0) {
if(s->k == 0)
initsema(&s->k);
mach_semrelease(s->k); mach_semrelease(s->k);
} }
}
// Event notifications. // Event notifications.
@ -109,8 +119,6 @@ noteclear(Note *n)
void void
notesleep(Note *n) notesleep(Note *n)
{ {
if(n->sema.k == 0)
initsema(&n->sema.k);
while(!n->wakeup) while(!n->wakeup)
usemacquire(&n->sema); usemacquire(&n->sema);
} }
@ -118,8 +126,6 @@ notesleep(Note *n)
void void
notewakeup(Note *n) notewakeup(Note *n)
{ {
if(n->sema.k == 0)
initsema(&n->sema.k);
n->wakeup = 1; n->wakeup = 1;
usemrelease(&n->sema); usemrelease(&n->sema);
} }