Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
futex.hpp
Go to the documentation of this file.
1
9#pragma once
10
11#include <cstdint>
12#include <ctime>
13
14#ifdef __APPLE__
15// Darwin's os_sync API (available since macOS 10.12 / iOS 10)
16// Forward declarations to avoid header dependency
17extern "C" {
18int os_sync_wait_on_address(void* addr, uint64_t value, size_t size, uint32_t flags);
19int os_sync_wait_on_address_with_timeout(
20 void* addr, uint64_t value, size_t size, uint32_t flags, uint32_t clockid, uint64_t timeout_ns);
21int os_sync_wake_by_address_any(void* addr, size_t size, uint32_t flags);
22}
23#define OS_SYNC_WAIT_ON_ADDRESS_SHARED 1u
24#define OS_SYNC_WAKE_BY_ADDRESS_SHARED 1u
25#define OS_CLOCK_MACH_ABSOLUTE_TIME 32u
26#else
27// Linux futex
28#include <cerrno>
29#include <linux/futex.h>
30#include <sys/syscall.h>
31#include <unistd.h>
32#endif
33
34namespace bb::ipc {
35
45inline int futex_wait(volatile uint32_t* addr, uint32_t expect)
46{
47#ifdef __APPLE__
48 // macOS: Use os_sync_wait_on_address with SHARED flag for cross-process
49 return os_sync_wait_on_address(
50 const_cast<uint32_t*>(addr), static_cast<uint64_t>(expect), sizeof(uint32_t), OS_SYNC_WAIT_ON_ADDRESS_SHARED);
51#else
52 // Linux futex
53 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
54 return static_cast<int>(syscall(SYS_futex, addr, FUTEX_WAIT, expect, nullptr, nullptr, 0));
55#endif
56}
57
69inline int futex_wait_timeout(volatile uint32_t* addr, uint32_t expect, uint64_t timeout_ns)
70{
71#ifdef __APPLE__
72 // macOS: Use os_sync_wait_on_address_with_timeout with SHARED flag for cross-process
73 // Uses MACH_ABSOLUTE_TIME clock (monotonic, measures time since boot)
74 return os_sync_wait_on_address_with_timeout(const_cast<uint32_t*>(addr),
75 static_cast<uint64_t>(expect),
76 sizeof(uint32_t),
77 OS_SYNC_WAIT_ON_ADDRESS_SHARED,
78 OS_CLOCK_MACH_ABSOLUTE_TIME,
79 timeout_ns);
80#else
81 // Linux futex with timeout
82 struct timespec timeout = { .tv_sec = static_cast<time_t>(timeout_ns / 1000000000ULL),
83 .tv_nsec = static_cast<long>(timeout_ns % 1000000000ULL) };
84 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
85 return static_cast<int>(syscall(SYS_futex, addr, FUTEX_WAIT, expect, &timeout, nullptr, 0));
86#endif
87}
88
98inline int futex_wake(volatile uint32_t* addr, int n)
99{
100#ifdef __APPLE__
101 // macOS: Use os_sync_wake_by_address with SHARED flag for cross-process
102 (void)n;
103 return os_sync_wake_by_address_any(const_cast<uint32_t*>(addr), sizeof(uint32_t), OS_SYNC_WAKE_BY_ADDRESS_SHARED);
104#else
105 // Linux futex
106 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
107 return static_cast<int>(syscall(SYS_futex, addr, FUTEX_WAKE, n, nullptr, nullptr, 0));
108#endif
109}
110
111} // namespace bb::ipc
int futex_wake(volatile uint32_t *addr, int n)
Wake waiters blocked on an address.
Definition futex.hpp:98
int futex_wait(volatile uint32_t *addr, uint32_t expect)
Atomic compare-and-wait operation.
Definition futex.hpp:45
int futex_wait_timeout(volatile uint32_t *addr, uint32_t expect, uint64_t timeout_ns)
Atomic compare-and-wait operation with timeout.
Definition futex.hpp:69