tvarious tweaks. - 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 e97ceade5e1bba5787e39429384336fa37797906
 (DIR) parent c715a6127a46b8090591972b5c4bb04dfabbca8b
 (HTM) Author: rsc <devnull@localhost>
       Date:   Sat,  6 Dec 2003 18:05:27 +0000
       
       various tweaks.
       
       Diffstat:
         M include/fcall.h                     |       8 ++++----
         M include/thread.h                    |       1 +
         M src/cmd/9term/9term.c               |       3 ++-
         M src/cmd/dict/dict.c                 |       1 -
         M src/cmd/mkfile                      |       2 +-
         M src/lib9/mkfile                     |       5 +++++
         M src/libthread/create.c              |      24 ++++++++++++++++++++++++
         M src/libthread/exit.c                |       2 ++
         M src/libthread/sched.c               |      33 ++++++++++++++++++++++++++++++-
         M src/libthread/threadimpl.h          |       3 +++
       
       10 files changed, 74 insertions(+), 8 deletions(-)
       ---
 (DIR) diff --git a/include/fcall.h b/include/fcall.h
       t@@ -1,7 +1,7 @@
        #ifndef _FCALL_H_
        #define _FCALL_H_ 1
       -#if defined(__cplusplus)
       -extern "C" { 
       +#ifdef __cplusplus
       +extern "C" {
        #endif
        /*
        #pragma        src        "/sys/src/libc/9sys"
       t@@ -9,7 +9,6 @@ extern "C" {
        */
        
        #define        VERSION9P        "9P2000"
       -
        #define        MAXWELEM        16
        
        typedef
       t@@ -123,7 +122,8 @@ int        read9pmsg(int, void*, uint);
        #pragma        varargck        type        "M"        ulong
        #pragma        varargck        type        "D"        Dir*
        */
       -#if defined(__cplusplus)
       +
       +#ifdef __cplusplus
        }
        #endif
        #endif
 (DIR) diff --git a/include/thread.h b/include/thread.h
       t@@ -88,6 +88,7 @@ int                send(Channel *c, void *v);
        int                sendp(Channel *c, void *v);
        int                sendul(Channel *c, unsigned long v);
        int                threadcreate(void (*f)(void *arg), void *arg, unsigned int stacksize);
       +int                threadcreateidle(void (*f)(void*), void*, unsigned int);
        void**                threaddata(void);
        void                threadexits(char *);
        void                threadexitsall(char *);
 (DIR) diff --git a/src/cmd/9term/9term.c b/src/cmd/9term/9term.c
       t@@ -318,7 +318,8 @@ aselect(uint *q0, uint *q1, Image *color)
                }
        
                /* clicked inside previous selection */
       -        if(oldq0 <= newq0 && newq0 < oldq1){
       +        /* the "<=" in newq0 <= oldq1 allows us to click the right edge */
       +        if(oldq0 <= newq0 && newq0 <= oldq1){
                        *q0 = oldq0;
                        *q1 = oldq1;
                        return 0;
 (DIR) diff --git a/src/cmd/dict/dict.c b/src/cmd/dict/dict.c
       t@@ -230,7 +230,6 @@ execcmd(int cmd)
                if(debug && doall && cmd == 'a')
                        Bprint(bout, "%d entries, cur=%d\n", dot->n, cur+1);
                for(;;){
       -print("execcmd dot->n %d\n", dot->n);
                        if(cur >= dot->n)
                                break;
                        if(doall) {
 (DIR) diff --git a/src/cmd/mkfile b/src/cmd/mkfile
       t@@ -2,7 +2,7 @@ PLAN9=../..
        <$PLAN9/src/mkhdr
        
        TARG=`ls *.c | sed 's/\.c//'`
       -LDFLAGS=$LDFLAGS -lsec -lregexp9 -l9 -lbio -lfmt -lutf
       +LDFLAGS=$LDFLAGS -lthread -lsec -lfs -lmux -lregexp9 -l9 -lbio -lfmt -lutf
        
        <$PLAN9/src/mkmany
        
 (DIR) diff --git a/src/lib9/mkfile b/src/lib9/mkfile
       t@@ -17,6 +17,10 @@ OFILES=\
                cistrncmp.$O\
                cistrstr.$O\
                cleanname.$O\
       +        convD2M.$O\
       +        convM2D.$O\
       +        convM2S.$O\
       +        convS2M.$O\
                create.$O\
                ctime.$O\
                date.$O\
       t@@ -31,6 +35,7 @@ OFILES=\
                encodefmt.$O\
                errstr.$O\
                exec.$O\
       +        fcallfmt.$O\
                ffork-$SYSNAME.$O\
                getcallerpc-$OBJTYPE.$O\
                getenv.$O\
 (DIR) diff --git a/src/libthread/create.c b/src/libthread/create.c
       t@@ -2,6 +2,8 @@
        
        Pqueue _threadpq;
        
       +int _threadmultiproc;
       +
        static int nextID(void);
        
        /*
       t@@ -81,6 +83,14 @@ procrfork(void (*f)(void *), void *arg, uint stacksize, int rforkflag)
        int
        proccreate(void (*f)(void*), void *arg, uint stacksize)
        {
       +        Proc *p;
       +
       +        p = _threadgetproc();
       +        if(p->idle){
       +                werrstr("cannot create procs once there is an idle thread");
       +                return -1;
       +        }
       +        _threadmultiproc = 1;
                return procrfork(f, arg, stacksize, 0);
        }
        
       t@@ -110,6 +120,20 @@ threadcreate(void (*f)(void *arg), void *arg, uint stacksize)
                return newthread(_threadgetproc(), f, arg, stacksize, nil, threadgetgrp());
        }
        
       +int
       +threadcreateidle(void (*f)(void *arg), void *arg, uint stacksize)
       +{
       +        int id;
       +
       +        if(_threadmultiproc){
       +                werrstr("cannot have idle thread in multi-proc program");
       +                return -1;
       +        }
       +        id = newthread(_threadgetproc(), f, arg, stacksize, nil, threadgetgrp());
       +        _threadidle();
       +        return id;
       +}
       +
        /*
         * Create and initialize a new Proc structure with a single Thread
         * running inside it.  Add the Proc to the global process list.
 (DIR) diff --git a/src/libthread/exit.c b/src/libthread/exit.c
       t@@ -12,6 +12,8 @@ threadexits(char *exitstr)
        
                p = _threadgetproc();
                t = p->thread;
       +        if(t == p->idle)
       +                p->idle = nil;
                t->moribund = 1;
                _threaddebug(DBGSCHED, "threadexits %s", exitstr);
                if(exitstr==nil)
 (DIR) diff --git a/src/libthread/sched.c b/src/libthread/sched.c
       t@@ -93,12 +93,21 @@ runthread(Proc *p)
                Thread *t;
                Tqueue *q;
        
       -        if(p->nthreads==0)
       +        if(p->nthreads==0 || (p->nthreads==1 && p->idle))
                        return nil;
                q = &p->ready;
                lock(&p->readylock);
                if(q->head == nil){
                        q->asleep = 1;
       +                if(p->idle){
       +                        if(p->idle->state != Ready){
       +                                fprint(2, "everyone is asleep\n");
       +                                exits("everyone is asleep");
       +                        }
       +                        unlock(&p->readylock);
       +                        return p->idle;
       +                }
       +
                        _threaddebug(DBGSCHED, "sleeping for more work (%d threads)", p->nthreads);
                        unlock(&p->readylock);
                        while(rendezvous((ulong)q, 0) == ~0){
       t@@ -167,6 +176,9 @@ _threadready(Thread *t)
        {
                Tqueue *q;
        
       +        if(t == t->proc->idle)
       +                return;
       +
                assert(t->state == Ready);
                _threaddebug(DBGSCHED, "readying %d.%d", t->proc->pid, t->id);
                q = &t->proc->ready;
       t@@ -191,6 +203,25 @@ _threadready(Thread *t)
        }
        
        void
       +_threadidle(void)
       +{
       +        Tqueue *q;
       +        Thread *t;
       +        Proc *p;
       +
       +        p = _threadgetproc();
       +        q = &p->ready;
       +        lock(&p->readylock);
       +        assert(q->head);
       +        t = q->head;
       +        q->head = t->next;
       +        if(q->tail == t)
       +                q->tail = nil;
       +        p->idle = t;
       +        unlock(&p->readylock);
       +}
       +
       +void
        yield(void)
        {
                _sched();
 (DIR) diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h
       t@@ -115,6 +115,7 @@ struct Proc
                int                pid;                        /* process id */
                int                splhi;                /* delay notes */
                Thread        *thread;                /* running thread */
       +        Thread        *idle;                        /* idle thread */
        
                int                needexec;
                Execargs        exec;                /* exec argument */
       t@@ -185,6 +186,7 @@ void                _threadinitstack(Thread*, void(*)(void*), void*);
        void*        _threadmalloc(long, int);
        void                _threadnote(void*, char*);
        void                _threadready(Thread*);
       +void                _threadidle(void);
        ulong        _threadrendezvous(ulong, ulong);
        void                _threadsignal(void);
        void                _threadsysfatal(char*, va_list);
       t@@ -192,6 +194,7 @@ long                _xdec(long*);
        void                _xinc(long*);
        void                _threadremove(Proc*, Thread*);
        
       +extern int        _threadmultiproc;
        extern int                        _threaddebuglevel;
        extern char*                _threadexitsallstatus;
        extern Pqueue                _threadpq;