Commit Diff


commit - e127e40bb1327662a05f5b70dd1bbca5c69b042c
commit + 955a2ca78d7efc2787864e38a3d902df16fc2541
blob - 4be2c48165f5be956dec2137fcfd4ead988b90c4
blob + d6d31afae5a91f9a5780f376091a3b20de32ab60
--- src/libthread/Linux.c
+++ src/libthread/Linux.c
@@ -87,6 +87,7 @@ _procsleep(_Procrendez *r)
 	 * unlock the vouslock so our waker can wake us,
 	 * and then suspend.
 	 */
+again:
 	r->asleep = 1;
 	r->pid = getpid();
 
@@ -101,9 +102,13 @@ _procsleep(_Procrendez *r)
 	/*
 	 * We're awake.  Make USR1 not interrupt system calls.
 	 */
-	ignusr1(1);
-	assert(r->asleep == 0);
 	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
@@ -233,6 +238,7 @@ static char *threadexitsmsg;
 void
 sigusr2handler(int s)
 {
+	print("%d usr2 %d\n", time(0), getpid());
 	if(threadexitsmsg)
 		_exits(threadexitsmsg);
 }
@@ -260,6 +266,35 @@ 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 - f31b004ad2099c50b0b2840210e0a5da05f35f7e
blob + dfdb71b614bf8d47b3a322ffc7611f9fc71293ea
--- src/libthread/exec.c
+++ src/libthread/exec.c
@@ -6,26 +6,36 @@
 
 static Lock thewaitlock;
 static Channel *thewaitchan;
-static Channel *dowaitchan;
-static Channel *execchan;
+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)
 {
 	Channel *c;
 	Waitmsg *w;
-	Execjob *e;
 
 	_threadsetsysproc();
+	_threadexecproc = proc();
+	threadcreate(execthread, nil, 65536);
 	for(;;){
-		for(;;){
-			while((e = nbrecvp(execchan)) != nil)
-				sendul(e->c, _threadspawn(e->fd, e->cmd, e->argv));
-			if((w = wait()) != nil)
-				break;
+		while((w = wait()) == nil)
 			if(errno == ECHILD)
-				recvul(dowaitchan);
-		}
+				recvul(_dowaitchan);
 		if((c = thewaitchan) != nil)
 			sendp(c, w);
 		else
@@ -94,20 +104,20 @@ _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);
+	channbsendul(_dowaitchan, 1);
 	return pid;
 }
 
 int
 threadspawn(int fd[3], char *cmd, char *argv[])
 {
-	if(dowaitchan == nil){
+	if(_dowaitchan == nil){
 		lock(&thewaitlock);
-		if(dowaitchan == nil){
-			dowaitchan = chancreate(sizeof(ulong), 1);
-			chansetname(dowaitchan, "dowaitchan");
-			execchan = chancreate(sizeof(void*), 0);
-			chansetname(execchan, "execchan");
+		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);
blob - /dev/null
blob + b3fd821c010796effab35c96da3cb54dac40d5aa (mode 644)
--- /dev/null
+++ src/libthread/test/mkfile
@@ -0,0 +1,8 @@
+<$PLAN9/src/mkhdr
+
+SHORTLIB=thread 9
+OFILES=
+
+TARG=tprimes tspawn tspawnloop
+
+<$PLAN9/src/mkmany
blob - 4116ac22ea4f9f0bccfd02fa313b97bb9bc26174
blob + 8f838b62adbb4ec1c63ad087394fa68d530373f9
--- src/libthread/thread.c
+++ src/libthread/thread.c
@@ -184,7 +184,9 @@ scheduler(Proc *p)
 			if(p->nthread == 0)
 				goto Out;
 			p->runrend.l = &p->lock;
+print("sleep for jobs %d\n", getpid());
 			_procsleep(&p->runrend);
+print("wake from jobs %d\n", getpid());
 		}
 		delthread(&p->runqueue, t);
 		unlock(&p->lock);
blob - 9f0a53d520a34727cbd144a540bd7934a7808a23
blob + 6bc8cbfcb86489009d0654c44cdfe315142aac05
--- src/libthread/threadimpl.h
+++ src/libthread/threadimpl.h
@@ -5,6 +5,8 @@ typedef struct Execjob Execjob;
 typedef struct Proc Proc;
 typedef struct _Procrendez _Procrendez;
 
+
+
 typedef struct Jmp Jmp;
 struct Jmp
 {
@@ -88,6 +90,10 @@ struct Proc
 
 extern Proc *_threadprocs;
 extern Lock _threadprocslock;
+extern Proc *_threadexecproc;
+extern Channel *_threadexecchan;
+extern QLock _threadexeclock;
+extern Channel *_dowaitchan;
 
 extern void _procstart(Proc*, void (*fn)(Proc*));
 extern _Thread *_threadcreate(Proc*, void(*fn)(void*), void*, uint);