starting to work on Linux

This commit is contained in:
rsc 2004-12-27 18:21:58 +00:00
parent e127e40bb1
commit 955a2ca78d
5 changed files with 80 additions and 19 deletions

View file

@ -87,6 +87,7 @@ _procsleep(_Procrendez *r)
* unlock the vouslock so our waker can wake us, * unlock the vouslock so our waker can wake us,
* and then suspend. * and then suspend.
*/ */
again:
r->asleep = 1; r->asleep = 1;
r->pid = getpid(); r->pid = getpid();
@ -101,9 +102,13 @@ _procsleep(_Procrendez *r)
/* /*
* We're awake. Make USR1 not interrupt system calls. * We're awake. Make USR1 not interrupt system calls.
*/ */
ignusr1(1);
assert(r->asleep == 0);
lock(r->l); 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 void
@ -233,6 +238,7 @@ static char *threadexitsmsg;
void void
sigusr2handler(int s) sigusr2handler(int s)
{ {
print("%d usr2 %d\n", time(0), getpid());
if(threadexitsmsg) if(threadexitsmsg)
_exits(threadexitsmsg); _exits(threadexitsmsg);
} }
@ -259,6 +265,35 @@ threadexitsall(char *msg)
exits(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 * per-process data, indexed by pid
* *

View file

@ -6,26 +6,36 @@
static Lock thewaitlock; static Lock thewaitlock;
static Channel *thewaitchan; static Channel *thewaitchan;
static Channel *dowaitchan; Channel *_dowaitchan;
static Channel *execchan; 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 static void
waitproc(void *v) waitproc(void *v)
{ {
Channel *c; Channel *c;
Waitmsg *w; Waitmsg *w;
Execjob *e;
_threadsetsysproc(); _threadsetsysproc();
_threadexecproc = proc();
threadcreate(execthread, nil, 65536);
for(;;){ for(;;){
for(;;){ while((w = wait()) == nil)
while((e = nbrecvp(execchan)) != nil)
sendul(e->c, _threadspawn(e->fd, e->cmd, e->argv));
if((w = wait()) != nil)
break;
if(errno == ECHILD) if(errno == ECHILD)
recvul(dowaitchan); recvul(_dowaitchan);
}
if((c = thewaitchan) != nil) if((c = thewaitchan) != nil)
sendp(c, w); sendp(c, w);
else else
@ -94,20 +104,20 @@ _threadspawn(int fd[3], char *cmd, char *argv[])
close(fd[1]); close(fd[1]);
if(fd[2] != fd[1] && fd[2] != fd[0]) if(fd[2] != fd[1] && fd[2] != fd[0])
close(fd[2]); close(fd[2]);
channbsendul(dowaitchan, 1); channbsendul(_dowaitchan, 1);
return pid; return pid;
} }
int int
threadspawn(int fd[3], char *cmd, char *argv[]) threadspawn(int fd[3], char *cmd, char *argv[])
{ {
if(dowaitchan == nil){ if(_dowaitchan == nil){
lock(&thewaitlock); lock(&thewaitlock);
if(dowaitchan == nil){ if(_dowaitchan == nil){
dowaitchan = chancreate(sizeof(ulong), 1); _dowaitchan = chancreate(sizeof(ulong), 1);
chansetname(dowaitchan, "dowaitchan"); chansetname(_dowaitchan, "dowaitchan");
execchan = chancreate(sizeof(void*), 0); _threadexecchan = chancreate(sizeof(void*), 1);
chansetname(execchan, "execchan"); chansetname(_threadexecchan, "execchan");
proccreate(waitproc, nil, STACK); proccreate(waitproc, nil, STACK);
} }
unlock(&thewaitlock); unlock(&thewaitlock);

View file

@ -0,0 +1,8 @@
<$PLAN9/src/mkhdr
SHORTLIB=thread 9
OFILES=
TARG=tprimes tspawn tspawnloop
<$PLAN9/src/mkmany

View file

@ -184,7 +184,9 @@ scheduler(Proc *p)
if(p->nthread == 0) if(p->nthread == 0)
goto Out; goto Out;
p->runrend.l = &p->lock; p->runrend.l = &p->lock;
print("sleep for jobs %d\n", getpid());
_procsleep(&p->runrend); _procsleep(&p->runrend);
print("wake from jobs %d\n", getpid());
} }
delthread(&p->runqueue, t); delthread(&p->runqueue, t);
unlock(&p->lock); unlock(&p->lock);

View file

@ -5,6 +5,8 @@ typedef struct Execjob Execjob;
typedef struct Proc Proc; typedef struct Proc Proc;
typedef struct _Procrendez _Procrendez; typedef struct _Procrendez _Procrendez;
typedef struct Jmp Jmp; typedef struct Jmp Jmp;
struct Jmp struct Jmp
{ {
@ -88,6 +90,10 @@ struct Proc
extern Proc *_threadprocs; extern Proc *_threadprocs;
extern Lock _threadprocslock; extern Lock _threadprocslock;
extern Proc *_threadexecproc;
extern Channel *_threadexecchan;
extern QLock _threadexeclock;
extern Channel *_dowaitchan;
extern void _procstart(Proc*, void (*fn)(Proc*)); extern void _procstart(Proc*, void (*fn)(Proc*));
extern _Thread *_threadcreate(Proc*, void(*fn)(void*), void*, uint); extern _Thread *_threadcreate(Proc*, void(*fn)(void*), void*, uint);