aboutsummaryrefslogtreecommitdiff
path: root/embassy-executor/src/raw/trace.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-executor/src/raw/trace.rs')
-rw-r--r--embassy-executor/src/raw/trace.rs77
1 files changed, 19 insertions, 58 deletions
diff --git a/embassy-executor/src/raw/trace.rs b/embassy-executor/src/raw/trace.rs
index f484abf58..b3086948c 100644
--- a/embassy-executor/src/raw/trace.rs
+++ b/embassy-executor/src/raw/trace.rs
@@ -95,17 +95,20 @@ use crate::spawner::{SpawnError, SpawnToken, Spawner};
95/// This static provides access to the global task tracker which maintains 95/// This static provides access to the global task tracker which maintains
96/// a list of all tasks in the system. It's automatically updated by the 96/// a list of all tasks in the system. It's automatically updated by the
97/// task lifecycle hooks in the trace module. 97/// task lifecycle hooks in the trace module.
98pub static TASK_TRACKER: TaskTracker = TaskTracker::new(); 98#[cfg(feature = "rtos-trace")]
99pub(crate) static TASK_TRACKER: TaskTracker = TaskTracker::new();
99 100
100/// A thread-safe tracker for all tasks in the system 101/// A thread-safe tracker for all tasks in the system
101/// 102///
102/// This struct uses an intrusive linked list approach to track all tasks 103/// This struct uses an intrusive linked list approach to track all tasks
103/// without additional memory allocations. It maintains a global list of 104/// without additional memory allocations. It maintains a global list of
104/// tasks that can be traversed to find all currently existing tasks. 105/// tasks that can be traversed to find all currently existing tasks.
105pub struct TaskTracker { 106#[cfg(feature = "rtos-trace")]
107pub(crate) struct TaskTracker {
106 head: AtomicPtr<TaskHeader>, 108 head: AtomicPtr<TaskHeader>,
107} 109}
108 110
111#[cfg(feature = "rtos-trace")]
109impl TaskTracker { 112impl TaskTracker {
110 /// Creates a new empty task tracker 113 /// Creates a new empty task tracker
111 /// 114 ///
@@ -125,7 +128,7 @@ impl TaskTracker {
125 /// # Arguments 128 /// # Arguments
126 /// * `task` - The task reference to add to the tracker 129 /// * `task` - The task reference to add to the tracker
127 pub fn add(&self, task: TaskRef) { 130 pub fn add(&self, task: TaskRef) {
128 let task_ptr = task.as_ptr() as *mut TaskHeader; 131 let task_ptr = task.as_ptr();
129 132
130 loop { 133 loop {
131 let current_head = self.head.load(Ordering::Acquire); 134 let current_head = self.head.load(Ordering::Acquire);
@@ -135,7 +138,7 @@ impl TaskTracker {
135 138
136 if self 139 if self
137 .head 140 .head
138 .compare_exchange(current_head, task_ptr, Ordering::Release, Ordering::Relaxed) 141 .compare_exchange(current_head, task_ptr.cast_mut(), Ordering::Release, Ordering::Relaxed)
139 .is_ok() 142 .is_ok()
140 { 143 {
141 break; 144 break;
@@ -165,50 +168,7 @@ impl TaskTracker {
165 } 168 }
166} 169}
167 170
168/// Extension trait for `TaskRef` that provides tracing functionality. 171#[cfg(feature = "trace")]
169///
170/// This trait is only available when the `trace` feature is enabled.
171/// It extends `TaskRef` with methods for accessing and modifying task identifiers
172/// and names, which are useful for debugging, logging, and performance analysis.
173pub trait TaskRefTrace {
174 /// Get the name for a task
175 fn name(&self) -> Option<&'static str>;
176
177 /// Set the name for a task
178 fn set_name(&self, name: Option<&'static str>);
179
180 /// Get the ID for a task
181 fn id(&self) -> u32;
182
183 /// Set the ID for a task
184 fn set_id(&self, id: u32);
185}
186
187impl TaskRefTrace for TaskRef {
188 fn name(&self) -> Option<&'static str> {
189 self.header().name
190 }
191
192 fn set_name(&self, name: Option<&'static str>) {
193 unsafe {
194 let header_ptr = self.ptr.as_ptr() as *mut TaskHeader;
195 (*header_ptr).name = name;
196 }
197 }
198
199 fn id(&self) -> u32 {
200 self.header().id
201 }
202
203 fn set_id(&self, id: u32) {
204 unsafe {
205 let header_ptr = self.ptr.as_ptr() as *mut TaskHeader;
206 (*header_ptr).id = id;
207 }
208 }
209}
210
211#[cfg(not(feature = "rtos-trace"))]
212extern "Rust" { 172extern "Rust" {
213 /// This callback is called when the executor begins polling. This will always 173 /// This callback is called when the executor begins polling. This will always
214 /// be paired with a later call to `_embassy_trace_executor_idle`. 174 /// be paired with a later call to `_embassy_trace_executor_idle`.
@@ -270,7 +230,7 @@ extern "Rust" {
270 230
271#[inline] 231#[inline]
272pub(crate) fn poll_start(executor: &SyncExecutor) { 232pub(crate) fn poll_start(executor: &SyncExecutor) {
273 #[cfg(not(feature = "rtos-trace"))] 233 #[cfg(feature = "trace")]
274 unsafe { 234 unsafe {
275 _embassy_trace_poll_start(executor as *const _ as u32) 235 _embassy_trace_poll_start(executor as *const _ as u32)
276 } 236 }
@@ -278,7 +238,7 @@ pub(crate) fn poll_start(executor: &SyncExecutor) {
278 238
279#[inline] 239#[inline]
280pub(crate) fn task_new(executor: &SyncExecutor, task: &TaskRef) { 240pub(crate) fn task_new(executor: &SyncExecutor, task: &TaskRef) {
281 #[cfg(not(feature = "rtos-trace"))] 241 #[cfg(feature = "trace")]
282 unsafe { 242 unsafe {
283 _embassy_trace_task_new(executor as *const _ as u32, task.as_ptr() as u32) 243 _embassy_trace_task_new(executor as *const _ as u32, task.as_ptr() as u32)
284 } 244 }
@@ -286,7 +246,7 @@ pub(crate) fn task_new(executor: &SyncExecutor, task: &TaskRef) {
286 #[cfg(feature = "rtos-trace")] 246 #[cfg(feature = "rtos-trace")]
287 { 247 {
288 rtos_trace::trace::task_new(task.as_ptr() as u32); 248 rtos_trace::trace::task_new(task.as_ptr() as u32);
289 let name = task.name().unwrap_or("unnamed task\0"); 249 let name = task.metadata().name().unwrap_or("unnamed task\0");
290 let info = rtos_trace::TaskInfo { 250 let info = rtos_trace::TaskInfo {
291 name, 251 name,
292 priority: 0, 252 priority: 0,
@@ -302,7 +262,7 @@ pub(crate) fn task_new(executor: &SyncExecutor, task: &TaskRef) {
302 262
303#[inline] 263#[inline]
304pub(crate) fn task_end(executor: *const SyncExecutor, task: &TaskRef) { 264pub(crate) fn task_end(executor: *const SyncExecutor, task: &TaskRef) {
305 #[cfg(not(feature = "rtos-trace"))] 265 #[cfg(feature = "trace")]
306 unsafe { 266 unsafe {
307 _embassy_trace_task_end(executor as u32, task.as_ptr() as u32) 267 _embassy_trace_task_end(executor as u32, task.as_ptr() as u32)
308 } 268 }
@@ -310,7 +270,7 @@ pub(crate) fn task_end(executor: *const SyncExecutor, task: &TaskRef) {
310 270
311#[inline] 271#[inline]
312pub(crate) fn task_ready_begin(executor: &SyncExecutor, task: &TaskRef) { 272pub(crate) fn task_ready_begin(executor: &SyncExecutor, task: &TaskRef) {
313 #[cfg(not(feature = "rtos-trace"))] 273 #[cfg(feature = "trace")]
314 unsafe { 274 unsafe {
315 _embassy_trace_task_ready_begin(executor as *const _ as u32, task.as_ptr() as u32) 275 _embassy_trace_task_ready_begin(executor as *const _ as u32, task.as_ptr() as u32)
316 } 276 }
@@ -320,7 +280,7 @@ pub(crate) fn task_ready_begin(executor: &SyncExecutor, task: &TaskRef) {
320 280
321#[inline] 281#[inline]
322pub(crate) fn task_exec_begin(executor: &SyncExecutor, task: &TaskRef) { 282pub(crate) fn task_exec_begin(executor: &SyncExecutor, task: &TaskRef) {
323 #[cfg(not(feature = "rtos-trace"))] 283 #[cfg(feature = "trace")]
324 unsafe { 284 unsafe {
325 _embassy_trace_task_exec_begin(executor as *const _ as u32, task.as_ptr() as u32) 285 _embassy_trace_task_exec_begin(executor as *const _ as u32, task.as_ptr() as u32)
326 } 286 }
@@ -330,7 +290,7 @@ pub(crate) fn task_exec_begin(executor: &SyncExecutor, task: &TaskRef) {
330 290
331#[inline] 291#[inline]
332pub(crate) fn task_exec_end(executor: &SyncExecutor, task: &TaskRef) { 292pub(crate) fn task_exec_end(executor: &SyncExecutor, task: &TaskRef) {
333 #[cfg(not(feature = "rtos-trace"))] 293 #[cfg(feature = "trace")]
334 unsafe { 294 unsafe {
335 _embassy_trace_task_exec_end(executor as *const _ as u32, task.as_ptr() as u32) 295 _embassy_trace_task_exec_end(executor as *const _ as u32, task.as_ptr() as u32)
336 } 296 }
@@ -340,7 +300,7 @@ pub(crate) fn task_exec_end(executor: &SyncExecutor, task: &TaskRef) {
340 300
341#[inline] 301#[inline]
342pub(crate) fn executor_idle(executor: &SyncExecutor) { 302pub(crate) fn executor_idle(executor: &SyncExecutor) {
343 #[cfg(not(feature = "rtos-trace"))] 303 #[cfg(feature = "trace")]
344 unsafe { 304 unsafe {
345 _embassy_trace_executor_idle(executor as *const _ as u32) 305 _embassy_trace_executor_idle(executor as *const _ as u32)
346 } 306 }
@@ -356,6 +316,7 @@ pub(crate) fn executor_idle(executor: &SyncExecutor) {
356/// 316///
357/// # Returns 317/// # Returns
358/// An iterator that yields `TaskRef` items for each task 318/// An iterator that yields `TaskRef` items for each task
319#[cfg(feature = "rtos-trace")]
359fn get_all_active_tasks() -> impl Iterator<Item = TaskRef> + 'static { 320fn get_all_active_tasks() -> impl Iterator<Item = TaskRef> + 'static {
360 struct TaskIterator<'a> { 321 struct TaskIterator<'a> {
361 tracker: &'a TaskTracker, 322 tracker: &'a TaskTracker,
@@ -384,6 +345,7 @@ fn get_all_active_tasks() -> impl Iterator<Item = TaskRef> + 'static {
384} 345}
385 346
386/// Perform an action on each active task 347/// Perform an action on each active task
348#[cfg(feature = "rtos-trace")]
387fn with_all_active_tasks<F>(f: F) 349fn with_all_active_tasks<F>(f: F)
388where 350where
389 F: FnMut(TaskRef), 351 F: FnMut(TaskRef),
@@ -395,9 +357,8 @@ where
395impl rtos_trace::RtosTraceOSCallbacks for crate::raw::SyncExecutor { 357impl rtos_trace::RtosTraceOSCallbacks for crate::raw::SyncExecutor {
396 fn task_list() { 358 fn task_list() {
397 with_all_active_tasks(|task| { 359 with_all_active_tasks(|task| {
398 let name = task.name().unwrap_or("unnamed task\0");
399 let info = rtos_trace::TaskInfo { 360 let info = rtos_trace::TaskInfo {
400 name, 361 name: task.metadata().name().unwrap_or("unnamed task\0"),
401 priority: 0, 362 priority: 0,
402 stack_base: 0, 363 stack_base: 0,
403 stack_size: 0, 364 stack_size: 0,