Skip to main content

task/manager/
mod.rs

1// - Dependencies
2use super::*;
3
4// - Submodules
5mod lifecycle;
6mod metadata;
7mod properties;
8mod registration;
9mod relationships;
10mod signals;
11mod spawner;
12mod utilities;
13
14#[cfg(test)]
15mod tests;
16
17// - Re-exports
18
19pub(crate) use metadata::*;
20pub use spawner::*;
21
22// Manager module - core Manager structure and initialization
23
24use crate::manager::Metadata;
25
26#[cfg(any(test, feature = "test_harness"))]
27use alloc::boxed::Box;
28use alloc::collections::BTreeMap;
29use synchronization::{blocking_mutex::raw::CriticalSectionRawMutex, rwlock::RwLock};
30
31pub(crate) struct Inner {
32    pub(crate) tasks: BTreeMap<TaskIdentifier, Metadata>,
33    pub(crate) identifiers: BTreeMap<usize, TaskIdentifier>,
34    pub(crate) spawners: BTreeMap<usize, ::embassy_executor::Spawner>,
35}
36
37unsafe impl Send for Manager {}
38
39/// A manager for tasks.
40pub struct Manager(pub(crate) RwLock<CriticalSectionRawMutex, Inner>);
41
42#[cfg(any(test, feature = "test_harness"))]
43static TEST_MANAGER: synchronization::once_lock::OnceLock<&'static Manager> =
44    synchronization::once_lock::OnceLock::new();
45
46#[cfg(any(test, feature = "test_harness"))]
47static TEST_MANAGER_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());
48
49#[cfg(any(test, feature = "test_harness"))]
50pub fn test_lock() -> &'static std::sync::Mutex<()> {
51    &TEST_MANAGER_LOCK
52}
53
54#[cfg(any(test, feature = "test_harness"))]
55#[doc(hidden)]
56pub fn test_manager() -> &'static Manager {
57    TEST_MANAGER.get_or_init(|| Box::leak(Box::new(Manager::new())))
58}
59
60#[cfg(any(test, feature = "test_harness"))]
61#[doc(hidden)]
62pub fn reset_test_manager() -> &'static Manager {
63    let manager = test_manager();
64    let mut inner = embassy_futures::block_on(manager.0.write());
65    inner.tasks.clear();
66    inner.identifiers.clear();
67    inner.spawners.clear();
68    drop(inner);
69    manager
70}
71
72#[cfg(any(test, feature = "test_harness"))]
73pub fn initialize() -> &'static Manager {
74    test_manager()
75}
76
77#[cfg(any(test, feature = "test_harness"))]
78pub fn get_instance() -> &'static Manager {
79    test_manager()
80}
81
82unsafe impl Sync for Manager {}
83
84impl Default for Manager {
85    fn default() -> Self {
86        Self::new()
87    }
88}
89
90impl Manager {
91    pub const ROOT_TASK_IDENTIFIER: TaskIdentifier = TaskIdentifier::new(0);
92
93    /// Create a new task manager instance,
94    /// create a root task and register current thread as the root task main thread.
95    pub const fn new() -> Self {
96        Manager(RwLock::new(Inner {
97            tasks: BTreeMap::new(),
98            identifiers: BTreeMap::new(),
99            spawners: BTreeMap::new(),
100        }))
101    }
102}