relibc/header/pthread/
rwlock.rs1use super::*;
2
3use crate::header::errno::{EBUSY, EINVAL};
4
5use crate::{header::time::CLOCK_REALTIME, pthread::Pshared};
6
7#[unsafe(no_mangle)]
9pub unsafe extern "C" fn pthread_rwlock_init(
10 rwlock: *mut pthread_rwlock_t,
11 attr: *const pthread_rwlockattr_t,
12) -> c_int {
13 let attr = unsafe { attr.cast::<RlctRwlockAttr>().as_ref() }
14 .copied()
15 .unwrap_or_default();
16
17 unsafe {
18 rwlock
19 .cast::<RlctRwlock>()
20 .write(RlctRwlock::new(attr.pshared))
21 };
22
23 0
24}
25#[unsafe(no_mangle)]
27pub unsafe extern "C" fn pthread_rwlock_rdlock(rwlock: *mut pthread_rwlock_t) -> c_int {
28 match unsafe { get(rwlock) }.acquire_read_lock(None) {
29 Ok(()) => 0,
30 Err(e) => e.0,
31 }
32}
33#[unsafe(no_mangle)]
35pub unsafe extern "C" fn pthread_rwlock_clockrdlock(
36 rwlock: *mut pthread_rwlock_t,
37 clock_id: clockid_t,
38 abstime: *const timespec,
39) -> c_int {
40 match unsafe { get(rwlock) }.acquire_read_lock(Some((unsafe { &*abstime }, clock_id))) {
41 Ok(()) => 0,
42 Err(e) => e.0,
43 }
44}
45#[unsafe(no_mangle)]
47pub unsafe extern "C" fn pthread_rwlock_timedrdlock(
48 rwlock: *mut pthread_rwlock_t,
49 abstime: *const timespec,
50) -> c_int {
51 match unsafe { get(rwlock) }.acquire_read_lock(Some((unsafe { &*abstime }, CLOCK_REALTIME))) {
52 Ok(()) => 0,
53 Err(e) => e.0,
54 }
55}
56#[unsafe(no_mangle)]
58pub unsafe extern "C" fn pthread_rwlock_clockwrlock(
59 rwlock: *mut pthread_rwlock_t,
60 clock_id: clockid_t,
61 abstime: *const timespec,
62) -> c_int {
63 match unsafe { get(rwlock) }.acquire_write_lock(Some((unsafe { &*abstime }, clock_id))) {
64 Ok(()) => 0,
65 Err(e) => e.0,
66 }
67}
68#[unsafe(no_mangle)]
70pub unsafe extern "C" fn pthread_rwlock_timedwrlock(
71 rwlock: *mut pthread_rwlock_t,
72 abstime: *const timespec,
73) -> c_int {
74 match unsafe { get(rwlock) }.acquire_write_lock(Some((unsafe { &*abstime }, CLOCK_REALTIME))) {
75 Ok(()) => 0,
76 Err(e) => e.0,
77 }
78}
79#[unsafe(no_mangle)]
81pub unsafe extern "C" fn pthread_rwlock_tryrdlock(rwlock: *mut pthread_rwlock_t) -> c_int {
82 match unsafe { get(rwlock) }.try_acquire_read_lock() {
83 Ok(()) => 0,
84 Err(_) => EBUSY,
85 }
86}
87#[unsafe(no_mangle)]
89pub unsafe extern "C" fn pthread_rwlock_trywrlock(rwlock: *mut pthread_rwlock_t) -> c_int {
90 match unsafe { get(rwlock) }.try_acquire_write_lock() {
91 Ok(()) => 0,
92 Err(_) => EBUSY,
93 }
94}
95#[unsafe(no_mangle)]
97pub unsafe extern "C" fn pthread_rwlock_unlock(rwlock: *mut pthread_rwlock_t) -> c_int {
98 unsafe { get(rwlock) }.unlock();
99
100 0
101}
102#[unsafe(no_mangle)]
104pub unsafe extern "C" fn pthread_rwlock_wrlock(rwlock: *mut pthread_rwlock_t) -> c_int {
105 match unsafe { get(rwlock) }.acquire_write_lock(None) {
106 Ok(()) => 0,
107 Err(e) => e.0,
108 }
109}
110
111#[unsafe(no_mangle)]
113pub unsafe extern "C" fn pthread_rwlockattr_init(attr: *mut pthread_rwlockattr_t) -> c_int {
114 unsafe {
115 attr.cast::<RlctRwlockAttr>()
116 .write(RlctRwlockAttr::default())
117 };
118
119 0
120}
121
122#[unsafe(no_mangle)]
124pub unsafe extern "C" fn pthread_rwlockattr_getpshared(
125 attr: *const pthread_rwlockattr_t,
126 pshared_out: *mut c_int,
127) -> c_int {
128 unsafe { core::ptr::write(pshared_out, (*attr.cast::<RlctRwlockAttr>()).pshared.raw()) };
129
130 0
131}
132
133#[unsafe(no_mangle)]
135pub unsafe extern "C" fn pthread_rwlockattr_setpshared(
136 attr: *mut pthread_rwlockattr_t,
137 pshared: c_int,
138) -> c_int {
139 let Some(pshared) = Pshared::from_raw(pshared) else {
140 return EINVAL;
141 };
142
143 (unsafe { *attr.cast::<RlctRwlockAttr>() }).pshared = pshared;
144 0
145}
146
147#[unsafe(no_mangle)]
149pub unsafe extern "C" fn pthread_rwlockattr_destroy(attr: *mut pthread_rwlockattr_t) -> c_int {
150 unsafe { core::ptr::drop_in_place(attr) };
151
152 0
153}
154#[unsafe(no_mangle)]
156pub unsafe extern "C" fn pthread_rwlock_destroy(rwlock: *mut pthread_rwlock_t) -> c_int {
157 unsafe { core::ptr::drop_in_place(rwlock) };
158
159 0
160}
161
162pub(crate) type RlctRwlock = crate::sync::rwlock::InnerRwLock;
163
164#[derive(Clone, Copy, Default)]
165pub(crate) struct RlctRwlockAttr {
166 pshared: Pshared,
167}
168#[inline]
169unsafe fn get<'a>(ptr: *mut pthread_rwlock_t) -> &'a RlctRwlock {
170 unsafe { &*ptr.cast() }
171}