pub(crate) const DEFAULT_L2_CACHE_BYTES: usize = 256 * 1024;
pub(crate) fn detect_l2_cache_bytes() -> Option<usize> {
#[cfg(target_os = "linux")]
{
detect_l2_cache_linux()
}
#[cfg(target_os = "macos")]
{
detect_l2_cache_macos()
}
#[cfg(not(any(target_os = "linux", target_os = "macos")))]
{
None
}
}
#[cfg(target_os = "linux")]
fn detect_l2_cache_linux() -> Option<usize> {
let content = std::fs::read_to_string("/sys/devices/system/cpu/cpu0/cache/index2/size").ok()?;
parse_cache_size(&content)
}
#[cfg(target_os = "macos")]
fn detect_l2_cache_macos() -> Option<usize> {
let output = std::process::Command::new("sysctl")
.arg("-n")
.arg("hw.l2cachesize")
.output()
.ok()?;
let s = String::from_utf8(output.stdout).ok()?;
let val = s.trim().parse::<usize>().ok()?;
if val > 0 { Some(val) } else { None }
}
fn parse_cache_size(s: &str) -> Option<usize> {
let s = s.trim();
if let Some(k) = s.strip_suffix('K') {
k.parse::<usize>().ok().map(|v| v * 1024)
} else if let Some(m) = s.strip_suffix('M') {
m.parse::<usize>().ok().map(|v| v * 1024 * 1024)
} else {
s.parse().ok()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_cache_size_kb() {
assert_eq!(parse_cache_size("32K"), Some(32 * 1024));
assert_eq!(parse_cache_size("256K\n"), Some(256 * 1024));
assert_eq!(parse_cache_size("1024K"), Some(1024 * 1024));
}
#[test]
fn test_parse_cache_size_mb() {
assert_eq!(parse_cache_size("1M"), Some(1024 * 1024));
assert_eq!(parse_cache_size("8M"), Some(8 * 1024 * 1024));
}
#[test]
fn test_parse_cache_size_raw() {
assert_eq!(parse_cache_size("262144"), Some(262144));
assert_eq!(parse_cache_size("0"), Some(0));
}
#[test]
fn test_parse_cache_size_invalid() {
assert_eq!(parse_cache_size("abc"), None);
assert_eq!(parse_cache_size(""), None);
}
#[test]
fn test_detect_returns_something() {
let _ = detect_l2_cache_bytes();
}
#[cfg(target_os = "linux")]
#[test]
fn test_detect_linux_returns_value() {
if let Some(bytes) = detect_l2_cache_linux() {
assert!(bytes >= 1024, "L2 cache too small: {bytes}");
}
}
#[cfg(target_os = "macos")]
#[test]
fn test_detect_macos_returns_value() {
if let Some(bytes) = detect_l2_cache_macos() {
assert!(bytes >= 1024, "L2 cache too small: {bytes}");
}
}
}