starting to work on Linux
This commit is contained in:
parent
e127e40bb1
commit
955a2ca78d
5 changed files with 80 additions and 19 deletions
|
|
@ -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
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
8
src/libthread/test/mkfile
Normal file
8
src/libthread/test/mkfile
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
<$PLAN9/src/mkhdr
|
||||||
|
|
||||||
|
SHORTLIB=thread 9
|
||||||
|
OFILES=
|
||||||
|
|
||||||
|
TARG=tprimes tspawn tspawnloop
|
||||||
|
|
||||||
|
<$PLAN9/src/mkmany
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue