R=r
DELTA=43 (29 added, 5 deleted, 9 changed)
OCL=23608
CL=23611
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);
}
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;
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);
}
// 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){
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;
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.
//
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.
}