Skip to content

Commit b85226a

Browse files
committed
move TaskTracker to trace
1 parent 8a8deb7 commit b85226a

File tree

2 files changed

+72
-70
lines changed

2 files changed

+72
-70
lines changed

embassy-executor/src/raw/mod.rs

-68
Original file line numberDiff line numberDiff line change
@@ -97,75 +97,7 @@ pub(crate) struct TaskHeader {
9797
all_tasks_next: AtomicPtr<TaskHeader>,
9898
}
9999

100-
/// A thread-safe tracker for all tasks in the system
101-
///
102-
/// This struct uses an intrusive linked list approach to track all tasks
103-
/// without additional memory allocations. It maintains a global list of
104-
/// tasks that can be traversed to find all currently existing tasks.
105-
#[cfg(feature = "trace")]
106-
pub struct TaskTracker {
107-
head: AtomicPtr<TaskHeader>,
108-
}
109-
110-
#[cfg(feature = "trace")]
111-
impl TaskTracker {
112-
/// Creates a new empty task tracker
113-
///
114-
/// Initializes a tracker with no tasks in its list.
115-
pub const fn new() -> Self {
116-
Self {
117-
head: AtomicPtr::new(core::ptr::null_mut()),
118-
}
119-
}
120-
121-
/// Adds a task to the tracker
122-
///
123-
/// This method inserts a task at the head of the intrusive linked list.
124-
/// The operation is thread-safe and lock-free, using atomic operations
125-
/// to ensure consistency even when called from different contexts.
126-
///
127-
/// # Arguments
128-
/// * `task` - The task reference to add to the tracker
129-
pub fn add(&self, task: TaskRef) {
130-
let task_ptr = task.as_ptr() as *mut TaskHeader;
131-
132-
loop {
133-
let current_head = self.head.load(Ordering::Acquire);
134-
unsafe {
135-
(*task_ptr).all_tasks_next.store(current_head, Ordering::Relaxed);
136-
}
137100

138-
if self
139-
.head
140-
.compare_exchange(current_head, task_ptr, Ordering::Release, Ordering::Relaxed)
141-
.is_ok()
142-
{
143-
break;
144-
}
145-
}
146-
}
147-
148-
/// Performs an operation on each task in the tracker
149-
///
150-
/// This method traverses the entire list of tasks and calls the provided
151-
/// function for each task. This allows inspecting or processing all tasks
152-
/// in the system without modifying the tracker's structure.
153-
///
154-
/// # Arguments
155-
/// * `f` - A function to call for each task in the tracker
156-
pub fn for_each<F>(&self, mut f: F)
157-
where
158-
F: FnMut(TaskRef),
159-
{
160-
let mut current = self.head.load(Ordering::Acquire);
161-
while !current.is_null() {
162-
let task = unsafe { TaskRef::from_ptr(current) };
163-
f(task);
164-
165-
current = unsafe { (*current).all_tasks_next.load(Ordering::Acquire) };
166-
}
167-
}
168-
}
169101

170102
/// This is essentially a `&'static TaskStorage<F>` where the type of the future has been erased.
171103
#[derive(Clone, Copy, PartialEq)]

embassy-executor/src/raw/trace.rs

+72-2
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,11 @@
8282
#![allow(unused)]
8383

8484
use core::cell::UnsafeCell;
85-
use core::sync::atomic::{AtomicUsize, Ordering};
85+
use core::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
8686

8787
use rtos_trace::TaskInfo;
8888

89-
use crate::raw::{SyncExecutor, TaskHeader, TaskRef, TaskTracker};
89+
use crate::raw::{SyncExecutor, TaskHeader, TaskRef};
9090
use crate::spawner::{SpawnError, SpawnToken, Spawner};
9191

9292
/// Extension trait adding tracing capabilities to the Spawner
@@ -139,6 +139,76 @@ impl TraceExt for Spawner {
139139
#[cfg(feature = "trace")]
140140
pub static TASK_TRACKER: TaskTracker = TaskTracker::new();
141141

142+
/// A thread-safe tracker for all tasks in the system
143+
///
144+
/// This struct uses an intrusive linked list approach to track all tasks
145+
/// without additional memory allocations. It maintains a global list of
146+
/// tasks that can be traversed to find all currently existing tasks.
147+
#[cfg(feature = "trace")]
148+
pub struct TaskTracker {
149+
head: AtomicPtr<TaskHeader>,
150+
}
151+
152+
#[cfg(feature = "trace")]
153+
impl TaskTracker {
154+
/// Creates a new empty task tracker
155+
///
156+
/// Initializes a tracker with no tasks in its list.
157+
pub const fn new() -> Self {
158+
Self {
159+
head: AtomicPtr::new(core::ptr::null_mut()),
160+
}
161+
}
162+
163+
/// Adds a task to the tracker
164+
///
165+
/// This method inserts a task at the head of the intrusive linked list.
166+
/// The operation is thread-safe and lock-free, using atomic operations
167+
/// to ensure consistency even when called from different contexts.
168+
///
169+
/// # Arguments
170+
/// * `task` - The task reference to add to the tracker
171+
pub fn add(&self, task: TaskRef) {
172+
let task_ptr = task.as_ptr() as *mut TaskHeader;
173+
174+
loop {
175+
let current_head = self.head.load(Ordering::Acquire);
176+
unsafe {
177+
(*task_ptr).all_tasks_next.store(current_head, Ordering::Relaxed);
178+
}
179+
180+
if self
181+
.head
182+
.compare_exchange(current_head, task_ptr, Ordering::Release, Ordering::Relaxed)
183+
.is_ok()
184+
{
185+
break;
186+
}
187+
}
188+
}
189+
190+
/// Performs an operation on each task in the tracker
191+
///
192+
/// This method traverses the entire list of tasks and calls the provided
193+
/// function for each task. This allows inspecting or processing all tasks
194+
/// in the system without modifying the tracker's structure.
195+
///
196+
/// # Arguments
197+
/// * `f` - A function to call for each task in the tracker
198+
pub fn for_each<F>(&self, mut f: F)
199+
where
200+
F: FnMut(TaskRef),
201+
{
202+
let mut current = self.head.load(Ordering::Acquire);
203+
while !current.is_null() {
204+
let task = unsafe { TaskRef::from_ptr(current) };
205+
f(task);
206+
207+
current = unsafe { (*current).all_tasks_next.load(Ordering::Acquire) };
208+
}
209+
}
210+
}
211+
142212
#[cfg(not(feature = "rtos-trace"))]
143213
extern "Rust" {
144214
/// This callback is called when the executor begins polling. This will always

0 commit comments

Comments
 (0)