The futex man page provides a simple demo, but I can't get the result as the page described, the result seems to be deadlock on my machine (linux 5.2.1); the parent process isn't awaken by its child. Is the man page wrong?
Example of output on my machine:
[root@archlinux ~]# ./a.out
Child (12877) 0
Parent (12876) 0
Child (12877) 1
// block here
my system:
[root@archlinux ~]# uname -a
Linux archlinux 5.2.1-arch1-1-ARCH #1 SMP PREEMPT Sun Jul 14 14:52:52 UTC 2019 x86_64 GNU/Linux
Indeed the example in the man page is erroneous, at two places the code deviates from the correct depiction in the corresponding comment.
/* Acquire the futex pointed to by 'futexp': wait for its value to
become 1, and then set the value to 0. */
static void
fwait(int *futexp)
{
int s;
/* atomic_compare_exchange_strong(ptr, oldval, newval)
atomically performs the equivalent of:
if (*ptr == *oldval)
*ptr = newval;
It returns true if the test yielded true and *ptr was updated. */
while (1) {
/* Is the futex available? */
const int zero = 0;
if (atomic_compare_exchange_strong(futexp, &zero, 1))
break; /* Yes */
has to be the other way round:
/* Is the futex available? */
if (atomic_compare_exchange_strong(futexp, &(int){1}, 0))
break; /* Yes */
/* Release the futex pointed to by 'futexp': if the futex currently
has the value 0, set its value to 1 and the wake any futex waiters,
so that if the peer is blocked in fpost(), it can proceed. */
static void
fpost(int *futexp)
{
int s;
/* atomic_compare_exchange_strong() was described in comments above */
const int one = 1;
if (atomic_compare_exchange_strong(futexp, &one, 0)) {
…
has to be the other way round:
if (atomic_compare_exchange_strong(futexp, &(int){0}, 1)) {
…
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.