sync: export C futex_wake/futex_wait for portable futex users (Mesa)
Mesa's util/futex declares int futex_wake(uint32_t*, int32_t) / int futex_wait(uint32_t*, int32_t, const struct timespec*) and its drivers (ANV) call them. relibc already has the correct Redox futex internally; expose it under these C symbols so Mesa's Redox branch links against a working futex.
This commit is contained in:
@@ -128,6 +128,39 @@ pub fn futex_wait<T: FutexAtomicTy>(
|
||||
unsafe { futex_wait_ptr(atomic.ptr(), value, deadline_opt) }
|
||||
}
|
||||
|
||||
/// C-ABI futex primitives for consumers such as Mesa's `util/futex`, which
|
||||
/// expects `int futex_wake(uint32_t *addr, int32_t count)` and
|
||||
/// `int futex_wait(uint32_t *addr, int32_t value, const struct timespec *)`.
|
||||
/// Backed by relibc's own futex (the correct primitive for Redox), so these
|
||||
/// give portable code a working futex without reimplementing the Redox ABI.
|
||||
///
|
||||
/// # Safety
|
||||
/// `addr` must point to a valid, properly-aligned `u32`; `timeout` is null or a
|
||||
/// valid `timespec`.
|
||||
#[unsafe(export_name = "futex_wake")]
|
||||
pub unsafe extern "C" fn c_futex_wake(addr: *mut u32, count: c_int) -> c_int {
|
||||
unsafe { futex_wake_ptr(addr, count) as c_int }
|
||||
}
|
||||
|
||||
/// See [`c_futex_wake`].
|
||||
///
|
||||
/// # Safety
|
||||
/// As for [`c_futex_wake`].
|
||||
#[unsafe(export_name = "futex_wait")]
|
||||
pub unsafe extern "C" fn c_futex_wait(
|
||||
addr: *mut u32,
|
||||
value: c_int,
|
||||
timeout: *const timespec,
|
||||
) -> c_int {
|
||||
let deadline = if timeout.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(unsafe { &*timeout })
|
||||
};
|
||||
let _ = unsafe { futex_wait_ptr(addr, value as u32, deadline) };
|
||||
0
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum FutexWaitResult {
|
||||
Waited, // possibly spurious
|
||||
|
||||
Reference in New Issue
Block a user