This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
Re: pthread_cond_wait with multiple mutex variables
Hi,
Bharath Ramesh wrote:
> What is confusing to me is that in the man page it states that "condition
> variable becomes bound to a unique mutex when a thread waits on a the
> condition variable".
Agh, sorry, Bharath. I misunderstood your question (indeed, I stupidly
assumed the question had come on a completely different mailing list).
As penance, here's some investigation.
There doesn't appear to be an NPTL manual, so I will be drawing from (1)
POSIX and (2) the source code.
POSIX sayeth[1]:
When a thread waits on a condition variable, having specified
a particular mutex to either the pthread_cond_timedwait() or
the pthread_cond_wait() operation, a dynamic binding is formed
between that mutex and condition variable that remains in
effect as long as at least one thread is blocked on the
condition variable. During this time, the effect of an attempt
by any thread to wait on that condition variable using a
different mutex is undefined.
So I believe from the point of view of POSIX, your test case invokes
undefined behavior.
The actual implementation: pthread_cond_wait
1. locks an internal (condvar) mutex.
2. releases the mutex that was passed in.
3. adds 1 to the waiters count.
4.
/* Remember the mutex we are using here. If there is already a
different address store this is a bad user bug. Do not store
anything for pshared condvars. */
if (cond->__data.__mutex != (void *) ~0l)
cond->__data.__mutex = mutex;
5. installs a cancellation handler, preparing to block.
6. records the broadcast counter.
7. releases the internal (condvar) mutex.
8. enables async cancellation.
9. waits on the internal futex.
10. disables async cancellation.
11. re-acquires the internal (condvar) mutex.
12. goes back to 7, unless we are eligible for wakeup.
13. subtracts one from the waiters count.
14. handles pthread_cond_destroy.
15. unlocks internal (condvar) mutex, removes cancellation handler.
16. acquires the mutex that was passed in.
Nothing in the above accesses cond->__data.__mutex, so your test case would
probably happen to work.
However. pthread_cond_broadcast uses __data.__mutex to decide what
the woken threads should wait on. Other functions probably use it as
well. And maybe some future version of pthread_cond_wait will break
this without warning.
So you're in trouble.
Sorry for the lack of clarity, and hope that helps.
Regards,
Jonathan