| tbetter exec handling - plan9port - [fork] Plan 9 from user space | |
| git clone git://src.adamsgaard.dk/plan9port | |
| Log | |
| Files | |
| Refs | |
| README | |
| LICENSE | |
| --- | |
| commit 8cbd854a8ab2c4f8c738c5bea5263217cb892a77 | |
| parent 03417610742c4a67bb0345a8fa0fb4e13dee07f7 | |
| Author: rsc <devnull@localhost> | |
| Date: Mon, 27 Dec 2004 19:11:33 +0000 | |
| better exec handling | |
| Diffstat: | |
| M src/libthread/Linux.c | 33 +++--------------------------… | |
| M src/libthread/exec.c | 62 +++++++++++++----------------… | |
| M src/libthread/pthread.c | 6 ------ | |
| M src/libthread/thread.c | 19 ++++++++++++++----- | |
| M src/libthread/threadimpl.h | 1 + | |
| 5 files changed, 43 insertions(+), 78 deletions(-) | |
| --- | |
| diff --git a/src/libthread/Linux.c b/src/libthread/Linux.c | |
| t@@ -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; | |
| } | |
| t@@ -266,35 +268,6 @@ threadexitsall(char *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 | |
| * | |
| * could use modify_ldt and a segment register | |
| diff --git a/src/libthread/exec.c b/src/libthread/exec.c | |
| t@@ -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* | |
| t@@ -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 | |
| t@@ -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 | |
| t@@ -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 | |
| t@@ -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 | |
| t@@ -74,6 +74,7 @@ struct Proc | |
| uint osprocid; | |
| #endif | |
| Lock lock; | |
| + int nswitch; | |
| _Thread *thread; | |
| _Threadlist runqueue; | |
| _Threadlist allthreads; |