diff options
author | Andrei Vagin <avagin@google.com> | 2019-12-19 17:25:18 -0800 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2019-12-19 17:26:44 -0800 |
commit | 29955a4797e8264f75886a989dbc81b2b5443f4c (patch) | |
tree | c030fd27dd08c2ebc08f02315b3546a2a492f112 /test/syscalls | |
parent | 7419e0e5d74621b2be60e9b18e4e2d7bb2a65cc3 (diff) |
futex: wake one waiter if futex_wake is called with a non-positive value
This change is needed to be compatible with the Linux kernel.
There is no glibc wrapper for the futex system call, so it is easy to
make a mistake and call syscall(__NR_futex, FUTEX_WAKE, addr) without
the fourth argument. This works on Linux, because it wakes one waiter
even if val is nonpositive.
PiperOrigin-RevId: 286494396
Diffstat (limited to 'test/syscalls')
-rw-r--r-- | test/syscalls/linux/futex.cc | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/test/syscalls/linux/futex.cc b/test/syscalls/linux/futex.cc index d3e3f998c..40c80a6e1 100644 --- a/test/syscalls/linux/futex.cc +++ b/test/syscalls/linux/futex.cc @@ -239,6 +239,27 @@ TEST_P(PrivateAndSharedFutexTest, Wake1_NoRandomSave) { EXPECT_THAT(futex_wake(IsPrivate(), &a, 1), SyscallSucceedsWithValue(1)); } +TEST_P(PrivateAndSharedFutexTest, Wake0_NoRandomSave) { + constexpr int kInitialValue = 1; + std::atomic<int> a = ATOMIC_VAR_INIT(kInitialValue); + + // Prevent save/restore from interrupting futex_wait, which will cause it to + // return EAGAIN instead of the expected result if futex_wait is restarted + // after we change the value of a below. + DisableSave ds; + ScopedThread thread([&] { + EXPECT_THAT(futex_wait(IsPrivate(), &a, kInitialValue), + SyscallSucceedsWithValue(0)); + }); + absl::SleepFor(kWaiterStartupDelay); + + // Change a so that if futex_wake happens before futex_wait, the latter + // returns EAGAIN instead of hanging the test. + a.fetch_add(1); + // The Linux kernel wakes one waiter even if val is 0 or negative. + EXPECT_THAT(futex_wake(IsPrivate(), &a, 0), SyscallSucceedsWithValue(1)); +} + TEST_P(PrivateAndSharedFutexTest, WakeAll_NoRandomSave) { constexpr int kInitialValue = 1; std::atomic<int> a = ATOMIC_VAR_INIT(kInitialValue); |