From ac2e60f8913f5d262065d094275e3334caf78146 Mon Sep 17 00:00:00 2001 From: Smallorange666 <141314494+Smallorange666@users.noreply.github.com> Date: Wed, 5 Jun 2024 03:42:27 +0800 Subject: [PATCH] Lab/7 (#36) --- docs/labs/0x07/tasks.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/docs/labs/0x07/tasks.md b/docs/labs/0x07/tasks.md index 5e48fdb..0c7b5ca 100644 --- a/docs/labs/0x07/tasks.md +++ b/docs/labs/0x07/tasks.md @@ -35,7 +35,7 @@ 迭代器是懒惰的,只有在需要时才会进行计算,因此在进行逐帧分配时,并没有额外的内存开销。但是,当需要进行内存回收时,就需要额外的数据结构来记录已经分配的帧,以便进行再次分配。 -相对于真实的操作系统,本实验中的内存回收是很激进的:即能回收时就回收,不考虑回收对性能的影响。在实际的操作系统中,内存回收是一个复杂的问题,需要考虑到内存的碎片化、内存的使用情况、页面的大小等细节;进而使用标记清除、分段等策略来减缓内存回收等频率和碎片化。 +相对于真实的操作系统,本实验中的内存回收是很激进的:即能回收时就回收,不考虑回收对性能的影响。在实际的操作系统中,内存回收是一个复杂的问题,需要考虑到内存的碎片化、内存的使用情况、页面的大小等细节;进而使用标记清除、分段等策略来减少内存回收的频率和碎片化。 因此对于本实验的帧分配器来说,内存回收的操作是非常简单的,只需要**将已经分配的帧重新加入到可用帧的集合中即可**。 @@ -206,7 +206,7 @@ mysql 1820 0.1 10.5 1750680 365696 ? Sl Apr22 75:39 /url/bin/my 在目前的实现(Lab 3)中,用户程序在进程结构体中记录的内存区域只有栈区,堆区由内核进行代劳,同时 ELF 文件映射的内存区域也从来没有被释放过,无法被其他程序复用。 -而相较于 Linux,本实验的并没有将内存管理抽象为具有上述复杂功能的结构:用户程序的内存占用严格等同于其虚拟内存大小,并且所有页面都会被加载到物理内存中,不存在文件映射等概念,只有堆内存和栈内存是可变的。 +而相较于 Linux,本实验并没有将内存管理抽象为具有上述复杂功能的结构:用户程序的内存占用严格等同于其虚拟内存大小,并且所有页面都会被加载到物理内存中,不存在文件映射等概念,只有堆内存和栈内存是可变的。 因此,其内存统计并没有那么多的细节,只需要统计用户程序的栈区和堆区的大小即可。在 `Stack` 和 `Heap` 中,已经实现了 `memory_usage` 函数来获取栈区和堆区的内存占用字节数。 @@ -448,7 +448,7 @@ pub fn using_count(&self) -> usize { ```rust impl Stack { - fn clean_up( + pub fn clean_up( &mut self, // following types are defined in // `pkg/kernel/src/proc/vm/mod.rs` @@ -776,11 +776,10 @@ pub struct Heap { 下面对 `brk` 系统调用的参数和行为进行简单的约定: -- `brk` 系统调用的参数是一个可为 `NULL` 的指针,表示用户程序希望调整的堆区结束地址; -- 如果参数为 `NULL`,则表示用户程序希望获取当前的堆区结束地址,即返回 `end` 的值; -- 在系统调用的实现时,用户参数采用 `0` 表示 `NULL`,返回值采用 `-1` 表示失败; -- 在内核内部处理时,参数使用 `Option` 进行传递,`None` 表示用户程序传入的参数为 `NULL`;`brk` 的返回值也为 `Option`,表示内核调整后的堆区结束地址,如果调整失败则返回 `None`; -- 如果用户程序传入的参数不为 `NULL`,则检查用户传入的地址是否合法,即在 `[HEAP_START, HEAP_END]` 区间内,如果不合法则返回 `None`。 +- 用户态下,传递给 `sys_brk` 函数的参数是一个 `Option` 。若参数为 `None` ,表示用户程序希望获取当前的堆区结束地址,即返回 `end` 的值;若参数为 `Some(addr)` ,表示用户程序希望将堆区结束地址调整到 `addr`; +- `sys_brk` 函数中,若传来的参数为 `None` ,变成 `0` 后传递给 `syscall!`,`syscall!` 的返回值为 `-1` 时表示调整失败; +- 内核态下,将拿到的 `usize` 参数重新变为 `Option` 进行传递;`brk` 的返回值也为 `Option`,如果为 `None` 表示调整失败,否则表示内核调整后的堆区结束地址; +- 如果用户程序传入的参数不为 `None`,则检查用户传入的地址是否合法,即是否在 `[HEAP_START, HEAP_END]` 区间内,如果不合法则返回 `None`。 根据上述约定,给出用户态的系统调用函数: