sw사관학교정글/PintOS(KAIST's CS330 class)

[week12] PintOS - Project 3(Virtual Memory) : 핀토스는 확률게임인가

D cron 2022. 1. 26. 00:58

Project 3 : 핀토스는 확률게임인가

현재상황


FAIL tests/filesys/base/syn-read
FAIL tests/userprog/create-null 
FAIL tests/userprog/open-null 
FAIL tests/vm/swap-file 
FAIL tests/vm/swap-anon 
FAIL tests/vm/swap-iter 
FAIL tests/vm/swap-fork 
FAIL tests/vm/cow/cow-simple //extra


수정 시작

swap tests를 고쳐보자.


victim을 찾아야 되는데 return 을 NULL로 하고 있었다.

static struct frame *
	vm_evict_frame (void) {
    // project 3
    struct frame *victim = vm_get_victim ();
    /* TODO: swap out the victim and return the evicted frame. */
    swap_out(victim->page);
    return victim; // return NULL;로 되어있었다
}

이걸 고치니까 swap test 4개중에 3개가 통과했다.

pass tests/vm/swap-file
pass tests/vm/swap-anon
pass tests/vm/swap-iter


open-null, create-null tests를 고쳐보자.

file이 NULL일 경우 바로 return -1을 해주자.

// userprog/syscall.c
int open(const char *file) {
    ...
    if(file == NULL){
        return -1;
    }
    ...
}
// userprog/syscall.c
bool create(const char *filename, unsigned initial_size) 
{
    ...
    if (!filename){
        exit(-1);
    }
    ...
}

if문 처리를 해주면 null 관련 test들이 통과된다.

pass tests/userprog/create-null 
pass tests/userprog/open-null 

swap-fork 가능하게 해보자.

FAIL이 뜨는 원인을 살펴보니까 thread_yield 함수에 ASSERT (!intr_context ()) 부분에서 발생하는 것 같았다. intr_context() 함수는 externel interrupt일 때는 true를 return하고 그게 아니라면 false를 return하는 함수다. 그러니까 저 ASSERT에서는 외부 인터럽트가 들어오면 바로 FAIL이 뜨는 구조인 것이다. 그래서 외부 인터럽트가 아닐 때만 thread_yield를 하도록 코드를 수정해 주었다.

// threads/thread.c
// priority scheduling 
void thread_test_preemption (void)
{
    if (!list_empty (&ready_list) && thread_current ()->priority 
    < list_entry (list_front(&ready_list), struct thread, elem)->priority){
        if (!intr_context()) {
            thread_yield ();
        }
    }
}

이걸 수정하면 swap-fork는 pass를 볼 수 있게 된다.

이렇게까지 수정하고 돌렸더니 1 fail이 떴다! 너무 기분이 좋았다!!!!



그래서 이제 끝났다고 생각했다... 이건 내 큰 착각이었다.

핀토스가 확률게임이라고 한게 syn-read가 터질때도 있고 안터질 때도 있다. merge 부분들도 터질때도 있고 안터질 때가 있다.

race condition이나 dead lock에 관련된것 같아서 load 함수안에서 file을 open하거나 read할 때 lock을 걸어주고 test를 돌렸다.



약간 더 안정적이 된건지 아니면 기분탓인지 아니면 내가 지금 운이 좋은건지 판단할 수가 없다.

또 돌려봤다. 그랬더니 이번에는 2 fail이 떴다.




터질때도 왜 터졌는지 어디서 터졌는지 왜 터졌다가 안터졌다가 하는지 터질 때마다 여러 case가 나와서 도저히 어디서부터 고쳐야 할지를 모르겠다. 새벽까지 팀원 형들과 디버깅을 돌리면서 어떤 상황이고 어디를 고쳐야 할지 계속 얘기해보면서 실험해보다가 내일 아침 회고 및 발표시간에 참석을 못할것 같아서 기숙사로 들어갔다... 사실 내가 고칠 수 있는 범위를 넘어선 것 같기도 하다 ㅋㅋ

// 가끔가다가 터지는 것들 목록
FAIL tests/filesys/base/syn-read
FAIL tests/vm/page-merge-seq
FAIL tests/vm/page-merge-par
FAIL tests/vm/page-merge-stkmake
FAIL tests/vm/page-merge-mm
FAIL tests/vm/mmap-overlap

사람들이 왜 project 3가 어렵다고 한지 알겠다. 일단 양이 너무너무 많고 방대해서 내가 지금 무엇을 하고 있는지 인지하기가 어렵다. 또한 양도 많은데 내용은 또 얼마나 깊은지... 그리고 project 1과2 위에서 동작하다보니까 코드 구현하면서 되던게 안되는 경우가 많아지고, 이전 코드들을 수정해야 하는 경우도 많이 생겼다.


또한 GITBOOK에서 구현하라고 한거 이외에 것들을 구현해야 통과되기 때문에 무엇을 추가로 구현해야 pass가 뜨는지 알아내는 것도 어려운 작업이었다. 사실 어려운게 너무 많아서 다 나열할 수가 없다.


핀토스 project 3에 관한 눈물나게 공감되는 (꿀잼) 포스팅이 있어서 공유한다.

핀토스는 사람을 무기력하게 만든다.


코치님은 현업에서는 race condition을 통해 공격당할 수도 있으므로 race condition을 만들지 않는것이 맞다고 하셨다. 그러나 나는 여기까지다...


아무튼 project 3은 이렇게 마무리!