Skip to content

Commit 779c45a

Browse files
committedMar 1, 2013
runtime: improved scheduler
Distribute runnable queues, memory cache and cache of dead G's per processor. Faster non-blocking syscall enter/exit. More conservative worker thread blocking/unblocking. R=dave, bradfitz, remyoudompheng, rsc CC=golang-dev https://golang.org/cl/7314062
1 parent d17506e commit 779c45a

File tree

3 files changed

+993
-826
lines changed

3 files changed

+993
-826
lines changed
 

‎src/pkg/runtime/mgc0.c

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1633,20 +1633,12 @@ runtime·gchelper(void)
16331633
// extra memory used).
16341634
static int32 gcpercent = GcpercentUnknown;
16351635

1636-
static void
1637-
stealcache(void)
1638-
{
1639-
M *mp;
1640-
1641-
for(mp=runtime·allm; mp; mp=mp->alllink)
1642-
runtime·MCache_ReleaseAll(mp->mcache);
1643-
}
1644-
16451636
static void
16461637
cachestats(GCStats *stats)
16471638
{
16481639
M *mp;
16491640
MCache *c;
1641+
P *p, **pp;
16501642
int32 i;
16511643
uint64 stacks_inuse;
16521644
uint64 *src, *dst;
@@ -1655,8 +1647,6 @@ cachestats(GCStats *stats)
16551647
runtime·memclr((byte*)stats, sizeof(*stats));
16561648
stacks_inuse = 0;
16571649
for(mp=runtime·allm; mp; mp=mp->alllink) {
1658-
c = mp->mcache;
1659-
runtime·purgecachedstats(c);
16601650
stacks_inuse += mp->stackinuse*FixedStack;
16611651
if(stats) {
16621652
src = (uint64*)&mp->gcstats;
@@ -1665,6 +1655,12 @@ cachestats(GCStats *stats)
16651655
dst[i] += src[i];
16661656
runtime·memclr((byte*)&mp->gcstats, sizeof(mp->gcstats));
16671657
}
1658+
}
1659+
for(pp=runtime·allp; p=*pp; pp++) {
1660+
c = p->mcache;
1661+
if(c==nil)
1662+
continue;
1663+
runtime·purgecachedstats(c);
16681664
for(i=0; i<nelem(c->local_by_size); i++) {
16691665
mstats.by_size[i].nmalloc += c->local_by_size[i].nmalloc;
16701666
c->local_by_size[i].nmalloc = 0;
@@ -1819,12 +1815,11 @@ gc(struct gc_args *args)
18191815
runtime·parfordo(work.sweepfor);
18201816
t3 = runtime·nanotime();
18211817

1822-
stealcache();
1823-
cachestats(&stats);
1824-
18251818
if(work.nproc > 1)
18261819
runtime·notesleep(&work.alldone);
18271820

1821+
cachestats(&stats);
1822+
18281823
stats.nprocyield += work.sweepfor->nprocyield;
18291824
stats.nosyield += work.sweepfor->nosyield;
18301825
stats.nsleep += work.sweepfor->nsleep;

‎src/pkg/runtime/proc.c

Lines changed: 961 additions & 805 deletions
Large diffs are not rendered by default.

‎src/pkg/runtime/runtime.h

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,19 @@ enum
118118
Grunning,
119119
Gsyscall,
120120
Gwaiting,
121-
Gmoribund,
121+
Gmoribund_unused, // currently unused, but hardcoded in gdb scripts
122122
Gdead,
123123
};
124124
enum
125+
{
126+
// P status
127+
Pidle,
128+
Prunning,
129+
Psyscall,
130+
Pgcstop,
131+
Pdead,
132+
};
133+
enum
125134
{
126135
true = 1,
127136
false = 0,
@@ -214,6 +223,7 @@ struct G
214223
Gobuf sched;
215224
uintptr gcstack; // if status==Gsyscall, gcstack = stackbase to use during gc
216225
uintptr gcsp; // if status==Gsyscall, gcsp = sched.sp to use during gc
226+
byte* gcpc; // if status==Gsyscall, gcpc = sched.pc to use during gc
217227
uintptr gcguard; // if status==Gsyscall, gcguard = stackguard to use during gc
218228
uintptr stack0;
219229
FuncVal* fnstart; // initial function
@@ -224,13 +234,11 @@ struct G
224234
uint32 selgen; // valid sudog pointer
225235
int8* waitreason; // if status==Gwaiting
226236
G* schedlink;
227-
bool readyonstop;
228237
bool ispanic;
229238
bool issystem;
230239
int8 raceignore; // ignore race detection events
231240
M* m; // for debuggers, but offset not hard-coded
232241
M* lockedm;
233-
M* idlem;
234242
int32 sig;
235243
int32 writenbuf;
236244
byte* writebuf;
@@ -259,22 +267,24 @@ struct M
259267
G* gsignal; // signal-handling G
260268
uint32 tls[8]; // thread-local storage (for 386 extern register)
261269
G* curg; // current running goroutine
270+
P* p; // attached P for executing Go code (nil if not executing Go code)
271+
P* nextp;
262272
int32 id;
263273
int32 mallocing;
264274
int32 throwing;
265275
int32 gcing;
266276
int32 locks;
267277
int32 nomemprof;
268-
int32 waitnextg;
269278
int32 dying;
270279
int32 profilehz;
271280
int32 helpgc;
281+
bool blockingsyscall;
282+
bool spinning;
272283
uint32 fastrand;
273284
uint64 ncgocall; // number of cgo calls in total
274285
int32 ncgo; // number of cgo calls currently in progress
275286
CgoMal* cgomal;
276-
Note havenextg;
277-
G* nextg;
287+
Note park;
278288
M* alllink; // on allm
279289
M* schedlink;
280290
uint32 machport; // Return address for Mach IPC (OS X)
@@ -284,7 +294,6 @@ struct M
284294
uint32 stackcachecnt;
285295
void* stackcache[StackCacheSize];
286296
G* lockedg;
287-
G* idleg;
288297
uintptr createstack[32]; // Stack that created this thread.
289298
uint32 freglo[16]; // D[i] lsb and F[i]
290299
uint32 freghi[16]; // D[i] msb and F[i+16]
@@ -298,6 +307,8 @@ struct M
298307
bool racecall;
299308
bool needextram;
300309
void* racepc;
310+
void (*waitunlockf)(Lock*);
311+
Lock* waitlock;
301312
uint32 moreframesize_minalloc;
302313

303314
uintptr settype_buf[1024];
@@ -317,7 +328,11 @@ struct P
317328
{
318329
Lock;
319330

331+
uint32 status; // one of Pidle/Prunning/...
320332
P* link;
333+
uint32 tick; // incremented on every scheduler or system call
334+
M* m; // back-link to associated M (nil if idle)
335+
MCache* mcache;
321336

322337
// Queue of runnable goroutines.
323338
G** runq;
@@ -608,6 +623,7 @@ extern uintptr runtime·zerobase;
608623
extern G* runtime·allg;
609624
extern G* runtime·lastg;
610625
extern M* runtime·allm;
626+
extern P** runtime·allp;
611627
extern int32 runtime·gomaxprocs;
612628
extern bool runtime·singleproc;
613629
extern uint32 runtime·panicking;

0 commit comments

Comments
 (0)
Please sign in to comment.