From 955a2ca78d7efc2787864e38a3d902df16fc2541 Mon Sep 17 00:00:00 2001 From: rsc Date: Mon, 27 Dec 2004 18:21:58 +0000 Subject: starting to work on Linux --- src/libthread/Linux.c | 39 +++++++++++++++++++++++++++++++++++++-- src/libthread/exec.c | 44 +++++++++++++++++++++++++++----------------- src/libthread/test/mkfile | 8 ++++++++ src/libthread/thread.c | 2 ++ src/libthread/threadimpl.h | 6 ++++++ 5 files changed, 80 insertions(+), 19 deletions(-) create mode 100644 src/libthread/test/mkfile diff --git a/src/libthread/Linux.c b/src/libthread/Linux.c index 4be2c481..d6d31afa 100644 --- a/src/libthread/Linux.c +++ b/src/libthread/Linux.c @@ -87,6 +87,7 @@ _procsleep(_Procrendez *r) * unlock the vouslock so our waker can wake us, * and then suspend. */ +again: r->asleep = 1; r->pid = getpid(); @@ -101,9 +102,13 @@ _procsleep(_Procrendez *r) /* * We're awake. Make USR1 not interrupt system calls. */ - ignusr1(1); - assert(r->asleep == 0); lock(r->l); + ignusr1(1); + if(r->asleep && r->pid == getpid()){ +print("resleep %d\n", getpid()); + /* Didn't really wake up - signal from something else */ + goto again; + } } void @@ -233,6 +238,7 @@ static char *threadexitsmsg; void sigusr2handler(int s) { + print("%d usr2 %d\n", time(0), getpid()); if(threadexitsmsg) _exits(threadexitsmsg); } @@ -259,6 +265,35 @@ 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 f31b004a..dfdb71b6 100644 --- a/src/libthread/exec.c +++ b/src/libthread/exec.c @@ -6,26 +6,36 @@ static Lock thewaitlock; static Channel *thewaitchan; -static Channel *dowaitchan; -static Channel *execchan; +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) { Channel *c; Waitmsg *w; - Execjob *e; _threadsetsysproc(); + _threadexecproc = proc(); + threadcreate(execthread, nil, 65536); for(;;){ - for(;;){ - while((e = nbrecvp(execchan)) != nil) - sendul(e->c, _threadspawn(e->fd, e->cmd, e->argv)); - if((w = wait()) != nil) - break; + while((w = wait()) == nil) if(errno == ECHILD) - recvul(dowaitchan); - } + recvul(_dowaitchan); if((c = thewaitchan) != nil) sendp(c, w); else @@ -94,20 +104,20 @@ _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); + channbsendul(_dowaitchan, 1); return pid; } int threadspawn(int fd[3], char *cmd, char *argv[]) { - if(dowaitchan == nil){ + if(_dowaitchan == nil){ lock(&thewaitlock); - if(dowaitchan == nil){ - dowaitchan = chancreate(sizeof(ulong), 1); - chansetname(dowaitchan, "dowaitchan"); - execchan = chancreate(sizeof(void*), 0); - chansetname(execchan, "execchan"); + 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); diff --git a/src/libthread/test/mkfile b/src/libthread/test/mkfile new file mode 100644 index 00000000..b3fd821c --- /dev/null +++ b/src/libthread/test/mkfile @@ -0,0 +1,8 @@ +<$PLAN9/src/mkhdr + +SHORTLIB=thread 9 +OFILES= + +TARG=tprimes tspawn tspawnloop + +<$PLAN9/src/mkmany diff --git a/src/libthread/thread.c b/src/libthread/thread.c index 4116ac22..8f838b62 100644 --- a/src/libthread/thread.c +++ b/src/libthread/thread.c @@ -184,7 +184,9 @@ scheduler(Proc *p) if(p->nthread == 0) goto Out; p->runrend.l = &p->lock; +print("sleep for jobs %d\n", getpid()); _procsleep(&p->runrend); +print("wake from jobs %d\n", getpid()); } delthread(&p->runqueue, t); unlock(&p->lock); diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h index 9f0a53d5..6bc8cbfc 100644 --- a/src/libthread/threadimpl.h +++ b/src/libthread/threadimpl.h @@ -5,6 +5,8 @@ typedef struct Execjob Execjob; typedef struct Proc Proc; typedef struct _Procrendez _Procrendez; + + typedef struct Jmp Jmp; struct Jmp { @@ -88,6 +90,10 @@ struct Proc extern Proc *_threadprocs; extern Lock _threadprocslock; +extern Proc *_threadexecproc; +extern Channel *_threadexecchan; +extern QLock _threadexeclock; +extern Channel *_dowaitchan; extern void _procstart(Proc*, void (*fn)(Proc*)); extern _Thread *_threadcreate(Proc*, void(*fn)(void*), void*, uint); -- cgit v1.2.3