Speed up system calls 加速系统调用

有些操作系统会通过在用户空间和内核空间之间共享一些内存来加速系统调用。该实验题目要求在内核中保存一个映射到用户内存空间的结构体,该结构体中保存当前进程的pid以加速pid的获取。

// Look in the process table for an UNUSED proc.
// If found, initialize state required to run in the kernel,
// and return with p->lock held.
// If there are no free procs, or a memory allocation fails, return 0.
static struct proc*
allocproc(void)
{struct proc *p;for(p = proc; p < &proc[NPROC]; p++) {acquire(&p->lock);if(p->state == UNUSED) {goto found;} else {release(&p->lock);}}return 0;found:p->pid = allocpid();p->state = USED;// Allocate a trapframe page.if((p->trapframe = (struct trapframe *)kalloc()) == 0){freeproc(p);release(&p->lock);return 0;}// Allocate a usyscall page.if((p->usyscall = (struct usyscall *)kalloc()) == 0){freeproc(p);release(&p->lock);return 0;}p->usyscall->pid = p->pid;// An empty user page table.p->pagetable = proc_pagetable(p);if(p->pagetable == 0){freeproc(p);release(&p->lock);return 0;}// Set up new context to start executing at forkret,// which returns to user space.memset(&p->context, 0, sizeof(p->context));p->context.ra = (uint64)forkret;p->context.sp = p->kstack + PGSIZE;return p;
}// free a proc structure and the data hanging from it,
// including user pages.
// p->lock must be held.
static void
freeproc(struct proc *p)
{if(p->usyscall) {kfree((void*)p->usyscall);}p->usyscall = 0;if(p->trapframe)kfree((void*)p->trapframe);p->trapframe = 0;if(p->pagetable)proc_freepagetable(p->pagetable, p->sz);p->pagetable = 0;p->sz = 0;p->pid = 0;p->parent = 0;p->name[0] = 0;p->chan = 0;p->killed = 0;p->xstate = 0;p->state = UNUSED;
}// Create a user page table for a given process,
// with no user memory, but with trampoline pages.
pagetable_t
proc_pagetable(struct proc *p)
{pagetable_t pagetable;// An empty page table.pagetable = uvmcreate();if(pagetable == 0)return 0;// map the trampoline code (for system call return)// at the highest user virtual address.// only the supervisor uses it, on the way// to/from user space, so not PTE_U.if(mappages(pagetable, TRAMPOLINE, PGSIZE,(uint64)trampoline, PTE_R | PTE_X) < 0){uvmfree(pagetable, 0);return 0;}// map the trapframe just below TRAMPOLINE, for trampoline.S.if(mappages(pagetable, TRAPFRAME, PGSIZE,(uint64)(p->trapframe), PTE_R | PTE_W) < 0){uvmunmap(pagetable, TRAMPOLINE, 1, 0);uvmfree(pagetable, 0);return 0;}// map the usyscall below trapframeif(mappages(pagetable, USYSCALL, PGSIZE,(uint64)(p->usyscall), PTE_R | PTE_U) < 0){uvmunmap(pagetable, TRAMPOLINE, 1, 0);uvmunmap(pagetable, TRAPFRAME, 1, 0);uvmfree(pagetable, 0);return 0;}return pagetable;
}// Free a process's page table, and free the
// physical memory it refers to.
void
proc_freepagetable(pagetable_t pagetable, uint64 sz)
{uvmunmap(pagetable, TRAMPOLINE, 1, 0);uvmunmap(pagetable, TRAPFRAME, 1, 0);uvmunmap(pagetable, USYSCALL, 1, 0);uvmfree(pagetable, sz);
}

打印页表 Print a page table

// 递归打印页表
void vmprint_search(int depth, pte_t pte, int index) {for(int i = 0; i < depth; i++) {printf(".. ");}pagetable_t pt = (pagetable_t)PTE2PA(pte);printf("%d: pte %p pa %p\n", index, pte, pt);if ((pte & (PTE_R|PTE_W|PTE_X)) != 0) {return;}for (int i = 0; i < 512; i++) {pte = pt[i];if((pte & PTE_V) && (pte & (PTE_R|PTE_W|PTE_X)) == 0) {vmprint_search(depth + 1, pte, i);} else if (pte & PTE_V) {vmprint_search(depth + 1, pte, i);}}
}// print vm.
void vmprint(pagetable_t pagetable)
{printf("page table %p\n", pagetable);// there are 2^9 = 512 PTEs in a page table.for(int i = 0; i < 512; i++){pte_t pte = pagetable[i];if((pte & PTE_V) && (pte & (PTE_R|PTE_W|PTE_X)) == 0){// this PTE points to a lower-level page table.vmprint_search(1, pte, i);}}
}

Detecting which pages have been accessed

Your job is to implement pgaccess(), a system call that reports which pages have been accessed. The system call takes three arguments. First, it takes the starting virtual address of the first user page to check. Second, it takes the number of pages to check. Finally, it takes a user address to a buffer to store the results into a bitmask (a datastructure that uses one bit per page and where the first page corresponds to the least significant bit). You will receive full credit for this part of the lab if the pgaccess test case passes when running pgtbltest.

int
sys_pgaccess(void)
{// lab pgtbl: your code here.uint64 addr;int page_num;uint64 mask_addr;if(argaddr(0, &addr) < 0)return -1;if(argint(1, &page_num) < 0)return -1;if(argaddr(2, &mask_addr) < 0)return -1;struct proc *the_proc = myproc();pagetable_t pt = the_proc->pagetable;uint32 mask = 0;for(int i = 0; i < page_num; i++) {pte_t *pte = walk(pt, addr + i * PGSIZE, 0);if ((*pte & PTE_A)) {mask = mask | (1 << i);*pte = *pte & (~PTE_A);}}copyout(pt, mask_addr, (char*)&mask, sizeof(uint32));return 0;
}

6.S081 Lab3 page tables 页表相关推荐

  1. 6.S081 Lab3 page tables

    6.S081 Lab3 page tables 未完成 文章目录 6.S081 Lab3 page tables 未完成 1. Print a page table ([easy](https://p ...

  2. MIT6.S081 Lab3 Page tables

    lab1.2不是太难,lab 3太变态了,github上记一下代码,源代码地址 :https://github.com/CodePpoi/mit-lab 参考博客 : https://blog.csd ...

  3. MIT6.S081 Lab3: page tables

    Print a page table 接收一个pagetable_t并把它指向的页表打印. 在kernel/def.h中增加函数声明void vmprint(void)并在kernel/vm.c中定义 ...

  4. linux内核学习笔记【一】临时内核页表 Provisional kernel Page Tables

    最近开始学习linux内核,看了<深入理解linux内核>,开始写点学习收获.内核版本为2.6.11 临时全局目录(provisional page global directory)是在 ...

  5. xv6---Lab3: page tables

    目录 参考资料 RISC -V页表的简化图如下所示 ​编辑​ 多级页表 xv6内核页表 3.6 Process Address Space 3.7 Code: Sbrk 3.8 Code: Exec ...

  6. XV6 Lab2:Page Tables

    Lab2:Page Tables 本 lab 的任务是理解 xv6 页表的实现. 参考文章: xv6实验课程–页表(2021) 6.S081-2021FALL-Lab3:pgtbl MIT6.S081 ...

  7. xv6 6.S081 Lab3: alloc

    xv6 6.S081 Lab3: alloc 写在前面 实验介绍 开始! 任务再描述 任务一实现 任务二实现 Buddy Allocator Code Thru 任务二的实现 alloc代码在这里.另 ...

  8. 2020 MIT6.s081 os Lab: page tables

    文章目录 实验链接 Print a page table A kernel page table per process Simplify 实验结果 提交实验 查看结果 参考链接 github地址 友 ...

  9. 6.s081 lab3

    lab3 页表初始化过程: 物理页是一组由run结构体保存的,每个runmain函数调用kinit,初始化物理页.kinit调用了freerange.把内核对应的物理页全部释放掉,加入到freelis ...

最新文章

  1. Putty 工具 保存配置的 小技巧
  2. java kryo 序列化_java中的序列化方式及dubbo使用kryo序列化
  3. 8月数据库排行榜:SQL Server分数下降最多
  4. AngularJS2 环境搭建:
  5. 天天象棋 残局闯关 第19关
  6. 脑洞大开!油画渲染的新算法 Paint Transformer!ICCV2021 Oral!
  7. 节省内存的嵌入式软件设计技巧
  8. PHP------继承、多态
  9. 【SQL】数值型函数
  10. linux搭建一个配置简单的nginx反向代理服务器 2个tomcat
  11. Child returned status 1问题解决
  12. Mac浏览器提示安装证书错误,如何修复 Mac 上的无效证书错误
  13. DVM,ART,JVM之间的关系
  14. 首次曝光:大厂都是这样过1024的,看的我酸了
  15. Android--ImageView读取本地路径图片
  16. Java极速入门系列:第一章Java概述、Java环境、IDEA开发工具
  17. 【随笔】野生在左 科班在右——数据结构学习誓师贴
  18. MTK Android MCC(移动国家码)和 MNC(移动网络码)
  19. 数学基础:斜率、正切与 math.tan()
  20. Arduino使用SK6812(WS2812) 全彩RGB模块/ArduinoC、Mixly/Scartch

热门文章

  1. linux安装软件imagemagick,在Linux系统下ImageMagick的安装及使用方法
  2. 元宇宙专题002 | 在家就可以和医生面对面啦~
  3. BCB 给图片的16进制中叠加字符,图片字符叠加器,图片字符叠加软件
  4. Linux鼠标回报率修改,鼠标回报率修改(hidusbf)
  5. 大数据引领 开创发展新局面
  6. 游戏开发完整流程之美
  7. js 解决在当前页面下载文档问题
  8. linux编译fdk aac,使用NDK编译ffmpeg4.1+fdk-aac2.0
  9. 在我的工程中移植文件系统--FATFS v14
  10. easyUI -datagrid表格数据不显示