-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[libc] refactor futex and remove dependency cycle #117923
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| //===--- Futex With Timeout Support -----------------------------*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| #ifndef LLVM_LIBC_SRC_SUPPORT_THREADS_FUTEX_TIMEOUT_H | ||
| #define LLVM_LIBC_SRC_SUPPORT_THREADS_FUTEX_TIMEOUT_H | ||
|
|
||
| // TODO: implement futex for other platforms. | ||
| #ifdef __linux__ | ||
| #include "src/__support/threads/linux/futex_timeout.h" | ||
| #else | ||
| #error "Unsupported platform" | ||
| #endif | ||
|
|
||
| #endif // LLVM_LIBC_SRC_SUPPORT_THREADS_FUTEX_TIMEOUT_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| //===--- Futex Utilities ----------------------------------------*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| //===--- Futex Wrapper ------------------------------------------*- C++ -*-===// | ||
| // We take the name "futex" from Linux system. This library provides a general | ||
| // wrapper for waiting and notifying on atomic words. Various platforms support | ||
| // futex-like operations. | ||
| // - Windows: WaitOnAddress and WakeByAddressSingle/WakeByAddressAll | ||
| // (Windows futex cannot be used in inter-process synchronization) | ||
| // - MacOS: os_sync_wait_on_address or __ulock_wait/__ulock_wake | ||
| // - FreeBSD: _umtx_op | ||
|
|
||
| #ifndef LLVM_LIBC_SRC_SUPPORT_THREADS_FUTEX_UTILS_H | ||
| #define LLVM_LIBC_SRC_SUPPORT_THREADS_FUTEX_UTILS_H | ||
|
|
||
| // TODO: implement futex for other platforms. | ||
| #ifdef __linux__ | ||
| #include "src/__support/threads/linux/futex_utils.h" | ||
| #else | ||
| #error "Unsupported platform" | ||
| #endif | ||
|
|
||
| #endif // LLVM_LIBC_SRC_SUPPORT_THREADS_FUTEX_UTILS_H |
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,62 @@ | ||||||||||||
| //===--- Futex Wrapper ------------------------------------------*- C++ -*-===// | ||||||||||||
| // | ||||||||||||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||||||||||||
| // See https://llvm.org/LICENSE.txt for license information. | ||||||||||||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||||||||||
| // | ||||||||||||
| //===----------------------------------------------------------------------===// | ||||||||||||
|
|
||||||||||||
| #ifndef LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_FUTEX_TIMEOUT_H | ||||||||||||
| #define LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_FUTEX_TIMEOUT_H | ||||||||||||
|
|
||||||||||||
| #include "src/__support/CPP/atomic.h" | ||||||||||||
| #include "src/__support/CPP/limits.h" | ||||||||||||
| #include "src/__support/CPP/optional.h" | ||||||||||||
| #include "src/__support/OSUtil/syscall.h" | ||||||||||||
| #include "src/__support/macros/attributes.h" | ||||||||||||
| #include "src/__support/macros/config.h" | ||||||||||||
| #include "src/__support/threads/linux/futex_utils.h" | ||||||||||||
| #include "src/__support/time/linux/abs_timeout.h" | ||||||||||||
|
|
||||||||||||
| namespace LIBC_NAMESPACE_DECL { | ||||||||||||
| class TimedFutex : public Futex { | ||||||||||||
| public: | ||||||||||||
| using Timeout = internal::AbsTimeout; | ||||||||||||
| using Futex::Futex; | ||||||||||||
| using Futex::operator=; | ||||||||||||
| LIBC_INLINE long wait(FutexWordType expected, | ||||||||||||
| cpp::optional<Timeout> timeout = cpp::nullopt, | ||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So if we make the distinction between |
||||||||||||
| bool is_shared = false) { | ||||||||||||
| // use bitset variants to enforce abs_time | ||||||||||||
| uint32_t op = is_shared ? FUTEX_WAIT_BITSET : FUTEX_WAIT_BITSET_PRIVATE; | ||||||||||||
| if (timeout && timeout->is_realtime()) { | ||||||||||||
| op |= FUTEX_CLOCK_REALTIME; | ||||||||||||
| } | ||||||||||||
|
Comment on lines
+32
to
+34
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
| for (;;) { | ||||||||||||
| if (this->load(cpp::MemoryOrder::RELAXED) != expected) | ||||||||||||
| return 0; | ||||||||||||
|
|
||||||||||||
| long ret = syscall_impl<long>( | ||||||||||||
| /* syscall number */ FUTEX_SYSCALL_ID, | ||||||||||||
| /* futex address */ this, | ||||||||||||
| /* futex operation */ op, | ||||||||||||
| /* expected value */ expected, | ||||||||||||
| /* timeout */ timeout ? &timeout->get_timespec() : nullptr, | ||||||||||||
| /* ignored */ nullptr, | ||||||||||||
| /* bitset */ FUTEX_BITSET_MATCH_ANY); | ||||||||||||
|
|
||||||||||||
| // continue waiting if interrupted; otherwise return the result | ||||||||||||
| // which should normally be 0 or -ETIMEOUT | ||||||||||||
| if (ret == -EINTR) | ||||||||||||
| continue; | ||||||||||||
|
|
||||||||||||
| return ret; | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
| }; | ||||||||||||
|
|
||||||||||||
| static_assert(__is_standard_layout(TimedFutex), | ||||||||||||
| "Futex must be a standard layout type."); | ||||||||||||
| } // namespace LIBC_NAMESPACE_DECL | ||||||||||||
|
|
||||||||||||
| #endif // LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_FUTEX_TIMEOUT_H | ||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need
usingstatement for the assignment operator?