mod common;
use astrodynamics_gnss::rtk_filter::{update_epoch_with_scratch, FilterState, RtkFilterScratch};
use std::alloc::{GlobalAlloc, Layout, System};
use std::collections::BTreeMap;
use std::sync::atomic::{AtomicUsize, Ordering};
static ALLOCS: AtomicUsize = AtomicUsize::new(0);
struct Counting;
unsafe impl GlobalAlloc for Counting {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
ALLOCS.fetch_add(1, Ordering::Relaxed);
System.alloc(layout)
}
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
System.dealloc(ptr, layout)
}
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
ALLOCS.fetch_add(1, Ordering::Relaxed);
System.realloc(ptr, layout, new_size)
}
}
#[global_allocator]
static GLOBAL: Counting = Counting;
#[test]
fn update_epoch_allocations_per_solve_bounded() {
let (epoch, base, model, wl, off, opts) = common::inputs();
let mut state = FilterState::new(
BTreeMap::from([("G".to_string(), "G01".to_string())]),
[-30.0, 25.0, -10.0],
1.0e4,
1.0e4,
);
let mut scratch = RtkFilterScratch::new();
for _ in 0..5 {
state =
update_epoch_with_scratch(state, &epoch, base, &model, &wl, &off, &opts, &mut scratch)
.unwrap()
.state;
}
let n = 200;
let before = ALLOCS.load(Ordering::Relaxed);
for _ in 0..n {
state =
update_epoch_with_scratch(state, &epoch, base, &model, &wl, &off, &opts, &mut scratch)
.unwrap()
.state;
}
let per_solve = (ALLOCS.load(Ordering::Relaxed) - before) / n;
eprintln!("rtk_filter update_epoch_with_scratch allocations/solve = {per_solve}");
const EXPECTED: usize = 6;
assert_eq!(per_solve, EXPECTED, "allocations/solve changed");
}