mirror of
https://github.com/golang/go
synced 2024-11-21 21:34:40 -07:00
runtime: fix GC bitmap corruption
The corruption can occur when GOMAXPROCS is changed from >1 to 1, since GOMAXPROCS=1 does not imply there is only 1 goroutine running, other goroutines can still be not parked after the change. R=golang-dev, rsc CC=golang-dev https://golang.org/cl/4873050
This commit is contained in:
parent
01dd57b312
commit
a2677cf363
@ -737,11 +737,11 @@ runtime·markallocated(void *v, uintptr n, bool noptr)
|
||||
bits = (obits & ~(bitMask<<shift)) | (bitAllocated<<shift);
|
||||
if(noptr)
|
||||
bits |= bitNoPointers<<shift;
|
||||
if(runtime·gomaxprocs == 1) {
|
||||
if(runtime·singleproc) {
|
||||
*b = bits;
|
||||
break;
|
||||
} else {
|
||||
// gomaxprocs > 1: use atomic op
|
||||
// more than one goroutine is potentially running: use atomic op
|
||||
if(runtime·casp((void**)b, (void*)obits, (void*)bits))
|
||||
break;
|
||||
}
|
||||
@ -767,11 +767,11 @@ runtime·markfreed(void *v, uintptr n)
|
||||
for(;;) {
|
||||
obits = *b;
|
||||
bits = (obits & ~(bitMask<<shift)) | (bitBlockBoundary<<shift);
|
||||
if(runtime·gomaxprocs == 1) {
|
||||
if(runtime·singleproc) {
|
||||
*b = bits;
|
||||
break;
|
||||
} else {
|
||||
// gomaxprocs > 1: use atomic op
|
||||
// more than one goroutine is potentially running: use atomic op
|
||||
if(runtime·casp((void**)b, (void*)obits, (void*)bits))
|
||||
break;
|
||||
}
|
||||
@ -878,11 +878,11 @@ runtime·setblockspecial(void *v)
|
||||
for(;;) {
|
||||
obits = *b;
|
||||
bits = obits | (bitSpecial<<shift);
|
||||
if(runtime·gomaxprocs == 1) {
|
||||
if(runtime·singleproc) {
|
||||
*b = bits;
|
||||
break;
|
||||
} else {
|
||||
// gomaxprocs > 1: use atomic op
|
||||
// more than one goroutine is potentially running: use atomic op
|
||||
if(runtime·casp((void**)b, (void*)obits, (void*)bits))
|
||||
break;
|
||||
}
|
||||
|
@ -126,6 +126,7 @@ enum {
|
||||
|
||||
Sched runtime·sched;
|
||||
int32 runtime·gomaxprocs;
|
||||
bool runtime·singleproc;
|
||||
|
||||
// An m that is waiting for notewakeup(&m->havenextg). This may be
|
||||
// only be accessed while the scheduler lock is held. This is used to
|
||||
@ -199,6 +200,7 @@ runtime·schedinit(void)
|
||||
runtime·gomaxprocs = n;
|
||||
}
|
||||
setmcpumax(runtime·gomaxprocs);
|
||||
runtime·singleproc = runtime·gomaxprocs == 1;
|
||||
runtime·sched.predawn = 1;
|
||||
|
||||
m->nomemprof--;
|
||||
@ -585,6 +587,7 @@ runtime·stoptheworld(void)
|
||||
runtime·notesleep(&runtime·sched.stopped);
|
||||
schedlock();
|
||||
}
|
||||
runtime·singleproc = runtime·gomaxprocs == 1;
|
||||
schedunlock();
|
||||
}
|
||||
|
||||
@ -1416,6 +1419,8 @@ runtime·gomaxprocsfunc(int32 n)
|
||||
if(n > maxgomaxprocs)
|
||||
n = maxgomaxprocs;
|
||||
runtime·gomaxprocs = n;
|
||||
if(runtime·gomaxprocs > 1)
|
||||
runtime·singleproc = false;
|
||||
if(runtime·gcwaiting != 0) {
|
||||
if(atomic_mcpumax(runtime·sched.atomic) != 1)
|
||||
runtime·throw("invalid mcpumax during gc");
|
||||
|
@ -383,6 +383,7 @@ extern String runtime·emptystring;
|
||||
G* runtime·allg;
|
||||
M* runtime·allm;
|
||||
extern int32 runtime·gomaxprocs;
|
||||
extern bool runtime·singleproc;
|
||||
extern uint32 runtime·panicking;
|
||||
extern int32 runtime·gcwaiting; // gc is waiting to run
|
||||
int8* runtime·goos;
|
||||
|
Loading…
Reference in New Issue
Block a user