106 OS homework 2-2 成果報告書

組長:B10415052、葉力維
組員:B10415012、黃政維
組員:B10415050、施心偉
github: https://github.com/xinwei0323/xv6-public


🙂 使用情境說明(包含流程圖)

run make
run make qemu
run testshmget

😇 成功畫面

🏃 實作過程(修改哪些檔案[含圖片])

NOTE:
The files is changed:
* Makefile
* defs.h
* proc.c
* proc.h
* syscall.c
* syscall.h
* sysproc.c
* created testshmget.c //測試shmget功能
* user.h
* usys.S
* vm.c

Makefile

UPROGS=
_testshmget\
//增加一個可以在qemu使用的指令

defs.h

int shmmanip(uint token, char *addr, uint size);
//宣告一個配合shmmanip的function

proc.c

struct proc*
shmemowner(uint token) {
struct proc owner = (void) 0, *p;

acquire(&ptable.lock);
for(p = ptable.proc; p < &ptable.proc[NPROC]; p++) {
if(p->state == UNUSED)
continue;
if (p->shmem_tok == token) {
owner = p;
break;
}
}
release(&ptable.lock);
return owner;
}

proc.h

uint shmem_tok; //shared memory的token
char * startaddr; //process虛擬位置的地址
uint shmem_size; //shared memory的size
struct proc* shmemowner (uint token);

syscall.c

extern int sys_shmget(void); //extern用在變量或者函數的聲明前,用來說明“此變量/函數是在別處定義的
[SYS_shmget] sys_shmget,
//呼叫syscall shm_get

syscall.h

#define SYS_shmget 22
//增加一個syscall

sysproc.c

int
sys_shmget(void) {
//uint token, char *addr, uint size
int token, size;
char addr;
int i;
//配置shmget的token, addres, size
argint(0, &token);
argint(1, &i);
addr = (char
)i;
argint(2, &size);

return shmmanip(token, addr, size);
}

testghmget.c

#include “types.h”
#include “user.h”

int main(void){
int i=0;
int j=0;
//parent process初始化shared memory
if(shmget(12,(char *)0x7FFF0000,20480)<0){
printf(1,“error\n”);
}

char test = (char) 0x7FFF0000;
char *temp = test;
//page 1裡面都給定A
for(;i<4096; i++){
*test = ‘A’;
test++;
}
//page 2裡面都給定B
for(;i<8192; i++){
*test = ‘B’;
test++;
}
//page 3裡面都給定C
for(;i<20479;i++){
*test = ‘C’;
test++;
}
*test = ‘\0’;
test = temp;

if(fork()==0){
//新增一個child process
sleep(100);
char *test1;
//設定child process共享parent process的shared memory
if(shmget(12,(char )0x20000000,0) < 0){
printf(1,“Child error”);
exit();
}
//測試page 1是否一樣
test1 =(char
) 0x20000000;
for(;j<4096;j++){
if(*test1 != ‘A’){
printf(1,“Fail on Page 1 %c\n”, *test1);
exit();
}
test1++;
}
//測試page 2是否一樣
for(;j<8192;j++){
if(*test1 != ‘B’){
printf(1,“Fail on page2\n”);
exit();
}
test1++;
}
//測試page 3是否一樣
for(;j<20479;j++){
if(*test1 != ‘C’){
printf(1,“Fail on page 3 -> 5\n”);
exit();
}
test1++;
}
printf(1,“Child exiting with success!\n”);
}
wait();
exit();
}

user.h

int shmget(uint token, char *addr, uint size);
//宣告一個配合shmget的function

usyu.S

SYSCALL(shmget)
//define system call

vm.c

int shmmanip(uint token, char *addr, uint size) {

uint a = (uint) addr;
char *mem;

// Asserts
if((uint)addr+size >= KERNBASE)
return -1;

a = PGROUNDUP(a);
if (size == 0) {
struct proc owner = (void) 0;
if ((owner = shmemowner(token)) == 0) {
cprintf (“Token not found!”);
return -1;
}

// Loop through parent directory structure through proc->parent->pgdir
// and get the page where va == proc->startaddr
// and then copy the next n pages on to this addr.

pde_t *ppgdir = owner->pgdir;
pte_t *pte;
uint pa;
uint i = (uint) proc->parent->startaddr;
uint end = ((uint) proc->parent->startaddr + proc->parent->shmemsize);
for(; i < end; i += PGSIZE, a+=PGSIZE){
  if((pte = walkpgdir(ppgdir, (void ) i, 0)) == 0)
    panic("shmget: pte should exist");
  if(!(pte & PTEP))
    panic("shmget: page not present");
  pa = PTEADDR(pte);
  mappages(proc->pgdir, (char) a, PGSIZE, pa, PTEW|PTEU);
}
return 0;

}
proc->startaddr = (void) 0;
for (; a < (uint)addr + size; a += PGSIZE) {
mem = kalloc();
if (mem == 0) {
cprintf(“shmget out of memory\n”);
return -1;
}
memset(mem, 0, PGSIZE);
mappages(proc->pgdir, (char
) a, PGSIZE, v2p(mem), PTE_W|PTE_U);
if (proc->startaddr == 0) {
proc->startaddr = (char*)a;
}
}

proc->shmem_tok = token;
proc->shmem_size = size;
return 0;
}
//int shmmanip是初始化 涉及檢查和創建內存用的

😎 結論

我們實作了一個shared memory的shmget,一個process配置一個shared memory的segment,如果不同virtual address的process想要去共享,只要使用相同的token且把size設定0。但是在分配memory range的時候,要注意buffer有多大,如果一不小心超過memory range的話,就容易造成page fault。

📅 組員分工

葉力維:寫code、trace code
黃政維:debug、找資料、trace code
施心偉:找資料、測試程式正確性、trace code