URI: 
       tadd _procwakeupandunlock to help ease locking contention on Linux 2.4. - 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 a0a331aad99bbca5a13fa4b69593061f29dc3a29
   DIR parent 815552b9ed41df2f20892f6467dd47f91f93aca1
  HTML Author: rsc <devnull@localhost>
       Date:   Thu,  6 Jan 2005 23:43:42 +0000
       
       add _procwakeupandunlock
       tto help ease locking contention
       on Linux 2.4.
       
       Diffstat:
         M src/libthread/Linux.c               |      27 +++++++++++++++++----------
         M src/libthread/daemonize.c           |      12 ++++++++++++
         M src/libthread/pthread.c             |      10 ++++++++++
         M src/libthread/thread.c              |       6 ++++--
         M src/libthread/threadimpl.h          |       1 +
       
       5 files changed, 44 insertions(+), 12 deletions(-)
       ---
   DIR diff --git a/src/libthread/Linux.c b/src/libthread/Linux.c
       t@@ -32,7 +32,7 @@ _threadlock(Lock *l, int block, ulong pc)
        {
                int i;
        static int first=1;
       -if(first) {first=0; fmtinstall('T', timefmt);}
       +if(first) {first=0; fmtinstall('\001', timefmt);}
        
                USED(pc);
        
       t@@ -48,43 +48,43 @@ if(first) {first=0; fmtinstall('T', timefmt);}
                                return 1;
                        sched_yield();
                }
       -        /* now nice and slow */
       +        /* now increasingly slow */
                for(i=0; i<10; i++){
                        if(!_tas(&l->held))
                                return 1;
                        usleep(1);
                }
       -fprint(2, "%T lock loop %p from %lux\n", l, pc);
       +fprint(2, "%\001 %s: lock loop1 %p from %lux\n", argv0, l, pc);
                for(i=0; i<10; i++){
                        if(!_tas(&l->held))
                                return 1;
                        usleep(10);
                }
       -fprint(2, "%T lock loop %p from %lux\n", l, pc);
       +fprint(2, "%\001 %s: lock loop2 %p from %lux\n", argv0, l, pc);
                for(i=0; i<10; i++){
                        if(!_tas(&l->held))
                                return 1;
                        usleep(100);
                }
       -fprint(2, "%T lock loop %p from %lux\n", l, pc);
       +fprint(2, "%\001 %s: lock loop3 %p from %lux\n", argv0, l, pc);
                for(i=0; i<10; i++){
                        if(!_tas(&l->held))
                                return 1;
                        usleep(1000);
                }
       -fprint(2, "%T lock loop %p from %lux\n", l, pc);
       +fprint(2, "%\001 %s: lock loop4 %p from %lux\n", argv0, l, pc);
                for(i=0; i<10; i++){
                        if(!_tas(&l->held))
                                return 1;
                        usleep(10*1000);
                }
       -fprint(2, "%T lock loop %p from %lux\n", l, pc);
       +fprint(2, "%\001 %s: lock loop5 %p from %lux\n", argv0, l, pc);
                for(i=0; i<1000; i++){
                        if(!_tas(&l->held))
                                return 1;
                        usleep(100*1000);
                }
       -fprint(2, "%T lock loop %p from %lux\n", l, pc);
       +fprint(2, "%\001 %s: lock loop6 %p from %lux\n", argv0, l, pc);
                /* take your time */
                while(_tas(&l->held))
                        usleep(1000*1000);
       t@@ -150,13 +150,20 @@ again:
        }
        
        void
       -_procwakeup(_Procrendez *r)
       +_procwakeupandunlock(_Procrendez *r)
        {
       +        int pid;
       +
       +        pid = 0;
                if(r->asleep){
                        r->asleep = 0;
                        assert(r->pid >= 1);
       -                kill(r->pid, SIGUSR1);
       +                pid = r->pid;
                }
       +        assert(r->l);
       +        unlock(r->l);
       +        if(pid)
       +                kill(pid, SIGUSR1);
        }
        
        /*
   DIR diff --git a/src/libthread/daemonize.c b/src/libthread/daemonize.c
       t@@ -1,3 +1,6 @@
       +#include <u.h>
       +#include <sys/time.h>
       +#include <sys/resource.h>
        #include "threadimpl.h"
        
        #undef waitpid
       t@@ -11,6 +14,7 @@ static void
        child(void)
        {
                int status, pid;
       +        struct rlimit rl;
        
                notedisable("sys: child");
                pid = waitpid(sigpid, &status, 0);
       t@@ -21,6 +25,14 @@ child(void)
                if(WIFEXITED(status))
                         _exit(WEXITSTATUS(status));
                if(WIFSIGNALED(status)){
       +                /*
       +                 * Make sure we don't scribble over the nice
       +                 * core file that our child just wrote out.
       +                 */
       +                rl.rlim_cur = 0;
       +                rl.rlim_max = 0;
       +                setrlimit(RLIMIT_CORE, &rl);
       +
                        signal(WTERMSIG(status), SIG_DFL);
                        raise(WTERMSIG(status));
                        _exit(98);        /* not reached */
   DIR diff --git a/src/libthread/pthread.c b/src/libthread/pthread.c
       t@@ -67,6 +67,16 @@ _procwakeup(_Procrendez *r)
                }
        }
        
       +void
       +_procwakeupandunlock(_Procrendez *r)
       +{
       +        if(r->asleep){
       +                r->asleep = 0;
       +                pthread_cond_signal(&r->cond);
       +        }
       +        unlock(&r->l);
       +}
       +
        static void
        startprocfn(void *v)
        {
   DIR diff --git a/src/libthread/thread.c b/src/libthread/thread.c
       t@@ -166,11 +166,13 @@ _threadready(_Thread *t)
        
                p = t->proc;
                lock(&p->lock);
       +        p->runrend.l = &p->lock;
                addthread(&p->runqueue, t);
        //print("%d wake for job %d->%d\n", time(0), getpid(), p->osprocid);
                if(p != proc())
       -                _procwakeup(&p->runrend);
       -        unlock(&p->lock);
       +                _procwakeupandunlock(&p->runrend);
       +        else
       +                unlock(&p->lock);
        }
        
        int
   DIR diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h
       t@@ -76,6 +76,7 @@ struct _Procrendez
        
        extern        void        _procsleep(_Procrendez*);
        extern        void        _procwakeup(_Procrendez*);
       +extern        void        _procwakeupandunlock(_Procrendez*);
        
        struct Proc
        {