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


> -----Original Message-----
> From: Jonathan Nieder [mailto:jrnieder@gmail.com]
> 
> 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.

I really appreciate the time you put in to explain this to me. I will send a
note to the original authors of the benchmark so that they can fix their
code.

One thing that I am still unclear about is that you mentioned
pthread_cond_broadcast uses __data.__mutex to decide what the woken threads
should wait on. This then should cause all the threads to wait on a
different mutex than what they really should wait on? Wouldn't this still
cause undefined behavior?

Sorry for the trouble.

Regards,

Bharath

Attachment: smime.p7s
Description: S/MIME cryptographic signature


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