1
0
mirror of https://github.com/golang/go synced 2024-11-23 04:00:03 -07:00

only use mach kernel semaphores for actual contention.

running rob's powser p.go:

3.21u 2.58s 5.80r 	 6.out	# old
1.48u 0.05s 1.54r 	 6.out	# new

R=r
OCL=15748
CL=15750
This commit is contained in:
Russ Cox 2008-09-24 10:25:28 -07:00
parent eea21f8b85
commit 5ff12f871f
2 changed files with 33 additions and 8 deletions

View File

@ -262,7 +262,7 @@ xadd(uint32 volatile *val, int32 delta)
// releases the lock by decrementing l->key, l->key will // releases the lock by decrementing l->key, l->key will
// be >0, so it will increment the semaphore to wake up // be >0, so it will increment the semaphore to wake up
// one of the others. This is the same algorithm used // one of the others. This is the same algorithm used
// in Plan 9's user-space locks. // in Plan 9's user-level locks.
// //
// Note that semaphores are never destroyed (the kernel // Note that semaphores are never destroyed (the kernel
// will clean up when the process exits). We assume for now // will clean up when the process exits). We assume for now
@ -287,6 +287,25 @@ unlock(Lock *l)
} }
// 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)
semacquire(s->k);
}
void
usemrelease(Usema *s)
{
if((int32)xadd(&s->u, 1) <= 0)
semrelease(s->k);
}
// Event notifications. // Event notifications.
void void
noteclear(Note *n) noteclear(Note *n)
@ -297,19 +316,19 @@ noteclear(Note *n)
void void
notesleep(Note *n) notesleep(Note *n)
{ {
if(n->sema == 0) if(n->sema.k == 0)
initsema(&n->sema); initsema(&n->sema.k);
while(!n->wakeup) while(!n->wakeup)
semacquire(n->sema); usemacquire(&n->sema);
} }
void void
notewakeup(Note *n) notewakeup(Note *n)
{ {
if(n->sema == 0) if(n->sema.k == 0)
initsema(&n->sema); initsema(&n->sema.k);
n->wakeup = 1; n->wakeup = 1;
semrelease(n->sema); usemrelease(&n->sema);
} }

View File

@ -43,6 +43,7 @@ typedef struct Alg Alg;
typedef struct Lock Lock; typedef struct Lock Lock;
typedef union Note Note; typedef union Note Note;
typedef struct Mem Mem; typedef struct Mem Mem;
typedef struct Usema Usema;
/* /*
* per cpu declaration * per cpu declaration
@ -77,6 +78,11 @@ struct Lock
uint32 key; uint32 key;
uint32 sema; // for OS X uint32 sema; // for OS X
}; };
struct Usema
{
uint32 u;
uint32 k;
};
union Note union Note
{ {
struct { // Linux struct { // Linux
@ -84,7 +90,7 @@ union Note
}; };
struct { // OS X struct { // OS X
int32 wakeup; int32 wakeup;
uint32 sema; Usema sema;
}; };
}; };
struct String struct String