Better deallocation

This commit is contained in:
August 2025-09-30 15:17:41 -04:00
parent b93f707b0b
commit 9646f7de8b
Signed by: shibedrill
GPG Key ID: 5FE0CB25945EFAA2
2 changed files with 44 additions and 19 deletions

View File

@ -38,5 +38,3 @@ pub fn log_modules() {
log_trace!("{log_msg}") log_trace!("{log_msg}")
} }
} }
// TODO: make initramfs a lazy static somehow?

View File

@ -1,10 +1,13 @@
// Copyright (c) 2025 shibedrill // Copyright (c) 2025 shibedrill
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
use crate::boot::modules::MODULE_RESPONSE;
use crate::boot::params::EXECUTABLE_FILE_RESPONSE;
use crate::constants::NEWLINE; use crate::constants::NEWLINE;
use crate::{LOGGER, LogLevel, format, log_info, log_trace}; use crate::{LOGGER, LogLevel, format, log_info, log_trace};
use alloc::string::String; use alloc::string::String;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use limine::response::MemoryMapResponse;
use limine::{ use limine::{
memory_map::EntryType, memory_map::EntryType,
request::{ExecutableAddressRequest, HhdmRequest, MemoryMapRequest, PagingModeRequest}, request::{ExecutableAddressRequest, HhdmRequest, MemoryMapRequest, PagingModeRequest},
@ -12,25 +15,45 @@ use limine::{
}; };
use spin::Mutex; use spin::Mutex;
use talc::*; use talc::*;
use free_list::{FreeList, PageRange, PAGE_SIZE}; use free_list::{AllocError, FreeList, PageRange, PAGE_SIZE};
pub extern crate alloc; pub extern crate alloc;
static FREELIST: Mutex<FreeList<32>> = Mutex::new(FreeList::<32>::new()); static FREELIST: Mutex<FreeList<32>> = Mutex::new(FreeList::<32>::new());
lazy_static! {
pub static ref MEMMAP_RESPONSE: &'static MemoryMapResponse = MEMMAP_REQUEST.get_response().expect("Bootloader did not supply memory map");
}
pub fn deallocate_usable() -> Result<(), AllocError> {
init_statics();
let mut bytes_deallocated: u64 = 0;
for entry in MEMMAP_RESPONSE.entries() {
if (entry.entry_type == EntryType::USABLE) | (entry.entry_type == EntryType::BOOTLOADER_RECLAIMABLE) {
deallocate(**entry)?;
bytes_deallocated += entry.length;
}
}
log_trace!("Deallocated 0x{:x} bytes", bytes_deallocated);
Ok(())
}
pub fn deallocate(entry: limine::memory_map::Entry) -> Result<(), AllocError> {
let range = PageRange::from_start_len(entry.base as usize, entry.length as usize).expect("Could not convert map entry to range!");
unsafe {
FREELIST.lock().deallocate(range)
}
}
pub fn log_memory() { pub fn log_memory() {
// Panic if this is absent. It's needed to set up the GDT and paging if !MEMMAP_RESPONSE.entries().is_empty() {
let mmap_response = MEMMAP_REQUEST
.get_response()
.expect("Bootloader did not supply memory map");
log_info!("Memory map received");
if !mmap_response.entries().is_empty() {
let mut log_msg: String = String::from("Memory map:"); let mut log_msg: String = String::from("Memory map:");
let mut usable: u64 = 0; let mut usable: u64 = 0;
let mut reclaimable: u64 = 0; let mut reclaimable: u64 = 0;
let mut hardware: u64 = 0; let mut hardware: u64 = 0;
let mut unusable: u64 = 0; let mut unusable: u64 = 0;
for entry in mmap_response.entries() { for entry in MEMMAP_RESPONSE.entries() {
log_msg.push_str(&format!( log_msg.push_str(&format!(
"{NEWLINE}\t0x{:x} bytes ({} pages) @ 0x{:x}: {}", "{NEWLINE}\t0x{:x} bytes ({} pages) @ 0x{:x}: {}",
entry.length, entry.length,
@ -68,14 +91,6 @@ pub fn log_memory() {
} }
EntryType::USABLE => { EntryType::USABLE => {
usable += entry.length; usable += entry.length;
let range = PageRange::from_start_len(entry.base as usize, entry.length as usize).expect("Could not convert map entry to range!");
let dealloc_result = unsafe {
FREELIST.lock().deallocate(range)
};
match dealloc_result {
Err(e) => log_warning!("Could not deallocate free memory at {}: {}", range, e),
Ok(_) => log_trace!("Deallocated free memory at {}", range),
}
"usable" "usable"
} }
_ => "unidentified", _ => "unidentified",
@ -88,10 +103,14 @@ pub fn log_memory() {
"Memory report: {NEWLINE}\tFree: 0x{usable:x}{NEWLINE}\tAvailable: 0x{reclaimable:x}{NEWLINE}\tUsable: 0x{:x}{NEWLINE}\tHardware: 0x{hardware:x}{NEWLINE}\tUnusable: 0x{unusable:x}{NEWLINE}\tTotal: 0x{total:x}", "Memory report: {NEWLINE}\tFree: 0x{usable:x}{NEWLINE}\tAvailable: 0x{reclaimable:x}{NEWLINE}\tUsable: 0x{:x}{NEWLINE}\tHardware: 0x{hardware:x}{NEWLINE}\tUnusable: 0x{unusable:x}{NEWLINE}\tTotal: 0x{total:x}",
usable + reclaimable, usable + reclaimable,
); );
log_trace!("Deallocating available memory...");
let _ = deallocate_usable();
let free_bytes = { FREELIST.lock().free_space() };
log_info!("Freelist: 0x{:x} bytes ({} pages)", free_bytes, free_bytes / PAGE_SIZE);
} else { } else {
panic!("Memory map contains no entries"); panic!("Memory map contains no entries");
} }
log_info!("Freelist info: 0x{:x} bytes of memory deallocated", FREELIST.lock().free_space());
} }
pub fn log_address() { pub fn log_address() {
@ -110,6 +129,14 @@ pub fn log_address() {
); );
} }
fn init_statics() {
let _ = EXECUTABLE_FILE_RESPONSE;
let _ = HHDM_RESPONSE;
let _ = MODULE_RESPONSE;
let _ = MEMMAP_RESPONSE;
crate::device::init_statics();
}
#[used] #[used]
#[unsafe(link_section = ".requests")] #[unsafe(link_section = ".requests")]
pub static PAGING_REQUEST: PagingModeRequest = limine::request::PagingModeRequest::new(); pub static PAGING_REQUEST: PagingModeRequest = limine::request::PagingModeRequest::new();