forked from ROMEO/obsw
mutex refinements
This commit is contained in:
parent
6beb438508
commit
7ba3f23add
@ -52,9 +52,9 @@ impl<T: Clone + Default> OwnedDataset<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_default(default_values: T) -> OwnedDataset<T> {
|
||||
pub fn new_init_values(init_values: T) -> OwnedDataset<T> {
|
||||
OwnedDataset::<T> {
|
||||
actual_data: default_values,
|
||||
actual_data: init_values,
|
||||
mutex: mutex::RawMutex::new(),
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,13 @@
|
||||
use crate::check_global_threading_available;
|
||||
|
||||
use super::osal;
|
||||
|
||||
// for now, this is an implementation based on FreeRTOS, where we can preallocate mutexes
|
||||
// this allows us to assume that mutexes are valid starting from their creation until end of runtime
|
||||
// and so we do not use the global_threading lock
|
||||
// TODO we do not discern between a mutex (holding the descriptor) and a clone (pointing to the
|
||||
// original descriptor), waisting some memory
|
||||
|
||||
pub struct RawMutex {
|
||||
handle: *const core::ffi::c_void
|
||||
handle: Option<*const core::ffi::c_void>,
|
||||
descriptor: [u8; 10], //TODO which size?
|
||||
}
|
||||
|
||||
pub struct RawMutexGuard {
|
||||
@ -14,26 +16,59 @@ pub struct RawMutexGuard {
|
||||
|
||||
impl Drop for RawMutexGuard {
|
||||
fn drop(&mut self) {
|
||||
//TODO do we need some check here?
|
||||
unsafe{osal::give_mutex(self.handle)};
|
||||
check_global_threading_available!(); // tell me when you reach this one!
|
||||
// We use nullptr as marker for an uninitialized mutex, which we
|
||||
// must not give
|
||||
if self.handle != 0 as *const core::ffi::c_void {
|
||||
unsafe { osal::give_mutex(self.handle) };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RawMutex {
|
||||
pub fn new() -> Self {
|
||||
let handle = unsafe {osal::create_mutex()};
|
||||
if handle == 0 as *const core::ffi::c_void {
|
||||
panic!("Could not create mutex")
|
||||
}
|
||||
Self {
|
||||
handle: handle
|
||||
handle: None,
|
||||
descriptor: [0; 10],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn take(&self) -> Result<RawMutexGuard,()> {
|
||||
match unsafe {osal::take_mutex(self.handle)} {
|
||||
1 => Ok(RawMutexGuard { handle: self.handle }),
|
||||
_ => Err(()) //TODO error code
|
||||
fn initialize(&mut self) {
|
||||
// check_global_threading_available!(); we have a token, so this is redundant
|
||||
if self.handle != None {
|
||||
return;
|
||||
}
|
||||
// TODO verify handle size
|
||||
let handle = unsafe { osal::create_mutex() };
|
||||
if handle == 0 as *const core::ffi::c_void {
|
||||
panic!("Could not create mutex")
|
||||
}
|
||||
self.handle = Some(handle);
|
||||
}
|
||||
|
||||
pub fn take(&self) -> Result<RawMutexGuard, ()> {
|
||||
check_global_threading_available!();
|
||||
if let Some(handle) = self.handle {
|
||||
return match unsafe { osal::take_mutex(handle) } {
|
||||
1 => Ok(RawMutexGuard { handle: handle }),
|
||||
_ => Err(()), // Only when timeout expired (we have none) TODO error code
|
||||
};
|
||||
} else {
|
||||
// nullptr makes the guard do nothing
|
||||
Ok(RawMutexGuard {
|
||||
handle: 0 as *const core::ffi::c_void,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TODO protect with token
|
||||
pub fn clone(&self) -> Self {
|
||||
let mut_self = self as *const Self as *mut Self; //oh look, a C developer wrote this
|
||||
unsafe { (*mut_self).initialize() }; //TODO this might be safe (we are in init), but does not look very good
|
||||
// At this point self.handle must be valid, initialize would have panicked otherwise
|
||||
Self {
|
||||
handle: self.handle,
|
||||
descriptor: [0; 10],
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,11 +86,3 @@ impl RawMutex {
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
impl Clone for RawMutex {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
handle: self.handle
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user