Skip to content

Commit

Permalink
calls: Add unittest for futex()
Browse files Browse the repository at this point in the history
  • Loading branch information
XuShaohua committed Jul 29, 2024
1 parent ce5e47c commit 544a431
Show file tree
Hide file tree
Showing 11 changed files with 484 additions and 0 deletions.
44 changes: 44 additions & 0 deletions src/calls/futex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,50 @@
/// - `val`: expected value
/// - `utime`: waiting timeout
/// - `uaddr2`: target futext user address used for requeue
///
/// # Examples
///
/// ```rust
/// 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");
/// });
/// }
/// ```
pub unsafe fn futex(
uaddr: &AtomicU32,
op: i32,
Expand Down
44 changes: 44 additions & 0 deletions src/platform/linux-aarch64/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1457,6 +1457,50 @@ pub unsafe fn ftruncate(fd: i32, length: off_t) -> Result<(), Errno> {
/// - `val`: expected value
/// - `utime`: waiting timeout
/// - `uaddr2`: target futext user address used for requeue
///
/// # Examples
///
/// ```rust
/// 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");
/// });
/// }
/// ```
pub unsafe fn futex(
uaddr: &AtomicU32,
op: i32,
Expand Down
44 changes: 44 additions & 0 deletions src/platform/linux-arm/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1759,6 +1759,50 @@ pub unsafe fn ftruncate64(fd: i32, len: loff_t) -> Result<(), Errno> {
/// - `val`: expected value
/// - `utime`: waiting timeout
/// - `uaddr2`: target futext user address used for requeue
///
/// # Examples
///
/// ```rust
/// 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");
/// });
/// }
/// ```
pub unsafe fn futex(
uaddr: &AtomicU32,
op: i32,
Expand Down
44 changes: 44 additions & 0 deletions src/platform/linux-loongarch64/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1293,6 +1293,50 @@ pub unsafe fn ftruncate(fd: i32, length: off_t) -> Result<(), Errno> {
/// - `val`: expected value
/// - `utime`: waiting timeout
/// - `uaddr2`: target futext user address used for requeue
///
/// # Examples
///
/// ```rust
/// 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");
/// });
/// }
/// ```
pub unsafe fn futex(
uaddr: &AtomicU32,
op: i32,
Expand Down
44 changes: 44 additions & 0 deletions src/platform/linux-mips/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1822,6 +1822,50 @@ pub unsafe fn ftruncate64(fd: i32, len: loff_t) -> Result<(), Errno> {
/// - `val`: expected value
/// - `utime`: waiting timeout
/// - `uaddr2`: target futext user address used for requeue
///
/// # Examples
///
/// ```rust
/// 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");
/// });
/// }
/// ```
pub unsafe fn futex(
uaddr: &AtomicU32,
op: i32,
Expand Down
44 changes: 44 additions & 0 deletions src/platform/linux-mips64/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1687,6 +1687,50 @@ pub unsafe fn ftruncate(fd: i32, length: off_t) -> Result<(), Errno> {
/// - `val`: expected value
/// - `utime`: waiting timeout
/// - `uaddr2`: target futext user address used for requeue
///
/// # Examples
///
/// ```rust
/// 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");
/// });
/// }
/// ```
pub unsafe fn futex(
uaddr: &AtomicU32,
op: i32,
Expand Down
44 changes: 44 additions & 0 deletions src/platform/linux-ppc64/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1720,6 +1720,50 @@ pub unsafe fn ftruncate(fd: i32, length: off_t) -> Result<(), Errno> {
/// - `val`: expected value
/// - `utime`: waiting timeout
/// - `uaddr2`: target futext user address used for requeue
///
/// # Examples
///
/// ```rust
/// 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");
/// });
/// }
/// ```
pub unsafe fn futex(
uaddr: &AtomicU32,
op: i32,
Expand Down
Loading

0 comments on commit 544a431

Please sign in to comment.