mirror of
https://github.com/golang/go
synced 2024-11-12 06:20:22 -07:00
various race conditions.
R=r DELTA=43 (29 added, 5 deleted, 9 changed) OCL=23608 CL=23611
This commit is contained in:
parent
47ab1c1e99
commit
53e69e1db5
@ -397,7 +397,7 @@ nextgandunlock(void)
|
||||
throw("all goroutines are asleep - deadlock!");
|
||||
m->nextg = nil;
|
||||
noteclear(&m->havenextg);
|
||||
if(sched.waitstop) {
|
||||
if(sched.waitstop && sched.mcpu <= sched.mcpumax) {
|
||||
sched.waitstop = 0;
|
||||
notewakeup(&sched.stopped);
|
||||
}
|
||||
@ -590,6 +590,10 @@ sys·entersyscall(uint64 callerpc, int64 trap)
|
||||
sched.msyscall++;
|
||||
if(sched.gwait != 0)
|
||||
matchmg();
|
||||
if(sched.waitstop && sched.mcpu <= sched.mcpumax) {
|
||||
sched.waitstop = 0;
|
||||
notewakeup(&sched.stopped);
|
||||
}
|
||||
unlock(&sched);
|
||||
// leave SP around for gc; poison PC to make sure it's not used
|
||||
g->sched.SP = (byte*)&callerpc;
|
||||
|
@ -277,19 +277,25 @@ xadd(uint32 volatile *val, int32 delta)
|
||||
void
|
||||
lock(Lock *l)
|
||||
{
|
||||
if(m->locks < 0)
|
||||
throw("lock count");
|
||||
m->locks++;
|
||||
|
||||
// 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);
|
||||
m->locks++;
|
||||
}
|
||||
|
||||
void
|
||||
unlock(Lock *l)
|
||||
{
|
||||
m->locks--;
|
||||
if(m->locks < 0)
|
||||
throw("lock count");
|
||||
|
||||
if(xadd(&l->key, -1) > 0) // someone else is waiting
|
||||
mach_semrelease(l->sema);
|
||||
}
|
||||
|
@ -301,13 +301,11 @@ futexwakeup(uint32 *addr)
|
||||
// else return 0;
|
||||
// but atomically.
|
||||
|
||||
void
|
||||
lock(Lock *l)
|
||||
static void
|
||||
futexlock(Lock *l)
|
||||
{
|
||||
uint32 v;
|
||||
|
||||
m->locks++;
|
||||
|
||||
again:
|
||||
v = l->key;
|
||||
if((v&1) == 0){
|
||||
@ -346,13 +344,11 @@ again:
|
||||
goto again;
|
||||
}
|
||||
|
||||
void
|
||||
unlock(Lock *l)
|
||||
static void
|
||||
futexunlock(Lock *l)
|
||||
{
|
||||
uint32 v;
|
||||
|
||||
m->locks--;
|
||||
|
||||
// Atomically get value and clear lock bit.
|
||||
again:
|
||||
v = l->key;
|
||||
@ -366,6 +362,24 @@ again:
|
||||
futexwakeup(&l->key);
|
||||
}
|
||||
|
||||
void
|
||||
lock(Lock *l)
|
||||
{
|
||||
if(m->locks < 0)
|
||||
throw("lock count");
|
||||
m->locks++;
|
||||
futexlock(l);
|
||||
}
|
||||
|
||||
void
|
||||
unlock(Lock *l)
|
||||
{
|
||||
m->locks--;
|
||||
if(m->locks < 0)
|
||||
throw("lock count");
|
||||
futexunlock(l);
|
||||
}
|
||||
|
||||
|
||||
// One-time notifications.
|
||||
//
|
||||
@ -383,20 +397,20 @@ void
|
||||
noteclear(Note *n)
|
||||
{
|
||||
n->lock.key = 0; // memset(n, 0, sizeof *n)
|
||||
lock(&n->lock);
|
||||
futexlock(&n->lock);
|
||||
}
|
||||
|
||||
void
|
||||
notewakeup(Note *n)
|
||||
{
|
||||
unlock(&n->lock);
|
||||
futexunlock(&n->lock);
|
||||
}
|
||||
|
||||
void
|
||||
notesleep(Note *n)
|
||||
{
|
||||
lock(&n->lock);
|
||||
unlock(&n->lock); // Let other sleepers find out too.
|
||||
futexlock(&n->lock);
|
||||
futexunlock(&n->lock); // Let other sleepers find out too.
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user