这个作业主要是用 unix
系统的 mmap
和 unmap
函数来实现一个任务。
在这个任务里,我们有一个非常大的数组,其容量超过了物理内存的大小,所以内存放不下。其每个元素的值应该是 其下标的平方根值。 我们的目标是使用 unix
系统的 mmap
函数 和 信号处理 来进行按需计算, 即只对使用到的值进行计算。为了不超出物理内存限制,建议只使用一页内存,每当产生缺页,就将之前映射的页 unmap
。
当访问不存在的数组元素时会产生缺页,内核会转移到已注册好的 handle_sigsegv
缺页处理函数执行。所以我们在 handle_sigsegv
中只要在缺页的地址分配一个页,为了为了不超出物理内存限制,还要取消上次分配的页。再将新分配的页中的元素初试化成正确的平方根值即可。
总的来说比较简单,直接放代码:
static void
handle_sigsegv(int sig, siginfo_t *si, void *ctx)
{
// Your code here.
static void* last_page;
// replace these three lines with your implementation
uintptr_t fault_addr = (uintptr_t)si->si_addr;
// printf("oops got SIGSEGV at 0x%lx\n", fault_addr);
// exit(EXIT_FAILURE);
if (last_page)
munmap(last_page, page_size);
last_page = (void*)align_down(fault_addr, page_size);
mmap(last_page, page_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, 0, 0);
calculate_sqrts((double*)last_page, (last_page - (void*)sqrts) / sizeof(double), page_size / sizeof(double));
}
可以看到成功通过。