better exec handling

This commit is contained in:
rsc 2004-12-27 19:11:33 +00:00
parent 0341761074
commit 8cbd854a8a
5 changed files with 43 additions and 78 deletions

View file

@ -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
* *

View file

@ -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[])
{ {

View file

@ -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);
}

View file

@ -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);
//print("%d wake for job %d->%d\n", time(0), getpid(), p->osprocid);
if(p != proc())
_procwakeup(&p->runrend); _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;

View file

@ -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;