mirror of
https://github.com/javalsai/aoc.git
synced 2026-01-13 01:19:59 +01:00
add: internal timers
This commit is contained in:
@@ -113,15 +113,22 @@ pub mod dl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub mod loader {
|
pub mod loader {
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
use crate::dl::Handle;
|
use crate::dl::Handle;
|
||||||
|
|
||||||
pub type ChallengeFn<T> = unsafe extern "Rust" fn(&[u8]) -> T;
|
pub type ChallengeFn<T> = unsafe extern "Rust" fn(&[u8]) -> T;
|
||||||
|
pub type TimedChallengeFn<T> = unsafe extern "Rust" fn(&[u8], &Instant) -> T;
|
||||||
|
|
||||||
pub enum FnVariant {
|
pub enum FnVariant {
|
||||||
Isize(ChallengeFn<isize>),
|
Isize(ChallengeFn<isize>),
|
||||||
Usize(ChallengeFn<usize>),
|
Usize(ChallengeFn<usize>),
|
||||||
IsizeDuple(ChallengeFn<(isize, isize)>),
|
IsizeDuple(ChallengeFn<(isize, isize)>),
|
||||||
UsizeDuple(ChallengeFn<(usize, usize)>),
|
UsizeDuple(ChallengeFn<(usize, usize)>),
|
||||||
|
TIsize(TimedChallengeFn<isize>),
|
||||||
|
TUsize(TimedChallengeFn<usize>),
|
||||||
|
TIsizeDuple(TimedChallengeFn<(isize, isize)>),
|
||||||
|
TUsizeDuple(TimedChallengeFn<(usize, usize)>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
@@ -146,7 +153,7 @@ pub mod loader {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// Calls external arbitrary FNs.
|
/// Calls external arbitrary FNs.
|
||||||
pub unsafe fn call(&self, buf: &[u8]) -> FnRetVariant {
|
pub unsafe fn call(&self, buf: &[u8], instant: &Instant) -> FnRetVariant {
|
||||||
use FnRetVariant as R;
|
use FnRetVariant as R;
|
||||||
use FnVariant as V;
|
use FnVariant as V;
|
||||||
|
|
||||||
@@ -155,6 +162,26 @@ pub mod loader {
|
|||||||
V::Usize(f) => unsafe { R::Usize((f)(buf)) },
|
V::Usize(f) => unsafe { R::Usize((f)(buf)) },
|
||||||
V::IsizeDuple(f) => unsafe { R::IsizeDuple((f)(buf)) },
|
V::IsizeDuple(f) => unsafe { R::IsizeDuple((f)(buf)) },
|
||||||
V::UsizeDuple(f) => unsafe { R::UsizeDuple((f)(buf)) },
|
V::UsizeDuple(f) => unsafe { R::UsizeDuple((f)(buf)) },
|
||||||
|
V::TIsize(f) => unsafe { R::Isize((f)(buf, instant)) },
|
||||||
|
V::TUsize(f) => unsafe { R::Usize((f)(buf, instant)) },
|
||||||
|
V::TIsizeDuple(f) => unsafe { R::IsizeDuple((f)(buf, instant)) },
|
||||||
|
V::TUsizeDuple(f) => unsafe { R::UsizeDuple((f)(buf, instant)) },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// Calls external arbitrary FNs.
|
||||||
|
pub unsafe fn call_notimer(&self, buf: &[u8]) -> Option<FnRetVariant> {
|
||||||
|
use FnRetVariant as R;
|
||||||
|
use FnVariant as V;
|
||||||
|
|
||||||
|
match self {
|
||||||
|
V::Isize(f) => Some(unsafe { R::Isize((f)(buf)) }),
|
||||||
|
V::Usize(f) => Some(unsafe { R::Usize((f)(buf)) }),
|
||||||
|
V::IsizeDuple(f) => Some(unsafe { R::IsizeDuple((f)(buf)) }),
|
||||||
|
V::UsizeDuple(f) => Some(unsafe { R::UsizeDuple((f)(buf)) }),
|
||||||
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -171,6 +198,7 @@ pub mod loader {
|
|||||||
|
|
||||||
use ChallengeFn as C;
|
use ChallengeFn as C;
|
||||||
use FnVariant as V;
|
use FnVariant as V;
|
||||||
|
use TimedChallengeFn as TC;
|
||||||
|
|
||||||
// SAFETY: This is actually safe as it just creates the fn ptr, no weird fn with weird
|
// SAFETY: This is actually safe as it just creates the fn ptr, no weird fn with weird
|
||||||
// drop.
|
// drop.
|
||||||
@@ -185,8 +213,29 @@ pub mod loader {
|
|||||||
.map(V::UsizeDuple)
|
.map(V::UsizeDuple)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
untry!(unsafe { handle.symfn::<TC<isize>>(c"challenge_t_isize") }.map(V::TIsize));
|
||||||
|
untry!(unsafe { handle.symfn::<TC<usize>>(c"challenge_t_usize") }.map(V::TUsize));
|
||||||
|
untry!(
|
||||||
|
unsafe { handle.symfn::<TC<(isize, isize)>>(c"challenge_t_isize_duple") }
|
||||||
|
.map(V::TIsizeDuple)
|
||||||
|
);
|
||||||
|
untry!(
|
||||||
|
unsafe { handle.symfn::<TC<(usize, usize)>>(c"challenge_t_usize_duple") }
|
||||||
|
.map(V::TUsizeDuple)
|
||||||
|
);
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn load_timers_from(handle: &Handle) -> Option<&[(&str, Duration)]> {
|
||||||
|
// SAFETY: This is actually safe as it just creates the fn ptr, no weird fn with weird
|
||||||
|
// drop.
|
||||||
|
let at = unsafe { handle.sym::<(&str, Duration)>(c"TIMERS") }?;
|
||||||
|
let len = unsafe { handle.sym::<usize>(c"TIMERS_LEN") }?;
|
||||||
|
let len = unsafe { *len.as_ref() };
|
||||||
|
|
||||||
|
Some(unsafe { std::slice::from_raw_parts(at.as_ptr(), len) })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod performer {
|
pub mod performer {
|
||||||
@@ -240,18 +289,23 @@ fn main() -> io::Result<()> {
|
|||||||
|
|
||||||
let challenge = dl::open(so_path).expect("Couldn't load dyn library");
|
let challenge = dl::open(so_path).expect("Couldn't load dyn library");
|
||||||
let challenge_main = loader::load_fn_from(&challenge).expect(concat!(
|
let challenge_main = loader::load_fn_from(&challenge).expect(concat!(
|
||||||
"Didn't find any appropiate symbol in the compiled .so file. Make sure there is one and is ",
|
"Didn't find any appropiate symbol in the compiled .so file. Make sure there is one.",
|
||||||
stringify!(unsafe extern "Rust" fn(&[u8]) -> isize)
|
|
||||||
));
|
));
|
||||||
|
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let result = unsafe { challenge_main.call(&input) };
|
let result = unsafe { challenge_main.call(&input, &start) };
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"done in {:#?} and yielded result {:?}",
|
"done in {:#?} and yielded result {:?}",
|
||||||
start.elapsed(),
|
start.elapsed(),
|
||||||
result
|
result
|
||||||
);
|
);
|
||||||
|
if let Some(timers) = loader::load_timers_from(&challenge) {
|
||||||
|
println!("with timers:");
|
||||||
|
for (name, timer) in timers {
|
||||||
|
println!(" '{name}': {timer:#?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -260,10 +314,10 @@ const STUB_ISIZE: loader::FnVariant = loader::FnVariant::make_noop_stub_isize();
|
|||||||
fn measure_noop_overhead() -> (time::Duration, time::Duration) {
|
fn measure_noop_overhead() -> (time::Duration, time::Duration) {
|
||||||
let timer = Instant::now();
|
let timer = Instant::now();
|
||||||
// SAFETY: completely safe, not arbitrary fn but our stub
|
// SAFETY: completely safe, not arbitrary fn but our stub
|
||||||
unsafe { STUB_ISIZE.call(&[]) };
|
unsafe { STUB_ISIZE.call(&[], &timer) };
|
||||||
let cold = timer.elapsed();
|
let cold = timer.elapsed();
|
||||||
let hot = performer::get_avg_runt(u16::MAX.into(), || unsafe {
|
let hot = performer::get_avg_runt(u16::MAX.into(), || unsafe {
|
||||||
STUB_ISIZE.call(&[]);
|
STUB_ISIZE.call_notimer(&[]);
|
||||||
});
|
});
|
||||||
|
|
||||||
(cold, hot)
|
(cold, hot)
|
||||||
|
|||||||
Reference in New Issue
Block a user