Skip to content

Commit d513613

Browse files
committed
zephry: object: Create Fixed concept
The `Fixed` type encapsulates something that can either be a statically allocated object or a dynamically allocated one. It is conditional on `CONFIG_RUST_ALLOC`, and if that is not defined, will just end up represented as the underlying static pointer.
1 parent 43c0c8a commit d513613

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

zephyr/src/object.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,17 @@
7979
//! [`kobj_define!`]: crate::kobj_define
8080
//! [`init_once`]: StaticKernelObject::init_once
8181
82+
#[cfg(CONFIG_RUST_ALLOC)]
83+
extern crate alloc;
84+
8285
use core::{cell::UnsafeCell, mem};
8386

87+
#[cfg(CONFIG_RUST_ALLOC)]
88+
use core::pin::Pin;
89+
90+
#[cfg(CONFIG_RUST_ALLOC)]
91+
use alloc::boxed::Box;
92+
8493
use crate::sync::atomic::{AtomicUsize, Ordering};
8594

8695
// The kernel object itself must be wrapped in `UnsafeCell` in Rust. This does several thing, but
@@ -189,6 +198,41 @@ where
189198
}
190199
}
191200

201+
/// Objects that can be fixed or allocated.
202+
///
203+
/// When using Rust threads from userspace, the `kobj_define` declarations and the complexity behind
204+
/// it is required. If all Rust use of kernel objects is from system threads, and dynamic memory is
205+
/// available, kernel objects can be freeallocated, as long as the allocations themselves are
206+
/// pinned. This `Fixed` encapsulates both of these.
207+
pub enum Fixed<T> {
208+
/// Objects that have been statically declared and just pointed to.
209+
Static(*mut T),
210+
/// Objects that are owned by the wrapper, and contained here.
211+
#[cfg(CONFIG_RUST_ALLOC)]
212+
Owned(Pin<Box<UnsafeCell<T>>>),
213+
}
214+
215+
impl<T> Fixed<T> {
216+
/// Get the raw pointer out of the fixed object.
217+
///
218+
/// Returns the `*mut T` pointer held by this object. It is either just the static pointer, or
219+
/// the pointer outside of the unsafe cell holding the dynamic kernel object.
220+
pub fn get(&self) -> *mut T {
221+
match self {
222+
Fixed::Static(ptr) => *ptr,
223+
#[cfg(CONFIG_RUST_ALLOC)]
224+
Fixed::Owned(item) => item.get(),
225+
}
226+
}
227+
228+
/// Construct a new fixed from an allocation. Note that the object will not be fixed in memory,
229+
/// until _after_ this returns, and it should not be initialized until then.
230+
#[cfg(CONFIG_RUST_ALLOC)]
231+
pub fn new(item: T) -> Fixed<T> {
232+
Fixed::Owned(Box::pin(UnsafeCell::new(item)))
233+
}
234+
}
235+
192236
/// Declare a static kernel object. This helps declaring static values of Zephyr objects.
193237
///
194238
/// This can typically be used as:

0 commit comments

Comments
 (0)