This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]