1
0
mirror of https://github.com/golang/go synced 2024-11-20 03:14:43 -07:00

runtime: unset m->locks after actual lock unlock

This is needed for preemptive scheduler,
it will preempt only when m->locks==0,
and we do not want to be preempted while
we have not completely unlocked the lock.

R=golang-dev, khr, iant
CC=golang-dev
https://golang.org/cl/9196047
This commit is contained in:
Dmitriy Vyukov 2013-05-15 16:48:41 +04:00
parent e69012ce2a
commit 764bb36ea2
2 changed files with 6 additions and 6 deletions

View File

@ -91,14 +91,14 @@ runtime·unlock(Lock *l)
{ {
uint32 v; uint32 v;
if(--m->locks < 0)
runtime·throw("runtime·unlock: lock count");
v = runtime·xchg((uint32*)&l->key, MUTEX_UNLOCKED); v = runtime·xchg((uint32*)&l->key, MUTEX_UNLOCKED);
if(v == MUTEX_UNLOCKED) if(v == MUTEX_UNLOCKED)
runtime·throw("unlock of unlocked lock"); runtime·throw("unlock of unlocked lock");
if(v == MUTEX_SLEEPING) if(v == MUTEX_SLEEPING)
runtime·futexwakeup((uint32*)&l->key, 1); runtime·futexwakeup((uint32*)&l->key, 1);
if(--m->locks < 0)
runtime·throw("runtime·unlock: lock count");
} }
// One-time notifications. // One-time notifications.

View File

@ -93,9 +93,6 @@ runtime·unlock(Lock *l)
uintptr v; uintptr v;
M *mp; M *mp;
if(--m->locks < 0)
runtime·throw("runtime·unlock: lock count");
for(;;) { for(;;) {
v = (uintptr)runtime·atomicloadp((void**)&l->key); v = (uintptr)runtime·atomicloadp((void**)&l->key);
if(v == LOCKED) { if(v == LOCKED) {
@ -112,6 +109,9 @@ runtime·unlock(Lock *l)
} }
} }
} }
if(--m->locks < 0)
runtime·throw("runtime·unlock: lock count");
} }
// One-time notifications. // One-time notifications.