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