summaryrefslogtreecommitdiff
path: root/src/futex/linux.rs
diff options
context:
space:
mode:
authorMica White <botahamec@outlook.com>2025-12-08 20:14:03 -0500
committerMica White <botahamec@outlook.com>2025-12-08 20:14:03 -0500
commitc31f4ce84c3c8b3f89a05890df775d4e766aaadb (patch)
tree40169c1240717002197c85985f9bb652dd4b0af8 /src/futex/linux.rs
First commitHEADmain
Diffstat (limited to 'src/futex/linux.rs')
-rwxr-xr-xsrc/futex/linux.rs61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/futex/linux.rs b/src/futex/linux.rs
new file mode 100755
index 0000000..80ca5a6
--- /dev/null
+++ b/src/futex/linux.rs
@@ -0,0 +1,61 @@
+use core::ops::Deref;
+use core::sync::atomic::{AtomicU32, Ordering};
+
+use libc::{syscall, SYS_futex};
+
+#[repr(C)]
+pub struct Futex(AtomicU32);
+
+pub type Atomic = AtomicU32;
+pub type Primitive = u32;
+
+pub type SmallFutex = Futex;
+pub type SmallAtomic = Atomic;
+pub type SmallPrimitive = Primitive;
+
+impl Futex {
+ #[inline]
+ pub const fn new(initial_value: u32) -> Self {
+ Self(AtomicU32::new(initial_value))
+ }
+
+ #[inline]
+ pub fn wait(&self, expected_start_value: u32) {
+ unsafe {
+ syscall(
+ SYS_futex,
+ core::ptr::from_ref(&self.0),
+ libc::FUTEX_WAIT_BITSET | libc::FUTEX_PRIVATE_FLAG,
+ expected_start_value,
+ core::ptr::null::<()>(),
+ core::ptr::null::<u32>(), // This argument is unused for FUTEX_WAIT_BITSET.
+ !0u32, // A full bitmask, to make it behave like a regular FUTEX_WAIT.
+ );
+ }
+ }
+
+ #[inline]
+ pub fn wake(&self) -> bool {
+ let ptr = &self.0 as *const AtomicU32;
+ const OP: libc::c_int = libc::FUTEX_WAKE | libc::FUTEX_PRIVATE_FLAG;
+ unsafe { libc::syscall(libc::SYS_futex, ptr, OP, 1) > 0 }
+ }
+
+ #[inline]
+ pub fn wake_all(&self) {
+ let ptr = &raw const self.0;
+ let op = libc::FUTEX_WAKE | libc::FUTEX_PRIVATE_FLAG;
+ unsafe {
+ syscall(libc::SYS_futex, ptr, op, i32::MAX);
+ }
+ }
+}
+
+impl Deref for Futex {
+ type Target = Atomic;
+
+ #[inline]
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}