diff --git a/src/header/pthread/barrier.rs b/src/header/pthread/barrier.rs index e579449641..e2e74d939c 100644 --- a/src/header/pthread/barrier.rs +++ b/src/header/pthread/barrier.rs @@ -1,10 +1,13 @@ -use crate::header::errno::*; +use crate::header::errno::EINVAL; use core::num::NonZeroU32; -use crate::sync::barrier::*; +use crate::sync::barrier::{Barrier, WaitResult}; -use super::*; +use super::{ + PTHREAD_BARRIER_SERIAL_THREAD, PTHREAD_PROCESS_PRIVATE, c_int, c_uint, pthread_barrier_t, + pthread_barrierattr_t, +}; pub(crate) type RlctBarrier = Barrier; @@ -21,20 +24,45 @@ impl Default for RlctBarrierAttr { } } -// Not async-signal-safe. /// See . +/// +/// Destroys the barrier referenced by `barrier` and releases any resources +/// used by the barrier. +/// +/// Upon success, returns `0`. Upon error, returns an error number. +/// +/// # Implementation +/// Not async-signal-safe. +/// +/// # Safety +/// The following will result in undefined behaviour: +/// - Use of `barrier` after this function unless reinitialized by +/// `pthread_barrier_init()`. +/// - This function is called with an uninitialized `barrier`. +/// - This function is called when any thread is blocked on `barrier`. #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_barrier_destroy(barrier: *mut pthread_barrier_t) -> c_int { - // Behavior is undefined if any thread is currently waiting when this is called. - // No-op, currently. unsafe { core::ptr::drop_in_place(barrier.cast::()) }; 0 } -// Not async-signal-safe. /// See . +/// +/// Allocates any resources required to use the barrier referenced by `barrier` +/// and shall initialize the barrier with attributes referenced by `attr`. +/// +/// Upon success, returns `0`. Upon error, returns an error number. +/// +/// # Implementation +/// Not async-signal-safe. +/// +/// # Safety +/// The following will result in undefined behaviour: +/// - Use of `barrier` before this function is called. +/// - This function is called with an already initialized `barrier`. +/// - This function is called when any thread is blocked on `barrier`. #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_barrier_init( barrier: *mut pthread_barrier_t, @@ -57,8 +85,19 @@ fn unlikely(condition: bool) -> bool { condition } -// Not async-signal-safe. /// See . +/// +/// Synchronizes participating threads at the barrier referenced by `barrier`. +/// +/// Upon success, returns `PTHREAD_BARRIER_SERIAL_THREAD` for a single +/// (arbitrary) thread synchronized at the barrier and `0` for each of the +/// other threads. Upon failure, returns an error number. +/// +/// # Implementation +/// Not async-signal-safe. +/// +/// # Safety +/// Undefined behaviour will occur if `barrier` is uninitialized. #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_barrier_wait(barrier: *mut pthread_barrier_t) -> c_int { let barrier = unsafe { &*barrier.cast::() }; @@ -69,8 +108,18 @@ pub unsafe extern "C" fn pthread_barrier_wait(barrier: *mut pthread_barrier_t) - } } -// Not async-signal-safe. /// See . +/// +/// Initializes a barrier attributes object `attr` with the default value of +/// all of the attributes defined by the implementation. +/// +/// Upon success, returns `0`. Upon error, returns an error number. +/// +/// # Implementation +/// Not async-signal-safe. +/// +/// # Safety +/// Undefined behaviour will occur if `attr` is already initialized. #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_barrierattr_init(attr: *mut pthread_barrierattr_t) -> c_int { unsafe { core::ptr::write(attr.cast::(), RlctBarrierAttr::default()) }; @@ -78,8 +127,18 @@ pub unsafe extern "C" fn pthread_barrierattr_init(attr: *mut pthread_barrierattr 0 } -// Not async-signal-safe. /// See . +/// +/// Sets the process-shared attribute in an initialized attributes object +/// referenced by `attr`. +/// +/// Upon success, returns `0`. Upon error, returns an error number. +/// +/// # Implementation +/// Not async-signal-safe. +/// +/// # Safety +/// Undefined behaviour will occur if `attr` is uninitialized. #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_barrierattr_setpshared( attr: *mut pthread_barrierattr_t, @@ -91,8 +150,20 @@ pub unsafe extern "C" fn pthread_barrierattr_setpshared( 0 } -// Not async-signal-safe. /// See . +/// +/// Obtains the value of the process-shared attribute from the attributes +/// object referenced by `attr`. +/// +/// Upon success, returns `0` and stores the value of the process-shared +/// attribute of `attr` into the object referenced by `pshared`. Upon error, +/// returns an error number. +/// +/// # Implementation +/// Not async-signal-safe. +/// +/// # Safety +/// Undefined behaviour will occur if `attr` is uninitialized. #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_barrierattr_getpshared( attr: *const pthread_barrierattr_t, @@ -102,8 +173,18 @@ pub unsafe extern "C" fn pthread_barrierattr_getpshared( 0 } -// Not async-signal-safe. /// See . +/// +/// Destroys a barrier attributes object. +/// +/// Upon success, returns `0`. Upon error, returns an error number. +/// +/// # Implementation +/// Not async-signal-safe. +/// +/// # Safety +/// Undefined behaviour will occur if `attr` is uninitialized or if `attr` is +/// used after calling this function. #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_barrierattr_destroy(attr: *mut pthread_barrierattr_t) -> c_int { unsafe { core::ptr::drop_in_place(attr) };