no_std_time 0.15.4

Time measurments that work in no_std environments
Documentation

No_Std_Time: no_std-friendly timing and timestamping

The no_std_time crate provides no_std-friendly timing and high-performance timestamping utilities. It is a core component of the LibAFL fuzzing framework.

This crate offers two main pieces of functionality:

  1. A way to get the current system time as a Duration, even in no_std environments.
  2. A high-performance time counter using CPU-specific instructions (rdtsc, etc.) for fast measurements.

Usage

Getting the Current Time

You can get the current time using the current_time() function.

With the std feature enabled (the default), this works out of the box:

use no_std_time::current_time;

let time = current_time();
println!("Current time: {:?}", time);

In a no_std environment, you must provide an implementation for external_current_millis that returns the milliseconds since the UNIX epoch.

// In your no_std binary:
#[no_mangle]
pub extern "C" fn external_current_millis() -> u64 {
    // Return time from your platform-specific source, e.g., an RTC.
    1678886400000
}

High-Performance Timestamping

For high-performance measurements, read_time_counter() provides access to fast, low-level CPU cycle counters. This is useful for profiling and performance-critical code.

use no_std_time::read_time_counter;

let start = read_time_counter();
// ... do some work ...
let end = read_time_counter();
let elapsed = end - start;
println!("Work took {} cycles", elapsed);

This function is optimized for the following architectures:

  • x86 and x86_64 (using rdtsc)
  • aarch64 (using cntvct_el0)
  • arm (using the performance monitor unit)
  • riscv32 and riscv64 (using rdcycle)

On other architectures, it falls back to a system-time-based implementation.

Formatting Durations

The crate includes a utility to format a Duration into a human-readable string. This requires the alloc feature.

use core::time::Duration;
use no_std_time::format_duration;

let duration = Duration::from_secs(3661);
let formatted = format_duration(&duration);
assert_eq!(formatted, "1h-1m-1s");

Features

  • std (default): Enables functionality that depends on the standard library, such as getting the system time automatically.
  • alloc (default): Enables features that require heap allocation, such as format_duration.

The LibAFL Project

The LibAFL project is part of AFLplusplus and maintained by

Contributing

For bugs, feel free to open issues or contact us directly. Thank you for your support. <3

Even though we will gladly assist you in finishing up your PR, try to

  • keep all the crates compiling with stable rust (hide the eventual non-stable code under cfgs.)
  • run cargo nightly fmt on your code before pushing
  • check the output of cargo clippy --all or ./clippy.sh
  • run cargo build --no-default-features to check for no_std compatibility (and possibly add #[cfg(feature = "std")]) to hide parts of your code.

Some parts in this list may sound hard, but don't be afraid to open a PR if you cannot fix them by yourself. We will gladly assist.

License