Skip to content

Commit d8dc4fe

Browse files
committed
zephyr: sys: sync: sempahore: Add dynamic support
Add support for dynamically allocated Semaphores. These can be freely allocated, but are not usable from userspace.
1 parent d513613 commit d8dc4fe

File tree

1 file changed

+24
-14
lines changed

1 file changed

+24
-14
lines changed

zephyr/src/sys/sync/semaphore.rs

+24-14
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,13 @@
1313
1414
use core::ffi::c_uint;
1515
use core::fmt;
16+
use core::mem;
1617

1718
use crate::{
18-
error::{Result, to_result_void},
19-
object::{StaticKernelObject, Wrapped},
19+
error::{to_result_void, Result},
20+
object::{Fixed, StaticKernelObject, Wrapped},
2021
raw::{
21-
k_sem,
22-
k_sem_init,
23-
k_sem_take,
24-
k_sem_give,
25-
k_sem_reset,
26-
k_sem_count_get,
22+
k_sem, k_sem_count_get, k_sem_give, k_sem_init, k_sem_reset, k_sem_take
2723
},
2824
time::Timeout,
2925
};
@@ -33,7 +29,7 @@ pub use crate::raw::K_SEM_MAX_LIMIT;
3329
/// A zephyr `k_sem` usable from safe Rust code.
3430
pub struct Semaphore {
3531
/// The raw Zephyr `k_sem`.
36-
item: *mut k_sem,
32+
item: Fixed<k_sem>,
3733
}
3834

3935
/// By nature, Semaphores are both Sync and Send. Safety is handled by the underlying Zephyr
@@ -42,6 +38,20 @@ unsafe impl Sync for Semaphore {}
4238
unsafe impl Send for Semaphore {}
4339

4440
impl Semaphore {
41+
/// Create a new semaphore.
42+
///
43+
/// Create a new dynamically allocated Semaphore. This semaphore can only be used from system
44+
/// threads. The arguments are as described in [the
45+
/// docs](https://docs.zephyrproject.org/latest/kernel/services/synchronization/semaphores.html).
46+
#[cfg(CONFIG_RUST_ALLOC)]
47+
pub fn new(initial_count: c_uint, limit: c_uint) -> Result<Semaphore> {
48+
let item: Fixed<k_sem> = Fixed::new(unsafe { mem::zeroed() });
49+
unsafe {
50+
to_result_void(k_sem_init(item.get(), initial_count, limit))?;
51+
}
52+
Ok(Semaphore { item })
53+
}
54+
4555
/// Take a semaphore.
4656
///
4757
/// Can be called from ISR if called with [`NoWait`].
@@ -52,7 +62,7 @@ impl Semaphore {
5262
{
5363
let timeout: Timeout = timeout.into();
5464
let ret = unsafe {
55-
k_sem_take(self.item, timeout.0)
65+
k_sem_take(self.item.get(), timeout.0)
5666
};
5767
to_result_void(ret)
5868
}
@@ -63,7 +73,7 @@ impl Semaphore {
6373
/// permitted count.
6474
pub fn give(&self) {
6575
unsafe {
66-
k_sem_give(self.item)
76+
k_sem_give(self.item.get())
6777
}
6878
}
6979

@@ -75,7 +85,7 @@ impl Semaphore {
7585
/// [`take`]: Self::take
7686
pub fn reset(&mut self) {
7787
unsafe {
78-
k_sem_reset(self.item)
88+
k_sem_reset(self.item.get())
7989
}
8090
}
8191

@@ -84,7 +94,7 @@ impl Semaphore {
8494
/// Returns the current count.
8595
pub fn count_get(&mut self) -> usize {
8696
unsafe {
87-
k_sem_count_get(self.item) as usize
97+
k_sem_count_get(self.item.get()) as usize
8898
}
8999
}
90100
}
@@ -114,7 +124,7 @@ impl Wrapped for StaticKernelObject<k_sem> {
114124
k_sem_init(ptr, arg.0, arg.1);
115125
}
116126
Semaphore {
117-
item: ptr,
127+
item: Fixed::Static(ptr),
118128
}
119129
}
120130
}

0 commit comments

Comments
 (0)