File indexing completed on 2025-07-30 08:46:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef __TBB_detail__address_waiters_H
0018 #define __TBB_detail__address_waiters_H
0019
0020 #include "_utils.h"
0021
0022 namespace tbb {
0023 namespace detail {
0024
0025 namespace r1 {
0026 TBB_EXPORT void __TBB_EXPORTED_FUNC wait_on_address(void* address, d1::delegate_base& wakeup_condition, std::uintptr_t context);
0027 TBB_EXPORT void __TBB_EXPORTED_FUNC notify_by_address(void* address, std::uintptr_t context);
0028 TBB_EXPORT void __TBB_EXPORTED_FUNC notify_by_address_one(void* address);
0029 TBB_EXPORT void __TBB_EXPORTED_FUNC notify_by_address_all(void* address);
0030 }
0031
0032 namespace d1 {
0033
0034 template <typename Predicate>
0035 void adaptive_wait_on_address(void* address, Predicate wakeup_condition, std::uintptr_t context) {
0036 if (!timed_spin_wait_until(wakeup_condition)) {
0037 d1::delegated_function<Predicate> pred(wakeup_condition);
0038 r1::wait_on_address(address, pred, context);
0039 }
0040 }
0041
0042 template <typename T>
0043 class waitable_atomic {
0044 public:
0045 waitable_atomic() = default;
0046
0047 explicit waitable_atomic(T value) : my_atomic(value) {}
0048
0049 waitable_atomic(const waitable_atomic&) = delete;
0050 waitable_atomic& operator=(const waitable_atomic&) = delete;
0051
0052 T load(std::memory_order order) const noexcept {
0053 return my_atomic.load(order);
0054 }
0055
0056 T exchange(T desired) noexcept {
0057 return my_atomic.exchange(desired);
0058 }
0059
0060 void wait(T old, std::uintptr_t context, std::memory_order order) {
0061 auto wakeup_condition = [&] { return my_atomic.load(order) != old; };
0062 if (!timed_spin_wait_until(wakeup_condition)) {
0063
0064
0065 d1::delegated_function<decltype(wakeup_condition)> pred(wakeup_condition);
0066 do {
0067 r1::wait_on_address(this, pred, context);
0068 } while (!wakeup_condition());
0069 }
0070 }
0071
0072 void notify_one_relaxed() {
0073 r1::notify_by_address_one(this);
0074 }
0075
0076
0077
0078
0079
0080
0081
0082 private:
0083 std::atomic<T> my_atomic{};
0084 };
0085
0086 }
0087 }
0088 }
0089
0090 #endif