URI: 
       tmake -> mk - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit cd7ddc9b5f34da33a2eb0ea761681c2330284e69
   DIR parent b7e6f4150f0974a3f3b145a23911b7c8a4b9399b
  HTML Author: rsc <devnull@localhost>
       Date:   Sun, 23 Nov 2003 18:18:00 +0000
       
       make -> mk
       
       remove clumsy stack hack.
       fix exec.
       fix nthreads maintenance.
       fix threadexitsall not to kill self.
       add sun support.
       
       Diffstat:
         D src/libthread/Makefile              |      52 -------------------------------
         M src/libthread/create.c              |      57 ++++---------------------------
         M src/libthread/exec-unix.c           |      11 +++++++++++
         M src/libthread/exit.c                |      14 ++++++++++----
         M src/libthread/kill.c                |       2 +-
         M src/libthread/label.h               |       8 ++++++++
         M src/libthread/main.c                |      10 ++++++++--
         A src/libthread/mkfile                |      52 +++++++++++++++++++++++++++++++
         M src/libthread/sched.c               |      10 ++++++----
         M src/libthread/texec.c               |       5 +++--
       
       10 files changed, 105 insertions(+), 116 deletions(-)
       ---
   DIR diff --git a/src/libthread/Makefile b/src/libthread/Makefile
       t@@ -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
       -
   DIR diff --git a/src/libthread/create.c b/src/libthread/create.c
       t@@ -7,54 +7,10 @@ static int nextID(void);
        /*
         * 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
       t@@ -62,16 +18,15 @@ newthread(Proc *p, void (*f)(void *arg), void *arg, uint stacksize, char *name, 
        {
                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;
       t@@ -138,7 +93,7 @@ _freeproc(Proc *p)
                        if(t->cmdname)
                                free(t->cmdname);
                        assert(t->stk != nil);
       -                _stackfree((Stack*)t->stk);
       +                _stackfree(t->stk);
                        nextt = t->nextt;
                        free(t);
                }
   DIR diff --git a/src/libthread/exec-unix.c b/src/libthread/exec-unix.c
       t@@ -9,11 +9,13 @@ procexec(Channel *pidc, char *prog, char *args[])
                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)
       t@@ -34,26 +36,35 @@ procexec(Channel *pidc, char *prog, char *args[])
                 * 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);
        
   DIR diff --git a/src/libthread/exit.c b/src/libthread/exit.c
       t@@ -1,5 +1,5 @@
       -#include "threadimpl.h"
        #include <signal.h>
       +#include "threadimpl.h"
        
        char *_threadexitsallstatus;
        Channel *_threadwaitchan;
       t@@ -13,6 +13,7 @@ threadexits(char *exitstr)
                p = _threadgetproc();
                t = p->thread;
                t->moribund = 1;
       +        _threaddebug(DBGSCHED, "threadexits %s", exitstr);
                if(exitstr==nil)
                        exitstr="";
                utfecpy(p->exitstr, p->exitstr+ERRMAX, exitstr);
       t@@ -26,6 +27,7 @@ threadexitsall(char *exitstr)
                int *pid;
                int i, npid, mypid;
        
       +        _threaddebug(DBGSCHED, "threadexitsall %s", exitstr);
                if(exitstr == nil)
                        exitstr = "";
                _threadexitsallstatus = exitstr;
       t@@ -34,7 +36,7 @@ threadexitsall(char *exitstr)
        
                /*
                 * 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);
       t@@ -46,9 +48,13 @@ threadexitsall(char *exitstr)
                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);
   DIR diff --git a/src/libthread/kill.c b/src/libthread/kill.c
       t@@ -1,5 +1,5 @@
       -#include "threadimpl.h"
        #include <signal.h>
       +#include "threadimpl.h"
        
        static void tinterrupt(Proc*, Thread*);
        
   DIR diff --git a/src/libthread/label.h b/src/libthread/label.h
       t@@ -32,6 +32,14 @@ struct Label
        //        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
   DIR diff --git a/src/libthread/main.c b/src/libthread/main.c
       t@@ -1,5 +1,5 @@
       -#include "threadimpl.h"
        #include <signal.h>
       +#include "threadimpl.h"
        
        typedef struct Mainarg Mainarg;
        struct Mainarg
       t@@ -74,7 +74,13 @@ _threadsignalpasser(void)
        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
   DIR diff --git a/src/libthread/mkfile b/src/libthread/mkfile
       t@@ -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
       +
   DIR diff --git a/src/libthread/sched.c b/src/libthread/sched.c
       t@@ -1,5 +1,5 @@
       -#include "threadimpl.h"
        #include <signal.h>
       +#include "threadimpl.h"
        
        //static Thread        *runthread(Proc*);
        
       t@@ -27,11 +27,11 @@ _schedinit(void *arg)
                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);
       t@@ -59,6 +59,7 @@ _schedinit(void *arg)
                                _stackfree(t->stk);
                                free(t->cmdname);
                                free(t);        /* XXX how do we know there are no references? */
       +                        p->nthreads--;
                                t = nil;
                                _sched();
                        }
       t@@ -94,7 +95,7 @@ runthread(Proc *p)
                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)
       t@@ -173,6 +174,7 @@ _threadready(Thread *t)
                        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);
   DIR diff --git a/src/libthread/texec.c b/src/libthread/texec.c
       t@@ -7,6 +7,7 @@ doexec(void *v)
        {
                char **argv = v;
        
       +print("doexec\n");
                procexec(nil, argv[0], argv);
                sendp(threadwaitchan(), nil);
        }
       t@@ -27,8 +28,8 @@ threadmain(int argc, char **argv)
                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);
        }