Skip to content

Commit 34a0fab

Browse files
committed
zephyr: sys: Add sys::Condvar
`sys::Condvar` is a thin wrapper around Zephyr's `k_condvar`, and provides support for static declaration of the kernel objects. Signed-off-by: David Brown <[email protected]>
1 parent c6db0c9 commit 34a0fab

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

zephyr/src/object.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,20 @@ macro_rules! _kobj_rule {
180180
unsafe { ::core::mem::zeroed() };
181181
};
182182

183+
($v:vis, $name:ident, StaticCondvar) => {
184+
#[link_section = concat!("._k_condvar.static.", stringify!($name), ".", file!(), line!())]
185+
$v static $name: $crate::sys::sync::StaticCondvar =
186+
$crate::sys::sync::StaticCondvar::new();
187+
};
188+
($v:vis, $name:ident, [StaticCondvar; $size:expr]) => {
189+
#[link_section = concat!("._k_condvar.static.", stringify!($name), ".", file!(), line!())]
190+
$v static $name: [$crate::sys::sync::StaticCondvar; $size] =
191+
// This isn't Copy, intentionally, so initialize the whole thing with zerored memory.
192+
// Relying on the atomic to be 0 for the uninitialized state.
193+
// [$crate::sys::sync::StaticMutex::new(); $size];
194+
unsafe { ::core::mem::zeroed() };
195+
};
196+
183197
($v:vis, $name:ident, StaticThread) => {
184198
// Since the static object has an atomic that we assume is initialized, let the compiler put
185199
// this in the data section it finds appropriate (probably .bss if it is initialized to zero).

zephyr/src/sys/sync.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ use core::fmt;
3434

3535
use crate::error::{Result, to_result_void};
3636
use crate::raw::{
37+
k_condvar,
38+
k_condvar_init,
39+
k_condvar_broadcast,
40+
k_condvar_signal,
41+
k_condvar_wait,
3742
k_mutex,
3843
k_mutex_init,
3944
k_mutex_lock,
@@ -46,6 +51,7 @@ use crate::object::{
4651
use crate::time::{
4752
Timeout,
4853
};
54+
use super::K_FOREVER;
4955

5056
/// A Zephyr `k_mutux` usable from safe Rust code.
5157
///
@@ -122,3 +128,59 @@ impl StaticMutex {
122128
})
123129
}
124130
}
131+
132+
/// A Condition Variable
133+
///
134+
/// Lightweight wrappers for Zephyr's `k_condvar`.
135+
#[derive(Clone)]
136+
pub struct Condvar {
137+
pub item: *mut k_condvar,
138+
}
139+
140+
unsafe impl Sync for StaticKernelObject<k_condvar> { }
141+
142+
unsafe impl Sync for Condvar {}
143+
unsafe impl Send for Condvar {}
144+
145+
impl KobjInit<k_condvar, Condvar> for StaticKernelObject<k_condvar> {
146+
fn wrap(ptr: *mut k_condvar) -> Condvar {
147+
Condvar { item: ptr }
148+
}
149+
}
150+
151+
pub type StaticCondvar = StaticKernelObject<k_condvar>;
152+
153+
impl StaticCondvar {
154+
pub fn init(&self) {
155+
self.init_help(|raw| {
156+
unsafe {
157+
k_condvar_init(raw);
158+
}
159+
})
160+
}
161+
}
162+
163+
impl Condvar {
164+
/// Wait for someone else using this mutex/condvar pair to notify. Note that this requires the
165+
/// lock to be held by use, but as this is a low-level binding to Zephyr's interfaces, this is
166+
/// not enforced. See [`sync::Condvar`] for a safer and easier to use interface.
167+
pub fn wait(&self, lock: &Mutex) {
168+
unsafe { k_condvar_wait(self.item, lock.item, K_FOREVER); }
169+
}
170+
171+
// TODO: timeout.
172+
173+
pub fn notify_one(&self) {
174+
unsafe { k_condvar_signal(self.item); }
175+
}
176+
177+
pub fn notify_all(&self) {
178+
unsafe { k_condvar_broadcast(self.item); }
179+
}
180+
}
181+
182+
impl fmt::Debug for Condvar {
183+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
184+
write!(f, "sys::Condvar {:?}", self.item)
185+
}
186+
}

0 commit comments

Comments
 (0)