9vx/OSX: attempt at fixing spurious pthread wakeups - vx32 - Local 9vx git repository for patches.
       
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
 (DIR) commit b73f901985b9aaada2c11d977276a2d064555048
 (DIR) parent f4b577eb84fd57b6e5835b3776ac2976f9302ed9
 (HTM) Author: Russ Cox <rsc@swtch.com>
       Date:   Sat, 28 Jun 2008 11:37:35 -0400
       
       9vx/OSX: attempt at fixing spurious pthread wakeups
       
       Diffstat:
         src/9vx/sched.c                     |      20 +++++++++++++++++++-
       
       1 file changed, 19 insertions(+), 1 deletion(-)
       ---
 (DIR) diff --git a/src/9vx/sched.c b/src/9vx/sched.c
       @@ -44,6 +44,17 @@ punlock(Psleep *p)
        static 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.
       +         */
       +        pthread_cond_init(&p->cond, nil);
                pthread_cond_wait(&p->cond, &p->mutex);
        }
        
       @@ -69,8 +80,10 @@ void
        idlehands(void)
        {
                plock(&idling);
       -        while(!idlewakeup)
       +        while(!idlewakeup){
                        psleep(&idling);
       +                iprint("idlehands spurious wakeup\n");
       +        }
                idlewakeup = 0;
                punlock(&idling);
        }
       @@ -124,6 +137,7 @@ ready(Proc *p)
                kprocq.n++;
                if(kprocq.n > nrunproc)
                        newmach();
       +iprint("ready p\n");
                pwakeup(&run);
                unlock(&kprocq.lk);
                punlock(&run);
       @@ -137,11 +151,13 @@ ready(Proc *p)
        Proc*
        runproc(void)
        {
       +        int nbad;
                Proc *p;
        
                if(m->machno == 0)
                        return _runproc();
        
       +        nbad = 0;
                plock(&run);
                lock(&kprocq.lk);        /* redundant but fine */
                while((p = kprocq.head) == nil){
       @@ -149,6 +165,8 @@ runproc(void)
                        unlock(&kprocq.lk);
                        psleep(&run);
                        lock(&kprocq.lk);
       +                if(kprocq.head == nil && ++nbad%1000 == 0)
       +                        iprint("cpu%d: runproc spurious wakeup\n", m->machno);        
                        nrunproc--;
                }
                kprocq.head = p->rnext;