Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Baebang mmap #5

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"inttypes.h": "c",
"process.h": "c",
"*.inc": "c",
"syscall.h": "c"
"syscall.h": "c",
"main.h": "c"
}
}
1 change: 1 addition & 0 deletions filesys/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <debug.h>
#include "filesys/inode.h"
#include "threads/malloc.h"
#include "userprog/process.h"

/* An open file. */
struct file {
Expand Down
4 changes: 4 additions & 0 deletions include/threads/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ struct thread {
int next_fd;
struct file **fdt;
struct file *running;
void *user_rsp; /*project 3 stack_growth */


#ifdef USERPROG
/* Owned by userprog/process.c. */
Expand All @@ -129,6 +131,8 @@ struct thread {
#ifdef VM
/* Table for whole virtual memory owned by thread. */
struct supplemental_page_table spt;
// void *stack_bottom; /* project 3 anon page */

#endif

/* Owned by thread.c. */
Expand Down
3 changes: 2 additions & 1 deletion include/threads/vaddr.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
/* Round up to nearest page boundary. */
#define pg_round_up(va) ((void *) (((uint64_t) (va) + PGSIZE - 1) & ~PGMASK))

/* Round down to nearest page boundary. */
/* Round down to nearest page boundary.
va를 페이지 크기에 맞게 내림하여 가장 가까운 페이지 경계로 정렬함*/
#define pg_round_down(va) (void *) ((uint64_t) (va) & ~PGMASK)

/* Kernel virtual address start */
Expand Down
14 changes: 14 additions & 0 deletions include/userprog/process.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#define VM
#ifndef USERPROG_PROCESS_H
#define USERPROG_PROCESS_H

#include "threads/thread.h"
#include "filesys/file.h"

#include "vm/vm.h"

tid_t process_create_initd (const char *file_name);
tid_t process_fork (const char *name, struct intr_frame *if_);
int process_exec (void *f_name);
Expand All @@ -13,4 +16,15 @@ void process_activate (struct thread *next);
struct file *search_file_to_fdt (int fd);
int add_file_to_fdt (struct file *file);
void process_close_file(int fd);
bool lazy_load_segment (struct page *page, void *aux);

// project 3 - anon page
// aux로 넘겨줄 정보 값을 저장하는 구조체
struct lazy_load_container {
struct file *file;
off_t ofs;
uint32_t read_bytes;
uint32_t zero_bytes;
};

#endif /* userprog/process.h */
3 changes: 3 additions & 0 deletions include/vm/anon.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ struct page;
enum vm_type;

struct anon_page {
int swap_index;
};

void vm_anon_init (void);
bool anon_initializer (struct page *page, enum vm_type type, void *kva);

struct bitmap *swap_table; // 0 - empty, 1 - filled
size_t bitcnt;
#endif
4 changes: 4 additions & 0 deletions include/vm/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ struct page;
enum vm_type;

struct file_page {
struct file *file;
off_t read_byte;
off_t offset;

};

void vm_file_init (void);
Expand Down
19 changes: 18 additions & 1 deletion include/vm/vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
#include <stdbool.h>
#include "threads/palloc.h"

#include <hash.h>
#include "threads/mmu.h"
#include "threads/vaddr.h"
#include <list.h>


enum vm_type {
/* page not initialized */
VM_UNINIT = 0,
Expand All @@ -27,6 +33,8 @@ enum vm_type {
#include "vm/uninit.h"
#include "vm/anon.h"
#include "vm/file.h"

#include "lib/kernel/hash.h"
#ifdef EFILESYS
#include "filesys/page_cache.h"
#endif
Expand All @@ -44,9 +52,13 @@ struct page {
const struct page_operations *operations;
void *va; /* Address in terms of user space */
struct frame *frame; /* Back reference for frame */
struct list_elem frame_elem; // frame_table을 위한 list_elem 추가

/* Your implementation */

/* project 3-1 */
struct hash_elem hash_elem;
bool writable;
int page_cnt;
/* Per-type data are binded into the union.
* Each function automatically detects the current union */
union {
Expand All @@ -59,10 +71,14 @@ struct page {
};
};

struct list frame_table;
struct lock frame_lock;

/* The representation of "frame" */
struct frame {
void *kva;
struct page *page;
struct list_elem elem; /* P3 추가 */
};

/* The function table for page operations.
Expand All @@ -85,6 +101,7 @@ struct page_operations {
* We don't want to force you to obey any specific design for this struct.
* All designs up to you for this. */
struct supplemental_page_table {
struct hash spt_hash;
};

#include "threads/thread.h"
Expand Down
1 change: 0 additions & 1 deletion tests/vm/mmap-unmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include "tests/vm/sample.inc"
#include "tests/lib.h"
#include "tests/main.h"

#define ACTUAL ((void *) 0x10000000)


Expand Down
4 changes: 3 additions & 1 deletion userprog/exception.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,15 +139,17 @@ page_fault (struct intr_frame *f) {
not_present = (f->error_code & PF_P) == 0;
write = (f->error_code & PF_W) != 0;
user = (f->error_code & PF_U) != 0;
exit(-1);
// exit(-1); project 2일때 여기서 exit(-1)
#ifdef VM
/* For project 3 and later. */
if (vm_try_handle_fault (f, fault_addr, user, write, not_present))
return;

#endif

/* Count page faults. */
page_fault_cnt++;
exit(-1);

/* If the fault is true fault, show info and exit. */
printf ("Page fault at %p: %s error %s page in %s context.\n",
Expand Down
77 changes: 67 additions & 10 deletions userprog/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@ struct thread *get_child_process(int pid){
}

struct file *search_file_to_fdt (int fd){
//process_get_file
struct thread *curr = thread_current();
if (fd < 0 || fd >= FDCOUNT_LIMIT) {
if (fd < 2 || fd >= FDCOUNT_LIMIT) {
return NULL;
}
return curr->fdt[fd];
Expand Down Expand Up @@ -110,7 +111,7 @@ initd (void *f_name) {
supplemental_page_table_init (&thread_current ()->spt);
#endif

process_init ();
// process_init ();

if (process_exec (f_name) < 0)
PANIC("Fail to launch initd\n");
Expand Down Expand Up @@ -165,8 +166,8 @@ duplicate_pte (uint64_t *pte, void *va, void *aux) {

/* 3. TODO: Allocate new PAL_USER page for the child and set result to
* TODO: NEWPAGE. */
// newpage = palloc_get_page (PAL_USER); /////
newpage = palloc_get_page(PAL_USER | PAL_ZERO); ///////////////////
// newpage = palloc_get_page (PAL_USER);
newpage = palloc_get_page(PAL_USER | PAL_ZERO);
if(newpage == NULL){
return false;
}
Expand Down Expand Up @@ -394,10 +395,11 @@ process_exit (void) {

file_close(curr->running);

process_cleanup ();
sema_up(&curr->wait_sema);
sema_down(&curr->free_sema);

process_cleanup ();
// process_cleanup ();
}

/* Free the current process's resources. */
Expand Down Expand Up @@ -754,12 +756,46 @@ install_page (void *upage, void *kpage, bool writable) {
/* From here, codes will be used after project 3.
* If you want to implement the function for only project 2, implement it on the
* upper block. */

static bool
// project 3 - anon page
// aux로 넘겨줄 정보 값을 저장하는 구조체
// struct lazy_load_container {
// struct file *file;
// off_t ofs;
// uint32_t read_bytes;
// uint32_t zero_bytes;
// };

// 함수 다시 보기
bool
lazy_load_segment (struct page *page, void *aux) {
/* TODO: Load the segment from the file */
/* TODO: This called when the first page fault occurs on address VA. */
/* TODO: VA is available when calling this function. */
// 콘텐츠를 메모리에 넣어줌
struct lazy_load_container *container = (struct lazy_load_container *) aux;


uint32_t read_bytes = container->read_bytes;
uint32_t zero_bytes = container->zero_bytes;
off_t ofs = container->ofs;
struct file *file = container->file;

file_seek (file, ofs);

/* Get a page of memory. */
//uint8_t *kpage = palloc_get_page (PAL_USER);
uint8_t *kpage = page->frame->kva;
if (kpage == NULL)
return false;

/* Load this page. */
if (file_read (file, kpage, read_bytes) != (int) read_bytes) {
palloc_free_page (kpage);
return false;
}
memset (kpage + read_bytes, 0, zero_bytes);

return true;
}

/* Loads a segment starting at offset OFS in FILE at address
Expand Down Expand Up @@ -789,9 +825,18 @@ load_segment (struct file *file, off_t ofs, uint8_t *upage,
* and zero the final PAGE_ZERO_BYTES bytes. */
size_t page_read_bytes = read_bytes < PGSIZE ? read_bytes : PGSIZE;
size_t page_zero_bytes = PGSIZE - page_read_bytes;

/* TODO: Set up aux to pass information to the lazy_load_segment. */
void *aux = NULL;
// 로딩 중인 파일의 정보나 로딩할 페이지의 위치(세그먼트)를
// load_segment의 aux값을 저장해뒀다가 lazy_load_segment에 인자로 넘겨줘야함
/* Project 3 anon page */
struct lazy_load_container *aux = NULL;
aux = (struct lazy_load_container*)malloc(sizeof(struct lazy_load_container));

aux->file = file;
aux->ofs = ofs;
aux->read_bytes = page_read_bytes;
aux->zero_bytes = page_zero_bytes;

if (!vm_alloc_page_with_initializer (VM_ANON, upage,
writable, lazy_load_segment, aux))
return false;
Expand All @@ -800,6 +845,8 @@ load_segment (struct file *file, off_t ofs, uint8_t *upage,
read_bytes -= page_read_bytes;
zero_bytes -= page_zero_bytes;
upage += PGSIZE;
// 추가
ofs += page_read_bytes;
}
return true;
}
Expand All @@ -814,7 +861,17 @@ setup_stack (struct intr_frame *if_) {
* TODO: If success, set the rsp accordingly.
* TODO: You should mark the page is stack. */
/* TODO: Your code goes here */

// vm_alloc_page() 호출해서 하나의 uninit 페이지 생성
// 해당 페이지는 바로 물리 프레임을 할당 시켜서 anon 타입 페이지 설정
// 호출 성공 시 rsp 값을 USER_STACK으로 변경
// 현재 스레드의 stack_bottom을 stack_bottom으로 받음
if(vm_alloc_page(VM_ANON | VM_MARKER_0, stack_bottom, 1)){
success = vm_claim_page(stack_bottom);
if(success){
if_->rsp = USER_STACK;
}
}
return success;

}
#endif /* VM */
Loading