Skip to content

Commit 8cdf4a6

Browse files
committed
zephyr: sys: sync: Add Mutex::new()
Add support for dynamically allocated sys::Mutexes Signed-off-by: David Brown <[email protected]>
1 parent ad0924d commit 8cdf4a6

File tree

1 file changed

+37
-12
lines changed

1 file changed

+37
-12
lines changed

zephyr/src/sys/sync/mutex.rs

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
//! [`object`]: crate::object
1010
1111
use core::fmt;
12+
use core::mem;
1213
use crate::{
1314
error::{Result, to_result_void},
1415
raw::{
@@ -25,6 +26,7 @@ use crate::{
2526
time::Timeout,
2627
};
2728
use crate::object::{
29+
Fixed,
2830
StaticKernelObject,
2931
Wrapped,
3032
};
@@ -54,10 +56,22 @@ use crate::sys::K_FOREVER;
5456
/// [`sync::Mutex`]: http://example.com/TODO
5557
pub struct Mutex {
5658
/// The raw Zephyr mutex.
57-
item: *mut k_mutex,
59+
item: Fixed<k_mutex>,
5860
}
5961

6062
impl Mutex {
63+
/// Create a new Mutex in an unlocked state.
64+
///
65+
/// Create a new dynamically allocated Mutex. The Mutex can only be used from system threads.
66+
#[cfg(CONFIG_RUST_ALLOC)]
67+
pub fn new() -> Result<Mutex> {
68+
let item: Fixed<k_mutex> = Fixed::new(unsafe { mem::zeroed() });
69+
unsafe {
70+
to_result_void(k_mutex_init(item.get()))?;
71+
}
72+
Ok(Mutex { item })
73+
}
74+
6175
/// Lock a Zephyr Mutex.
6276
///
6377
/// Will wait for the lock, returning status, with `Ok(())` indicating the lock has been
@@ -67,15 +81,15 @@ impl Mutex {
6781
where T: Into<Timeout>,
6882
{
6983
let timeout: Timeout = timeout.into();
70-
to_result_void(unsafe { k_mutex_lock(self.item, timeout.0) })
84+
to_result_void(unsafe { k_mutex_lock(self.item.get(), timeout.0) })
7185
}
7286

7387
/// Unlock a Zephyr Mutex.
7488
///
7589
/// The mutex must already be locked by the calling thread. Mutexes may not be unlocked in
7690
/// ISRs.
7791
pub fn unlock(&self) -> Result<()> {
78-
to_result_void(unsafe { k_mutex_unlock(self.item) })
92+
to_result_void(unsafe { k_mutex_unlock(self.item.get()) })
7993
}
8094
}
8195

@@ -109,24 +123,23 @@ impl Wrapped for StaticKernelObject<k_mutex> {
109123
k_mutex_init(ptr);
110124
}
111125
Mutex {
112-
item: ptr,
126+
item: Fixed::Static(ptr),
113127
}
114128
}
115129
}
116130

117131
impl fmt::Debug for Mutex {
118132
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
119-
write!(f, "sys::Mutex {:?}", self.item)
133+
write!(f, "sys::Mutex {:?}", self.item.get())
120134
}
121135
}
122136

123137
/// A Condition Variable
124138
///
125139
/// Lightweight wrappers for Zephyr's `k_condvar`.
126-
#[derive(Clone)]
127140
pub struct Condvar {
128141
/// The underlying `k_condvar`.
129-
item: *mut k_condvar,
142+
item: Fixed<k_condvar>,
130143
}
131144

132145
#[doc(hidden)]
@@ -138,6 +151,18 @@ unsafe impl Sync for Condvar {}
138151
unsafe impl Send for Condvar {}
139152

140153
impl Condvar {
154+
/// Create a new Condvar.
155+
///
156+
/// Create a new dynamically allocated Condvar. The Condvar can only be used from system threads.
157+
#[cfg(CONFIG_RUST_ALLOC)]
158+
pub fn new() -> Result<Condvar> {
159+
let item: Fixed<k_condvar> = Fixed::new(unsafe { mem::zeroed() });
160+
unsafe {
161+
to_result_void(k_condvar_init(item.get()))?;
162+
}
163+
Ok(Condvar { item })
164+
}
165+
141166
/// Wait for someone else using this mutex/condvar pair to notify.
142167
///
143168
/// Note that this requires the lock to be held by use, but as this is a low-level binding to
@@ -147,25 +172,25 @@ impl Condvar {
147172
/// [`sync::Condvar`]: http://www.example.com/TODO
148173
// /// [`sync::Condvar`]: crate::sync::Condvar
149174
pub fn wait(&self, lock: &Mutex) {
150-
unsafe { k_condvar_wait(self.item, lock.item, K_FOREVER); }
175+
unsafe { k_condvar_wait(self.item.get(), lock.item.get(), K_FOREVER); }
151176
}
152177

153178
// TODO: timeout.
154179

155180
/// Wake a single thread waiting on this condition variable.
156181
pub fn notify_one(&self) {
157-
unsafe { k_condvar_signal(self.item); }
182+
unsafe { k_condvar_signal(self.item.get()); }
158183
}
159184

160185
/// Wake all threads waiting on this condition variable.
161186
pub fn notify_all(&self) {
162-
unsafe { k_condvar_broadcast(self.item); }
187+
unsafe { k_condvar_broadcast(self.item.get()); }
163188
}
164189
}
165190

166191
impl fmt::Debug for Condvar {
167192
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
168-
write!(f, "sys::Condvar {:?}", self.item)
193+
write!(f, "sys::Condvar {:?}", self.item.get())
169194
}
170195
}
171196

@@ -181,7 +206,7 @@ impl Wrapped for StaticCondvar {
181206
k_condvar_init(ptr);
182207
}
183208
Condvar {
184-
item: ptr,
209+
item: Fixed::Static(ptr),
185210
}
186211
}
187212
}

0 commit comments

Comments
 (0)