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

ch4
zhangxinyu 12 months ago
parent 7fcb653679
commit 1719976696

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

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

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

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

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

@ -3,44 +3,63 @@
use core::ptr::slice_from_raw_parts_mut;
use user_lib::*;
use user_lib::syscall::sys_sbrk;
#[no_mangle]
fn main() -> i32 {
return 0;
// println!("Test sbrk start.");
// const PAGE_SIZE: usize = 0x1000;
// let origin_brk = sbrk(0);
// println!("origin break point = {:x}", origin_brk);
// let brk = sbrk(PAGE_SIZE as i32);
// if brk != origin_brk {
// return -1;
// }
// let brk = sbrk(0);
// println!("one page allocated, break point = {:x}", brk);
// println!("try write to allocated page");
// let new_page = unsafe {
// &mut *slice_from_raw_parts_mut(origin_brk as usize as *const u8 as *mut u8, PAGE_SIZE)
// };
// for pos in 0..PAGE_SIZE {
// new_page[pos] = 1;
// }
// println!("write ok");
// sbrk(PAGE_SIZE as i32 * 10);
// let brk = sbrk(0);
// println!("10 page allocated, break point = {:x}", brk);
// sbrk(PAGE_SIZE as i32 * -11);
// let brk = sbrk(0);
// println!("11 page DEALLOCATED, break point = {:x}", brk);
// println!("try DEALLOCATED more one page, should be failed.");
// let ret = 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;
// }
// 0
println!("Test sbrk start.");
// 设置申请颗粒度
const PAGE_SIZE: usize = 0x1000;
// 查看当前堆 end
let origin_brk = sys_sbrk(0);
println!("origin break point = {:x}", origin_brk);
// 申请一页
let brk = sys_sbrk(PAGE_SIZE as i32);
if brk != origin_brk {
return -1;
}
// 申请一页之后 查看堆 end
let brk = sys_sbrk(0);
println!("one page allocated, break point = {:x}", brk);
println!("try write to allocated page");
// 得到 申请的堆 的字节数组, 并写入为1
let new_page = unsafe {
&mut *slice_from_raw_parts_mut(origin_brk as usize as *const u8 as *mut u8, PAGE_SIZE)
};
for pos in 0..PAGE_SIZE {
new_page[pos] = 1;
}
println!("write ok");
// 再申请10页内存 并得到当前 堆end
sys_sbrk(PAGE_SIZE as i32 * 10);
let brk = sys_sbrk(0);
println!("10 page allocated, break point = {:x}", brk);
// 释放 11页(之前已经申请了 1 + 10页了)
sys_sbrk(PAGE_SIZE as i32 * -11);
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_YIELD: usize = 124;
const SYSCALL_GET_TIME: usize = 169;
const SYSCALL_SBRK: usize = 214;
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])
}
pub fn sys_sbrk(size: i32) -> isize {
syscall(SYSCALL_SBRK, [size as usize, 0, 0])
}

Loading…
Cancel
Save