Skip to content

Commit

Permalink
refactor(bench)!: move benchmarking facilities to their own crate
Browse files Browse the repository at this point in the history
  • Loading branch information
ROMemories committed Mar 21, 2024
1 parent 0d3dd10 commit bf3d4bf
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 42 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ jobs:
- name: clippy
uses: clechasseur/rs-clippy-check@v3
with:
args: --verbose --locked -p riot-rs-embassy
args: --verbose --locked -p riot-rs-embassy -p riot-rs-bench

# TODO: we'll eventually want to enable relevant features
- name: "rustdoc"
Expand Down
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ esp-wifi = { git = "https://github.com/kaspar030/esp-wifi", branch = "update-esp
linkme = { version = "0.3.21", features = ["used_linker"] }

riot-rs = { path = "src/riot-rs", default-features = false }
riot-rs-bench = { path = "src/riot-rs-bench", default-features = false }
riot-rs-debug = { path = "src/riot-rs-debug", default-features = false }
riot-rs-rt = { path = "src/riot-rs-rt" }
riot-rs-runqueue = { path = "src/riot-rs-runqueue" }
Expand Down
2 changes: 1 addition & 1 deletion examples/benchmark/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use riot_rs::debug::println;

#[riot_rs::thread]
fn main() {
match riot_rs::rt::benchmark(10000, || {
match riot_rs::bench::benchmark(10000, || {
//
}) {
Ok(ticks) => {
Expand Down
15 changes: 15 additions & 0 deletions src/riot-rs-bench/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "riot-rs-bench"
version.workspace = true
authors.workspace = true
edition.workspace = true
repository.workspace = true

[lints]
workspace = true

[dependencies]
cfg-if = { workspace = true }

[target.'cfg(context = "cortex-m")'.dependencies]
cortex-m = { workspace = true, features = ["critical-section-single-core"] }
36 changes: 36 additions & 0 deletions src/riot-rs-bench/src/cortexm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use cortex_m::{
peripheral::{syst::SystClkSource, SYST},
Peripherals,
};

use crate::Error;

#[allow(missing_docs)]
pub fn benchmark<F: Fn() -> ()>(iterations: usize, f: F) -> Result<usize, Error> {
let mut p = unsafe { Peripherals::steal() };
//
p.SCB.clear_sleepdeep();

//
p.SYST.set_clock_source(SystClkSource::Core);
p.SYST.set_reload(0x00FFFFFF);
p.SYST.clear_current();
p.SYST.enable_counter();

// Wait for the system timer to be ready
while SYST::get_current() == 0 {}

let before = SYST::get_current();

for _ in 0..iterations {
f();
}

let total = before - SYST::get_current();

if p.SYST.has_wrapped() {
Err(Error::SystemTimerWrapped)
} else {
Ok(total as usize / iterations)
}
}
55 changes: 55 additions & 0 deletions src/riot-rs-bench/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//! Provides on-board benchmarking facilities.

#![cfg_attr(not(test), no_std)]
#![feature(error_in_core)]
#![deny(clippy::pedantic)]
#![deny(missing_docs)]

cfg_if::cfg_if! {
if #[cfg(context = "cortex-m")] {
mod cortexm;
use cortexm as bench;
}
else if #[cfg(context = "riot-rs")] {
// When run with laze but the architecture is not supported
compile_error!("benchmarking is not supported for this architecture");
} else {
// Provide a default bench module, for arch-independent tooling
mod bench {
use crate::Error;

/// Benchmarks "time" required to run the provided function.
///
/// Runs the provided function `iterations` times, and returns the mean number of system timer
/// increments per iteration.
///
/// # Errors
///
/// Returns [`Error::SystemTimerWrapped`] if the system timer counter has wrapped when
/// benchmarking.
#[allow(unused_variables)]
pub fn benchmark<F: Fn()>(iterations: usize, f: F) -> Result<usize, Error> {
unimplemented!();
}
}
}
}

pub use bench::benchmark;

/// Possible errors happening when benchmarking.
#[derive(Debug)]
pub enum Error {
/// The system timer wrapped when benchmarking.
SystemTimerWrapped,
}

impl core::fmt::Display for Error {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::SystemTimerWrapped => write!(f, "system timer wrapped"),
}
}
}

impl core::error::Error for Error {}
31 changes: 0 additions & 31 deletions src/riot-rs-rt/src/cortexm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,34 +208,3 @@ pub fn init() {
p.SCB.set_priority(SystemHandler::PendSV, 0xFF);
}
}

pub fn benchmark<F: Fn() -> ()>(iterations: usize, f: F) -> core::result::Result<usize, ()> {
use cortex_m::peripheral::syst::SystClkSource;
use cortex_m::Peripherals;

let mut p = unsafe { Peripherals::steal() };
//
p.SCB.clear_sleepdeep();

//
p.SYST.set_clock_source(SystClkSource::Core);
p.SYST.set_reload(0x00FFFFFF);
p.SYST.clear_current();
p.SYST.enable_counter();

while cortex_m::peripheral::SYST::get_current() == 0 {}

let before = cortex_m::peripheral::SYST::get_current();

for _ in 0..iterations {
f();
}

let total = before - cortex_m::peripheral::SYST::get_current();

if p.SYST.has_wrapped() {
Err(())
} else {
Ok((total) as usize / iterations)
}
}
4 changes: 0 additions & 4 deletions src/riot-rs-rt/src/esp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,3 @@ fn main() -> ! {
}

pub fn init() {}

pub fn benchmark<F: Fn() -> ()>(_iterations: usize, _f: F) -> core::result::Result<usize, ()> {
unimplemented!()
}
5 changes: 0 additions & 5 deletions src/riot-rs-rt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,10 @@ cfg_if::cfg_if! {
// Provide a default architecture, for arch-independent tooling
mod arch {
pub fn init() {}

Check warning on line 38 in src/riot-rs-rt/src/lib.rs

View workflow job for this annotation

GitHub Actions / lint

function `init` is never used

warning: function `init` is never used --> src/riot-rs-rt/src/lib.rs:38:20 | 38 | pub fn init() {} | ^^^^
pub fn benchmark<F: Fn()>(_iterations: usize, _f: F) -> core::result::Result<usize, ()> {
unimplemented!();
}
}
}
}

pub use arch::benchmark;

const ISR_STACKSIZE: usize =
riot_rs_utils::usize_from_env_or!("CONFIG_ISR_STACKSIZE", 8192, "ISR stack size (in bytes)");

Expand Down
1 change: 1 addition & 0 deletions src/riot-rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ workspace = true

[dependencies]
linkme = { workspace = true }
riot-rs-bench = { workspace = true }
riot-rs-boards = { path = "../riot-rs-boards" }
riot-rs-buildinfo = { path = "../riot-rs-buildinfo" }
riot-rs-debug = { workspace = true }
Expand Down
3 changes: 3 additions & 0 deletions src/riot-rs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
//! This is a meta-package, pulling in the sub-crates of RIOT-rs.

#![no_std]
#![feature(doc_cfg)]

#[doc(inline)]
pub use riot_rs_bench as bench;
pub use riot_rs_buildinfo as buildinfo;
pub use riot_rs_debug as debug;
pub use riot_rs_embassy::{self as embassy, define_peripherals};
Expand Down

0 comments on commit bf3d4bf

Please sign in to comment.