mirror of
https://github.com/golang/go
synced 2024-11-21 22:04:39 -07:00
runtime: check for preemption due to garbage collection
in various already expensive routines. helps keep cpu utilization up when GOMAXPROCS > 1, but not a full solution. http://groups.google.com/group/golang-nuts/t/7a9535c4136d3e2 R=r CC=golang-dev https://golang.org/cl/184043
This commit is contained in:
parent
752b1702d0
commit
5328df6534
@ -174,6 +174,9 @@ chansend(Hchan *c, byte *ep, bool *pres)
|
|||||||
SudoG *sg;
|
SudoG *sg;
|
||||||
G* gp;
|
G* gp;
|
||||||
|
|
||||||
|
if(gcwaiting)
|
||||||
|
gosched();
|
||||||
|
|
||||||
if(debug) {
|
if(debug) {
|
||||||
prints("chansend: chan=");
|
prints("chansend: chan=");
|
||||||
runtime·printpointer(c);
|
runtime·printpointer(c);
|
||||||
@ -277,6 +280,9 @@ chanrecv(Hchan* c, byte *ep, bool* pres)
|
|||||||
SudoG *sg;
|
SudoG *sg;
|
||||||
G *gp;
|
G *gp;
|
||||||
|
|
||||||
|
if(gcwaiting)
|
||||||
|
gosched();
|
||||||
|
|
||||||
if(debug) {
|
if(debug) {
|
||||||
prints("chanrecv: chan=");
|
prints("chanrecv: chan=");
|
||||||
runtime·printpointer(c);
|
runtime·printpointer(c);
|
||||||
@ -631,6 +637,9 @@ runtime·selectgo(Select *sel)
|
|||||||
G *gp;
|
G *gp;
|
||||||
byte *as;
|
byte *as;
|
||||||
|
|
||||||
|
if(gcwaiting)
|
||||||
|
gosched();
|
||||||
|
|
||||||
if(debug) {
|
if(debug) {
|
||||||
prints("selectgo: sel=");
|
prints("selectgo: sel=");
|
||||||
runtime·printpointer(sel);
|
runtime·printpointer(sel);
|
||||||
@ -908,6 +917,9 @@ runtime·closechan(Hchan *c)
|
|||||||
SudoG *sg;
|
SudoG *sg;
|
||||||
G* gp;
|
G* gp;
|
||||||
|
|
||||||
|
if(gcwaiting)
|
||||||
|
gosched();
|
||||||
|
|
||||||
lock(c);
|
lock(c);
|
||||||
incerr(c);
|
incerr(c);
|
||||||
c->closed |= Wclosed;
|
c->closed |= Wclosed;
|
||||||
|
@ -744,6 +744,9 @@ mapaccess(Hmap *h, byte *ak, byte *av, bool *pres)
|
|||||||
{
|
{
|
||||||
byte *res;
|
byte *res;
|
||||||
|
|
||||||
|
if(gcwaiting)
|
||||||
|
gosched();
|
||||||
|
|
||||||
res = nil;
|
res = nil;
|
||||||
if(hash_lookup(h, ak, (void**)&res)) {
|
if(hash_lookup(h, ak, (void**)&res)) {
|
||||||
*pres = true;
|
*pres = true;
|
||||||
@ -812,6 +815,9 @@ mapassign(Hmap *h, byte *ak, byte *av)
|
|||||||
byte *res;
|
byte *res;
|
||||||
int32 hit;
|
int32 hit;
|
||||||
|
|
||||||
|
if(gcwaiting)
|
||||||
|
gosched();
|
||||||
|
|
||||||
res = nil;
|
res = nil;
|
||||||
if(av == nil) {
|
if(av == nil) {
|
||||||
hash_remove(h, ak, (void**)&res);
|
hash_remove(h, ak, (void**)&res);
|
||||||
@ -908,6 +914,9 @@ mapiterinit(Hmap *h)
|
|||||||
void
|
void
|
||||||
runtime·mapiternext(struct hash_iter *it)
|
runtime·mapiternext(struct hash_iter *it)
|
||||||
{
|
{
|
||||||
|
if(gcwaiting)
|
||||||
|
gosched();
|
||||||
|
|
||||||
it->data = hash_next(it);
|
it->data = hash_next(it);
|
||||||
if(debug) {
|
if(debug) {
|
||||||
prints("runtime·mapiternext: iter=");
|
prints("runtime·mapiternext: iter=");
|
||||||
|
@ -27,10 +27,11 @@ mallocgc(uintptr size, uint32 refflag, int32 dogc)
|
|||||||
void *v;
|
void *v;
|
||||||
uint32 *ref;
|
uint32 *ref;
|
||||||
|
|
||||||
|
if(gcwaiting && g != m->g0)
|
||||||
|
gosched();
|
||||||
if(m->mallocing)
|
if(m->mallocing)
|
||||||
throw("malloc/free - deadlock");
|
throw("malloc/free - deadlock");
|
||||||
m->mallocing = 1;
|
m->mallocing = 1;
|
||||||
|
|
||||||
if(size == 0)
|
if(size == 0)
|
||||||
size = 1;
|
size = 1;
|
||||||
|
|
||||||
|
@ -244,7 +244,7 @@ gc(int32 force)
|
|||||||
sweep();
|
sweep();
|
||||||
mstats.next_gc = mstats.inuse_pages+mstats.inuse_pages*gcpercent/100;
|
mstats.next_gc = mstats.inuse_pages+mstats.inuse_pages*gcpercent/100;
|
||||||
}
|
}
|
||||||
starttheworld();
|
|
||||||
m->gcing = 0;
|
m->gcing = 0;
|
||||||
semrelease(&gcsema);
|
semrelease(&gcsema);
|
||||||
|
starttheworld();
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,8 @@ G g0; // idle goroutine for m0
|
|||||||
|
|
||||||
static int32 debug = 0;
|
static int32 debug = 0;
|
||||||
|
|
||||||
|
int32 gcwaiting;
|
||||||
|
|
||||||
// Go scheduler
|
// Go scheduler
|
||||||
//
|
//
|
||||||
// The go scheduler's job is to match ready-to-run goroutines (`g's)
|
// The go scheduler's job is to match ready-to-run goroutines (`g's)
|
||||||
@ -362,6 +364,7 @@ void
|
|||||||
stoptheworld(void)
|
stoptheworld(void)
|
||||||
{
|
{
|
||||||
lock(&sched);
|
lock(&sched);
|
||||||
|
gcwaiting = 1;
|
||||||
sched.mcpumax = 1;
|
sched.mcpumax = 1;
|
||||||
while(sched.mcpu > 1) {
|
while(sched.mcpu > 1) {
|
||||||
noteclear(&sched.stopped);
|
noteclear(&sched.stopped);
|
||||||
@ -379,6 +382,7 @@ void
|
|||||||
starttheworld(void)
|
starttheworld(void)
|
||||||
{
|
{
|
||||||
lock(&sched);
|
lock(&sched);
|
||||||
|
gcwaiting = 0;
|
||||||
sched.mcpumax = sched.gomaxprocs;
|
sched.mcpumax = sched.gomaxprocs;
|
||||||
matchmg();
|
matchmg();
|
||||||
unlock(&sched);
|
unlock(&sched);
|
||||||
|
@ -316,6 +316,7 @@ extern int32 gomaxprocs;
|
|||||||
extern int32 panicking;
|
extern int32 panicking;
|
||||||
extern int32 maxround;
|
extern int32 maxround;
|
||||||
extern int32 fd; // usually 1; set to 2 when panicking
|
extern int32 fd; // usually 1; set to 2 when panicking
|
||||||
|
extern int32 gcwaiting; // gc is waiting to run
|
||||||
int8* goos;
|
int8* goos;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user