laddu-memory 0.21.4

Amplitude analysis tools for Rust
Documentation
use super::{CapacitySnapshot, ProbeFailure, ProbeOutcome};
use crate::CapacitySource;

pub(super) fn probe(pci_bus_id: &str) -> ProbeOutcome {
    if pci_bus_id.is_empty() {
        return Err(ProbeFailure::MissingIdentity);
    }
    let entries = std::fs::read_dir("/sys/class/drm").map_err(|_| ProbeFailure::Unavailable)?;
    for entry in entries.flatten() {
        let name = entry.file_name();
        if !name.to_string_lossy().starts_with("card") || name.to_string_lossy().contains('-') {
            continue;
        }
        let device = entry.path().join("device");
        let Ok(uevent) = std::fs::read_to_string(device.join("uevent")) else {
            continue;
        };
        let matches_device = uevent.lines().any(|line| {
            line.strip_prefix("PCI_SLOT_NAME=")
                .is_some_and(|slot| slot.eq_ignore_ascii_case(pci_bus_id))
        });
        if !matches_device {
            continue;
        }
        let total = read_sysfs_u64(device.join("mem_info_vram_total"))?;
        let used = read_sysfs_u64(device.join("mem_info_vram_used")).unwrap_or(0);
        return CapacitySnapshot::new(total, total.saturating_sub(used), CapacitySource::Drm);
    }
    Err(ProbeFailure::AdapterMismatch)
}

fn read_sysfs_u64(path: impl AsRef<std::path::Path>) -> Result<u64, ProbeFailure> {
    std::fs::read_to_string(path)
        .map_err(|_| ProbeFailure::Unavailable)?
        .trim()
        .parse()
        .map_err(|_| ProbeFailure::Malformed)
}