mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-12 11:10:07 +00:00
better exec handling
This commit is contained in:
parent
0341761074
commit
8cbd854a8a
5 changed files with 43 additions and 78 deletions
|
@ -99,13 +99,15 @@ again:
|
||||||
sigdelset(&mask, SIGUSR1);
|
sigdelset(&mask, SIGUSR1);
|
||||||
sigsuspend(&mask);
|
sigsuspend(&mask);
|
||||||
|
|
||||||
|
//print("%d %d awake again\n", time(0), getpid());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We're awake. Make USR1 not interrupt system calls.
|
* We're awake. Make USR1 not interrupt system calls.
|
||||||
*/
|
*/
|
||||||
lock(r->l);
|
lock(r->l);
|
||||||
ignusr1(1);
|
ignusr1(1);
|
||||||
if(r->asleep && r->pid == getpid()){
|
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 */
|
/* Didn't really wake up - signal from something else */
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
|
@ -265,35 +267,6 @@ 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,41 +6,42 @@
|
||||||
|
|
||||||
static Lock thewaitlock;
|
static Lock thewaitlock;
|
||||||
static Channel *thewaitchan;
|
static Channel *thewaitchan;
|
||||||
Channel *_dowaitchan;
|
|
||||||
Channel *_threadexecchan;
|
|
||||||
Proc *_threadexecproc;
|
|
||||||
QLock _threadexeclock;
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
execthread(void *v)
|
execproc(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)
|
|
||||||
{
|
{
|
||||||
|
int pid;
|
||||||
Channel *c;
|
Channel *c;
|
||||||
|
Execjob *e;
|
||||||
Waitmsg *w;
|
Waitmsg *w;
|
||||||
|
|
||||||
_threadsetsysproc();
|
e = v;
|
||||||
_threadexecproc = proc();
|
pid = _threadspawn(e->fd, e->cmd, e->argv);
|
||||||
threadcreate(execthread, nil, 65536);
|
sendul(e->c, pid);
|
||||||
for(;;){
|
if(pid > 0){
|
||||||
while((w = wait()) == nil)
|
w = waitfor(pid);
|
||||||
if(errno == ECHILD)
|
|
||||||
recvul(_dowaitchan);
|
|
||||||
if((c = thewaitchan) != nil)
|
if((c = thewaitchan) != nil)
|
||||||
sendp(c, w);
|
sendp(c, w);
|
||||||
else
|
else
|
||||||
free(w);
|
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*
|
Channel*
|
||||||
|
@ -104,28 +105,15 @@ _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);
|
|
||||||
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){
|
|
||||||
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);
|
return _runthreadspawn(fd, cmd, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
_threadexec(Channel *cpid, int fd[3], char *cmd, char *argv[])
|
_threadexec(Channel *cpid, int fd[3], char *cmd, char *argv[])
|
||||||
{
|
{
|
||||||
|
|
|
@ -130,9 +130,3 @@ _pthreadinit(void)
|
||||||
pthread_key_create(&prockey, 0);
|
pthread_key_create(&prockey, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
_runthreadspawn(int *fd, char *cmd, char **argv)
|
|
||||||
{
|
|
||||||
return _threadspawn(fd, cmd, argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -138,15 +138,23 @@ _threadready(_Thread *t)
|
||||||
p = t->proc;
|
p = t->proc;
|
||||||
lock(&p->lock);
|
lock(&p->lock);
|
||||||
addthread(&p->runqueue, t);
|
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);
|
unlock(&p->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
threadyield(void)
|
threadyield(void)
|
||||||
{
|
{
|
||||||
_threadready(proc()->thread);
|
int n;
|
||||||
|
Proc *p;
|
||||||
|
|
||||||
|
p = proc();
|
||||||
|
n = p->nswitch;
|
||||||
|
_threadready(p->thread);
|
||||||
_threadswitch();
|
_threadswitch();
|
||||||
|
return p->nswitch - n;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -184,13 +192,14 @@ 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());
|
//print("%d sleep for jobs %d\n", time(0), getpid());
|
||||||
_procsleep(&p->runrend);
|
_procsleep(&p->runrend);
|
||||||
print("wake from jobs %d\n", getpid());
|
//print("%d wake from jobs %d\n", time(0), getpid());
|
||||||
}
|
}
|
||||||
delthread(&p->runqueue, t);
|
delthread(&p->runqueue, t);
|
||||||
unlock(&p->lock);
|
unlock(&p->lock);
|
||||||
p->thread = t;
|
p->thread = t;
|
||||||
|
p->nswitch++;
|
||||||
// print("run %s %d\n", t->name, t->id);
|
// print("run %s %d\n", t->name, t->id);
|
||||||
contextswitch(&p->schedcontext, &t->context);
|
contextswitch(&p->schedcontext, &t->context);
|
||||||
p->thread = nil;
|
p->thread = nil;
|
||||||
|
|
|
@ -74,6 +74,7 @@ struct Proc
|
||||||
uint osprocid;
|
uint osprocid;
|
||||||
#endif
|
#endif
|
||||||
Lock lock;
|
Lock lock;
|
||||||
|
int nswitch;
|
||||||
_Thread *thread;
|
_Thread *thread;
|
||||||
_Threadlist runqueue;
|
_Threadlist runqueue;
|
||||||
_Threadlist allthreads;
|
_Threadlist allthreads;
|
||||||
|
|
Loading…
Reference in a new issue