commit 8cbd854a8ab2c4f8c738c5bea5263217cb892a77 from: rsc date: Mon Dec 27 19:11:33 2004 UTC better exec handling commit - 03417610742c4a67bb0345a8fa0fb4e13dee07f7 commit + 8cbd854a8ab2c4f8c738c5bea5263217cb892a77 blob - d6d31afae5a91f9a5780f376091a3b20de32ab60 blob + 357e9260003242de3aac7ea87b5549bd83d51abe --- src/libthread/Linux.c +++ src/libthread/Linux.c @@ -99,13 +99,15 @@ again: sigdelset(&mask, SIGUSR1); sigsuspend(&mask); +//print("%d %d awake again\n", time(0), getpid()); + /* * We're awake. Make USR1 not interrupt system calls. */ lock(r->l); ignusr1(1); 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 */ goto again; } @@ -266,35 +268,6 @@ threadexitsall(char *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 * * could use modify_ldt and a segment register blob - dfdb71b614bf8d47b3a322ffc7611f9fc71293ea blob + 6a7ca1dbf151e508c7c0a05d94f2a701170cbe78 --- src/libthread/exec.c +++ src/libthread/exec.c @@ -6,43 +6,44 @@ static Lock thewaitlock; static Channel *thewaitchan; -Channel *_dowaitchan; -Channel *_threadexecchan; -Proc *_threadexecproc; -QLock _threadexeclock; 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; + Execjob *e; Waitmsg *w; - _threadsetsysproc(); - _threadexecproc = proc(); - threadcreate(execthread, nil, 65536); - for(;;){ - while((w = wait()) == nil) - if(errno == ECHILD) - recvul(_dowaitchan); + e = v; + pid = _threadspawn(e->fd, e->cmd, e->argv); + sendul(e->c, pid); + if(pid > 0){ + w = waitfor(pid); if((c = thewaitchan) != nil) sendp(c, w); else 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* threadwaitchan(void) { @@ -104,28 +105,15 @@ _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); return pid; } int 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); } - int _threadexec(Channel *cpid, int fd[3], char *cmd, char *argv[]) { blob - e1fed2bff4a43749abe88446e367ba5254e32ced blob + 2ddd8c72777c7d410ba56c615e54b4725aa727bb --- src/libthread/pthread.c +++ src/libthread/pthread.c @@ -130,9 +130,3 @@ _pthreadinit(void) pthread_key_create(&prockey, 0); } -int -_runthreadspawn(int *fd, char *cmd, char **argv) -{ - return _threadspawn(fd, cmd, argv); -} - blob - 8f838b62adbb4ec1c63ad087394fa68d530373f9 blob + 1837e7d910d2d4b364c5d29a157f7b841b035f83 --- src/libthread/thread.c +++ src/libthread/thread.c @@ -138,15 +138,23 @@ _threadready(_Thread *t) p = t->proc; lock(&p->lock); 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); } -void +int threadyield(void) { - _threadready(proc()->thread); + int n; + Proc *p; + + p = proc(); + n = p->nswitch; + _threadready(p->thread); _threadswitch(); + return p->nswitch - n; } void @@ -184,13 +192,14 @@ scheduler(Proc *p) if(p->nthread == 0) goto Out; 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); -print("wake from jobs %d\n", getpid()); +//print("%d wake from jobs %d\n", time(0), getpid()); } delthread(&p->runqueue, t); unlock(&p->lock); p->thread = t; + p->nswitch++; // print("run %s %d\n", t->name, t->id); contextswitch(&p->schedcontext, &t->context); p->thread = nil; blob - 6bc8cbfcb86489009d0654c44cdfe315142aac05 blob + 164ba978e9554cee376792e7c69ff9dc70cedacd --- src/libthread/threadimpl.h +++ src/libthread/threadimpl.h @@ -74,6 +74,7 @@ struct Proc uint osprocid; #endif Lock lock; + int nswitch; _Thread *thread; _Threadlist runqueue; _Threadlist allthreads;