1
0
mirror of https://github.com/golang/go synced 2024-11-22 02:14:40 -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");
m->locks++;
if(xadd(&l->key, 1) > 1) { // someone else has it; wait
// Allocate semaphore if needed.
if(l->sema == 0)
initsema(&l->sema);
if(xadd(&l->key, 1) > 1) // someone else has it; wait
mach_semacquire(l->sema);
}
}
void
unlock(Lock *l)
@ -75,9 +75,13 @@ unlock(Lock *l)
if(m->locks < 0)
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);
}
}
// User-level semaphore implementation:
@ -87,16 +91,22 @@ unlock(Lock *l)
void
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);
}
}
void
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);
}
}
// Event notifications.
@ -109,8 +119,6 @@ noteclear(Note *n)
void
notesleep(Note *n)
{
if(n->sema.k == 0)
initsema(&n->sema.k);
while(!n->wakeup)
usemacquire(&n->sema);
}
@ -118,8 +126,6 @@ notesleep(Note *n)
void
notewakeup(Note *n)
{
if(n->sema.k == 0)
initsema(&n->sema.k);
n->wakeup = 1;
usemrelease(&n->sema);
}