伟大的进化! "伤齿龙"动态申请释放内存完成!!!

ch4
zhangxinyu 2 years ago
parent 7fcb653679
commit 1719976696

@ -155,8 +155,8 @@ impl MapArea {
// 当前段, 缩小到新的结束位置, 即把new_end后面的页, 都还给物理页帧管理器, 并取消映射(通过unmap_one方法即可) // 当前段, 缩小到新的结束位置, 即把new_end后面的页, 都还给物理页帧管理器, 并取消映射(通过unmap_one方法即可)
pub fn shrink_to(&mut self, page_table: &mut PageTable, new_end: VirtPageNum) { pub fn shrink_to(&mut self, page_table: &mut PageTable, new_end: VirtPageNum) {
let tmp_vpn_range = VPNRange{ let tmp_vpn_range = VPNRange{
l: self.vpn_range.l, l: new_end,
r: new_end, r: self.vpn_range.r,
}; };
for vpn in tmp_vpn_range { for vpn in tmp_vpn_range {
self.unmap_one(page_table, vpn) self.unmap_one(page_table, vpn)

@ -20,7 +20,7 @@ pub fn sys_get_time() -> isize {
get_time_ms() as isize get_time_ms() as isize
} }
// 根据传入的 size 对当前堆进行扩容和缩小 // 根据传入的 size 对当前堆进行扩容和缩小, 返回值为 失败 或者 申请的空间的起始位置
pub fn sys_sbrk(size: i32) -> isize { pub fn sys_sbrk(size: i32) -> isize {
if let Some(old_brk) = change_program_brk(size) { if let Some(old_brk) = change_program_brk(size) {
old_brk as isize old_brk as isize

@ -1,6 +1,7 @@
use crate::config::{kernel_stack_position, TRAP_CONTEXT}; use crate::config::{kernel_stack_position, TRAP_CONTEXT};
use crate::mm::address::{PhysPageNum, VirtAddr}; use crate::mm::address::{PhysPageNum, VirtAddr};
use crate::mm::memory_set::{KERNEL_SPACE, MapPermission, MemorySet}; use crate::mm::memory_set::{KERNEL_SPACE, MapPermission, MemorySet};
use crate::println;
use crate::task::context::{TaskContext}; use crate::task::context::{TaskContext};
use crate::trap::{trap_handler, TrapContext}; use crate::trap::{trap_handler, TrapContext};
@ -117,7 +118,7 @@ impl TaskControlBlock {
self.memory_set self.memory_set
.append_to(VirtAddr(self.heap_bottom), VirtAddr(new_brk as usize)) .append_to(VirtAddr(self.heap_bottom), VirtAddr(new_brk as usize))
}; };
println!("size: {}, old_break: {}", size, old_break);
// 如果成功就把新的堆顶的地址, 复制到结构提上记录, 并把旧的堆顶返回 // 如果成功就把新的堆顶的地址, 复制到结构提上记录, 并把旧的堆顶返回
if result { if result {
self.program_brk = new_brk as usize; self.program_brk = new_brk as usize;

@ -7,12 +7,13 @@ use core::ptr::{null_mut, read_volatile};
#[no_mangle] #[no_mangle]
fn main() -> i32 { fn main() -> i32 {
return 0; println!("\nload_fault APP running...\n");
// println!("\nload_fault APP running...\n"); // 在Test load_fault中我们将插入一个无效的加载操作
// println!("Into Test load_fault, we will insert an invalid load operation..."); println!("Into Test load_fault, we will insert an invalid load operation...");
// println!("Kernel should kill this application!"); // 内核应该终止这个应用程序!
// unsafe { println!("Kernel should kill this application!");
// let _i = read_volatile(null_mut::<u8>()); unsafe {
// } let _i = read_volatile(null_mut::<u8>());
// 0 }
0
} }

@ -5,12 +5,13 @@ use user_lib::*;
#[no_mangle] #[no_mangle]
fn main() -> i32 { fn main() -> i32 {
return 0; println!("\nstore_fault APP running...\n");
// println!("\nload_fault APP running...\n"); // 在Test store_fault中我们将插入一个无效的存储操作…
// println!("Into Test load_fault, we will insert an invalid load operation..."); println!("Into Test store_fault, we will insert an invalid store operation...");
// println!("Kernel should kill this application!");
// unsafe { println!("Kernel should kill this application!");
// let _i = read_volatile(null_mut::<u8>()); unsafe {
// } null_mut::<u8>().write_volatile(1);
// 0 }
0
} }

@ -3,44 +3,63 @@
use core::ptr::slice_from_raw_parts_mut; use core::ptr::slice_from_raw_parts_mut;
use user_lib::*; use user_lib::*;
use user_lib::syscall::sys_sbrk;
#[no_mangle] #[no_mangle]
fn main() -> i32 { fn main() -> i32 {
return 0; println!("Test sbrk start.");
// println!("Test sbrk start.");
// const PAGE_SIZE: usize = 0x1000; // 设置申请颗粒度
// let origin_brk = sbrk(0); const PAGE_SIZE: usize = 0x1000;
// println!("origin break point = {:x}", origin_brk);
// let brk = sbrk(PAGE_SIZE as i32); // 查看当前堆 end
// if brk != origin_brk { let origin_brk = sys_sbrk(0);
// return -1; println!("origin break point = {:x}", origin_brk);
// }
// let brk = sbrk(0); // 申请一页
// println!("one page allocated, break point = {:x}", brk); let brk = sys_sbrk(PAGE_SIZE as i32);
// println!("try write to allocated page"); if brk != origin_brk {
// let new_page = unsafe { return -1;
// &mut *slice_from_raw_parts_mut(origin_brk as usize as *const u8 as *mut u8, PAGE_SIZE) }
// };
// for pos in 0..PAGE_SIZE { // 申请一页之后 查看堆 end
// new_page[pos] = 1; let brk = sys_sbrk(0);
// } println!("one page allocated, break point = {:x}", brk);
// println!("write ok"); println!("try write to allocated page");
// sbrk(PAGE_SIZE as i32 * 10);
// let brk = sbrk(0); // 得到 申请的堆 的字节数组, 并写入为1
// println!("10 page allocated, break point = {:x}", brk); let new_page = unsafe {
// sbrk(PAGE_SIZE as i32 * -11); &mut *slice_from_raw_parts_mut(origin_brk as usize as *const u8 as *mut u8, PAGE_SIZE)
// let brk = sbrk(0); };
// println!("11 page DEALLOCATED, break point = {:x}", brk); for pos in 0..PAGE_SIZE {
// println!("try DEALLOCATED more one page, should be failed."); new_page[pos] = 1;
// let ret = sbrk(PAGE_SIZE as i32 * -1); }
// if ret != -1 { println!("write ok");
// println!("Test sbrk failed!");
// return -1; // 再申请10页内存 并得到当前 堆end
// } sys_sbrk(PAGE_SIZE as i32 * 10);
// println!("Test sbrk almost OK!"); let brk = sys_sbrk(0);
// println!("now write to deallocated page, should cause page fault."); println!("10 page allocated, break point = {:x}", brk);
// for pos in 0..PAGE_SIZE {
// new_page[pos] = 2; // 释放 11页(之前已经申请了 1 + 10页了)
// } sys_sbrk(PAGE_SIZE as i32 * -11);
// 0 let brk = sys_sbrk(0);
println!("11 page DEALLOCATED, break point = {:x}", brk);
println!("try DEALLOCATED more one page, should be failed.");
// 继续释放1页, 非法释放的测试
let ret = sys_sbrk(PAGE_SIZE as i32 * -1);
if ret != -1 {
println!("Test sbrk failed!");
return -1;
}
println!("Test sbrk almost OK!");
println!("now write to deallocated page, should cause page fault.");
for pos in 0..PAGE_SIZE {
new_page[pos] = 2;
}
println!("{:?}", new_page);
// 不应该走到这里
0
} }

@ -4,6 +4,7 @@ const SYSCALL_WRITE: usize = 64;
const SYSCALL_EXIT: usize = 93; const SYSCALL_EXIT: usize = 93;
const SYSCALL_YIELD: usize = 124; const SYSCALL_YIELD: usize = 124;
const SYSCALL_GET_TIME: usize = 169; const SYSCALL_GET_TIME: usize = 169;
const SYSCALL_SBRK: usize = 214;
fn syscall(id: usize, args: [usize; 3]) -> isize { fn syscall(id: usize, args: [usize; 3]) -> isize {
@ -38,4 +39,8 @@ pub fn sys_get_time() -> isize {
syscall(SYSCALL_GET_TIME, [0, 0, 0]) syscall(SYSCALL_GET_TIME, [0, 0, 0])
} }
pub fn sys_sbrk(size: i32) -> isize {
syscall(SYSCALL_SBRK, [size as usize, 0, 0])
}

Loading…
Cancel
Save