diff --git a/src/allocation.rs b/src/allocation.rs index 68a72e2..151d55e 100644 --- a/src/allocation.rs +++ b/src/allocation.rs @@ -36,6 +36,7 @@ pub fn init() { unsafe { sys::init_heap(); MAIN_SECTOR = sys::alloc(PAGE_SIZE) as usize; + core::ptr::write_bytes(MAIN_SECTOR as *mut u8, 0, PAGE_SIZE); // make sector table start clean } } } @@ -47,14 +48,14 @@ pub fn malloc(size: usize) -> *mut u8 { if (addr as usize) != 0 { let sec = addr; - let mut hdr = *(addr as *const SectorHeader); + let hdr = &mut *(addr as *mut SectorHeader); let sec_start_blocks = (sec as usize) + size_of::(); if hdr.size_left >= size { let mut j = sec_start_blocks; let mut first_found_block_addr = 0; while j <= sec_start_blocks + hdr.size { - let mut block = *(j as *const BlockHeader); + let block = &mut *(j as *mut BlockHeader); match block.sign { Sign::Active => { // If block is occupated - pass @@ -63,7 +64,7 @@ pub fn malloc(size: usize) -> *mut u8 { } Sign::Free => { - if first_found_block_addr != 0 { + if first_found_block_addr == 0 { first_found_block_addr = j; } @@ -73,26 +74,32 @@ pub fn malloc(size: usize) -> *mut u8 { j += (size_of::()) + block.size; } else if size - sum_size < size_of::() { // Create 2 blocks - let mut main_block = - *(first_found_block_addr as *const BlockHeader); + let main_block = + &mut *(first_found_block_addr as *mut BlockHeader); main_block.sign = Sign::Active; main_block.size = size; - let mut secondary_block = *(first_found_block_addr - as *const BlockHeader) - .add(size_of::() + size); - secondary_block.sign = Sign::Free; - secondary_block.size = + let secondary_block = (first_found_block_addr + + size_of::() + + size) + as *mut BlockHeader; + (*secondary_block).sign = Sign::Free; + (*secondary_block).size = sum_size - size - size_of::(); + hdr.size_left -= size + size_of::(); + return (first_found_block_addr as *mut u8) .add(size_of::()); } else { // Create 1 block - let mut main_block = - *(first_found_block_addr as *const BlockHeader); + let main_block = + &mut *(first_found_block_addr as *mut BlockHeader); main_block.sign = Sign::Active; main_block.size = sum_size - size_of::(); + + hdr.size_left -= main_block.size + size_of::(); + return (first_found_block_addr as *mut u8) .add(size_of::()); } @@ -117,9 +124,11 @@ pub fn malloc(size: usize) -> *mut u8 { } } } else { - let sec_size = size + PAGE_SIZE - size % PAGE_SIZE; + // round requested size up to whole pages + let sec_size = (size + PAGE_SIZE - 1) & !(PAGE_SIZE - 1); let new_sec = sys::alloc(sec_size); let sec_hdr = new_sec as *mut SectorHeader; + *((MAIN_SECTOR + i * 4) as *mut u32) = new_sec as u32; // remember this sector in the table *sec_hdr = SectorHeader { size: sec_size, size_left: sec_size - size_of::(), @@ -138,26 +147,26 @@ pub fn malloc(size: usize) -> *mut u8 { fn free(block: *const u8) { unsafe { - let mut block_hdr = *(block.sub(size_of::()) as *mut BlockHeader); + let block_hdr = &mut *(block.sub(size_of::()) as *mut BlockHeader); for i in 0..PAGE_SIZE / 4 { let addr = *((MAIN_SECTOR + i * 4) as *const u32) as *const u8; - let mut hdr = *(addr as *const SectorHeader); + if addr.is_null() { + continue; + } + let hdr = &mut *(addr as *mut SectorHeader); if addr < block && (block as usize) < (addr as usize) + hdr.size { - hdr.size_left += block_hdr.size; + hdr.size_left += block_hdr.size + size_of::(); if hdr.size_left == hdr.size - size_of::() { - free(addr) + sys::free(addr); // whole sector is free, hand it back to OS + *((MAIN_SECTOR + i * 4) as *mut u32) = 0; // and drop from the table } else { block_hdr.sign = Sign::Free; } break; } } - - if !sys::free(block) { - panic!("Free failed"); - } } } @@ -181,4 +190,4 @@ unsafe impl alloc::alloc::GlobalAlloc for GlobalAlloc { } #[global_allocator] -static ALLOC: GlobalAlloc = GlobalAlloc; +static ALLOC: GlobalAlloc = GlobalAlloc; \ No newline at end of file