Commit Diff


commit - 929fcfe0e3affc81cb02e49c0f1320408ce9260c
commit + 2c87dda8f89e84082523b03b62c5d47d55c13341
blob - 7ba96e6730cbc0efe96cc0b2174f9819416ad41d
blob + 84adb220118aef68cf2244054f7f694c460f2f00
--- include/thread.h
+++ include/thread.h
@@ -22,6 +22,11 @@ _Thread	*_threadwakeup(Rendez*);
 #define	yield		threadyield
 
 /*
+ * daemonize
+ */
+void	threaddaemonize(void);
+
+/*
  * per proc and thread data
  */
 void		**procdata(void);
blob - 357e9260003242de3aac7ea87b5549bd83d51abe
blob + 1c9d8c202149e981fb1c773c1dd7408a2c512052
--- src/libthread/Linux.c
+++ src/libthread/Linux.c
@@ -8,6 +8,9 @@
 #include "thread.h"
 #include "threadimpl.h"
 
+int ngetpid;
+
+
 /*
  * spin locks
  */
@@ -99,15 +102,12 @@ 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());
 		/* Didn't really wake up - signal from something else */
 		goto again;
 	}
@@ -160,11 +160,15 @@ dofreestacks(void)
 		next = sf->next;
 		if(sf->pid >= 1 && kill(sf->pid, 0) < 0 && errno == ESRCH){
 			free(sf);
-			last->next = next;
+			if(last)
+				last->next = next;
+			else
+				stackfree = next;
 			sf = last;
 		}
 	}
-}	
+	unlock(&stacklock);
+}
 
 static int
 startprocfn(void *v)
@@ -240,7 +244,7 @@ static char *threadexitsmsg;
 void
 sigusr2handler(int s)
 {
-	print("%d usr2 %d\n", time(0), getpid());
+/*	fprint(2, "%d usr2 %d\n", time(0), getpid()); */
 	if(threadexitsmsg)
 		_exits(threadexitsmsg);
 }
@@ -341,7 +345,8 @@ _threadsetproc(Proc *p)
 {
 	Perproc *pp;
 
-	p->osprocid = getpid();
+	if(p)
+		p->osprocid = getpid();
 	pp = newperproc();
 	pp->proc = p;
 	if(p == nil)
blob - 2296690f4a624694d84e7ca9a118608a876b37cd
blob + 0bf7946840ff7bf69283564d9ad65559579ba10e
--- src/libthread/ioproc.c
+++ src/libthread/ioproc.c
@@ -20,6 +20,8 @@ static void
 xioproc(void *a)
 {
 	Ioproc *io, *x;
+
+	threadsetname("ioproc");
 	io = a;
 	/*
 	 * first recvp acquires the ioproc.
blob - a301d48f122092d8bd34d14b495abd352ce1a62b
blob + fc681492034f7127bd863e11208bf2132bca79d2
--- src/libthread/mkfile
+++ src/libthread/mkfile
@@ -6,6 +6,7 @@ LIB=libthread.a
 OFILES=\
 	$SYSOFILES\
 	channel.$O\
+	daemonize.$O\
 	exec.$O\
 	ioproc.$O\
 	iorw.$O\
blob - b3fd821c010796effab35c96da3cb54dac40d5aa
blob + 87dd932c91b0dd3e87fdb87f007643747b66679c
--- src/libthread/test/mkfile
+++ src/libthread/test/mkfile
@@ -3,6 +3,6 @@
 SHORTLIB=thread 9
 OFILES=
 
-TARG=tprimes tspawn tspawnloop
+TARG=tprimes tspawn tspawnloop tdaemon
 
 <$PLAN9/src/mkmany
blob - 1837e7d910d2d4b364c5d29a157f7b841b035f83
blob + b41f9f341b366be3e7e34545ebef9192c7de0664
--- src/libthread/thread.c
+++ src/libthread/thread.c
@@ -20,6 +20,25 @@ static	void		delthreadinproc(Proc*, _Thread*);
 static	void		contextswitch(Context *from, Context *to);
 static	void		scheduler(Proc*);
 
+static void
+_threaddebug(char *fmt, ...)
+{
+	va_list arg;
+	char buf[128];
+	_Thread *t;
+
+	return;
+
+	va_start(arg, fmt);
+	vsnprint(buf, sizeof buf, fmt, arg);
+	va_end(arg);
+	t = proc()->thread;
+	if(t)
+		fprint(2, "%d.%d: %s\n", getpid(), t->id, buf);
+	else
+		fprint(2, "%d._: %s\n", getpid(), buf);
+}
+
 static _Thread*
 getthreadnow(void)
 {
@@ -50,6 +69,7 @@ threadstart(void *v)
 
 	t = v;
 	t->startfn(t->startarg);
+	memset(&v, 0xff, 32);	/* try to cut off stack traces */
 	threadexits(nil);
 }
 
@@ -81,7 +101,7 @@ threadalloc(void (*fn)(void*), void *arg, uint stack)
 	/* call makecontext to do the real work. */
 	/* leave a few words open on both ends */
 	t->context.uc.uc_stack.ss_sp = t->stk+8;
-	t->context.uc.uc_stack.ss_size = t->stksize-16;
+	t->context.uc.uc_stack.ss_size = t->stksize-64;
 	makecontext(&t->context.uc, (void(*)())threadstart, 1, t);
 
 	return t;
@@ -185,6 +205,7 @@ scheduler(Proc *p)
 	_Thread *t;
 
 	setproc(p);
+	_threaddebug("scheduler enter");
 	// print("s %p %d\n", p, gettid());
 	lock(&p->lock);
 	for(;;){
@@ -192,15 +213,15 @@ scheduler(Proc *p)
 			if(p->nthread == 0)
 				goto Out;
 			p->runrend.l = &p->lock;
-//print("%d sleep for jobs %d\n", time(0), getpid());
+			_threaddebug("scheduler sleep");
 			_procsleep(&p->runrend);
-//print("%d wake from jobs %d\n", time(0), getpid());
+			_threaddebug("scheduler wake");
 		}
 		delthread(&p->runqueue, t);
 		unlock(&p->lock);
 		p->thread = t;
 		p->nswitch++;
-		// print("run %s %d\n", t->name, t->id);
+		_threaddebug("run %d (%s)", t->id, t->name);
 		contextswitch(&p->schedcontext, &t->context);
 		p->thread = nil;
 		lock(&p->lock);
@@ -212,6 +233,7 @@ scheduler(Proc *p)
 	}
 
 Out:
+	_threaddebug("scheduler exit");
 	delproc(p);
 	lock(&threadnproclock);
 	if(p->sysproc)
@@ -445,6 +467,11 @@ threadmainstart(void *v)
 	USED(v);
 	threadmainproc = proc();
 	threadmain(threadargc, threadargv);
+}
+
+void
+threadlinklibrary(void)
+{
 }
 
 int
@@ -452,6 +479,8 @@ main(int argc, char **argv)
 {
 	Proc *p;
 
+	_threadsetupdaemonize();
+
 	threadargc = argc;
 	threadargv = argv;
 
blob - 164ba978e9554cee376792e7c69ff9dc70cedacd
blob + d4acebeb2d2ed417d063483a6bd641f00a546880
--- src/libthread/threadimpl.h
+++ src/libthread/threadimpl.h
@@ -5,8 +5,6 @@ typedef struct Execjob Execjob;
 typedef struct Proc Proc;
 typedef struct _Procrendez _Procrendez;
 
-
-
 typedef struct Jmp Jmp;
 struct Jmp
 {
@@ -106,3 +104,5 @@ extern void _threadunlock(Lock*, ulong);
 extern void _pthreadinit(void);
 extern int _threadspawn(int*, char*, char**);
 extern int _runthreadspawn(int*, char*, char**);
+extern void _threadsetupdaemonize(void);
+extern void _threaddodaemonize(char*);