Skip to main content

relibc/header/pthread/
cond.rs

1// Used design from https://www.remlab.net/op/futex-condvar.shtml
2
3use crate::header::time::CLOCK_REALTIME;
4
5use super::*;
6
7// PTHREAD_COND_INITIALIZER is defined manually in bits_pthread/cbindgen.toml
8
9/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_cond_broadcast.html>.
10#[unsafe(no_mangle)]
11pub unsafe extern "C" fn pthread_cond_broadcast(cond: *mut pthread_cond_t) -> c_int {
12    e((unsafe { &*cond.cast::<RlctCond>() }).broadcast())
13}
14
15/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_cond_destroy.html>.
16#[unsafe(no_mangle)]
17pub unsafe extern "C" fn pthread_cond_destroy(cond: *mut pthread_cond_t) -> c_int {
18    // No-op
19    unsafe { core::ptr::drop_in_place(cond.cast::<RlctCond>()) };
20    0
21}
22
23/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_cond_init.html>.
24#[unsafe(no_mangle)]
25pub unsafe extern "C" fn pthread_cond_init(
26    cond: *mut pthread_cond_t,
27    attr: *const pthread_condattr_t,
28) -> c_int {
29    let attr = unsafe { attr.cast::<RlctCondAttr>().as_ref() }
30        .copied()
31        .unwrap_or_default();
32
33    if attr.clock != CLOCK_REALTIME {
34        // As monotonic clock always smaller than realtime clock, this always result in instant timeout.
35        todo_skip!(0, "pthread_cond_init with monotonic clock");
36    }
37
38    unsafe { cond.cast::<RlctCond>().write(RlctCond::new()) };
39
40    0
41}
42
43/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_cond_signal.html>.
44#[unsafe(no_mangle)]
45pub unsafe extern "C" fn pthread_cond_signal(cond: *mut pthread_cond_t) -> c_int {
46    e((unsafe { &*cond.cast::<RlctCond>() }).signal())
47}
48
49/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_cond_timedwait.html>.
50#[unsafe(no_mangle)]
51pub unsafe extern "C" fn pthread_cond_timedwait(
52    cond: *mut pthread_cond_t,
53    mutex: *mut pthread_mutex_t,
54    timeout: *const timespec,
55) -> c_int {
56    e((unsafe { &*cond.cast::<RlctCond>() })
57        .timedwait(unsafe { &*mutex.cast::<RlctMutex>() }, unsafe { &*timeout }))
58}
59
60/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_cond_clockwait.html>.
61#[unsafe(no_mangle)]
62pub unsafe extern "C" fn pthread_cond_clockwait(
63    cond: *mut pthread_cond_t,
64    mutex: *mut pthread_mutex_t,
65    clock_id: clockid_t,
66    timeout: *const timespec,
67) -> c_int {
68    e((unsafe { &*cond.cast::<RlctCond>() }).clockwait(
69        unsafe { &*mutex.cast::<RlctMutex>() },
70        unsafe { &*timeout },
71        clock_id,
72    ))
73}
74
75/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_cond_wait.html>.
76#[unsafe(no_mangle)]
77pub unsafe extern "C" fn pthread_cond_wait(
78    cond: *mut pthread_cond_t,
79    mutex: *mut pthread_mutex_t,
80) -> c_int {
81    e((unsafe { &*cond.cast::<RlctCond>() }).wait(unsafe { &*mutex.cast::<RlctMutex>() }))
82}
83
84/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_condattr_destroy.html>.
85#[unsafe(no_mangle)]
86pub unsafe extern "C" fn pthread_condattr_destroy(condattr: *mut pthread_condattr_t) -> c_int {
87    unsafe { core::ptr::drop_in_place(condattr.cast::<RlctCondAttr>()) };
88    // No-op
89    0
90}
91
92/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_condattr_getclock.html>.
93#[unsafe(no_mangle)]
94pub unsafe extern "C" fn pthread_condattr_getclock(
95    condattr: *const pthread_condattr_t,
96    clock: *mut clockid_t,
97) -> c_int {
98    unsafe { core::ptr::write(clock, (*condattr.cast::<RlctCondAttr>()).clock) };
99    0
100}
101
102/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_condattr_getpshared.html>.
103#[unsafe(no_mangle)]
104pub unsafe extern "C" fn pthread_condattr_getpshared(
105    condattr: *const pthread_condattr_t,
106    pshared: *mut c_int,
107) -> c_int {
108    unsafe { core::ptr::write(pshared, (*condattr.cast::<RlctCondAttr>()).pshared) };
109    0
110}
111
112/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_condattr_init.html>.
113#[unsafe(no_mangle)]
114pub unsafe extern "C" fn pthread_condattr_init(condattr: *mut pthread_condattr_t) -> c_int {
115    unsafe {
116        condattr
117            .cast::<RlctCondAttr>()
118            .write(RlctCondAttr::default())
119    };
120    0
121}
122
123/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_condattr_setclock.html>.
124#[unsafe(no_mangle)]
125pub unsafe extern "C" fn pthread_condattr_setclock(
126    condattr: *mut pthread_condattr_t,
127    clock: clockid_t,
128) -> c_int {
129    (unsafe { *condattr.cast::<RlctCondAttr>() }).clock = clock;
130    0
131}
132
133/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_condattr_setpshared.html>.
134#[unsafe(no_mangle)]
135pub unsafe extern "C" fn pthread_condattr_setpshared(
136    condattr: *mut pthread_condattr_t,
137    pshared: c_int,
138) -> c_int {
139    (unsafe { *condattr.cast::<RlctCondAttr>() }).pshared = pshared;
140    0
141}
142
143pub(crate) type RlctCondAttr = crate::sync::cond::CondAttr;
144
145pub(crate) type RlctCond = crate::sync::cond::Cond;