arceos_posix_api/imp/pthread/
mutex.rs

1use crate::{ctypes, utils::check_null_mut_ptr};
2
3use axerrno::LinuxResult;
4use axsync::Mutex;
5
6use core::ffi::c_int;
7use core::mem::{ManuallyDrop, size_of};
8
9static_assertions::const_assert_eq!(
10    size_of::<ctypes::pthread_mutex_t>(),
11    size_of::<PthreadMutex>()
12);
13
14#[repr(C)]
15pub struct PthreadMutex(Mutex<()>);
16
17impl PthreadMutex {
18    const fn new() -> Self {
19        Self(Mutex::new(()))
20    }
21
22    fn lock(&self) -> LinuxResult {
23        let _guard = ManuallyDrop::new(self.0.lock());
24        Ok(())
25    }
26
27    fn unlock(&self) -> LinuxResult {
28        unsafe { self.0.force_unlock() };
29        Ok(())
30    }
31}
32
33/// Initialize a mutex.
34pub fn sys_pthread_mutex_init(
35    mutex: *mut ctypes::pthread_mutex_t,
36    _attr: *const ctypes::pthread_mutexattr_t,
37) -> c_int {
38    debug!("sys_pthread_mutex_init <= {:#x}", mutex as usize);
39    syscall_body!(sys_pthread_mutex_init, {
40        check_null_mut_ptr(mutex)?;
41        unsafe {
42            mutex.cast::<PthreadMutex>().write(PthreadMutex::new());
43        }
44        Ok(0)
45    })
46}
47
48/// Lock the given mutex.
49pub fn sys_pthread_mutex_lock(mutex: *mut ctypes::pthread_mutex_t) -> c_int {
50    debug!("sys_pthread_mutex_lock <= {:#x}", mutex as usize);
51    syscall_body!(sys_pthread_mutex_lock, {
52        check_null_mut_ptr(mutex)?;
53        unsafe {
54            (*mutex.cast::<PthreadMutex>()).lock()?;
55        }
56        Ok(0)
57    })
58}
59
60/// Unlock the given mutex.
61pub fn sys_pthread_mutex_unlock(mutex: *mut ctypes::pthread_mutex_t) -> c_int {
62    debug!("sys_pthread_mutex_unlock <= {:#x}", mutex as usize);
63    syscall_body!(sys_pthread_mutex_unlock, {
64        check_null_mut_ptr(mutex)?;
65        unsafe {
66            (*mutex.cast::<PthreadMutex>()).unlock()?;
67        }
68        Ok(0)
69    })
70}