78 lines
2.0 KiB
Rust
78 lines
2.0 KiB
Rust
use types::address::{PhysicalAddress, VirtualAddress};
|
|
use types::id::ProcessId;
|
|
|
|
use crate::error::KernelError;
|
|
|
|
const USER_HEAP_START: usize = 0x40000;
|
|
const PAGE_SIZE: usize = 4096;
|
|
const MAX_ALLOCATIONS: usize = 16;
|
|
|
|
pub struct ProcessMemory {
|
|
process: ProcessId,
|
|
page_count: usize,
|
|
limit: usize,
|
|
next_heap_va: usize,
|
|
allocations: [(PhysicalAddress, usize); MAX_ALLOCATIONS],
|
|
alloc_count: usize,
|
|
}
|
|
|
|
impl ProcessMemory {
|
|
pub const DEFAULT_PAGE_LIMIT: usize = 1024;
|
|
|
|
pub fn new(process: ProcessId, limit: usize) -> Self {
|
|
Self {
|
|
process,
|
|
page_count: 0,
|
|
limit,
|
|
next_heap_va: USER_HEAP_START,
|
|
allocations: [(PhysicalAddress::from_raw(0), 0); MAX_ALLOCATIONS],
|
|
alloc_count: 0,
|
|
}
|
|
}
|
|
|
|
pub fn alloc_user_va(&mut self, pages: usize) -> VirtualAddress {
|
|
let va = self.next_heap_va;
|
|
self.next_heap_va += pages * PAGE_SIZE;
|
|
VirtualAddress::from_raw(va)
|
|
}
|
|
|
|
pub fn record_allocation(&mut self, pa: PhysicalAddress, count: usize) {
|
|
if self.alloc_count < MAX_ALLOCATIONS {
|
|
self.allocations[self.alloc_count] = (pa, count);
|
|
self.alloc_count += 1;
|
|
}
|
|
}
|
|
|
|
pub fn allocations(&self) -> &[(PhysicalAddress, usize)] {
|
|
&self.allocations[..self.alloc_count]
|
|
}
|
|
|
|
pub fn process(&self) -> ProcessId {
|
|
self.process
|
|
}
|
|
|
|
pub fn page_count(&self) -> usize {
|
|
self.page_count
|
|
}
|
|
|
|
pub fn limit(&self) -> usize {
|
|
self.limit
|
|
}
|
|
|
|
pub fn grant(&mut self, count: usize) -> Result<(), KernelError> {
|
|
if self.page_count + count > self.limit {
|
|
return Err(KernelError::OutOfMemory);
|
|
}
|
|
self.page_count += count;
|
|
Ok(())
|
|
}
|
|
|
|
pub fn release(&mut self, count: usize) -> Result<(), KernelError> {
|
|
if count > self.page_count {
|
|
return Err(KernelError::OutOfMemory);
|
|
}
|
|
self.page_count -= count;
|
|
Ok(())
|
|
}
|
|
}
|