proper handling of signals.
do not run init on g0.
R=r
DELTA=161 (124 added, 23 deleted, 14 changed)
OCL=15490
CL=15497
diff --git a/src/runtime/proc.c b/src/runtime/proc.c
index 62efd45..84f5a06 100644
--- a/src/runtime/proc.c
+++ b/src/runtime/proc.c
@@ -70,7 +70,18 @@
// Scheduler loop.
static void scheduler(void);
-// Called before main·init_function.
+// The bootstrap sequence is:
+//
+// call osinit
+// call schedinit
+// make & queue new G
+// call mstart
+//
+// The new G does:
+//
+// call main·init_function
+// call initdone
+// call main·main
void
schedinit(void)
{
@@ -85,9 +96,9 @@
sched.predawn = 1;
}
-// Called after main·init_function; main·main is on ready queue.
+// Called after main·init_function; main·main will be called on return.
void
-m0init(void)
+initdone(void)
{
int32 i;
@@ -100,8 +111,6 @@
// would have, had it not been pre-dawn.
for(i=1; i<sched.gcount && i<sched.mmax; i++)
mnew();
-
- scheduler();
}
void
@@ -116,6 +125,21 @@
sys·gosched();
}
+G*
+malg(int32 stacksize)
+{
+ G *g;
+ byte *stk;
+
+ // 160 is the slop amount known to the stack growth code
+ g = mal(sizeof(G));
+ stk = mal(160 + stacksize);
+ g->stack0 = stk;
+ g->stackguard = stk + 160;
+ g->stackbase = stk + 160 + stacksize;
+ return g;
+}
+
void
sys·newproc(int32 siz, byte* fn, byte* arg0)
{
@@ -135,15 +159,13 @@
if((newg = gfget()) != nil){
newg->status = Gwaiting;
- stk = newg->stack0;
}else{
- newg = mal(sizeof(G));
- stk = mal(4096);
- newg->stack0 = stk;
+ newg = malg(4096);
newg->status = Gwaiting;
newg->alllink = allg;
allg = newg;
}
+ stk = newg->stack0;
newg->stackguard = stk+160;
@@ -335,6 +357,14 @@
return gp;
}
+// Called to start an M.
+void
+mstart(void)
+{
+ minit();
+ scheduler();
+}
+
// Scheduler loop: find g to run, run it, repeat.
static void
scheduler(void)
@@ -342,11 +372,13 @@
G* gp;
lock(&sched);
-
if(gosave(&m->sched)){
- // Jumped here via gosave/gogo, so didn'
+ // Jumped here via gosave/gogo, so didn't
// execute lock(&sched) above.
lock(&sched);
+
+ if(sched.predawn)
+ throw("init sleeping");
// Just finished running m->curg.
gp = m->curg;
@@ -371,7 +403,6 @@
// Find (or wait for) g to run. Unlocks sched.
gp = nextgandunlock();
-
noteclear(&gp->stopped);
gp->status = Grunning;
m->curg = gp;
@@ -388,10 +419,6 @@
sys·gosched(void)
{
if(gosave(&g->sched) == 0){
- // TODO(rsc) signal race here?
- // If a signal comes in between
- // changing g and changing SP,
- // growing the stack will fail.
g = m->g0;
gogo(&m->sched);
}
@@ -402,8 +429,6 @@
mnew(void)
{
M *m;
- G *g;
- byte *stk, *stktop;
sched.mcount++;
if(debug){
@@ -411,18 +436,9 @@
prints(" threads\n");
}
- // Allocate m, g, stack in one chunk.
- // 1024 and 104 are the magic constants
- // use in rt0_amd64.s when setting up g0.
- m = mal(sizeof(M)+sizeof(G)+104+1024);
- g = (G*)(m+1);
- stk = (byte*)g + 104;
- stktop = stk + 1024;
-
- m->g0 = g;
- g->stackguard = stk;
- g->stackbase = stktop;
- newosproc(m, g, stktop, scheduler);
+ m = mal(sizeof(M));
+ m->g0 = malg(1024);
+ newosproc(m, m->g0, m->g0->stackbase, mstart);
}
//