-
Notifications
You must be signed in to change notification settings - Fork 126
/
ch8-01-futex.rs
49 lines (43 loc) · 1.29 KB
/
ch8-01-futex.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#![cfg(target_os = "linux")]
use std::sync::atomic::AtomicU32;
use std::sync::atomic::Ordering::Relaxed;
use std::thread;
use std::time::Duration;
pub fn wait(a: &AtomicU32, expected: u32) {
// Refer to the futex (2) man page for the syscall signature.
unsafe {
libc::syscall(
libc::SYS_futex, // The futex syscall.
a as *const AtomicU32, // The atomic to operate on.
libc::FUTEX_WAIT, // The futex operation.
expected, // The expected value.
std::ptr::null::<libc::timespec>(), // No timeout.
);
}
}
pub fn wake_one(a: &AtomicU32) {
// Refer to the futex (2) man page for the syscall signature.
unsafe {
libc::syscall(
libc::SYS_futex, // The futex syscall.
a as *const AtomicU32, // The atomic to operate on.
libc::FUTEX_WAKE, // The futex operation.
1, // The number of threads to wake up.
);
}
}
fn main() {
let a = AtomicU32::new(0);
thread::scope(|s| {
s.spawn(|| {
thread::sleep(Duration::from_secs(3));
a.store(1, Relaxed);
wake_one(&a);
});
println!("Waiting...");
while a.load(Relaxed) == 0 {
wait(&a, 0);
}
println!("Done!");
});
}