make -> mk remove clumsy stack hack. fix exec. fix nthreads maintenance. fix threadexitsall not to kill self. add sun support.
diff --git a/src/libthread/Makefile b/src/libthread/Makefile deleted file mode 100644 index 654c031..0000000 --- a/src/libthread/Makefile +++ /dev/null
@@ -1,52 +0,0 @@ -PLAN9=../.. -include $(PLAN9)/src/Makehdr - -LIB=libthread.a - -OFILES=\ - $(OBJTYPE).$O\ - asm-$(SYSNAME)-$(OBJTYPE).$O\ - channel.$O\ - chanprint.$O\ - create.$O\ - debug.$O\ - exec-unix.$O\ - exit.$O\ - getpid.$O\ - id.$O\ - iocall.$O\ - ioclose.$O\ - ioopen.$O\ - ioproc.$O\ - ioread.$O\ - ioreadn.$O\ - iowrite.$O\ - kill.$O\ - lib.$O\ - main.$O\ - memset.$O\ - memsetd.$O\ - note.$O\ - proctab.$O\ - ref.$O\ - rendez.$O\ - sched.$O\ - -HFILES=\ - $(PLAN9)/include/thread.h\ - label.h\ - threadimpl.h\ - -include $(PLAN9)/src/Makesyslib - -tprimes: tprimes.$O $(PLAN9)/lib/$(LIB) - $(LD) -o tprimes tprimes.$O $(LDFLAGS) -lthread -l9 -lfmt -lutf - -texec: texec.$O $(PLAN9)/lib/$(LIB) - $(LD) -o texec texec.$O $(LDFLAGS) -lthread -l9 -lfmt -lutf - -trend: trend.$O $(PLAN9)/lib/$(LIB) - $(LD) -o trend trend.$O $(LDFLAGS) -lthread -l9 -lfmt -lutf - -CLEANFILES+=tprimes texec -
diff --git a/src/libthread/create.c b/src/libthread/create.c index 49e1572..6a44c24 100644 --- a/src/libthread/create.c +++ b/src/libthread/create.c
@@ -7,54 +7,10 @@ /* * Create and initialize a new Thread structure attached to a given proc. */ - -typedef struct Stack Stack; -struct Stack { - ulong magic; - Thread *thr; - Stack *next; - uchar buf[STKSIZE-12]; -}; - -static Stack *stkfree; -static Lock stklock; - void _stackfree(void *v) { - Stack *s; - - s = v; - lock(&stklock); - s->thr = nil; - s->magic = 0; - s->next = stkfree; - stkfree = s; - unlock(&stklock); -} - -static Stack* -stackalloc(void) -{ - char *buf; - Stack *s; - int i; - - lock(&stklock); - while(stkfree == nil){ - unlock(&stklock); - assert(STKSIZE == sizeof(Stack)); - buf = malloc(STKSIZE+128*STKSIZE); - s = (Stack*)(((ulong)buf+STKSIZE)&~(STKSIZE-1)); - for(i=0; i<128; i++) - _stackfree(&s[i]); - lock(&stklock); - } - s = stkfree; - stkfree = stkfree->next; - unlock(&stklock); - s->magic = STKMAGIC; - return s; + free(v); } static int @@ -62,16 +18,15 @@ { int id; Thread *t; - Stack *s; + char *s; if(stacksize < 32) sysfatal("bad stacksize %d", stacksize); t = _threadmalloc(sizeof(Thread), 1); - s = stackalloc(); - s->thr = t; + s = _threadmalloc(stacksize, 0); t->stk = (char*)s; - t->stksize = STKSIZE; - _threaddebugmemset(s->buf, 0xFE, sizeof s->buf); + t->stksize = stacksize; + _threaddebugmemset(s, 0xFE, stacksize); _threadinitstack(t, f, arg); t->proc = p; t->grp = grp; @@ -138,7 +93,7 @@ if(t->cmdname) free(t->cmdname); assert(t->stk != nil); - _stackfree((Stack*)t->stk); + _stackfree(t->stk); nextt = t->nextt; free(t); }
diff --git a/src/libthread/exec-unix.c b/src/libthread/exec-unix.c index 5a37e34..6e4f728 100644 --- a/src/libthread/exec-unix.c +++ b/src/libthread/exec-unix.c
@@ -9,11 +9,13 @@ Proc *p; Thread *t; +print("procexec\n"); _threaddebug(DBGEXEC, "procexec %s", prog); /* must be only thread in proc */ p = _threadgetproc(); t = p->thread; if(p->threads.head != t || p->threads.head->nextt != nil){ +print("not only thread\n"); werrstr("not only thread in proc"); Bad: if(pidc) @@ -34,26 +36,35 @@ * pipe to us. */ if(pipe(p->exec.fd) < 0) +{ +print("pipe\n"); goto Bad; +} if(fcntl(p->exec.fd[1], F_SETFD, 1) < 0) +{ +print("fcntl\n"); goto Bad; +} /* exec in parallel via the scheduler */ assert(p->needexec==0); p->exec.prog = prog; p->exec.args = args; p->needexec = 1; +print("sched\n"); _sched(); close(p->exec.fd[1]); if((n = read(p->exec.fd[0], p->exitstr, ERRMAX-1)) > 0){ /* exec failed */ p->exitstr[n] = '\0'; +print("read got %s\n", p->exitstr); errstr(p->exitstr, ERRMAX); close(p->exec.fd[0]); goto Bad; } close(p->exec.fd[0]); +print("exec %d\n", pidc); if(pidc) sendul(pidc, t->ret);
diff --git a/src/libthread/exit.c b/src/libthread/exit.c index ddf7001..511e5bc 100644 --- a/src/libthread/exit.c +++ b/src/libthread/exit.c
@@ -1,5 +1,5 @@ -#include "threadimpl.h" #include <signal.h> +#include "threadimpl.h" char *_threadexitsallstatus; Channel *_threadwaitchan; @@ -13,6 +13,7 @@ p = _threadgetproc(); t = p->thread; t->moribund = 1; + _threaddebug(DBGSCHED, "threadexits %s", exitstr); if(exitstr==nil) exitstr=""; utfecpy(p->exitstr, p->exitstr+ERRMAX, exitstr); @@ -26,6 +27,7 @@ int *pid; int i, npid, mypid; + _threaddebug(DBGSCHED, "threadexitsall %s", exitstr); if(exitstr == nil) exitstr = ""; _threadexitsallstatus = exitstr; @@ -34,7 +36,7 @@ /* * signal others. - * copying all the pids first avoids other threads + * copying all the pids first avoids other thread's * teardown procedures getting in the way. */ lock(&_threadpq.lock); @@ -46,9 +48,13 @@ for(p = _threadpq.head; p; p=p->next) pid[npid++] = p->pid; unlock(&_threadpq.lock); - for(i=0; i<npid; i++) - if(pid[i] != mypid) + for(i=0; i<npid; i++){ + _threaddebug(DBGSCHED, "threadexitsall kill %d", pid[i]); + if(pid[i]==0 || pid[i]==-1) + fprint(2, "bad pid in threadexitsall: %d\n", pid[i]); + else if(pid[i] != mypid) kill(pid[i], SIGTERM); + } /* leave */ exit(0);
diff --git a/src/libthread/kill.c b/src/libthread/kill.c index a9392ea..31dc3d5 100644 --- a/src/libthread/kill.c +++ b/src/libthread/kill.c
@@ -1,5 +1,5 @@ -#include "threadimpl.h" #include <signal.h> +#include "threadimpl.h" static void tinterrupt(Proc*, Thread*);
diff --git a/src/libthread/label.h b/src/libthread/label.h index a1f6fa5..874fb07 100644 --- a/src/libthread/label.h +++ b/src/libthread/label.h
@@ -32,6 +32,14 @@ // uvlong fpr[18]; /* callee saved: f14-f31 */ // ulong vr[4*12]; /* callee saved: v20-v31, 256-bits each */ }; +#elif defined(__sun__) +struct Label +{ + ulong input[8]; /* %i registers */ + ulong local[8]; /* %l registers */ + ulong sp; /* %o6 */ + ulong link; /* %o7 */ +}; #else #error "Unknown or unsupported architecture" #endif
diff --git a/src/libthread/main.c b/src/libthread/main.c index 1acd834..06c1293 100644 --- a/src/libthread/main.c +++ b/src/libthread/main.c
@@ -1,5 +1,5 @@ -#include "threadimpl.h" #include <signal.h> +#include "threadimpl.h" typedef struct Mainarg Mainarg; struct Mainarg @@ -74,7 +74,13 @@ int _schedfork(Proc *p) { - return ffork(RFMEM|RFNOWAIT, _schedinit, p); + int pid; + lock(&p->lock); + pid = ffork(RFMEM|RFNOWAIT, _schedinit, p); + p->pid = pid; + unlock(&p->lock); + return pid; + } void
diff --git a/src/libthread/mkfile b/src/libthread/mkfile new file mode 100644 index 0000000..739aaf8 --- /dev/null +++ b/src/libthread/mkfile
@@ -0,0 +1,52 @@ +PLAN9=../.. +<$PLAN9/src/mkhdr + +LIB=libthread.a + +OFILES=\ + $OBJTYPE.$O\ + asm-$SYSNAME-$OBJTYPE.$O\ + channel.$O\ + chanprint.$O\ + create.$O\ + debug.$O\ + exec-unix.$O\ + exit.$O\ + getpid.$O\ + id.$O\ + iocall.$O\ + ioclose.$O\ + ioopen.$O\ + ioproc.$O\ + ioread.$O\ + ioreadn.$O\ + iowrite.$O\ + kill.$O\ + lib.$O\ + main.$O\ + memset.$O\ + memsetd.$O\ + note.$O\ + proctab.$O\ + ref.$O\ + rendez.$O\ + sched.$O\ + +HFILES=\ + $PLAN9/include/thread.h\ + label.h\ + threadimpl.h\ + +<$PLAN9/src/mksyslib + +tprimes: tprimes.$O $PLAN9/lib/$LIB + $LD -o tprimes tprimes.$O $LDFLAGS -lthread -l9 -lfmt -lutf + +texec: texec.$O $PLAN9/lib/$LIB + $LD -o texec texec.$O $LDFLAGS -lthread -l9 -lfmt -lutf + +trend: trend.$O $PLAN9/lib/$LIB + $LD -o trend trend.$O $LDFLAGS -lthread -l9 -lfmt -lutf + +CLEANFILES=$CLEANFILES tprimes texec +
diff --git a/src/libthread/sched.c b/src/libthread/sched.c index 8609833..9ac2241 100644 --- a/src/libthread/sched.c +++ b/src/libthread/sched.c
@@ -1,5 +1,5 @@ -#include "threadimpl.h" #include <signal.h> +#include "threadimpl.h" //static Thread *runthread(Proc*); @@ -27,11 +27,11 @@ ignusr1(); signal(SIGTERM, _threaddie); - - p = arg; + lock(&p->lock); p->pid = _threadgetpid(); _threadsetproc(p); + unlock(&p->lock); while(_setlabel(&p->sched)) ; _threaddebug(DBGSCHED, "top of schedinit, _threadexitsallstatus=%p", _threadexitsallstatus); @@ -59,6 +59,7 @@ _stackfree(t->stk); free(t->cmdname); free(t); /* XXX how do we know there are no references? */ + p->nthreads--; t = nil; _sched(); } @@ -94,7 +95,7 @@ lock(&p->readylock); if(q->head == nil){ q->asleep = 1; - _threaddebug(DBGSCHED, "sleeping for more work"); + _threaddebug(DBGSCHED, "sleeping for more work (%d threads)", p->nthreads); unlock(&p->readylock); while(rendezvous((ulong)q, 0) == ~0){ if(_threadexitsallstatus) @@ -173,6 +174,7 @@ q->tail->next = t; q->tail = t; if(q->asleep){ + assert(q->asleep == 1); q->asleep = 0; /* lock passes to runthread */ _threaddebug(DBGSCHED, "waking process %d", t->proc->pid);
diff --git a/src/libthread/texec.c b/src/libthread/texec.c index 9ba8682..87c3f77 100644 --- a/src/libthread/texec.c +++ b/src/libthread/texec.c
@@ -7,6 +7,7 @@ { char **argv = v; +print("doexec\n"); procexec(nil, argv[0], argv); sendp(threadwaitchan(), nil); } @@ -27,8 +28,8 @@ proccreate(doexec, argv, 8192); w = recvp(c); if(w == nil) - print("exec failed\n"); + print("exec failed: %r\n"); else - print("%d %lu %lu %lu %s\n", w->pid, w->time[0], w->time[1], w->time[2], w->msg); + print("%d %lud %lud %lud %s\n", w->pid, w->time[0], w->time[1], w->time[2], w->msg); threadexits(nil); }