tadd threaddaemonize(), more bug fixes - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 2c87dda8f89e84082523b03b62c5d47d55c13341
 (DIR) parent 929fcfe0e3affc81cb02e49c0f1320408ce9260c
 (HTM) Author: rsc <devnull@localhost>
       Date:   Tue, 28 Dec 2004 01:35:38 +0000
       
       add threaddaemonize(), more bug fixes
       
       Diffstat:
         M include/thread.h                    |       5 +++++
         M src/libthread/Linux.c               |      19 ++++++++++++-------
         M src/libthread/ioproc.c              |       2 ++
         M src/libthread/mkfile                |       1 +
         M src/libthread/test/mkfile           |       2 +-
         M src/libthread/thread.c              |      37 +++++++++++++++++++++++++++----
         M src/libthread/threadimpl.h          |       4 ++--
       
       7 files changed, 56 insertions(+), 14 deletions(-)
       ---
 (DIR) diff --git a/include/thread.h b/include/thread.h
       t@@ -22,6 +22,11 @@ _Thread        *_threadwakeup(Rendez*);
        #define        yield                threadyield
        
        /*
       + * daemonize
       + */
       +void        threaddaemonize(void);
       +
       +/*
         * per proc and thread data
         */
        void                **procdata(void);
 (DIR) diff --git a/src/libthread/Linux.c b/src/libthread/Linux.c
       t@@ -8,6 +8,9 @@
        #include "thread.h"
        #include "threadimpl.h"
        
       +int ngetpid;
       +
       +
        /*
         * spin locks
         */
       t@@ -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;
                }
       t@@ -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)
       t@@ -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);
        }
       t@@ -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)
 (DIR) diff --git a/src/libthread/ioproc.c b/src/libthread/ioproc.c
       t@@ -20,6 +20,8 @@ static void
        xioproc(void *a)
        {
                Ioproc *io, *x;
       +
       +        threadsetname("ioproc");
                io = a;
                /*
                 * first recvp acquires the ioproc.
 (DIR) diff --git a/src/libthread/mkfile b/src/libthread/mkfile
       t@@ -6,6 +6,7 @@ LIB=libthread.a
        OFILES=\
                $SYSOFILES\
                channel.$O\
       +        daemonize.$O\
                exec.$O\
                ioproc.$O\
                iorw.$O\
 (DIR) diff --git a/src/libthread/test/mkfile b/src/libthread/test/mkfile
       t@@ -3,6 +3,6 @@
        SHORTLIB=thread 9
        OFILES=
        
       -TARG=tprimes tspawn tspawnloop
       +TARG=tprimes tspawn tspawnloop tdaemon
        
        <$PLAN9/src/mkmany
 (DIR) diff --git a/src/libthread/thread.c b/src/libthread/thread.c
       t@@ -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)
        {
       t@@ -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);
        }
        
       t@@ -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;
       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(;;){
       t@@ -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);
       t@@ -212,6 +233,7 @@ scheduler(Proc *p)
                }
        
        Out:
       +        _threaddebug("scheduler exit");
                delproc(p);
                lock(&threadnproclock);
                if(p->sysproc)
       t@@ -447,11 +469,18 @@ threadmainstart(void *v)
                threadmain(threadargc, threadargv);
        }
        
       +void
       +threadlinklibrary(void)
       +{
       +}
       +
        int
        main(int argc, char **argv)
        {
                Proc *p;
        
       +        _threadsetupdaemonize();
       +
                threadargc = argc;
                threadargv = argv;
        
 (DIR) diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h
       t@@ -5,8 +5,6 @@ typedef struct Execjob Execjob;
        typedef struct Proc Proc;
        typedef struct _Procrendez _Procrendez;
        
       -
       -
        typedef struct Jmp Jmp;
        struct Jmp
        {
       t@@ -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*);