devela::_dep::nc

Function futex

pub unsafe fn futex(
    uaddr: &AtomicU32,
    op: i32,
    val: u32,
    utime: Option<&timespec_t>,
    uaddr2: Option<&AtomicU32>,
    val3: u32,
) -> Result<i32, i32> 
Available on crate feature dep_nc only.
Expand description

Fast user-space locking.

Parameters

  • uaddr: futex user address
  • op: futex operations
  • val: expected value
  • utime: waiting timeout
  • uaddr2: target futext user address used for requeue

§Exampless

use std::sync::atomic::{AtomicU32, Ordering};
use std::thread;
use std::time::Duration;

const NOTIFY_WAIT: u32 = 0;
const NOTIFY_WAKE: u32 = 1;

fn wake_one(count: &AtomicU32) {
    let ret = unsafe { nc::futex(count, nc::FUTEX_WAKE, NOTIFY_WAKE, None, None, 0) };
    assert!(ret.is_ok());
}

fn wait(count: &AtomicU32, expected: u32) {
    let ret = unsafe { nc::futex(count, nc::FUTEX_WAIT, expected, None, None, 0) };
    assert!(ret.is_ok());
}

fn main() {
    let notify = AtomicU32::new(0);

    thread::scope(|s| {
        // Create the notify thread.
        s.spawn(|| {
            // Wake up some other threads after one second.
            println!("[notify] Sleep for 1s");
            thread::sleep(Duration::from_secs(1));
            println!("[notify] Wake up main thread");
            notify.store(NOTIFY_WAKE, Ordering::Relaxed);
            wake_one(&notify);
        });

        // Main thread will wait until the notify thread wakes it up.
        println!("[main] Waiting for notification..");
        while notify.load(Ordering::Relaxed) == NOTIFY_WAIT {
            wait(&notify, NOTIFY_WAIT);
        }
        println!("[main] Got wake up");
    });
}