hardware 0.0.9

A no_std bare-metal hardware abstraction layer — all port I/O, memory and swap allocations are guarded at runtime. Do not consider this dependency stable before x.1.x
Documentation
use crate::common::once::OnceCopy;

#[derive(Copy, Clone)]
pub struct MemoryInfo {
    pub total_bytes: u64,
    pub free_bytes: u64,
    pub available_bytes: u64,
    pub swap_total_bytes: u64,
    pub swap_free_bytes: u64,
}

pub type DetectMemoryFn = fn() -> Option<MemoryInfo>;

static DETECT_FN: OnceCopy<DetectMemoryFn> = OnceCopy::new();

pub fn set_detect_memory_fn(f: DetectMemoryFn) {
    DETECT_FN.set(f);
}

pub fn detect_memory_info() -> Option<MemoryInfo> {
    if let Some(f) = DETECT_FN.get() {
        return f();
    }
    detect_memory_native()
}

#[repr(C)]
struct Sysinfo {
    uptime: i64,
    loads: [u64; 3],
    totalram: u64,
    freeram: u64,
    sharedram: u64,
    bufferram: u64,
    totalswap: u64,
    freeswap: u64,
    procs: u16,
    _pad: u16,
    _pad2: u32,
    totalhigh: u64,
    freehigh: u64,
    mem_unit: u32,
}

fn detect_memory_native() -> Option<MemoryInfo> {
    let nr_sysinfo = crate::arch::shim::nr_sysinfo();
    if nr_sysinfo == crate::common::error::ERR_NOT_IMPLEMENTED {
        return None;
    }

    let mut info = Sysinfo {
        uptime: 0,
        loads: [0; 3],
        totalram: 0,
        freeram: 0,
        sharedram: 0,
        bufferram: 0,
        totalswap: 0,
        freeswap: 0,
        procs: 0,
        _pad: 0,
        _pad2: 0,
        totalhigh: 0,
        freehigh: 0,
        mem_unit: 0,
    };

    let ret = unsafe {
        crate::sys::arch::shim::raw_syscall(
            nr_sysinfo,
            &mut info as *mut Sysinfo as u64,
            0,
            0,
            0,
            0,
            0,
        )
    };
    if ret < 0 {
        return None;
    }

    let unit = if info.mem_unit == 0 {
        1u64
    } else {
        info.mem_unit as u64
    };
    Some(MemoryInfo {
        total_bytes: info.totalram * unit,
        free_bytes: info.freeram * unit,
        available_bytes: info.freeram * unit,
        swap_total_bytes: info.totalswap * unit,
        swap_free_bytes: info.freeswap * unit,
    })
}