This is the mail archive of the
cygwin@cygwin.com
mailing list for the Cygwin project.
RE: pthread_cond_wait does not relock mutex on release
- From: "Gerald S. Williams" <gsw at agere dot com>
- To: <cygwin at cygwin dot com>
- Date: Wed, 17 Apr 2002 10:04:20 -0400
- Subject: RE: pthread_cond_wait does not relock mutex on release
Independent of any other issues, the test case is wrong.
Specifically, pthread_cond_wait is allowed to spuriously
return (it's in the standard that way). You do have the
lock, though. That allows you to look at the variable and
determine if this was a spurious signal.
You have to wrap cond_wait with a check of the associated
variable (which would have to be set when you signalled
it).
In other words, this:
> void *foo(void*)
> {
> int status = ::pthread_mutex_lock(&(_pwait_condition->_mutex));
> ::printf("foo mutex lock\n");
>
> status = ::pthread_cond_signal(&(_pwait_condition->_cond));
> ::printf("foo mutex lock and signal condition then sleep...\n");
>
> ::sleep(1);
> status = ::pthread_mutex_unlock(&(_pwait_condition->_mutex));
> ::printf("foo mutex unlock\n");
>
> return 0;
> };
>
> void *bar(void*)
> {
> ::pthread_mutex_lock(&(_pwait_condition->_mutex));
> ::printf("bar mutex lock and wait\n");
>
> ::pthread_cond_wait(&(_pwait_condition->_cond)
> , &(_pwait_condition->_mutex));
> ::printf("bar mutex lock and wait released\n");
>
> ::pthread_mutex_unlock(&(_pwait_condition->_mutex));
> ::printf("bar mutex unlock\n");
>
> return 0;
> };
should become something like this:
void *foo(void*)
{
int status = ::pthread_mutex_lock(&(_pwait_condition->_mutex));
::printf("foo mutex lock\n");
_pwait_condition->_status = false;
status = ::pthread_cond_signal(&(_pwait_condition->_cond));
::printf("foo mutex lock and signal condition then sleep...\n");
::sleep(1);
status = ::pthread_mutex_unlock(&(_pwait_condition->_mutex));
::printf("foo mutex unlock\n");
return 0;
};
void *bar(void*)
{
::pthread_mutex_lock(&(_pwait_condition->_mutex));
::printf("bar mutex lock and wait\n");
while (_pwait_condition->_status) {
::pthread_cond_wait(&(_pwait_condition->_cond)
, &(_pwait_condition->_mutex));
::printf("bar mutex lock and wait released\n");
}
::pthread_mutex_unlock(&(_pwait_condition->_mutex));
::printf("bar mutex unlock\n");
return 0;
};
That could cause the results you are seeing. Or it could
be something much simpler. Calling printf simultaneously
from multiple threads can mess up the output. Mine was
really strange for this program. You might want to try
adding this to the top of your program:
#include <stdarg.h>
void SAFE_PRINTF(char *format,...)
{
va_list vargs;
static pthread_mutex_t printMutex;
static int initialized = 0;
/* OK as long as printf is called in single-threaded context first: */
if (!initialized)
{
int status = pthread_mutex_init(&printMutex, 0);
assert(0==status);
initialized = 1;
}
pthread_mutex_lock(&printMutex);
va_start(vargs,format);
vprintf(format,vargs);
va_end(vargs);
pthread_mutex_unlock(&printMutex);
}
#define printf SAFE_PRINTF
I get the following output after changing printf:
create Test
start
bar mutex lock and wait
foo mutex lock
foo mutex lock and signal condition then sleep...
bar mutex lock and wait released
foo mutex unlock
bar mutex unlock
end
delete Test
That is still not exactly what you expected, but makes sense
since foo()'s printf is racing the two in bar(). (I.e., bar()
gets to run before foo()'s mutex_unlock() returns, then foo()
gets to run while bar() is unlocking the mutex again.)
-Jerry
-O Gerald S. Williams, 55A-134A-E : mailto:gsw@agere.com O-
-O AGERE SYSTEMS, 6755 SNOWDRIFT RD : office:610-712-8661 O-
-O ALLENTOWN, PA, USA 18106-9353 : mobile:908-672-7592 O-
--
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/