Skip to main content

relibc/header/pthread/
mutex.rs

1// FIXME(andypython): remove this when #![allow(warnings, unused_variables)] is
2// dropped from src/lib.rs.
3#![warn(warnings, unused_variables)]
4
5use super::*;
6pub use crate::sync::pthread_mutex::RlctMutex;
7use crate::{error::Errno, header::time::timespec_realtime_to_monotonic};
8
9// PTHREAD_MUTEX_INITIALIZER is defined in bits_pthread/cbindgen.toml
10
11/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_mutex_consistent.html>.
12#[unsafe(no_mangle)]
13pub unsafe extern "C" fn pthread_mutex_consistent(mutex: *mut pthread_mutex_t) -> c_int {
14    e((unsafe { &*mutex.cast::<RlctMutex>() }).make_consistent())
15}
16/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_mutex_destroy.html>.
17#[unsafe(no_mangle)]
18pub unsafe extern "C" fn pthread_mutex_destroy(mutex: *mut pthread_mutex_t) -> c_int {
19    // No-op
20    unsafe { core::ptr::drop_in_place(mutex.cast::<RlctMutex>()) };
21    0
22}
23
24/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_mutex_getprioceiling.html>.
25#[unsafe(no_mangle)]
26pub unsafe extern "C" fn pthread_mutex_getprioceiling(
27    mutex: *const pthread_mutex_t,
28    prioceiling: *mut c_int,
29) -> c_int {
30    match (unsafe { &*mutex.cast::<RlctMutex>() }).prioceiling() {
31        Ok(value) => {
32            unsafe { prioceiling.write(value) };
33            0
34        }
35        Err(Errno(errno)) => errno,
36    }
37}
38
39/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_mutex_init.html>.
40#[unsafe(no_mangle)]
41pub unsafe extern "C" fn pthread_mutex_init(
42    mutex: *mut pthread_mutex_t,
43    attr: *const pthread_mutexattr_t,
44) -> c_int {
45    let attr = unsafe { attr.cast::<RlctMutexAttr>().as_ref() }
46        .cloned()
47        .unwrap_or_default();
48
49    match RlctMutex::new(&attr) {
50        Ok(new) => {
51            unsafe { mutex.cast::<RlctMutex>().write(new) };
52
53            0
54        }
55        Err(Errno(errno)) => errno,
56    }
57}
58/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_mutex_lock.html>.
59#[unsafe(no_mangle)]
60pub unsafe extern "C" fn pthread_mutex_lock(mutex: *mut pthread_mutex_t) -> c_int {
61    e((unsafe { &*mutex.cast::<RlctMutex>() }).lock())
62}
63
64/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_mutex_setprioceiling.html>.
65#[unsafe(no_mangle)]
66pub unsafe extern "C" fn pthread_mutex_setprioceiling(
67    mutex: *mut pthread_mutex_t,
68    prioceiling: c_int,
69    old_prioceiling: *mut c_int,
70) -> c_int {
71    match (unsafe { &*mutex.cast::<RlctMutex>() }).replace_prioceiling(prioceiling) {
72        Ok(old) => {
73            unsafe { old_prioceiling.write(old) };
74            0
75        }
76        Err(Errno(errno)) => errno,
77    }
78}
79
80/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_mutex_timedlock.html>.
81#[unsafe(no_mangle)]
82pub unsafe extern "C" fn pthread_mutex_timedlock(
83    mutex: *mut pthread_mutex_t,
84    abstime: &timespec,
85) -> c_int {
86    let relative = match timespec_realtime_to_monotonic(abstime) {
87        Ok(relative) => relative,
88        Err(err) => return e(Err(err)),
89    };
90
91    e((unsafe { &*mutex.cast::<RlctMutex>() }).lock_with_timeout(&relative))
92}
93
94/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_mutex_trylock.html>.
95#[unsafe(no_mangle)]
96pub unsafe extern "C" fn pthread_mutex_trylock(mutex: *mut pthread_mutex_t) -> c_int {
97    e((unsafe { &*mutex.cast::<RlctMutex>() }).try_lock())
98}
99/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_mutex_unlock.html>.
100#[unsafe(no_mangle)]
101pub unsafe extern "C" fn pthread_mutex_unlock(mutex: *mut pthread_mutex_t) -> c_int {
102    e((unsafe { &*mutex.cast::<RlctMutex>() }).unlock())
103}
104
105/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_mutexattr_destroy.html>.
106#[unsafe(no_mangle)]
107pub unsafe extern "C" fn pthread_mutexattr_destroy(attr: *mut pthread_mutexattr_t) -> c_int {
108    // No-op
109    unsafe { core::ptr::drop_in_place(attr.cast::<RlctMutexAttr>()) };
110    0
111}
112
113/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_mutexattr_getprioceiling.html>.
114#[unsafe(no_mangle)]
115pub unsafe extern "C" fn pthread_mutexattr_getprioceiling(
116    attr: *const pthread_mutexattr_t,
117    prioceiling: &mut c_int,
118) -> c_int {
119    *prioceiling = unsafe { &*attr.cast::<RlctMutexAttr>() }.prioceiling;
120    0
121}
122
123/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_mutexattr_getprotocol.html>.
124#[unsafe(no_mangle)]
125pub unsafe extern "C" fn pthread_mutexattr_getprotocol(
126    attr: *const pthread_mutexattr_t,
127    protocol: &mut c_int,
128) -> c_int {
129    *protocol = unsafe { &*attr.cast::<RlctMutexAttr>() }.protocol;
130    0
131}
132
133/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_mutexattr_getpshared.html>.
134#[unsafe(no_mangle)]
135pub unsafe extern "C" fn pthread_mutexattr_getpshared(
136    attr: *const pthread_mutexattr_t,
137    pshared: &mut c_int,
138) -> c_int {
139    *pshared = unsafe { &*attr.cast::<RlctMutexAttr>() }.pshared;
140    0
141}
142
143/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_mutexattr_getrobust.html>.
144#[unsafe(no_mangle)]
145pub unsafe extern "C" fn pthread_mutexattr_getrobust(
146    attr: *const pthread_mutexattr_t,
147    robust: &mut c_int,
148) -> c_int {
149    *robust = unsafe { &*attr.cast::<RlctMutexAttr>() }.robust;
150    0
151}
152/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_mutexattr_gettype.html>.
153#[unsafe(no_mangle)]
154pub unsafe extern "C" fn pthread_mutexattr_gettype(
155    attr: *const pthread_mutexattr_t,
156    ty: &mut c_int,
157) -> c_int {
158    *ty = unsafe { &*attr.cast::<RlctMutexAttr>() }.ty;
159    0
160}
161/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_mutexattr_init.html>.
162#[unsafe(no_mangle)]
163pub unsafe extern "C" fn pthread_mutexattr_init(attr: *mut pthread_mutexattr_t) -> c_int {
164    unsafe { attr.cast::<RlctMutexAttr>().write(RlctMutexAttr::default()) };
165    0
166}
167
168/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_mutexattr_setprioceiling.html>.
169#[unsafe(no_mangle)]
170pub unsafe extern "C" fn pthread_mutexattr_setprioceiling(
171    attr: *mut pthread_mutexattr_t,
172    prioceiling: c_int,
173) -> c_int {
174    unsafe { &mut *attr.cast::<RlctMutexAttr>() }.prioceiling = prioceiling;
175    0
176}
177
178/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_mutexattr_setprotocol.html>.
179#[unsafe(no_mangle)]
180pub unsafe extern "C" fn pthread_mutexattr_setprotocol(
181    attr: *mut pthread_mutexattr_t,
182    protocol: c_int,
183) -> c_int {
184    unsafe { &mut *attr.cast::<RlctMutexAttr>() }.protocol = protocol;
185    0
186}
187
188/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_mutexattr_setpshared.html>.
189#[unsafe(no_mangle)]
190pub unsafe extern "C" fn pthread_mutexattr_setpshared(
191    attr: *mut pthread_mutexattr_t,
192    pshared: c_int,
193) -> c_int {
194    unsafe { &mut *attr.cast::<RlctMutexAttr>() }.pshared = pshared;
195    0
196}
197
198/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_mutexattr_setrobust.html>.
199#[unsafe(no_mangle)]
200pub unsafe extern "C" fn pthread_mutexattr_setrobust(
201    attr: *mut pthread_mutexattr_t,
202    robust: c_int,
203) -> c_int {
204    unsafe { &mut *attr.cast::<RlctMutexAttr>() }.robust = robust;
205    0
206}
207/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_mutexattr_settype.html>.
208#[unsafe(no_mangle)]
209pub unsafe extern "C" fn pthread_mutexattr_settype(
210    attr: *mut pthread_mutexattr_t,
211    ty: c_int,
212) -> c_int {
213    unsafe { &mut *attr.cast::<RlctMutexAttr>() }.ty = ty;
214    0
215}
216
217#[repr(C)]
218#[derive(Clone)]
219pub(crate) struct RlctMutexAttr {
220    pub prioceiling: c_int,
221    pub protocol: c_int,
222    pub pshared: c_int,
223    pub robust: c_int,
224    pub ty: c_int,
225}
226
227impl Default for RlctMutexAttr {
228    fn default() -> Self {
229        Self {
230            robust: PTHREAD_MUTEX_STALLED,
231            pshared: PTHREAD_PROCESS_PRIVATE,
232            protocol: PTHREAD_PRIO_NONE,
233            // TODO
234            prioceiling: 0,
235            ty: PTHREAD_MUTEX_DEFAULT,
236        }
237    }
238}