Mail Archives: cygwin/2002/04/18/09:25:19
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/
- Raw text -