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

정영 Memory Management #2

Open
wants to merge 4 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 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
5 changes: 5 additions & 0 deletions include/vm/vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define VM_VM_H
#include <stdbool.h>
#include "threads/palloc.h"
#include "lib/kernel/hash.h"

enum vm_type {
/* page not initialized */
Expand Down Expand Up @@ -44,8 +45,11 @@ 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;

/* Per-type data are binded into the union.
* Each function automatically detects the current union */
Expand Down Expand Up @@ -85,6 +89,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
89 changes: 81 additions & 8 deletions vm/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@
#include "threads/malloc.h"
#include "vm/vm.h"
#include "vm/inspect.h"
#include "lib/kernel/hash.h"

#include "threads/thread.h"
#include "../include/userprog/process.h"
#include "threads/mmu.h"

unsigned page_hash (const struct hash_elem *p_, void *aux UNUSED);
bool page_less (const struct hash_elem *a_, const struct hash_elem *b_, void *aux UNUSED);
bool page_insert(struct hash *h, struct page *p);

struct list frame_table;

/* Initializes the virtual memory subsystem by invoking each subsystem's
* intialize codes. */
Expand Down Expand Up @@ -55,28 +66,50 @@ vm_alloc_page_with_initializer (enum vm_type type, void *upage, bool writable,
* TODO: should modify the field after calling the uninit_new. */

/* TODO: Insert the page into the spt. */
//palloc으로 new_page를 할당 받고
// sutruct page *new_page = palloc_get_page(PAL_USER);
//switch로 anon, file에 따라
// switch(type)
// uninit_new를 분리해서 호출해줌
// case anon_:
// uninit_new(new_page, upage, init, aux, anon_initializer);
}
// return true // 를 해줘야 load_세그먼트가 다시 불러도 넘어감
err:
return false;
}

// project 3-1
/* Find VA from spt and return page. On error, return NULL. */
// 해시 테이블에서 인자로 받은 va가 있는지 찾는 함수, va가 속해있는 페이지가 해시테이블에 있으면 이를 리턴함
struct page *
spt_find_page (struct supplemental_page_table *spt UNUSED, void *va UNUSED) {
struct page *page = NULL;
// struct page *page = NULL;
/* TODO: Fill this function. */

return page;
struct page *page = (struct page *)malloc(sizeof(struct page));
struct hash_elem *e;

page->va = pg_round_down(va); // 가상 주소를 내려 주소값의 시작 주소를 받음
e = hash_find(&spt->spt_hash,&page->hash_elem);
free(page); //더미 페이지이므로 찾았으면 free해줘야함
// return page;
if (e != NULL) {
return hash_entry(e, struct page, hash_elem);
} else {
return NULL;
}
}

// project 3-1
/* Insert PAGE into spt with validation. */
bool
spt_insert_page (struct supplemental_page_table *spt UNUSED,
struct page *page UNUSED) {
int succ = false;
//int succ = false;
/* TODO: Fill this function. */

return succ;

//return succ;
return page_insert(&spt->spt_hash, page);
}

void
Expand Down Expand Up @@ -112,6 +145,12 @@ static struct frame *
vm_get_frame (void) {
struct frame *frame = NULL;
/* TODO: Fill this function. */
frame = palloc_get_page(PAL_USER);

if (frame == NULL) {
PANIC("to do");
}
frame->page = NULL;

ASSERT (frame != NULL);
ASSERT (frame->page == NULL);
Expand All @@ -136,7 +175,7 @@ vm_try_handle_fault (struct intr_frame *f UNUSED, void *addr UNUSED,
struct page *page = NULL;
/* TODO: Validate the fault */
/* TODO: Your code goes here */

// page-fault가
return vm_do_claim_page (page);
}

Expand All @@ -153,7 +192,9 @@ bool
vm_claim_page (void *va UNUSED) {
struct page *page = NULL;
/* TODO: Fill this function */

struct thread *curr = thread_current();
page = spt_find_page(&curr->spt, va);

return vm_do_claim_page (page);
}

Expand All @@ -165,15 +206,23 @@ vm_do_claim_page (struct page *page) {
/* Set links */
frame->page = page;
page->frame = frame;
// uint64_t pte = pml4e_walk(thread_current()->pml4, page->va,0);

/* TODO: Insert page table entry to map page's VA to frame's PA. */
// if (install_page(page,frame,is_writable(&pte)) == true){
// return true;
// }
// return false;
// return swap_in (page, frame->kva);
pml4_set_page(thread_current()->pml4, page->va, frame->kva, is_writable(thread_current()->pml4));

return swap_in (page, frame->kva);
}

/* Initialize new supplemental page table */
void
supplemental_page_table_init (struct supplemental_page_table *spt UNUSED) {
hash_init(&spt->spt_hash, page_hash, page_less, NULL);
}

/* Copy supplemental page table from src to dst */
Expand All @@ -188,3 +237,27 @@ supplemental_page_table_kill (struct supplemental_page_table *spt UNUSED) {
/* TODO: Destroy all the supplemental_page_table hold by thread and
* TODO: writeback all the modified contents to the storage. */
}

/* Returns a hash value for page p. */
unsigned page_hash (const struct hash_elem *p_, void *aux UNUSED) {
const struct page *p = hash_entry (p_, struct page, hash_elem);
return hash_bytes (&p->va, sizeof p->va);
}

/* Returns true if page a precedes page b. */
bool page_less (const struct hash_elem *a_,
const struct hash_elem *b_, void *aux UNUSED) {
const struct page *a = hash_entry (a_, struct page, hash_elem);
const struct page *b = hash_entry (b_, struct page, hash_elem);

return a->va < b->va;
}

//spt_insert_page()를 위한 bool 함수
bool page_insert(struct hash *h, struct page *p) {
if (!hash_insert(h,&p->hash_elem)) {
return true;
} else {
return false;
}
}