// loop if gp->atomicstatus is in a scan state giving
// GC time to finish and change the state to oldval.
while(!runtime·cas(&gp->atomicstatus, oldval, newval)) {
- // Help GC if needed.
- if(gp->preemptscan && !gp->gcworkdone && (oldval == Grunning || oldval == Gsyscall)) {
- gp->preemptscan = false;
- g->m->ptrarg[0] = gp;
- fn = helpcasgstatus;
- runtime·onM(&fn);
- }
+
}
}
return false;
case Grunning:
+ if(runtime·gcphase == GCscan) {
+ gp->gcworkdone = true;
+ return false;
+ // Running routines not scanned during
+ // GCscan phase, we only scan non-running routines.
+ }
+
// Claim goroutine, so we aren't racing with a status
// transition away from Grunning.
if(!runtime·castogscanstatus(gp, Grunning, Gscanrunning))
uint32 status;
uint32 activeglen;
- activeglen = runtime·allglen;
// enqueue the calling goroutine.
runtime·restartg(gpmaster);
+
+ activeglen = runtime·allglen;
for(i = 0; i < activeglen; i++) {
gp = runtime·allg[i];
if(runtime·readgstatus(gp) == Gdead)
mp->g0 = runtime·malg(-1);
else
mp->g0 = runtime·malg(8192);
+ runtime·writebarrierptr_nostore(&mp->g0, mp->g0);
mp->g0->m = mp;
+ runtime·writebarrierptr_nostore(&mp->g0->m, mp->g0->m);
if(p == g->m->p)
releasep();
unlockextra(mp);
}
-#define MLOCKED ((M*)1)
+#define MLOCKED 1
// lockextra locks the extra list and returns the list head.
// The caller must unlock the list by storing a new list head
static M*
lockextra(bool nilokay)
{
- M *mp;
+ uintptr mpx;
void (*yield)(void);
for(;;) {
- mp = runtime·atomicloadp(&runtime·extram);
- if(mp == MLOCKED) {
+ mpx = runtime·atomicloaduintptr((uintptr*)&runtime·extram);
+ if(mpx == MLOCKED) {
yield = runtime·osyield;
yield();
continue;
}
- if(mp == nil && !nilokay) {
+ if(mpx == 0 && !nilokay) {
runtime·usleep(1);
continue;
}
- if(!runtime·casp(&runtime·extram, mp, MLOCKED)) {
+ if(!runtime·casuintptr((uintptr*)&runtime·extram, mpx, MLOCKED)) {
yield = runtime·osyield;
yield();
continue;
}
break;
}
- return mp;
+ return (M*)mpx;
}
#pragma textflag NOSPLIT
// Freezetheworld sets stopwait but does not retake P's.
if(runtime·sched.stopwait) {
+ g->m->mcache = nil;
g->m->p = nil;
return false;
}
return true;
}
// Try to get any other idle P.
+ g->m->mcache = nil;
g->m->p = nil;
if(runtime·sched.pidle) {
fn = exitsyscallfast_pidle;
byte *argp;
void (*mfn)(void);
- if(thechar == '5')
+ if(thechar == '5' || thechar == '9')
argp = (byte*)(&fn+2); // skip caller's saved LR
else
argp = (byte*)(&fn+1);
sp -= 4*sizeof(uintreg); // extra space in case of reads slightly beyond frame
sp -= siz;
runtime·memmove(sp, argp, narg);
- if(thechar == '5') {
+ if(thechar == '5' || thechar == '9') {
// caller's LR
sp -= sizeof(void*);
*(void**)sp = nil;
P *runtime·newP(void);
// Change number of processors. The world is stopped, sched is locked.
+// gcworkbufs are not being modified by either the GC or
+// the write barrier code.
static void
procresize(int32 new)
{