File indexing completed on 2025-01-30 09:33:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef BOOST_ATOMIC_DETAIL_FUTEX_HPP_INCLUDED_
0018 #define BOOST_ATOMIC_DETAIL_FUTEX_HPP_INCLUDED_
0019
0020 #include <boost/atomic/detail/config.hpp>
0021
0022 #ifdef BOOST_HAS_PRAGMA_ONCE
0023 #pragma once
0024 #endif
0025
0026 #if defined(__linux__) || defined(__OpenBSD__) || defined(__NETBSD__) || defined(__NetBSD__)
0027
0028 #include <sys/syscall.h>
0029
0030 #if defined(SYS_futex)
0031 #define BOOST_ATOMIC_DETAIL_SYS_FUTEX SYS_futex
0032 #elif defined(SYS_futex_time64)
0033
0034
0035 #define BOOST_ATOMIC_DETAIL_SYS_FUTEX SYS_futex_time64
0036 #elif defined(__NR_futex)
0037
0038 #define BOOST_ATOMIC_DETAIL_SYS_FUTEX __NR_futex
0039 #elif defined(SYS___futex)
0040
0041
0042
0043
0044 #define BOOST_ATOMIC_DETAIL_SYS_FUTEX SYS___futex
0045 #define BOOST_ATOMIC_DETAIL_NETBSD_FUTEX
0046 #endif
0047
0048 #if defined(BOOST_ATOMIC_DETAIL_SYS_FUTEX)
0049
0050 #include <cstddef>
0051 #if defined(__linux__)
0052 #include <linux/futex.h>
0053 #else
0054 #include <sys/futex.h>
0055 #endif
0056 #include <boost/atomic/detail/intptr.hpp>
0057 #include <boost/atomic/detail/header.hpp>
0058
0059 #define BOOST_ATOMIC_DETAIL_HAS_FUTEX
0060
0061 #if defined(FUTEX_PRIVATE_FLAG)
0062 #define BOOST_ATOMIC_DETAIL_FUTEX_PRIVATE_FLAG FUTEX_PRIVATE_FLAG
0063 #elif defined(__ANDROID__)
0064
0065 #define BOOST_ATOMIC_DETAIL_FUTEX_PRIVATE_FLAG 128
0066 #else
0067 #define BOOST_ATOMIC_DETAIL_FUTEX_PRIVATE_FLAG 0
0068 #endif
0069
0070 namespace boost {
0071 namespace atomics {
0072 namespace detail {
0073
0074
0075 BOOST_FORCEINLINE int futex_invoke(void* addr1, int op, unsigned int val1, const void* timeout = NULL, void* addr2 = NULL, unsigned int val3 = 0) BOOST_NOEXCEPT
0076 {
0077 #if !defined(BOOST_ATOMIC_DETAIL_NETBSD_FUTEX)
0078 return ::syscall(BOOST_ATOMIC_DETAIL_SYS_FUTEX, addr1, op, val1, timeout, addr2, val3);
0079 #else
0080
0081 return ::syscall(BOOST_ATOMIC_DETAIL_SYS_FUTEX, addr1, op, val1, timeout, addr2, 0u, val3);
0082 #endif
0083 }
0084
0085
0086 BOOST_FORCEINLINE int futex_invoke(void* addr1, int op, unsigned int val1, unsigned int val2, void* addr2 = NULL, unsigned int val3 = 0) BOOST_NOEXCEPT
0087 {
0088 #if !defined(BOOST_ATOMIC_DETAIL_NETBSD_FUTEX)
0089 return ::syscall(BOOST_ATOMIC_DETAIL_SYS_FUTEX, addr1, op, val1, static_cast< atomics::detail::uintptr_t >(val2), addr2, val3);
0090 #else
0091
0092 return ::syscall(BOOST_ATOMIC_DETAIL_SYS_FUTEX, addr1, op, val1, static_cast< void* >(NULL), addr2, val2, val3);
0093 #endif
0094 }
0095
0096
0097 BOOST_FORCEINLINE int futex_wait(void* pval, unsigned int expected) BOOST_NOEXCEPT
0098 {
0099 return futex_invoke(pval, FUTEX_WAIT, expected);
0100 }
0101
0102
0103 BOOST_FORCEINLINE int futex_wait_private(void* pval, unsigned int expected) BOOST_NOEXCEPT
0104 {
0105 return futex_invoke(pval, FUTEX_WAIT | BOOST_ATOMIC_DETAIL_FUTEX_PRIVATE_FLAG, expected);
0106 }
0107
0108
0109 BOOST_FORCEINLINE int futex_signal(void* pval, unsigned int count = 1u) BOOST_NOEXCEPT
0110 {
0111 return futex_invoke(pval, FUTEX_WAKE, count);
0112 }
0113
0114
0115 BOOST_FORCEINLINE int futex_signal_private(void* pval, unsigned int count = 1u) BOOST_NOEXCEPT
0116 {
0117 return futex_invoke(pval, FUTEX_WAKE | BOOST_ATOMIC_DETAIL_FUTEX_PRIVATE_FLAG, count);
0118 }
0119
0120
0121 BOOST_FORCEINLINE int futex_broadcast(void* pval) BOOST_NOEXCEPT
0122 {
0123 return futex_signal(pval, (~static_cast< unsigned int >(0u)) >> 1);
0124 }
0125
0126
0127 BOOST_FORCEINLINE int futex_broadcast_private(void* pval) BOOST_NOEXCEPT
0128 {
0129 return futex_signal_private(pval, (~static_cast< unsigned int >(0u)) >> 1);
0130 }
0131
0132
0133 BOOST_FORCEINLINE int futex_requeue(void* pval1, void* pval2, unsigned int wake_count = 1u, unsigned int requeue_count = (~static_cast< unsigned int >(0u)) >> 1) BOOST_NOEXCEPT
0134 {
0135 return futex_invoke(pval1, FUTEX_REQUEUE, wake_count, requeue_count, pval2);
0136 }
0137
0138
0139 BOOST_FORCEINLINE int futex_requeue_private(void* pval1, void* pval2, unsigned int wake_count = 1u, unsigned int requeue_count = (~static_cast< unsigned int >(0u)) >> 1) BOOST_NOEXCEPT
0140 {
0141 return futex_invoke(pval1, FUTEX_REQUEUE | BOOST_ATOMIC_DETAIL_FUTEX_PRIVATE_FLAG, wake_count, requeue_count, pval2);
0142 }
0143
0144 }
0145 }
0146 }
0147
0148 #include <boost/atomic/detail/footer.hpp>
0149
0150 #endif
0151
0152 #endif
0153
0154 #endif