|
| 1 | +//! Measures the execution times of semaphore operations. |
| 2 | +//! |
| 3 | +//! ```text |
| 4 | +//! sem main task1 |
| 5 | +//! │1│ │ │ ┊ |
| 6 | +//! │ │ │ │ ┊ ┐ |
| 7 | +//! ├─┤ │ │ sem wait ┊ │ I_WAIT |
| 8 | +//! │0│ │ │ ┊ ┘ |
| 9 | +//! │ │ │ │ activate ┊ |
| 10 | +//! │ │ └┬┘ ─────────────► ┌┴┐ |
| 11 | +//! │ │ │ │ │ |
| 12 | +//! │ │ │ sem wait │ │ ┐ |
| 13 | +//! │ │ ┌┴┐ ◀──────────── └┬┘ │ I_WAIT_DISPATCING |
| 14 | +//! │ │ │ │ │ ┘ |
| 15 | +//! │ │ │ │ sem signal │ ┐ |
| 16 | +//! ├─┤ └┬┘ ─────────────► ┌┴┐ │ I_SIGNAL_DISPATCING |
| 17 | +//! │0│ ┊ │ │ ┘ |
| 18 | +//! │ │ ┊ │ │ ┐ |
| 19 | +//! ├─┤ ┊ │ │ sem signal │ I_SIGNAL |
| 20 | +//! │1│ ┊ exit_task │ │ ┘ |
| 21 | +//! │ │ ┌┴┐ ◀───────────── └┬┘ |
| 22 | +//! │ │ │ │ ┊ |
| 23 | +//! ``` |
| 24 | +//! |
| 25 | +use constance::kernel::{cfg::CfgBuilder, Kernel, Semaphore, Task}; |
| 26 | + |
| 27 | +use super::Bencher; |
| 28 | +use crate::utils::benchmark::Interval; |
| 29 | + |
| 30 | +use_benchmark_in_kernel_benchmark! { |
| 31 | + pub unsafe struct App<System> { |
| 32 | + inner: AppInner<System>, |
| 33 | + } |
| 34 | +} |
| 35 | + |
| 36 | +struct AppInner<System> { |
| 37 | + task1: Task<System>, |
| 38 | + sem: Semaphore<System>, |
| 39 | +} |
| 40 | + |
| 41 | +const I_WAIT_DISPATCHING: Interval = "wait semaphore with dispatch"; |
| 42 | +const I_WAIT: Interval = "wait semaphore"; |
| 43 | +const I_SIGNAL_DISPATCHING: Interval = "signal semaphore with dispatch"; |
| 44 | +const I_SIGNAL: Interval = "signal semaphore"; |
| 45 | + |
| 46 | +impl<System: Kernel> AppInner<System> { |
| 47 | + /// Used by `use_benchmark_in_kernel_benchmark!` |
| 48 | + const fn new<B: Bencher<Self>>(b: &mut CfgBuilder<System>) -> Self { |
| 49 | + let task1 = Task::build() |
| 50 | + .start(task1_body::<System, B>) |
| 51 | + .priority(1) |
| 52 | + .finish(b); |
| 53 | + |
| 54 | + let sem = Semaphore::build().initial(1).maximum(1).finish(b); |
| 55 | + |
| 56 | + Self { task1, sem } |
| 57 | + } |
| 58 | + |
| 59 | + /// Used by `use_benchmark_in_kernel_benchmark!` |
| 60 | + fn iter<B: Bencher<Self>>() { |
| 61 | + B::mark_start(); // I_WAIT |
| 62 | + B::app().sem.wait_one().unwrap(); |
| 63 | + B::mark_end(I_WAIT); |
| 64 | + |
| 65 | + B::app().task1.activate().unwrap(); |
| 66 | + B::mark_end(I_WAIT_DISPATCHING); |
| 67 | + |
| 68 | + B::mark_start(); // I_SIGNAL_DISPATCHING |
| 69 | + B::app().sem.signal_one().unwrap(); |
| 70 | + } |
| 71 | +} |
| 72 | + |
| 73 | +fn task1_body<System: Kernel, B: Bencher<AppInner<System>>>(_: usize) { |
| 74 | + B::mark_start(); // I_WAIT_DISPATCHING |
| 75 | + B::app().sem.wait_one().unwrap(); |
| 76 | + B::mark_end(I_SIGNAL_DISPATCHING); |
| 77 | + |
| 78 | + B::mark_start(); |
| 79 | + B::app().sem.signal_one().unwrap(); |
| 80 | + B::mark_end(I_SIGNAL); |
| 81 | +} |
0 commit comments