diff options
| author | Ulf Lilleengen <[email protected]> | 2024-12-09 15:16:03 +0100 |
|---|---|---|
| committer | Ulf Lilleengen <[email protected]> | 2024-12-09 15:16:03 +0100 |
| commit | f0be2fdce4856888bd412fe9475ae55e05cf20a2 (patch) | |
| tree | ae14a1f758a13d4b9d6ea079edeea8f7ce711a6c /embassy-executor/src/raw | |
| parent | 86578acaa4d4dbed06ed4fcecec25884f6883e82 (diff) | |
Extend tracing api to support executor id and end task
Allow applications to provide a trace implementation that only needs to
implement APIs used by the embassy executor, and provide more context in
the event of multiple executors being used.
Diffstat (limited to 'embassy-executor/src/raw')
| -rw-r--r-- | embassy-executor/src/raw/mod.rs | 52 | ||||
| -rw-r--r-- | embassy-executor/src/raw/trace.rs | 90 |
2 files changed, 102 insertions, 40 deletions
diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs index ebabee1ba..3f93eae6f 100644 --- a/embassy-executor/src/raw/mod.rs +++ b/embassy-executor/src/raw/mod.rs | |||
| @@ -18,6 +18,8 @@ mod state; | |||
| 18 | 18 | ||
| 19 | #[cfg(feature = "integrated-timers")] | 19 | #[cfg(feature = "integrated-timers")] |
| 20 | mod timer_queue; | 20 | mod timer_queue; |
| 21 | #[cfg(feature = "trace")] | ||
| 22 | mod trace; | ||
| 21 | pub(crate) mod util; | 23 | pub(crate) mod util; |
| 22 | #[cfg_attr(feature = "turbowakers", path = "waker_turbo.rs")] | 24 | #[cfg_attr(feature = "turbowakers", path = "waker_turbo.rs")] |
| 23 | mod waker; | 25 | mod waker; |
| @@ -31,8 +33,6 @@ use core::task::{Context, Poll}; | |||
| 31 | 33 | ||
| 32 | #[cfg(feature = "integrated-timers")] | 34 | #[cfg(feature = "integrated-timers")] |
| 33 | use embassy_time_driver::AlarmHandle; | 35 | use embassy_time_driver::AlarmHandle; |
| 34 | #[cfg(feature = "rtos-trace")] | ||
| 35 | use rtos_trace::trace; | ||
| 36 | 36 | ||
| 37 | use self::run_queue::{RunQueue, RunQueueItem}; | 37 | use self::run_queue::{RunQueue, RunQueueItem}; |
| 38 | use self::state::State; | 38 | use self::state::State; |
| @@ -352,8 +352,8 @@ impl SyncExecutor { | |||
| 352 | /// - `task` must NOT be already enqueued (in this executor or another one). | 352 | /// - `task` must NOT be already enqueued (in this executor or another one). |
| 353 | #[inline(always)] | 353 | #[inline(always)] |
| 354 | unsafe fn enqueue(&self, task: TaskRef) { | 354 | unsafe fn enqueue(&self, task: TaskRef) { |
| 355 | #[cfg(feature = "rtos-trace")] | 355 | #[cfg(feature = "trace")] |
| 356 | trace::task_ready_begin(task.as_ptr() as u32); | 356 | trace::task_ready_begin(self, &task); |
| 357 | 357 | ||
| 358 | if self.run_queue.enqueue(task) { | 358 | if self.run_queue.enqueue(task) { |
| 359 | self.pender.pend(); | 359 | self.pender.pend(); |
| @@ -369,8 +369,8 @@ impl SyncExecutor { | |||
| 369 | pub(super) unsafe fn spawn(&'static self, task: TaskRef) { | 369 | pub(super) unsafe fn spawn(&'static self, task: TaskRef) { |
| 370 | task.header().executor.set(Some(self)); | 370 | task.header().executor.set(Some(self)); |
| 371 | 371 | ||
| 372 | #[cfg(feature = "rtos-trace")] | 372 | #[cfg(feature = "trace")] |
| 373 | trace::task_new(task.as_ptr() as u32); | 373 | trace::task_new(self, &task); |
| 374 | 374 | ||
| 375 | self.enqueue(task); | 375 | self.enqueue(task); |
| 376 | } | 376 | } |
| @@ -400,14 +400,14 @@ impl SyncExecutor { | |||
| 400 | return; | 400 | return; |
| 401 | } | 401 | } |
| 402 | 402 | ||
| 403 | #[cfg(feature = "rtos-trace")] | 403 | #[cfg(feature = "trace")] |
| 404 | trace::task_exec_begin(p.as_ptr() as u32); | 404 | trace::task_exec_begin(self, &p); |
| 405 | 405 | ||
| 406 | // Run the task | 406 | // Run the task |
| 407 | task.poll_fn.get().unwrap_unchecked()(p); | 407 | task.poll_fn.get().unwrap_unchecked()(p); |
| 408 | 408 | ||
| 409 | #[cfg(feature = "rtos-trace")] | 409 | #[cfg(feature = "trace")] |
| 410 | trace::task_exec_end(); | 410 | trace::task_exec_end(self, &p); |
| 411 | 411 | ||
| 412 | // Enqueue or update into timer_queue | 412 | // Enqueue or update into timer_queue |
| 413 | #[cfg(feature = "integrated-timers")] | 413 | #[cfg(feature = "integrated-timers")] |
| @@ -430,8 +430,8 @@ impl SyncExecutor { | |||
| 430 | } | 430 | } |
| 431 | } | 431 | } |
| 432 | 432 | ||
| 433 | #[cfg(feature = "rtos-trace")] | 433 | #[cfg(feature = "trace")] |
| 434 | trace::system_idle(); | 434 | trace::executor_idle(self) |
| 435 | } | 435 | } |
| 436 | } | 436 | } |
| 437 | 437 | ||
| @@ -593,31 +593,3 @@ impl embassy_time_queue_driver::TimerQueue for TimerQueue { | |||
| 593 | 593 | ||
| 594 | #[cfg(feature = "integrated-timers")] | 594 | #[cfg(feature = "integrated-timers")] |
| 595 | embassy_time_queue_driver::timer_queue_impl!(static TIMER_QUEUE: TimerQueue = TimerQueue); | 595 | embassy_time_queue_driver::timer_queue_impl!(static TIMER_QUEUE: TimerQueue = TimerQueue); |
| 596 | |||
| 597 | #[cfg(all(feature = "rtos-trace", feature = "integrated-timers"))] | ||
| 598 | const fn gcd(a: u64, b: u64) -> u64 { | ||
| 599 | if b == 0 { | ||
| 600 | a | ||
| 601 | } else { | ||
| 602 | gcd(b, a % b) | ||
| 603 | } | ||
| 604 | } | ||
| 605 | |||
| 606 | #[cfg(feature = "rtos-trace")] | ||
| 607 | impl rtos_trace::RtosTraceOSCallbacks for Executor { | ||
| 608 | fn task_list() { | ||
| 609 | // We don't know what tasks exist, so we can't send them. | ||
| 610 | } | ||
| 611 | #[cfg(feature = "integrated-timers")] | ||
| 612 | fn time() -> u64 { | ||
| 613 | const GCD_1M: u64 = gcd(embassy_time_driver::TICK_HZ, 1_000_000); | ||
| 614 | embassy_time_driver::now() * (1_000_000 / GCD_1M) / (embassy_time_driver::TICK_HZ / GCD_1M) | ||
| 615 | } | ||
| 616 | #[cfg(not(feature = "integrated-timers"))] | ||
| 617 | fn time() -> u64 { | ||
| 618 | 0 | ||
| 619 | } | ||
| 620 | } | ||
| 621 | |||
| 622 | #[cfg(feature = "rtos-trace")] | ||
| 623 | rtos_trace::global_os_callbacks! {Executor} | ||
diff --git a/embassy-executor/src/raw/trace.rs b/embassy-executor/src/raw/trace.rs new file mode 100644 index 000000000..c7bcf9c11 --- /dev/null +++ b/embassy-executor/src/raw/trace.rs | |||
| @@ -0,0 +1,90 @@ | |||
| 1 | #![allow(unused)] | ||
| 2 | use crate::raw::{SyncExecutor, TaskRef}; | ||
| 3 | |||
| 4 | #[cfg(not(feature = "rtos-trace"))] | ||
| 5 | extern "Rust" { | ||
| 6 | fn _embassy_trace_task_new(executor_id: u32, task_id: u32); | ||
| 7 | fn _embassy_trace_task_exec_begin(executor_id: u32, task_id: u32); | ||
| 8 | fn _embassy_trace_task_exec_end(excutor_id: u32, task_id: u32); | ||
| 9 | fn _embassy_trace_task_ready_begin(executor_id: u32, task_id: u32); | ||
| 10 | fn _embassy_trace_executor_idle(executor_id: u32); | ||
| 11 | } | ||
| 12 | |||
| 13 | #[inline] | ||
| 14 | pub(crate) fn task_new(executor: &SyncExecutor, task: &TaskRef) { | ||
| 15 | #[cfg(not(feature = "rtos-trace"))] | ||
| 16 | unsafe { | ||
| 17 | _embassy_trace_task_new(executor as *const _ as u32, task.as_ptr() as u32) | ||
| 18 | } | ||
| 19 | |||
| 20 | #[cfg(feature = "rtos-trace")] | ||
| 21 | rtos_trace::trace::task_new(task.as_ptr() as u32); | ||
| 22 | } | ||
| 23 | |||
| 24 | #[inline] | ||
| 25 | pub(crate) fn task_ready_begin(executor: &SyncExecutor, task: &TaskRef) { | ||
| 26 | #[cfg(not(feature = "rtos-trace"))] | ||
| 27 | unsafe { | ||
| 28 | _embassy_trace_task_ready_begin(executor as *const _ as u32, task.as_ptr() as u32) | ||
| 29 | } | ||
| 30 | #[cfg(feature = "rtos-trace")] | ||
| 31 | rtos_trace::trace::task_ready_begin(task.as_ptr() as u32); | ||
| 32 | } | ||
| 33 | |||
| 34 | #[inline] | ||
| 35 | pub(crate) fn task_exec_begin(executor: &SyncExecutor, task: &TaskRef) { | ||
| 36 | #[cfg(not(feature = "rtos-trace"))] | ||
| 37 | unsafe { | ||
| 38 | _embassy_trace_task_exec_begin(executor as *const _ as u32, task.as_ptr() as u32) | ||
| 39 | } | ||
| 40 | #[cfg(feature = "rtos-trace")] | ||
| 41 | rtos_trace::trace::task_exec_begin(task.as_ptr() as u32); | ||
| 42 | } | ||
| 43 | |||
| 44 | #[inline] | ||
| 45 | pub(crate) fn task_exec_end(executor: &SyncExecutor, task: &TaskRef) { | ||
| 46 | #[cfg(not(feature = "rtos-trace"))] | ||
| 47 | unsafe { | ||
| 48 | _embassy_trace_task_exec_end(executor as *const _ as u32, task.as_ptr() as u32) | ||
| 49 | } | ||
| 50 | #[cfg(feature = "rtos-trace")] | ||
| 51 | rtos_trace::trace::task_exec_end(); | ||
| 52 | } | ||
| 53 | |||
| 54 | #[inline] | ||
| 55 | pub(crate) fn executor_idle(executor: &SyncExecutor) { | ||
| 56 | #[cfg(not(feature = "rtos-trace"))] | ||
| 57 | unsafe { | ||
| 58 | _embassy_trace_executor_idle(executor as *const _ as u32) | ||
| 59 | } | ||
| 60 | #[cfg(feature = "rtos-trace")] | ||
| 61 | rtos_trace::trace::system_idle(); | ||
| 62 | } | ||
| 63 | |||
| 64 | #[cfg(all(feature = "rtos-trace", feature = "integrated-timers"))] | ||
| 65 | const fn gcd(a: u64, b: u64) -> u64 { | ||
| 66 | if b == 0 { | ||
| 67 | a | ||
| 68 | } else { | ||
| 69 | gcd(b, a % b) | ||
| 70 | } | ||
| 71 | } | ||
| 72 | |||
| 73 | #[cfg(feature = "rtos-trace")] | ||
| 74 | impl rtos_trace::RtosTraceOSCallbacks for crate::raw::SyncExecutor { | ||
| 75 | fn task_list() { | ||
| 76 | // We don't know what tasks exist, so we can't send them. | ||
| 77 | } | ||
| 78 | #[cfg(feature = "integrated-timers")] | ||
| 79 | fn time() -> u64 { | ||
| 80 | const GCD_1M: u64 = gcd(embassy_time_driver::TICK_HZ, 1_000_000); | ||
| 81 | embassy_time_driver::now() * (1_000_000 / GCD_1M) / (embassy_time_driver::TICK_HZ / GCD_1M) | ||
| 82 | } | ||
| 83 | #[cfg(not(feature = "integrated-timers"))] | ||
| 84 | fn time() -> u64 { | ||
| 85 | 0 | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 89 | #[cfg(feature = "rtos-trace")] | ||
| 90 | rtos_trace::global_os_callbacks! {SyncExecutor} | ||
