mirror of
https://github.com/Cuprate/cuprate.git
synced 2024-12-22 19:49:28 +00:00
6502729d8c
* cargo.toml: add `allow_attributes` lint * fix lints * fixes * fmt * fix docs * fix docs * fix expect msg
101 lines
3.2 KiB
Rust
101 lines
3.2 KiB
Rust
//! System thread related
|
||
//!
|
||
//! Requires `std`.
|
||
|
||
//---------------------------------------------------------------------------------------------------- Use
|
||
use std::{cmp::max, num::NonZeroUsize};
|
||
|
||
//---------------------------------------------------------------------------------------------------- Thread Count & Percent
|
||
/// Get the total amount of system threads.
|
||
///
|
||
/// ```rust
|
||
/// # use cuprate_helper::thread::*;
|
||
/// assert!(threads().get() >= 1);
|
||
/// ```
|
||
pub fn threads() -> NonZeroUsize {
|
||
std::thread::available_parallelism().unwrap_or(NonZeroUsize::MIN)
|
||
}
|
||
|
||
// Implement a function for the various
|
||
// `x` thread-percent functions below.
|
||
macro_rules! impl_thread_percent {
|
||
($(
|
||
$(#[$doc:meta])*
|
||
$fn_name:ident => // Name of the function
|
||
$percent:literal // The target percent of threads
|
||
),* $(,)?) => {
|
||
$(
|
||
$(#[$doc])*
|
||
pub fn $fn_name() -> NonZeroUsize {
|
||
// unwrap here is okay because:
|
||
// - THREADS().get() is always non-zero
|
||
// - max() guards against 0
|
||
#[expect(
|
||
clippy::cast_possible_truncation,
|
||
clippy::cast_sign_loss,
|
||
clippy::cast_precision_loss,
|
||
reason = "we need to round integers"
|
||
)]
|
||
NonZeroUsize::new(max(1, (threads().get() as f64 * $percent).floor() as usize)).unwrap()
|
||
}
|
||
)*
|
||
}
|
||
}
|
||
impl_thread_percent! {
|
||
/// Get 90% (rounded down) of available amount of system threads.
|
||
threads_90 => 0.90,
|
||
/// Get 75% (rounded down) of available amount of system threads.
|
||
threads_75 => 0.75,
|
||
/// Get 50% (rounded down) of available amount of system threads.
|
||
threads_50 => 0.50,
|
||
/// Get 25% (rounded down) of available amount of system threads.
|
||
threads_25 => 0.25,
|
||
/// Get 10% (rounded down) of available amount of system threads.
|
||
threads_10 => 0.10,
|
||
}
|
||
|
||
//---------------------------------------------------------------------------------------------------- Thread Priority
|
||
/// Low Priority Thread
|
||
///
|
||
/// Sets the calling thread’s priority to the lowest platform-specific value possible.
|
||
///
|
||
/// Originally from <https://docs.rs/lpt>.
|
||
///
|
||
/// # Windows
|
||
/// Uses `SetThreadPriority()` with `THREAD_PRIORITY_IDLE` (-15).
|
||
///
|
||
/// # Unix
|
||
/// Uses `libc::nice()` with the max nice level.
|
||
///
|
||
/// On macOS and *BSD: +20
|
||
/// On Linux: +19
|
||
pub fn low_priority_thread() {
|
||
#[cfg(target_os = "windows")]
|
||
{
|
||
use target_os_lib as windows;
|
||
use windows::Win32::System::Threading::*;
|
||
|
||
// SAFETY: calling C.
|
||
// We are _lowering_ our priority, not increasing, so this function should never fail.
|
||
unsafe {
|
||
drop(SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE));
|
||
}
|
||
}
|
||
|
||
#[cfg(target_family = "unix")]
|
||
{
|
||
use target_os_lib as libc;
|
||
|
||
const NICE_MAX: libc::c_int = if cfg!(target_os = "linux") { 19 } else { 20 };
|
||
|
||
// SAFETY: calling C.
|
||
// We are _lowering_ our priority, not increasing, so this function should never fail.
|
||
unsafe {
|
||
libc::nice(NICE_MAX);
|
||
}
|
||
}
|
||
}
|
||
|
||
//---------------------------------------------------------------------------------------------------- TESTS
|
||
#[cfg(test)]
|
||
mod tests {}
|