9vx: try using many pthread_cond_t for scheduling - vx32 - Local 9vx git repository for patches.
       
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
 (DIR) commit d17c8f9f59623f72df8c2db16eeb9cad08806b1e
 (DIR) parent a6f16f2f73874054262169792554292d7bcce3cb
 (HTM) Author: Russ Cox <rsc@swtch.com>
       Date:   Sun, 29 Jun 2008 09:47:20 -0400
       
       9vx: try using many pthread_cond_t for scheduling
       
       Diffstat:
         src/9vx/a/dat.h                     |       3 ++-
         src/9vx/sched.c                     |      53 ++++++++++++++++---------------
       
       2 files changed, 30 insertions(+), 26 deletions(-)
       ---
 (DIR) diff --git a/src/9vx/a/dat.h b/src/9vx/a/dat.h
       @@ -352,10 +352,11 @@ extern int doabort;
        
        /* Pthreads-based sleep and wakeup. */
        ttypedef struct Psleep Psleep;
       +ttypedef struct Pwaiter Pwaiter;
        struct Psleep
        {
                pthread_mutex_t mutex;
       -        pthread_cond_t cond;
       +        Pwaiter *waiter;
                int fd[2];
                vlong nread;
                vlong nwrite;
 (DIR) diff --git a/src/9vx/sched.c b/src/9vx/sched.c
       @@ -10,7 +10,12 @@
         */
        
        #define        WANT_M
       +
       +#ifdef __APPLE__
        #define        PIPES 1
       +#else
       +#define PIPES 0
       +#endif
        
        #include        "u.h"
        #include        <pthread.h>
       @@ -23,19 +28,23 @@
        #include        "error.h"
        #include        "trace.h"
        
       -void
       -pinit(Psleep *p)
       +struct Pwaiter
        {
       -}
       +        pthread_cond_t cond;
       +        Pwaiter *next;
       +        int awake;
       +};
        
        void
        plock(Psleep *p)
        {
                pthread_mutex_lock(&p->mutex);
       +#if PIPES
                if(p->fd[1] == 0){
                        pipe(p->fd);
                        fcntl(p->fd[0], F_SETFL, fcntl(p->fd[0], F_GETFL)|O_NONBLOCK);
                }
       +#endif
        }
        
        void
       @@ -47,16 +56,6 @@ punlock(Psleep *p)
        void
        psleep(Psleep *p)
        {
       -        /*
       -         * OS X is trying to be helpful and has changed the behavior
       -         * of pthreads condition variables.  After pthread_cond_signal
       -         * any subsequent pthread_cond_wait returns immediately.
       -         * This is perhaps more sensible behavior than the standard,
       -         * but it's not actually what the standard requires.
       -         * So we have to pthread_cond_init to clear any pre-existing
       -         * condition.  This is okay because we hold the lock that
       -         * protects the condition in the first place.  Sigh.
       -         */
        #if PIPES
                p->nread++;
                punlock(p);
       @@ -70,8 +69,14 @@ psleep(Psleep *p)
                }
                plock(p);
        #else
       -        pthread_cond_init(&p->cond, nil);
       -        pthread_cond_wait(&p->cond, &p->mutex);
       +        Pwaiter w;
       +        memset(&w, 0, sizeof w);
       +        pthread_cond_init(&w.cond, nil);
       +        w.next = p->waiter;
       +        p->waiter = &w;
       +        while(!w.awake)
       +                pthread_cond_wait(&w.cond, &p->mutex);
       +        pthread_cond_destroy(&w.cond);
        #endif
        }
        
       @@ -89,7 +94,14 @@ pwakeup(Psleep *p)
                        }
                }
        #else
       -        pthread_cond_signal(&p->cond);
       +        Pwaiter *w;
       +
       +        w = p->waiter;
       +        if(w){
       +                p->waiter = w->next;
       +                w->awake = 1;
       +                pthread_cond_signal(&w->cond);
       +        }
        #endif
        }
        
       @@ -208,12 +220,3 @@ runproc(void)
                punlock(&run);
                return p;
        }
       -
       -void
       -schedinit0(void)
       -{
       -        pinit(&run);
       -        pinit(&idling);
       -iprint("pinit\n");
       -}
       -