0

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
X Ah
  • 11
  • 1

1 Answers1

1

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)) {
               …
Armali
  • 18,255
  • 14
  • 57
  • 171
  • 1
    FYI. Fixed now: https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/commit/?id=09e456c2d0a386af5bf01b9cfb38d6b2fc2c6aa8 – P.P Jan 11 '20 at 15:00