diff --git a/sys/src/libthread/create.c b/sys/src/libthread/create.c index 41a373c99..c58e6a837 100644 --- a/sys/src/libthread/create.c +++ b/sys/src/libthread/create.c @@ -97,7 +97,8 @@ procrfork(void (*f)(void *), void *arg, uint stacksize, int rforkflag) int id; p = _threadgetproc(); - assert(p->newproc == nil); + while(p->newproc) + _sched(); p->newproc = _newproc(f, arg, stacksize, nil, p->thread->grp, rforkflag); id = p->newproc->threads.head->id; _sched(); diff --git a/sys/src/libthread/exec.c b/sys/src/libthread/exec.c index 3bfbda3c6..b3ac6c213 100644 --- a/sys/src/libthread/exec.c +++ b/sys/src/libthread/exec.c @@ -45,8 +45,10 @@ procexec(Channel *pidc, char *prog, char *args[]) close(p->exec.fd[1]); p->exec.fd[1] = n; + while(p->needexec || p->newproc) + _sched(); + /* exec in parallel via the scheduler */ - assert(p->needexec==0); p->exec.prog = prog; p->exec.args = args; p->needexec = 1; @@ -61,6 +63,8 @@ procexec(Channel *pidc, char *prog, char *args[]) } close(p->exec.fd[0]); + if(t->ret == -1) + goto Bad; if(pidc) sendul(pidc, t->ret); diff --git a/sys/src/libthread/exit.c b/sys/src/libthread/exit.c index d36e11af4..a6ee207b2 100644 --- a/sys/src/libthread/exit.c +++ b/sys/src/libthread/exit.c @@ -2,7 +2,6 @@ #include #include #include "threadimpl.h" -#include char *_threadexitsallstatus; Channel *_threadwaitchan; @@ -33,7 +32,7 @@ threadexitsall(char *exitstr) exitstr = ""; _threadexitsallstatus = exitstr; _threaddebug(DBGSCHED, "_threadexitsallstatus set to %p", _threadexitsallstatus); - mypid = _tos->pid; //getpid(); + mypid = getpid(); /* * signal others. @@ -47,7 +46,7 @@ threadexitsall(char *exitstr) lock(&_threadpq.lock); npid = 0; for(p = _threadpq.head; p && npid < nelem(pid); p=p->next){ - if(p->threadint == 0 && p->pid != mypid){ + if(p->threadint == 0 && p->pid != mypid && p->pid != -1){ pid[npid++] = p->pid; p->threadint = 1; } diff --git a/sys/src/libthread/id.c b/sys/src/libthread/id.c index 289dc8698..778bdcd5c 100644 --- a/sys/src/libthread/id.c +++ b/sys/src/libthread/id.c @@ -2,7 +2,6 @@ #include #include #include "threadimpl.h" -#include int threadid(void) diff --git a/sys/src/libthread/main.c b/sys/src/libthread/main.c index a2a2eb0af..48a8acd52 100644 --- a/sys/src/libthread/main.c +++ b/sys/src/libthread/main.c @@ -28,8 +28,6 @@ main(int argc, char **argv) rfork(RFREND); mainp = &p; - if(setjmp(_mainjmp)) - _schedinit(p); //_threaddebuglevel = (DBGSCHED|DBGCHAN|DBGREND)^~0; _systhreadinit(); @@ -45,6 +43,7 @@ main(int argc, char **argv) a->argv = argv; p = _newproc(mainlauncher, a, mainstacksize, "threadmain", 0, 0); + setjmp(_mainjmp); _schedinit(p); abort(); /* not reached */ } @@ -117,18 +116,6 @@ void _schedexit(Proc *p) { char ex[ERRMAX]; - Proc **l; - - lock(&_threadpq.lock); - for(l=&_threadpq.head; *l; l=&(*l)->next){ - if(*l == p){ - *l = p->next; - if(*l == nil) - _threadpq.tail = l; - break; - } - } - unlock(&_threadpq.lock); utfecpy(ex, ex+sizeof ex, p->exitstr); free(p); diff --git a/sys/src/libthread/sched.c b/sys/src/libthread/sched.c index 50603a3c4..888d64cc2 100644 --- a/sys/src/libthread/sched.c +++ b/sys/src/libthread/sched.c @@ -2,15 +2,9 @@ #include #include #include "threadimpl.h" -#include - -static Thread *runthread(Proc*); static char *_psstate[] = { - "Moribund", "Dead", - "Exec", - "Fork", "Running", "Ready", "Rendezvous", @@ -24,6 +18,23 @@ psstate(int s) return _psstate[s]; } +static void +unlinkproc(Proc *p) +{ + Proc **l; + + lock(&_threadpq.lock); + for(l=&_threadpq.head; *l; l=&(*l)->next){ + if(*l == p){ + *l = p->next; + if(*l == nil) + _threadpq.tail = l; + break; + } + } + unlock(&_threadpq.lock); +} + void _schedinit(void *arg) { @@ -31,8 +42,8 @@ _schedinit(void *arg) Thread *t, **l; p = arg; + p->pid = getpid(); _threadsetproc(p); - p->pid = _tos->pid; //getpid(); while(setjmp(p->sched)) ; _threaddebug(DBGSCHED, "top of schedinit, _threadexitsallstatus=%p", _threadexitsallstatus); @@ -67,8 +78,15 @@ _schedinit(void *arg) p->needexec = 0; } if(p->newproc){ - t->ret = _schedfork(p->newproc); - p->newproc = nil; + Thread *x = p->newproc->threads.head; + if(x->moribund){ + x->proc = p; + _threadready(x); + unlinkproc(p->newproc); + free(p->newproc); + p->newproc = nil; + } else if(_schedfork(p->newproc) != -1) + p->newproc = nil; } t->state = t->nextstate; if(t->state == Ready) @@ -90,44 +108,12 @@ needstack(int n) if((uchar*)&x - n < (uchar*)t->stk){ fprint(2, "%s %lud: &x=%p n=%d t->stk=%p\n", - argv0, _tos->pid, &x, n, t->stk); - fprint(2, "%s %lud: stack overflow\n", argv0, _tos->pid); + argv0, (ulong)p->pid, &x, n, t->stk); + fprint(2, "%s %lud: stack overflow\n", argv0, (ulong)p->pid); abort(); } } -void -_sched(void) -{ - Proc *p; - Thread *t; - -Resched: - p = _threadgetproc(); - if((t = p->thread) != nil){ - needstack(128); - _threaddebug(DBGSCHED, "pausing, state=%s", psstate(t->state)); - if(setjmp(t->sched)==0) - longjmp(p->sched, 1); - return; - }else{ - t = runthread(p); - if(t == nil){ - _threaddebug(DBGSCHED, "all threads gone; exiting"); - _schedexit(p); - } - _threaddebug(DBGSCHED, "running %d.%d", t->proc->pid, t->id); - p->thread = t; - if(t->moribund){ - _threaddebug(DBGSCHED, "%d.%d marked to die"); - goto Resched; - } - t->state = Running; - t->nextstate = Ready; - longjmp(t->sched, 1); - } -} - static Thread* runthread(Proc *p) { @@ -154,6 +140,39 @@ runthread(Proc *p) return t; } +void +_sched(void) +{ + Proc *p; + Thread *t; + +Resched: + p = _threadgetproc(); + if((t = p->thread) != nil){ + needstack(128); + _threaddebug(DBGSCHED, "pausing, state=%s", psstate(t->state)); + if(setjmp(t->sched)==0) + longjmp(p->sched, 1); + return; + }else{ + t = runthread(p); + if(t == nil){ + _threaddebug(DBGSCHED, "all threads gone; exiting"); + unlinkproc(p); + _schedexit(p); /* frees proc */ + } + _threaddebug(DBGSCHED, "running %d.%d", t->proc->pid, t->id); + p->thread = t; + if(t->moribund){ + _threaddebug(DBGSCHED, "%d.%d marked to die"); + goto Resched; + } + t->state = Running; + t->nextstate = Ready; + longjmp(t->sched, 1); + } +} + void _threadready(Thread *t) {