runtime·throw("runtime·lock: lock count");
// Speculative grab for lock.
- v = runtime·xchg(&l->key, MUTEX_LOCKED);
+ v = runtime·xchg((uint32*)&l->key, MUTEX_LOCKED);
if(v == MUTEX_UNLOCKED)
return;
// Try for lock, spinning.
for(i = 0; i < spin; i++) {
while(l->key == MUTEX_UNLOCKED)
- if(runtime·cas(&l->key, MUTEX_UNLOCKED, wait))
+ if(runtime·cas((uint32*)&l->key, MUTEX_UNLOCKED, wait))
return;
runtime·procyield(ACTIVE_SPIN_CNT);
}
// Try for lock, rescheduling.
for(i=0; i < PASSIVE_SPIN; i++) {
while(l->key == MUTEX_UNLOCKED)
- if(runtime·cas(&l->key, MUTEX_UNLOCKED, wait))
+ if(runtime·cas((uint32*)&l->key, MUTEX_UNLOCKED, wait))
return;
runtime·osyield();
}
// Sleep.
- v = runtime·xchg(&l->key, MUTEX_SLEEPING);
+ v = runtime·xchg((uint32*)&l->key, MUTEX_SLEEPING);
if(v == MUTEX_UNLOCKED)
return;
wait = MUTEX_SLEEPING;
- runtime·futexsleep(&l->key, MUTEX_SLEEPING, -1);
+ runtime·futexsleep((uint32*)&l->key, MUTEX_SLEEPING, -1);
}
}
if(--m->locks < 0)
runtime·throw("runtime·unlock: lock count");
- v = runtime·xchg(&l->key, MUTEX_UNLOCKED);
+ v = runtime·xchg((uint32*)&l->key, MUTEX_UNLOCKED);
if(v == MUTEX_UNLOCKED)
runtime·throw("unlock of unlocked lock");
if(v == MUTEX_SLEEPING)
- runtime·futexwakeup(&l->key, 1);
+ runtime·futexwakeup((uint32*)&l->key, 1);
}
// One-time notifications.
runtime·throw("runtime·lock: lock count");
// Speculative grab for lock.
- if(runtime·casp(&l->waitm, nil, (void*)LOCKED))
+ if(runtime·casp((void**)&l->key, nil, (void*)LOCKED))
return;
if(m->waitsema == 0)
spin = ACTIVE_SPIN;
for(i=0;; i++) {
- v = (uintptr)runtime·atomicloadp(&l->waitm);
+ v = (uintptr)runtime·atomicloadp((void**)&l->key);
if((v&LOCKED) == 0) {
unlocked:
- if(runtime·casp(&l->waitm, (void*)v, (void*)(v|LOCKED)))
+ if(runtime·casp((void**)&l->key, (void*)v, (void*)(v|LOCKED)))
return;
i = 0;
}
// Queue this M.
for(;;) {
m->nextwaitm = (void*)(v&~LOCKED);
- if(runtime·casp(&l->waitm, (void*)v, (void*)((uintptr)m|LOCKED)))
+ if(runtime·casp((void**)&l->key, (void*)v, (void*)((uintptr)m|LOCKED)))
break;
- v = (uintptr)runtime·atomicloadp(&l->waitm);
+ v = (uintptr)runtime·atomicloadp((void**)&l->key);
if((v&LOCKED) == 0)
goto unlocked;
}
runtime·throw("runtime·unlock: lock count");
for(;;) {
- v = (uintptr)runtime·atomicloadp(&l->waitm);
+ v = (uintptr)runtime·atomicloadp((void**)&l->key);
if(v == LOCKED) {
- if(runtime·casp(&l->waitm, (void*)LOCKED, nil))
+ if(runtime·casp((void**)&l->key, (void*)LOCKED, nil))
break;
} else {
// Other M's are waiting for the lock.
// Dequeue an M.
mp = (void*)(v&~LOCKED);
- if(runtime·casp(&l->waitm, (void*)v, mp->nextwaitm)) {
+ if(runtime·casp((void**)&l->key, (void*)v, mp->nextwaitm)) {
// Dequeued an M. Wake it.
runtime·semawakeup(mp);
break;
typedef struct Func Func;
typedef struct G G;
typedef struct Gobuf Gobuf;
-typedef union Lock Lock;
+typedef struct Lock Lock;
typedef struct M M;
typedef struct P P;
typedef struct Mem Mem;
/*
* structures
*/
-union Lock
+struct Lock
{
- uint32 key; // futex-based impl
- M* waitm; // linked list of waiting M's (sema-based impl)
+ // Futex-based impl treats it as uint32 key,
+ // while sema-based impl as M* waitm.
+ // Used to be a union, but unions break precise GC.
+ uintptr key;
};
union Note
{