URI: 
       tbetter exec handling - 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 8cbd854a8ab2c4f8c738c5bea5263217cb892a77
   DIR parent 03417610742c4a67bb0345a8fa0fb4e13dee07f7
  HTML Author: rsc <devnull@localhost>
       Date:   Mon, 27 Dec 2004 19:11:33 +0000
       
       better exec handling
       
       Diffstat:
         M src/libthread/Linux.c               |      33 +++----------------------------
         M src/libthread/exec.c                |      62 +++++++++++++------------------
         M src/libthread/pthread.c             |       6 ------
         M src/libthread/thread.c              |      19 ++++++++++++++-----
         M src/libthread/threadimpl.h          |       1 +
       
       5 files changed, 43 insertions(+), 78 deletions(-)
       ---
   DIR diff --git a/src/libthread/Linux.c b/src/libthread/Linux.c
       t@@ -99,13 +99,15 @@ 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());
       +//print("resleep %d\n", getpid());
                        /* Didn't really wake up - signal from something else */
                        goto again;
                }
       t@@ -266,35 +268,6 @@ threadexitsall(char *msg)
        }
        
        /*
       - * exec - need to arrange for wait proc to run
       - * the execs so it gets the wait messages
       - */
       -int
       -_runthreadspawn(int *fd, char *cmd, char **argv)
       -{
       -        Execjob e;
       -        int pid;
       -
       -        e.fd = fd;
       -        e.cmd = cmd;
       -        e.argv = argv;
       -        e.c = chancreate(sizeof(ulong), 0);        
       -print("%d run\n", time(0));
       -        qlock(&_threadexeclock);
       -        sendp(_threadexecchan, &e);
       -print("%d sent\n", time(0));
       -        while(_threadexecproc == nil)
       -                yield();
       -        kill(_threadexecproc->osprocid, SIGUSR2);
       -print("%d killed\n", time(0));
       -        pid = recvul(e.c);
       -        qunlock(&_threadexeclock);
       -print("%d ran\n", time(0));
       -        return pid;
       -}
       -
       -
       -/*
         * per-process data, indexed by pid
         *
         * could use modify_ldt and a segment register
   DIR diff --git a/src/libthread/exec.c b/src/libthread/exec.c
       t@@ -6,41 +6,42 @@
        
        static Lock thewaitlock;
        static Channel *thewaitchan;
       -Channel        *_dowaitchan;
       -Channel        *_threadexecchan;
       -Proc        *_threadexecproc;
       -QLock        _threadexeclock;
        
        static void
       -execthread(void *v)
       -{
       -        Execjob *e;
       -
       -        USED(v);
       -        while((e = recvp(_threadexecchan)) != nil){
       -print("%d doexec pid %d\n", time(0), getpid());
       -                sendul(e->c, _threadspawn(e->fd, e->cmd, e->argv));
       -        }
       -}
       -
       -static void
       -waitproc(void *v)
       +execproc(void *v)
        {
       +        int pid;
                Channel *c;
       +        Execjob *e;
                Waitmsg *w;
        
       -        _threadsetsysproc();
       -        _threadexecproc = proc();
       -        threadcreate(execthread, nil, 65536);
       -        for(;;){
       -                while((w = wait()) == nil)
       -                        if(errno == ECHILD)
       -                                recvul(_dowaitchan);
       +        e = v;
       +        pid = _threadspawn(e->fd, e->cmd, e->argv);
       +        sendul(e->c, pid);
       +        if(pid > 0){
       +                w = waitfor(pid);
                        if((c = thewaitchan) != nil)
                                sendp(c, w);
                        else
                                free(w);
                }
       +        threadexits(nil);
       +}
       +
       +int
       +_runthreadspawn(int *fd, char *cmd, char **argv)
       +{
       +        int pid;
       +        Execjob e;
       +
       +        e.fd = fd;
       +        e.cmd = cmd;
       +        e.argv = argv;
       +        e.c = chancreate(sizeof(void*), 0);
       +        proccreate(execproc, &e, 65536);
       +        pid = recvul(e.c);
       +        chanfree(e.c);
       +        return pid;
        }
        
        Channel*
       t@@ -104,28 +105,15 @@ _threadspawn(int fd[3], char *cmd, char *argv[])
                        close(fd[1]);
                if(fd[2] != fd[1] && fd[2] != fd[0])
                        close(fd[2]);
       -        channbsendul(_dowaitchan, 1);
                return pid;
        }
        
        int
        threadspawn(int fd[3], char *cmd, char *argv[])
        {
       -        if(_dowaitchan == nil){
       -                lock(&thewaitlock);
       -                if(_dowaitchan == nil){
       -                        _dowaitchan = chancreate(sizeof(ulong), 1);
       -                        chansetname(_dowaitchan, "dowaitchan");
       -                        _threadexecchan = chancreate(sizeof(void*), 1);
       -                        chansetname(_threadexecchan, "execchan");
       -                        proccreate(waitproc, nil, STACK);
       -                }
       -                unlock(&thewaitlock);
       -        }
                return _runthreadspawn(fd, cmd, argv);
        }
        
       -
        int
        _threadexec(Channel *cpid, int fd[3], char *cmd, char *argv[])
        {
   DIR diff --git a/src/libthread/pthread.c b/src/libthread/pthread.c
       t@@ -130,9 +130,3 @@ _pthreadinit(void)
                pthread_key_create(&prockey, 0);
        }
        
       -int
       -_runthreadspawn(int *fd, char *cmd, char **argv)
       -{
       -        return _threadspawn(fd, cmd, argv);
       -}
       -
   DIR diff --git a/src/libthread/thread.c b/src/libthread/thread.c
       t@@ -138,15 +138,23 @@ _threadready(_Thread *t)
                p = t->proc;
                lock(&p->lock);
                addthread(&p->runqueue, t);
       -        _procwakeup(&p->runrend);
       +//print("%d wake for job %d->%d\n", time(0), getpid(), p->osprocid);
       +        if(p != proc())
       +                _procwakeup(&p->runrend);
                unlock(&p->lock);
        }
        
       -void
       +int
        threadyield(void)
        {
       -        _threadready(proc()->thread);
       +        int n;
       +        Proc *p;
       +
       +        p = proc();
       +        n = p->nswitch;
       +        _threadready(p->thread);
                _threadswitch();
       +        return p->nswitch - n;
        }
        
        void
       t@@ -184,13 +192,14 @@ scheduler(Proc *p)
                                if(p->nthread == 0)
                                        goto Out;
                                p->runrend.l = &p->lock;
       -print("sleep for jobs %d\n", getpid());
       +//print("%d sleep for jobs %d\n", time(0), getpid());
                                _procsleep(&p->runrend);
       -print("wake from jobs %d\n", getpid());
       +//print("%d wake from jobs %d\n", time(0), getpid());
                        }
                        delthread(&p->runqueue, t);
                        unlock(&p->lock);
                        p->thread = t;
       +                p->nswitch++;
                        // print("run %s %d\n", t->name, t->id);
                        contextswitch(&p->schedcontext, &t->context);
                        p->thread = nil;
   DIR diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h
       t@@ -74,6 +74,7 @@ struct Proc
                uint                osprocid;
        #endif
                Lock                lock;
       +        int                        nswitch;
                _Thread                *thread;
                _Threadlist        runqueue;
                _Threadlist        allthreads;