From 8cbd854a8ab2c4f8c738c5bea5263217cb892a77 Mon Sep 17 00:00:00 2001 From: rsc Date: Mon, 27 Dec 2004 19:11:33 +0000 Subject: better exec handling --- src/libthread/Linux.c | 33 +++--------------------- src/libthread/exec.c | 62 +++++++++++++++++++--------------------------- src/libthread/pthread.c | 6 ----- src/libthread/thread.c | 19 ++++++++++---- src/libthread/threadimpl.h | 1 + 5 files changed, 43 insertions(+), 78 deletions(-) (limited to 'src/libthread') diff --git a/src/libthread/Linux.c b/src/libthread/Linux.c index d6d31afa..357e9260 100644 --- a/src/libthread/Linux.c +++ b/src/libthread/Linux.c @@ -99,13 +99,15 @@ again: sigdelset(&mask, SIGUSR1); sigsuspend(&mask); +//print("%d %d awake again\n", time(0), getpid()); + /* * We're awake. Make USR1 not interrupt system calls. */ lock(r->l); ignusr1(1); if(r->asleep && r->pid == getpid()){ -print("resleep %d\n", getpid()); +//print("resleep %d\n", getpid()); /* Didn't really wake up - signal from something else */ goto again; } @@ -265,35 +267,6 @@ threadexitsall(char *msg) exits(msg); } -/* - * exec - need to arrange for wait proc to run - * the execs so it gets the wait messages - */ -int -_runthreadspawn(int *fd, char *cmd, char **argv) -{ - Execjob e; - int pid; - - e.fd = fd; - e.cmd = cmd; - e.argv = argv; - e.c = chancreate(sizeof(ulong), 0); -print("%d run\n", time(0)); - qlock(&_threadexeclock); - sendp(_threadexecchan, &e); -print("%d sent\n", time(0)); - while(_threadexecproc == nil) - yield(); - kill(_threadexecproc->osprocid, SIGUSR2); -print("%d killed\n", time(0)); - pid = recvul(e.c); - qunlock(&_threadexeclock); -print("%d ran\n", time(0)); - return pid; -} - - /* * per-process data, indexed by pid * diff --git a/src/libthread/exec.c b/src/libthread/exec.c index dfdb71b6..6a7ca1db 100644 --- a/src/libthread/exec.c +++ b/src/libthread/exec.c @@ -6,41 +6,42 @@ static Lock thewaitlock; static Channel *thewaitchan; -Channel *_dowaitchan; -Channel *_threadexecchan; -Proc *_threadexecproc; -QLock _threadexeclock; static void -execthread(void *v) -{ - Execjob *e; - - USED(v); - while((e = recvp(_threadexecchan)) != nil){ -print("%d doexec pid %d\n", time(0), getpid()); - sendul(e->c, _threadspawn(e->fd, e->cmd, e->argv)); - } -} - -static void -waitproc(void *v) +execproc(void *v) { + int pid; Channel *c; + Execjob *e; Waitmsg *w; - _threadsetsysproc(); - _threadexecproc = proc(); - threadcreate(execthread, nil, 65536); - for(;;){ - while((w = wait()) == nil) - if(errno == ECHILD) - recvul(_dowaitchan); + e = v; + pid = _threadspawn(e->fd, e->cmd, e->argv); + sendul(e->c, pid); + if(pid > 0){ + w = waitfor(pid); if((c = thewaitchan) != nil) sendp(c, w); else free(w); } + threadexits(nil); +} + +int +_runthreadspawn(int *fd, char *cmd, char **argv) +{ + int pid; + Execjob e; + + e.fd = fd; + e.cmd = cmd; + e.argv = argv; + e.c = chancreate(sizeof(void*), 0); + proccreate(execproc, &e, 65536); + pid = recvul(e.c); + chanfree(e.c); + return pid; } Channel* @@ -104,28 +105,15 @@ _threadspawn(int fd[3], char *cmd, char *argv[]) close(fd[1]); if(fd[2] != fd[1] && fd[2] != fd[0]) close(fd[2]); - channbsendul(_dowaitchan, 1); return pid; } int threadspawn(int fd[3], char *cmd, char *argv[]) { - if(_dowaitchan == nil){ - lock(&thewaitlock); - if(_dowaitchan == nil){ - _dowaitchan = chancreate(sizeof(ulong), 1); - chansetname(_dowaitchan, "dowaitchan"); - _threadexecchan = chancreate(sizeof(void*), 1); - chansetname(_threadexecchan, "execchan"); - proccreate(waitproc, nil, STACK); - } - unlock(&thewaitlock); - } return _runthreadspawn(fd, cmd, argv); } - int _threadexec(Channel *cpid, int fd[3], char *cmd, char *argv[]) { diff --git a/src/libthread/pthread.c b/src/libthread/pthread.c index e1fed2bf..2ddd8c72 100644 --- a/src/libthread/pthread.c +++ b/src/libthread/pthread.c @@ -130,9 +130,3 @@ _pthreadinit(void) pthread_key_create(&prockey, 0); } -int -_runthreadspawn(int *fd, char *cmd, char **argv) -{ - return _threadspawn(fd, cmd, argv); -} - diff --git a/src/libthread/thread.c b/src/libthread/thread.c index 8f838b62..1837e7d9 100644 --- a/src/libthread/thread.c +++ b/src/libthread/thread.c @@ -138,15 +138,23 @@ _threadready(_Thread *t) p = t->proc; lock(&p->lock); addthread(&p->runqueue, t); - _procwakeup(&p->runrend); +//print("%d wake for job %d->%d\n", time(0), getpid(), p->osprocid); + if(p != proc()) + _procwakeup(&p->runrend); unlock(&p->lock); } -void +int threadyield(void) { - _threadready(proc()->thread); + int n; + Proc *p; + + p = proc(); + n = p->nswitch; + _threadready(p->thread); _threadswitch(); + return p->nswitch - n; } void @@ -184,13 +192,14 @@ scheduler(Proc *p) if(p->nthread == 0) goto Out; p->runrend.l = &p->lock; -print("sleep for jobs %d\n", getpid()); +//print("%d sleep for jobs %d\n", time(0), getpid()); _procsleep(&p->runrend); -print("wake from jobs %d\n", getpid()); +//print("%d wake from jobs %d\n", time(0), getpid()); } delthread(&p->runqueue, t); unlock(&p->lock); p->thread = t; + p->nswitch++; // print("run %s %d\n", t->name, t->id); contextswitch(&p->schedcontext, &t->context); p->thread = nil; diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h index 6bc8cbfc..164ba978 100644 --- a/src/libthread/threadimpl.h +++ b/src/libthread/threadimpl.h @@ -74,6 +74,7 @@ struct Proc uint osprocid; #endif Lock lock; + int nswitch; _Thread *thread; _Threadlist runqueue; _Threadlist allthreads; -- cgit v1.2.3