futex_wake() in gomp_barrier_wait_end() in the case of multiple waiters

32 Views Asked by At

I am trying to understand the use of futex_wake(), as called from gomp_barrier_wait_end(), when invoked from gomp_team_start() (through gomp_barrier_wait()).

I see that futex_wake() is called in gomp_barrier_wait_end() only once. However, as I understand, it is possible that there are multiple waiters waiting on the supplied futex word. The futex man page, as I read it, indicates that a FUTEX_WAKE may not wake up all of the waiting threads.

FUTEX_WAKE (since Linux 2.6.0)

This operation wakes at most [emphasis added] val of the waiters that are waiting (e.g., inside FUTEX_WAIT) on the futex word at the address uaddr.

Since the FUTEX_WAKE in gomp_barrier_wait_end() may not wake up all of the waiters, it seems to me that one or more subsequent FUTEX_WAKE invocations may be needed to wake the remaining waiters. However, looking at the call stack leading up to the FUTEX_WAKE in gomp_barrier_wait_end() from gomp_team_start(), I do not see any enclosing loop that would provide for the case where some threads are still waiting after the first FUTEX_WAKE.

Am I misunderstanding the futex() man page's section on FUTEX_WAKE? Or, is there some other mechanism in libgomp that will guarantee that all the waiters are woken up?

Update - an answer from David Schwartz made me realize that I did not ask the right question above.

The question I should have asked was, does FUTEX_WAKE make a guarantee that it will wake up some minimum number of waiters?

2

There are 2 best solutions below

0
David Schwartz On

Saying the operation wakes "at most" val waiters means two things:

  1. It's not guaranteed not to wake fewer than val waiters.

  2. It will not wake more than val waiters.

You probably don't think 2 is a problem. But 1 very obviously isn't a problem either.

It would be impossible for FUTEX_WAKE to guarantee not to wake fewer than val waiters. There might not even be that many waiters. So this lack of guarantee is not at all unexpected.

So neither of the things that "at most" clause is saying are an issue for the code.

0
plafratt On

The futex man page says,

   FUTEX_WAIT (since Linux 2.6.0)

          This operation tests that the value at the futex word
          pointed to by the address uaddr still contains the
          expected value val, and if so, then sleeps waiting for a
          FUTEX_WAKE operation on the futex word.

I believe that a reasonable interpretation of this statement, in combination with the FUTEX_WAKE section (quoted in the original question), is that all waiters on futex word X will be woken up on the next FUTEX_WAKE invocation for X, unless the next FUTEX_WAKE invocation for X is made with a val argument that is less than the number of waiters.