mirror of
https://github.com/golang/go
synced 2024-11-20 06:44:40 -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:
parent
fdbbb066ed
commit
582fd17e11
@ -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.
|
// Put on `g' queue. Sched must be locked.
|
||||||
static void
|
static void
|
||||||
gput(G *g)
|
gput(G *g)
|
||||||
@ -177,6 +189,18 @@ gput(G *g)
|
|||||||
mnextg(m, g);
|
mnextg(m, g);
|
||||||
return;
|
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;
|
g->schedlink = nil;
|
||||||
if(runtime·sched.ghead == nil)
|
if(runtime·sched.ghead == nil)
|
||||||
@ -199,6 +223,9 @@ gget(void)
|
|||||||
if(runtime·sched.ghead == nil)
|
if(runtime·sched.ghead == nil)
|
||||||
runtime·sched.gtail = nil;
|
runtime·sched.gtail = nil;
|
||||||
runtime·sched.gwait--;
|
runtime·sched.gwait--;
|
||||||
|
} else if(m->idleg != nil) {
|
||||||
|
g = m->idleg;
|
||||||
|
m->idleg = nil;
|
||||||
}
|
}
|
||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
@ -532,6 +559,7 @@ scheduler(void)
|
|||||||
gp->lockedm = nil;
|
gp->lockedm = nil;
|
||||||
m->lockedg = nil;
|
m->lockedg = nil;
|
||||||
}
|
}
|
||||||
|
gp->idlem = nil;
|
||||||
unwindstack(gp, nil);
|
unwindstack(gp, nil);
|
||||||
gfput(gp);
|
gfput(gp);
|
||||||
if(--runtime·sched.gcount == 0)
|
if(--runtime·sched.gcount == 0)
|
||||||
|
@ -197,6 +197,7 @@ struct G
|
|||||||
bool ispanic;
|
bool ispanic;
|
||||||
M* m; // for debuggers, but offset not hard-coded
|
M* m; // for debuggers, but offset not hard-coded
|
||||||
M* lockedm;
|
M* lockedm;
|
||||||
|
M* idlem;
|
||||||
int32 sig;
|
int32 sig;
|
||||||
uintptr sigcode0;
|
uintptr sigcode0;
|
||||||
uintptr sigcode1;
|
uintptr sigcode1;
|
||||||
@ -233,6 +234,7 @@ struct M
|
|||||||
uint32 machport; // Return address for Mach IPC (OS X)
|
uint32 machport; // Return address for Mach IPC (OS X)
|
||||||
MCache *mcache;
|
MCache *mcache;
|
||||||
G* lockedg;
|
G* lockedg;
|
||||||
|
G* idleg;
|
||||||
uint32 freglo[16]; // D[i] lsb and F[i]
|
uint32 freglo[16]; // D[i] lsb and F[i]
|
||||||
uint32 freghi[16]; // D[i] msb and F[i+16]
|
uint32 freghi[16]; // D[i] msb and F[i+16]
|
||||||
uint32 fflag; // floating point compare flags
|
uint32 fflag; // floating point compare flags
|
||||||
|
Loading…
Reference in New Issue
Block a user