mirror of
https://github.com/golang/go
synced 2024-11-26 03:57:57 -07:00
runtime: change Note from union to struct
Unions can break precise GC. Update #5193. R=golang-dev, iant CC=golang-dev https://golang.org/cl/8362046
This commit is contained in:
parent
d617454379
commit
58030c541b
@ -111,9 +111,9 @@ runtime·noteclear(Note *n)
|
||||
void
|
||||
runtime·notewakeup(Note *n)
|
||||
{
|
||||
if(runtime·xchg(&n->key, 1))
|
||||
if(runtime·xchg((uint32*)&n->key, 1))
|
||||
runtime·throw("notewakeup - double wakeup");
|
||||
runtime·futexwakeup(&n->key, 1);
|
||||
runtime·futexwakeup((uint32*)&n->key, 1);
|
||||
}
|
||||
|
||||
void
|
||||
@ -121,8 +121,8 @@ runtime·notesleep(Note *n)
|
||||
{
|
||||
if(m->profilehz > 0)
|
||||
runtime·setprof(false);
|
||||
while(runtime·atomicload(&n->key) == 0)
|
||||
runtime·futexsleep(&n->key, 0, -1);
|
||||
while(runtime·atomicload((uint32*)&n->key) == 0)
|
||||
runtime·futexsleep((uint32*)&n->key, 0, -1);
|
||||
if(m->profilehz > 0)
|
||||
runtime·setprof(true);
|
||||
}
|
||||
@ -137,15 +137,15 @@ runtime·notetsleep(Note *n, int64 ns)
|
||||
return;
|
||||
}
|
||||
|
||||
if(runtime·atomicload(&n->key) != 0)
|
||||
if(runtime·atomicload((uint32*)&n->key) != 0)
|
||||
return;
|
||||
|
||||
if(m->profilehz > 0)
|
||||
runtime·setprof(false);
|
||||
deadline = runtime·nanotime() + ns;
|
||||
for(;;) {
|
||||
runtime·futexsleep(&n->key, 0, ns);
|
||||
if(runtime·atomicload(&n->key) != 0)
|
||||
runtime·futexsleep((uint32*)&n->key, 0, ns);
|
||||
if(runtime·atomicload((uint32*)&n->key) != 0)
|
||||
break;
|
||||
now = runtime·nanotime();
|
||||
if(now >= deadline)
|
||||
|
@ -118,7 +118,7 @@ runtime·unlock(Lock *l)
|
||||
void
|
||||
runtime·noteclear(Note *n)
|
||||
{
|
||||
n->waitm = nil;
|
||||
n->key = 0;
|
||||
}
|
||||
|
||||
void
|
||||
@ -127,8 +127,8 @@ runtime·notewakeup(Note *n)
|
||||
M *mp;
|
||||
|
||||
do
|
||||
mp = runtime·atomicloadp(&n->waitm);
|
||||
while(!runtime·casp(&n->waitm, mp, (void*)LOCKED));
|
||||
mp = runtime·atomicloadp((void**)&n->key);
|
||||
while(!runtime·casp((void**)&n->key, mp, (void*)LOCKED));
|
||||
|
||||
// Successfully set waitm to LOCKED.
|
||||
// What was it before?
|
||||
@ -148,8 +148,8 @@ runtime·notesleep(Note *n)
|
||||
{
|
||||
if(m->waitsema == 0)
|
||||
m->waitsema = runtime·semacreate();
|
||||
if(!runtime·casp(&n->waitm, nil, m)) { // must be LOCKED (got wakeup)
|
||||
if(n->waitm != (void*)LOCKED)
|
||||
if(!runtime·casp((void**)&n->key, nil, m)) { // must be LOCKED (got wakeup)
|
||||
if(n->key != LOCKED)
|
||||
runtime·throw("notesleep - waitm out of sync");
|
||||
return;
|
||||
}
|
||||
@ -176,8 +176,8 @@ runtime·notetsleep(Note *n, int64 ns)
|
||||
m->waitsema = runtime·semacreate();
|
||||
|
||||
// Register for wakeup on n->waitm.
|
||||
if(!runtime·casp(&n->waitm, nil, m)) { // must be LOCKED (got wakeup already)
|
||||
if(n->waitm != (void*)LOCKED)
|
||||
if(!runtime·casp((void**)&n->key, nil, m)) { // must be LOCKED (got wakeup already)
|
||||
if(n->key != LOCKED)
|
||||
runtime·throw("notetsleep - waitm out of sync");
|
||||
return;
|
||||
}
|
||||
@ -212,10 +212,10 @@ runtime·notetsleep(Note *n, int64 ns)
|
||||
// so that any notewakeup racing with the return does not
|
||||
// try to grant us the semaphore when we don't expect it.
|
||||
for(;;) {
|
||||
mp = runtime·atomicloadp(&n->waitm);
|
||||
mp = runtime·atomicloadp((void**)&n->key);
|
||||
if(mp == m) {
|
||||
// No wakeup yet; unregister if possible.
|
||||
if(runtime·casp(&n->waitm, mp, nil))
|
||||
if(runtime·casp((void**)&n->key, mp, nil))
|
||||
return;
|
||||
} else if(mp == (M*)LOCKED) {
|
||||
// Wakeup happened so semaphore is available.
|
||||
|
@ -54,7 +54,7 @@ typedef struct Lock Lock;
|
||||
typedef struct M M;
|
||||
typedef struct P P;
|
||||
typedef struct Mem Mem;
|
||||
typedef union Note Note;
|
||||
typedef struct Note Note;
|
||||
typedef struct Slice Slice;
|
||||
typedef struct Stktop Stktop;
|
||||
typedef struct String String;
|
||||
@ -163,10 +163,12 @@ struct Lock
|
||||
// Used to be a union, but unions break precise GC.
|
||||
uintptr key;
|
||||
};
|
||||
union Note
|
||||
struct Note
|
||||
{
|
||||
uint32 key; // futex-based impl
|
||||
M* waitm; // waiting M (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;
|
||||
};
|
||||
struct String
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user