1
0
mirror of https://github.com/golang/go synced 2024-11-25 06:57:58 -07:00

runtime: idle goroutine

This functionality might be used in environments
where programs are limited to a single thread,
to simulate a select-driven network server.  It is
not exposed via the standard runtime API.

R=r, r2
CC=golang-dev
https://golang.org/cl/4254041
This commit is contained in:
Russ Cox 2011-02-27 23:32:42 -05:00
parent fdbbb066ed
commit 582fd17e11
2 changed files with 30 additions and 0 deletions

View File

@ -166,6 +166,18 @@ runtime·tracebackothers(G *me)
}
}
// Mark this g as m's idle goroutine.
// This functionality might be used in environments where programs
// are limited to a single thread, to simulate a select-driven
// network server. It is not exposed via the standard runtime API.
void
runtime·idlegoroutine(void)
{
if(g->idlem != nil)
runtime·throw("g is already an idle goroutine");
g->idlem = m;
}
// Put on `g' queue. Sched must be locked.
static void
gput(G *g)
@ -177,6 +189,18 @@ gput(G *g)
mnextg(m, g);
return;
}
// If g is the idle goroutine for an m, hand it off.
if(g->idlem != nil) {
if(g->idlem->idleg != nil) {
runtime·printf("m%d idle out of sync: g%d g%d\n",
g->idlem->id,
g->idlem->idleg->goid, g->goid);
runtime·throw("runtime: double idle");
}
g->idlem->idleg = g;
return;
}
g->schedlink = nil;
if(runtime·sched.ghead == nil)
@ -199,6 +223,9 @@ gget(void)
if(runtime·sched.ghead == nil)
runtime·sched.gtail = nil;
runtime·sched.gwait--;
} else if(m->idleg != nil) {
g = m->idleg;
m->idleg = nil;
}
return g;
}
@ -532,6 +559,7 @@ scheduler(void)
gp->lockedm = nil;
m->lockedg = nil;
}
gp->idlem = nil;
unwindstack(gp, nil);
gfput(gp);
if(--runtime·sched.gcount == 0)

View File

@ -197,6 +197,7 @@ struct G
bool ispanic;
M* m; // for debuggers, but offset not hard-coded
M* lockedm;
M* idlem;
int32 sig;
uintptr sigcode0;
uintptr sigcode1;
@ -233,6 +234,7 @@ struct M
uint32 machport; // Return address for Mach IPC (OS X)
MCache *mcache;
G* lockedg;
G* idleg;
uint32 freglo[16]; // D[i] lsb and F[i]
uint32 freghi[16]; // D[i] msb and F[i+16]
uint32 fflag; // floating point compare flags