aboutsummaryrefslogtreecommitdiff
path: root/src/libthread
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2004-12-27 19:11:33 +0000
committerrsc <devnull@localhost>2004-12-27 19:11:33 +0000
commit8cbd854a8ab2c4f8c738c5bea5263217cb892a77 (patch)
tree0908a1e1cd3388a83308af104ae131fe663ef72b /src/libthread
parent03417610742c4a67bb0345a8fa0fb4e13dee07f7 (diff)
downloadplan9port-8cbd854a8ab2c4f8c738c5bea5263217cb892a77.tar.gz
plan9port-8cbd854a8ab2c4f8c738c5bea5263217cb892a77.tar.bz2
plan9port-8cbd854a8ab2c4f8c738c5bea5263217cb892a77.zip
better exec handling
Diffstat (limited to 'src/libthread')
-rw-r--r--src/libthread/Linux.c33
-rw-r--r--src/libthread/exec.c62
-rw-r--r--src/libthread/pthread.c6
-rw-r--r--src/libthread/thread.c19
-rw-r--r--src/libthread/threadimpl.h1
5 files changed, 43 insertions, 78 deletions
diff --git a/src/libthread/Linux.c b/src/libthread/Linux.c
index d6d31afa..357e9260 100644
--- a/src/libthread/Linux.c
+++ b/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
diff --git a/src/libthread/exec.c b/src/libthread/exec.c
index dfdb71b6..6a7ca1db 100644
--- a/src/libthread/exec.c
+++ b/src/libthread/exec.c
@@ -6,41 +6,42 @@
static Lock thewaitlock;
static Channel *thewaitchan;
-Channel *_dowaitchan;
-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
-waitproc(void *v)
+execproc(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*
@@ -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[])
{
diff --git a/src/libthread/pthread.c b/src/libthread/pthread.c
index e1fed2bf..2ddd8c72 100644
--- a/src/libthread/pthread.c
+++ b/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);
-}
-
diff --git a/src/libthread/thread.c b/src/libthread/thread.c
index 8f838b62..1837e7d9 100644
--- a/src/libthread/thread.c
+++ b/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;
diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h
index 6bc8cbfc..164ba978 100644
--- a/src/libthread/threadimpl.h
+++ b/src/libthread/threadimpl.h
@@ -74,6 +74,7 @@ struct Proc
uint osprocid;
#endif
Lock lock;
+ int nswitch;
_Thread *thread;
_Threadlist runqueue;
_Threadlist allthreads;