Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com From: "Gerald S. Williams" To: "Michael Labhard" , Subject: RE: pthread_cond_wait does not relock mutex on release Date: Thu, 18 Apr 2002 09:22:06 -0400 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 8bit X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4807.1700 Importance: Normal In-Reply-To: <02041720503405.01295@wrybread.labhard.com> It's interesting that your system behaves so differently. (I believe signals are supposed to interrupt condition variable waits--perhaps you're system is being flooded by them?) There are a few things you could try, including: o Disabling signals in the created threads. To do this, you have to disable them in the parent, create the threads, then reenable them. It's generally worth it. o Using a semaphore (you still have to check for a spurious wakeup due to a caught signal). Here are some code snippets you might find helpful: This creates threads, disabling signals (extracted from Python's POSIX threads module): sigset_t oldmask, newmask; sigfillset(&newmask); pthread_sigmask(SIG_BLOCK, &newmask, &oldmask); pthread_create(...); pthread_sigmask(SIG_SETMASK, &oldmask, NULL); These snippets should let you use semaphores to signal between threads: /* * As of February 2002, Cygwin thread implementations mistakenly report error * codes in the return value of the sem_ calls (like the pthread_ functions). * Correct implementations return -1 and put the code in errno. This supports * either. */ static int fix_status(int status) { return (status == -1) ? errno : status; } ... /* VARIABLES USED IN ALL SNIPPETS: */ sem_t *sem; int status; /* CREATE A SEMAPHORE */ sem = (sem_t *)malloc(sizeof(sem_t)); if (sem) { status = sem_init(sem,0,0); /* start "acquired" */ if (status != 0) { free((void *)sem); sem = NULL; } } if (!sem) REPORT_ERROR(); /* DESTROY THE SEMAPHORE */ if (sem) { status = sem_destroy(sem); if (status != 0) REPORT_ERROR(); free(sem); } /* WAIT FOR THE SIGNAL */ do { status = fix_status(sem_wait(sem)); } while (status == EINTR); /* Retry if interrupted by a signal */ if (status != 0) REPORT_ERROR(); /* SIGNAL THE SEMAPHORE */ status = sem_post(sem); if (status != 0) REPORT_ERROR(); I think the bug requiring the "fix_status" function has been fixed, but you might find it easier to understand this way. The "normal" way to wait for a semaphore is: do { status = sem_wait(sem); } while ((status == -1) && (errno == EINTR)); With semaphores you have to be careful to match the number of sem_wait() and sem_post() calls (extra sem_post() calls would cause future sem_wait()'s not to wait). -Jerry -O Gerald S. Williams, 55A-134A-E : mailto:gsw AT agere DOT com O- -O AGERE SYSTEMS, 6755 SNOWDRIFT RD : office:610-712-8661 O- -O ALLENTOWN, PA, USA 18106-9353 : mobile:908-672-7592 O- > Robert and Gerald: > >          Both quite right.  Although adding the SAFE_PRINTF made no > difference in the > output, checking a condition value in a loop made all the difference.   > Putting a printf in the loop revealed to my surprise that "spurious wakeups" > were occurring thousands of times per second.  I had naively assumed that a > condition would stay set until signalled.  Now I'm led to wonder if a > condition variable is any performance improvement over a simple loop and > short sleep.  Any thoughts? > >          Thanks very much for your time and effort.  It was a great help. > > -- Michael -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Bug reporting: http://cygwin.com/bugs.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/