Re: pthread_cond_signal/broadcast: necessary to hold mutex?
Valery Ushakov <[email protected]> Tue, 24 Mar 2026 17:07:33 +0300
| Newsgroups | gmane.os.netbsd.current |
|---|---|
| Message-ID | <[email protected]> |
On Tue, Mar 24, 2026 at 00:46:02 +0100, Tobias Nygren wrote: > On Mon, 23 Mar 2026 23:23:45 +0100 > Thomas Klausner <[email protected]> wrote: > > > On Mon, Mar 23, 2026 at 10:39:55PM +0100, Tobias Nygren wrote: > > > On Mon, 23 Mar 2026 21:50:41 +0100 > > > Thomas Klausner <[email protected]> wrote: > > > > > > > - Time for a bug report? > > > > - Any ideas where this requirement comes from? > > > > > > The hardcopy of "DEC OSF/1 Guide to DECthreads" DEC p/n AA-Q2DPB-TK > > > printed in 1994 which I happen to still have in my possession states on > > > page 56 for pthread_cond_wait: > > > > > > ``` > > > Call this routine after you have locked the mutex specified in /mutex/. The results of this routine are unpredictable without first locking the mutex. > > > ``` > > > > > > This predates the first publication of pthreads in IEEE 1003.1c-1995. > > > The wording strongly suggest that you should lock the mutex but doesn't > > > explicitly forbid not doing so. I guess POSIX copied those semantics but > > > made them more clear, as standards people do. > > > > > > I think it would be OK to > > > s/must be held/must be held for defined behaviour/ > > > in our manpage. > > > > Perhaps I gave too much context. > > > > I'm not talking about the *wait* part, I agree that the mutex needs to > > be held there. > > > > I was only talking about *signal and *broadcast. > > I see. The historical printed documentation explictly states for > pthread_cond_signal: > > ``` > You can call this routine regardless if the associated mutex is locked. > ``` > > And for pthread_cond_broadcast: > > ``` > You can call this routine whether the associated mutex is locked or not. > ``` My knowledge of synchronization primitives is cargo-cultish at best, and so I tend to defer to Solaris manuals. "can" above is a vague word. It probably tells you that the function itself doesn't touch the mutex and thus the function call itself does not depend on whether the mutex is locked or not. So you "can" call it either way, it won't explode in your face. Whether the system does what you expect (or, as POSIX glibly puts it, "if predictable scheduling behavior is required") is a different matter though. Solaris "Multithreaded Programming Guide": https://docs.oracle.com/cd/E19455-01/806-5257/sync-53686/index.html Call pthread_cond_signal() under the protection of the same mutex used with the condition variable being signaled. Otherwise, the condition variable could be signaled between the test of the associated condition and blocking in pthread_cond_wait(), which can cause an infinite wait. As far as I understand, the above caveat talks about the typical waiting code that does: pthread_mutex_lock(&m); { while (condition_is_false) { // // another thread can singal cv here IF it hasn't taken // the mutex first, and the wait below will be infinite // pthread_cond_wait(&cv, &m); } } pthread_mutex_unlock(&m); I guess POSIX just gives the buggy code a license to survive that signal-w/out-lock call; and an eager, righteous implementation must not deny the buggy code its right to live dangerously. -uwe