use super::*;
static CPU_CAPACITY: std::sync::OnceLock<usize> = std::sync::OnceLock::new();
static CPU_GROUPS: std::sync::OnceLock<Vec<pagesift_flow::CpuSet>> = std::sync::OnceLock::new();
pub fn set_cpu_capacity(cpus: usize) {
let _ = CPU_CAPACITY.set(cpus.max(1));
}
pub fn set_cpu_groups(groups: Vec<pagesift_flow::CpuSet>) {
let _ = CPU_GROUPS.set(groups);
}
thread_local! {
pub(super) static CONTENT_WORKSPACE: std::cell::RefCell<pagesift_content::ProcessWorkspace> =
std::cell::RefCell::new(pagesift_content::ProcessWorkspace::default());
}
pub fn pool() -> &'static pagesift_flow::Pool {
static POOL: std::sync::LazyLock<pagesift_flow::Pool> = std::sync::LazyLock::new(|| {
let n = CPU_CAPACITY
.get()
.copied()
.unwrap_or_else(|| std::thread::available_parallelism().map_or(1, |n| n.get()));
let groups = CPU_GROUPS.get().map_or(&[][..], Vec::as_slice);
let pin = (groups.len() > 1).then_some(
pagesift_policy::topology::pin_current_thread_to_set as fn(&[usize]) -> bool,
);
pagesift_flow::Pool::with_groups(n, groups, pin).expect("starting CPU workers")
});
&POOL
}
pub(super) fn install() {
static HOOK: std::sync::Once = std::sync::Once::new();
HOOK.call_once(|| {
pool();
pagesift_net::set_cpu_executor(|job| pool().spawn(job), || pool().round_trip());
});
}
pub(super) async fn cpu_task<T: Send + 'static>(
f: impl FnOnce() -> T + Send + 'static,
) -> Result<T, ApiError> {
pool()
.run(None, f)
.await
.map_err(|e| ApiError::new(ErrorCode::Internal, e.to_string()))
}