irid-std 0.3.1

A replacement for std when running without a filesystem on the irid kernel
Documentation
use core::{alloc::Layout, ptr::null_mut};

use irid_syscall::{io::FileDescriptor, memory::{MemoryFlags, memory_map}};
use spin::Mutex;
use talc::{TalcLock, base::{CHUNK_UNIT, Talc, binning::Binning}, min_first_heap_layout, source::Source};

use crate::eprintln;

#[global_allocator]
static ALLOCATOR: TalcLock<Mutex<()>, PageSource> = TalcLock::new(PageSource);

#[derive(Debug)]
struct PageSource;

unsafe impl Source for PageSource {
    fn acquire<B: Binning>(talc: &mut Talc<Self, B>, layout: Layout) -> Result<(), ()> {
        let mut required_size = layout.pad_to_align().size() + CHUNK_UNIT + CHUNK_UNIT;

        if !talc.is_metadata_established() {
            required_size += min_first_heap_layout::<B>().pad_to_align().size();
        }

        // Round up to nearest number of pages.
        let pages = required_size.div_ceil(0x1000);
        let length = pages * 0x1000;

        let address = unsafe { memory_map(null_mut(), length, MemoryFlags::READABLE | MemoryFlags::WRITEABLE, FileDescriptor::MAX, 0)
            .map_err(|err| {
                eprintln!("allocation error: {err}");

                ()
            }) }?;

        unsafe { talc.claim(address, length).expect("failed to claim") };

        Ok(())
    }
}