Does pthread_cond_signal or pthread_cond_broadcast call a write memory barrier?

Variable conditions are usually used in such a way that the state to which they refer changes under the mutex. However, when the state is only one flag for installation only, there is no need for a mutex to prevent simultaneous execution. Therefore, you can do something like this:

flag = 1; pthread_cond_broadcast(&cvar); 

However, it is safe if pthread_cond_broadcast implies a write memory barrier; otherwise, the waiting thread can see that the state variable is passed before the flag is written. That is, the waiting thread may wake up, consume the cvar signal, but see the flag 0 more.

So my question is: do pthread_cond_broadcast and pthread_cond_signal calls imply a write memory barrier? If so, where is it indicated in the corresponding POSIX (or other) specifications? The spectrum seemed obscure at this point.

Note. I know that in practice this leads to a memory barrier (on Linux, because waking up threads means a complete processor memory barrier, and calling a cross-library function means a compiler memory barrier). However, I'm interested here in what the specifiers are.

+4
source share
2 answers

Regardless of whether this implies a memory barrier, the code is still incorrect. Consider the reading side:

 while (flag == 0) pthread_cond_wait(&cvar, &mutex); 

If the read side is paused between testing flag == 0 and waiting, the write side can execute flag = 1; pthread_cond_signal(&cvar); flag = 1; pthread_cond_signal(&cvar); . Then the read side will miss the awakening - it will wait forever. Remember that awakenings are not queued - if there is no waiter, when the status signal is signaled, the signal does not work. To avoid this, the recording side needs to lock the mutex anyway.

+7
source

In POSIX, if you write a variable from one stream and read it from another, you must protect it with the mutex. An exception to pthread_cond_broadcast not.

If your platform / compiler offers atomic variables, they can provide additional guarantees. For example, if flag is C ++ 11 std::atomic<int> , then this code is fine.

+3
source

Source: https://habr.com/ru/post/1369553/


All Articles