Re: pthread_cond_signal/broadcast: necessary to hold mutex?
David Holland <[email protected]> Sun, 3 May 2026 07:39:53 +0000
| Newsgroups | gmane.os.netbsd.current |
|---|---|
| Message-ID | <[email protected]> |
On Tue, Mar 24, 2026 at 09:55:03PM +0700, Robert Elz wrote: > wiz, unless someone who knows more about this that I do (which means > just about anyone at all) contradicts this, I think you can safely > update the man pages to be like the posix spec says. Did this get finished? There is no inherent reason you must hold the mutex to signal or broadcast on a condition variable. There are three correctness requirements: first, that everyone involved holds the mutex when accessing the condition state; second, that the signal or broadcast operation associated with a state update doesn't come before said update; and third, that the implementation of wait queues the waiter on the condition variable before unlocking the mutex. Under these conditions, any state update either occurs before a prospective waiter inspects the condition state, in which case it takes that update into account when deciding what to do; or it occurs after the waiter has inspected the state, decided to wait, and gotten far enough in the process of going to sleep that a signal or broadcast will wake it up again. Because making the update requires holding the mutex, it can't happen until the waiter is queued and waiting. At that point it doesn't matter if the signal or broadcast call happens along with the state update or afterwards. There's generally no real reason to unlock the mutex before calling signal or broadcast; but there's also no real reason not to, and occasionally people do. It's also possible for an implementation of condition variables to rely on the caller holding the mutex to synchronize its own internals. Because of the above, this isn't a good implementation strategy, so our pthread library doesn't. Note that the definition of the signal and broadcast operations in an OS textbook generally will say that the caller must hold the mutex. This is probably grandfathering in old implementations as much as anything. We don't have to pay any attention. Please adjust the man pages as proposed. ... Since the question came up: it is not sensible to use the same condition variable with multiple mutexes. You need a consistent lockset for the condition state. (It is theoretically possible to use one condition variable for two or more mutexes that each protect _entirely different_ sets of condition state, and thus two or more entirely different conditions, at the cost of waking everyone up regardless of whether it was _their_ condition that changed. The classical uniprocessor Unix sleep/wakeup logic was kind of like this. But it's not sane, and apparently POSIX makes it UB for pthreads, so don't.) It is, though, perfectly reasonable to use two or more condition variables with the same mutex and same state but different logical conditions. For example, if you have a shared buffer, it's reasonable to use separate condition variables for "empty" and "full". -- David A. Holland [email protected]