|
79 | 79 | //! [`kobj_define!`]: crate::kobj_define
|
80 | 80 | //! [`init_once`]: StaticKernelObject::init_once
|
81 | 81 |
|
| 82 | +#[cfg(CONFIG_RUST_ALLOC)] |
| 83 | +extern crate alloc; |
| 84 | + |
82 | 85 | use core::{cell::UnsafeCell, mem};
|
83 | 86 |
|
| 87 | +#[cfg(CONFIG_RUST_ALLOC)] |
| 88 | +use core::pin::Pin; |
| 89 | + |
| 90 | +#[cfg(CONFIG_RUST_ALLOC)] |
| 91 | +use alloc::boxed::Box; |
| 92 | + |
84 | 93 | use crate::sync::atomic::{AtomicUsize, Ordering};
|
85 | 94 |
|
86 | 95 | // The kernel object itself must be wrapped in `UnsafeCell` in Rust. This does several thing, but
|
@@ -189,6 +198,41 @@ where
|
189 | 198 | }
|
190 | 199 | }
|
191 | 200 |
|
| 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 | + |
192 | 236 | /// Declare a static kernel object. This helps declaring static values of Zephyr objects.
|
193 | 237 | ///
|
194 | 238 | /// This can typically be used as:
|
|
0 commit comments