Skip to content
This repository was archived by the owner on Jun 10, 2024. It is now read-only.

Commit c74126e

Browse files
committed
Fix compilation under no_std
1 parent b5bb7be commit c74126e

File tree

4 files changed

+96
-46
lines changed

4 files changed

+96
-46
lines changed

liblumen_alloc/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
#![recursion_limit = "128"]
2+
#![cfg_attr(not(test), no_std)]
3+
// Do not fail the build when feature flags are stabilized on recent nightlies, just warn
24
#![allow(stable_features)]
5+
// Allow use of intrinsics, e.g. unlikely/copy_nonoverlapping/etc.
36
#![feature(core_intrinsics)]
7+
// Allocator APIs
48
#![feature(allocator_api)]
59
#![feature(alloc_layout_extra)]
10+
// Support offset_from pointer calculation
611
#![feature(ptr_offset_from)]
12+
// Support is_empty for ExactSizeIterator
713
#![feature(exact_size_is_empty)]
14+
// Support use of Self and other type aliases in matches on enum variants
815
#![feature(type_alias_enum_variants)]
916
#![feature(alloc)]
1017

liblumen_alloc/src/stats/histogram.rs

Lines changed: 77 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,16 @@
88
//! # Examples
99
//!
1010
//! ```
11-
//! use liblumen_alloc::stats::define_histogram;
12-
//!
13-
//! define_histogram!(10);
11+
//! use liblumen_alloc::stats::Histogram;
12+
//!
13+
//! mod stats {
14+
//! use liblumen_alloc::define_histogram;
15+
//! define_histogram!(10);
16+
//! }
1417
//! # fn main() {
1518
//! // Create a histogram that will spread the given range over
1619
//! // the 10 buckets the `Histogram` type was defined with.
17-
//! let mut histogram = Histogram::with_const_width(0, 10_000);
20+
//! let mut histogram = stats::Histogram::with_const_width(0, 10_000);
1821
//!
1922
//! // Adds some samples to the histogram.
2023
//! for sample in 0..100 {
@@ -56,7 +59,6 @@
5659
//! // ```
5760
//! # }
5861
//! ```
59-
#![deny(missing_docs)]
6062
#![deny(unsafe_code)]
6163

6264
use core::fmt;
@@ -65,7 +67,7 @@ pub use defaults::Histogram as DefaultHistogram;
6567

6668
/// This trait represents the bare minimum functionality needed
6769
/// to interact with an implementation by a mutator
68-
pub trait Histogram: Clone + Default + fmt::Display {
70+
pub trait Histogram: fmt::Display {
6971
/// Add a sample to the histogram.
7072
///
7173
/// Fails if the sample is out of range of the histogram.
@@ -219,9 +221,36 @@ macro_rules! define_histogram {
219221
pub fn range_max(&self) -> u64 {
220222
self.range[Self::LEN]
221223
}
224+
225+
/// Return the minimum value observed so far
226+
#[inline]
227+
pub fn min(&self) -> u64 {
228+
self.minmax.min().copied().unwrap_or(0)
229+
}
230+
231+
/// Return the maximum value observed so far
232+
#[inline]
233+
pub fn max(&self) -> u64 {
234+
self.minmax.max().copied().unwrap_or(0)
235+
}
236+
237+
#[inline]
238+
pub fn mean(&self) -> f64 {
239+
self.stats.mean()
240+
}
241+
242+
#[inline]
243+
pub fn stddev(&self) -> f64 {
244+
self.stats.stddev()
245+
}
246+
247+
#[inline]
248+
pub fn variance(&self) -> f64 {
249+
self.stats.variance()
250+
}
222251
}
223252

224-
impl $crate::stats::histogram::Histogram for Histogram {
253+
impl $crate::stats::Histogram for Histogram {
225254
/// Add a sample to the histogram.
226255
///
227256
/// Fails if the sample is out of range of the histogram.
@@ -274,6 +303,9 @@ macro_rules! define_histogram {
274303
use core::cmp;
275304
use core::fmt::Write;
276305

306+
#[cfg(not(test))]
307+
use alloc::string::String;
308+
277309
let num_samples: u64 = self.bins().iter().sum();
278310
writeln!(f, "# Number of samples = {}", num_samples)?;
279311
if num_samples == 0 {
@@ -357,71 +389,79 @@ mod defaults {
357389
// This histogram will spread all allocations across 100 buckets
358390
define_histogram!(100);
359391
// Provide a default implementation which will focus on the main sizes of concern
360-
impl Default for Histogram {
392+
impl Default for self::Histogram {
361393
fn default() -> Self {
362-
let mut ranges = Vec::with_capacity(100);
394+
use heapless::Vec;
395+
use heapless::consts::U100;
396+
let mut ranges = Vec::<_, U100>::new();
363397
// Use the fibonnaci sequence up to 1TB
364398
let mut n: u64 = 1;
365399
let mut m: u64 = 2;
366-
ranges.push(m);
400+
ranges.push(m).unwrap();
367401
for _ in 1..57u64 {
368402
let new_m = n + m;
369403
n = m;
370-
ranges.push(new_m);
404+
ranges.push(new_m).unwrap();
371405
m = new_m;
372406
}
373407
// Grow by 20% afterwards
374408
for _ in 57..99u64 {
375409
let new_m = m + (m as f64 * 0.2).ceil() as u64;
376-
ranges.push(new_m);
410+
ranges.push(new_m).unwrap();
377411
m = new_m;
378412
}
379413
// Add one final range that covers the remaining address space
380-
ranges.push(u64::max_value());
381-
Self::from_ranges(ranges.as_slice().iter().cloned()).unwrap()
414+
ranges.push(u64::max_value()).unwrap();
415+
Self::from_ranges(ranges.iter().cloned()).unwrap()
382416
}
383417
}
384418
}
385419

386420
#[cfg(test)]
387421
mod tests {
388-
use super::*;
422+
mod defaults {
423+
use crate::define_histogram;
424+
425+
define_histogram!(10);
426+
}
389427

390-
define_histogram!(10);
428+
use super::Histogram;
429+
use self::defaults::Histogram as DefaultHistogram;
391430

392431
#[test]
393-
fn with_const_width_test() {
394-
let mut h = Histogram::with_const_width(0, 100);
432+
fn histogram_with_const_width_test() {
433+
let mut h = DefaultHistogram::with_const_width(0, 100);
395434
for i in 0..100 {
396-
h.add(i);
435+
h.add(i).ok();
397436
}
398437
assert_eq!(h.max(), 99);
399438
assert_eq!(h.min(), 0);
400-
assert_eq!(h.mean(), 50);
401-
assert_eq!(h.bins(), &[10, 10, 10, 10, 10, 10, 10, 10, 10, 9])
439+
assert_eq!(h.mean(), 49.5);
440+
assert_eq!(h.bins(), &[10, 10, 10, 10, 10, 10, 10, 10, 10, 10])
402441
}
403442

404443
#[test]
405-
fn from_ranges_test() {
406-
let ranges = [
407-
(2, 4),
408-
(4, 8),
409-
(8, 16),
410-
(16, 32),
411-
(32, 64),
412-
(64, 128),
413-
(128, 256),
414-
(256, 512),
415-
(512, 1024),
416-
(1024, 2048),
444+
fn histogram_from_ranges_test() {
445+
let ranges: [u64; 11] = [
446+
2,
447+
4,
448+
8,
449+
16,
450+
32,
451+
64,
452+
128,
453+
256,
454+
512,
455+
1024,
456+
2048
417457
];
418-
let mut h = Histogram::from_ranges(&ranges);
458+
let mut h = DefaultHistogram::from_ranges(ranges.iter().copied()).unwrap();
419459
for i in 2..2048 {
420-
h.add(i);
460+
h.add(i).ok();
421461
}
422462
assert_eq!(h.max(), 2047);
423463
assert_eq!(h.min(), 2);
424-
assert_eq!(h.mean(), 50);
425-
assert_eq!(h.bins(), &[10, 10, 10, 10, 10, 10, 10, 10, 10, 9])
464+
assert_eq!(h.mean(), 1024.5);
465+
assert_eq!(h.bins(), &[2, 4, 8, 16, 32, 64, 128, 256, 512, 1024])
426466
}
427467
}

liblumen_alloc/src/stats_alloc.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use crate::stats::hooks;
2121
/// The `StatsAlloc` can be tagged to provide useful metadata bout
2222
/// what type of allocator is being traced and how it is used.
2323
#[derive(Debug)]
24-
pub struct StatsAlloc<T, H: Histogram = DefaultHistogram> {
24+
pub struct StatsAlloc<T, H: Histogram + Clone + Default = DefaultHistogram> {
2525
alloc_calls: AtomicUsize,
2626
dealloc_calls: AtomicUsize,
2727
realloc_calls: AtomicUsize,
@@ -32,7 +32,7 @@ pub struct StatsAlloc<T, H: Histogram = DefaultHistogram> {
3232
tag: &'static str,
3333
allocator: T,
3434
}
35-
impl<T, H: Histogram> StatsAlloc<T, H> {
35+
impl<T, H: Histogram + Clone + Default> StatsAlloc<T, H> {
3636
#[inline]
3737
pub fn new(t: T) -> Self {
3838
Self {
@@ -77,19 +77,19 @@ impl<T, H: Histogram> StatsAlloc<T, H> {
7777
}
7878
}
7979
}
80-
impl<T: Default, H: Histogram> Default for StatsAlloc<T, H> {
80+
impl<T: Default, H: Histogram + Clone + Default> Default for StatsAlloc<T, H> {
8181
#[inline]
8282
fn default() -> Self {
8383
Self::new(T::default())
8484
}
8585
}
86-
unsafe impl<T: Alloc + Sync, H: Histogram> Sync for StatsAlloc<T, H> {}
87-
unsafe impl<T: Alloc + Send, H: Histogram> Send for StatsAlloc<T, H> {}
86+
unsafe impl<T: Alloc + Sync, H: Histogram + Clone + Default> Sync for StatsAlloc<T, H> {}
87+
unsafe impl<T: Alloc + Send, H: Histogram + Clone + Default> Send for StatsAlloc<T, H> {}
8888

8989
/// This struct represents a snapshot of the stats gathered
9090
/// by an instances of `StatsAlloc`, and is used for display
9191
#[derive(Debug)]
92-
pub struct Statistics<H: Histogram> {
92+
pub struct Statistics<H: Histogram + Clone + Default> {
9393
alloc_calls: usize,
9494
dealloc_calls: usize,
9595
realloc_calls: usize,
@@ -99,7 +99,7 @@ pub struct Statistics<H: Histogram> {
9999
tag: &'static str,
100100
histogram: H,
101101
}
102-
impl<H: Histogram> fmt::Display for Statistics<H> {
102+
impl<H: Histogram + Clone + Default> fmt::Display for Statistics<H> {
103103
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
104104
writeln!(f, "## Allocator Statistics (tag = {})", self.tag)?;
105105
writeln!(f, "# Calls to alloc = {}", self.alloc_calls)?;
@@ -114,7 +114,7 @@ impl<H: Histogram> fmt::Display for Statistics<H> {
114114
}
115115
}
116116

117-
unsafe impl<T: Alloc, H: Histogram> Alloc for StatsAlloc<T, H> {
117+
unsafe impl<T: Alloc, H: Histogram + Clone + Default> Alloc for StatsAlloc<T, H> {
118118
#[inline]
119119
unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
120120
let size = layout.size();
@@ -195,7 +195,7 @@ unsafe impl<T: Alloc, H: Histogram> Alloc for StatsAlloc<T, H> {
195195
}
196196
}
197197

198-
unsafe impl<T: GlobalAlloc, H: Histogram> GlobalAlloc for StatsAlloc<T, H> {
198+
unsafe impl<T: GlobalAlloc, H: Histogram + Clone + Default> GlobalAlloc for StatsAlloc<T, H> {
199199
#[inline]
200200
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
201201
let size = layout.size();

liblumen_alloc/src/std_alloc.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ use core::alloc::{Alloc, AllocErr, Layout};
3737
use core::cmp;
3838
use core::ptr::{self, NonNull};
3939

40+
#[cfg(not(test))]
41+
use alloc::vec::Vec;
42+
4043
use cfg_if::cfg_if;
4144
use lazy_static::lazy_static;
4245

0 commit comments

Comments
 (0)