use std::cell::Cell;
use std::marker::PhantomData;
use std::ptr::NonNull;
use idakit::prelude::Ida;
pub struct KernelTest {
pub module: &'static str,
pub name: &'static str,
pub isolation: Isolation,
pub should_panic: Option<&'static str>,
pub run: fn(),
}
inventory::collect!(KernelTest);
impl KernelTest {
pub fn case_name(&self) -> String {
let module = self.module.split_once("::").map_or("", |(_, rest)| rest);
if module.is_empty() {
self.name.to_owned()
} else {
format!("{module}::{}", self.name)
}
}
}
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Isolation {
ReadOnly,
Writes,
}
thread_local! {
static WARM: Cell<Option<NonNull<Ida>>> = const { Cell::new(None) };
}
pub fn with_warm_kernel<R>(body: impl FnOnce(&Ida) -> R) -> Option<R> {
let ida = WARM.get()?;
Some(body(unsafe { ida.as_ref() }))
}
pub struct Warm<'a>(PhantomData<&'a Ida>);
impl<'a> Warm<'a> {
pub fn new(ida: &'a Ida) -> Self {
WARM.set(Some(NonNull::from(ida)));
Self(PhantomData)
}
}
impl Drop for Warm<'_> {
fn drop(&mut self) {
WARM.set(None);
}
}