PintOS Project3 Day-17

솔다·2023년 1월 15일
0

프로젝트 마감일이 다 되었는데, Memory_Mapped_File을 진행하면서, Thread 관련 테스트가 fail로 바뀐 것을 알았다.

fail이 뜨는 테스트를 통과에만 집중하다가 보니 아래쪽에 Thread_관련 테스트 fail이 뜨는 것을 늦게 발견했다.

그래서 다시 thread 통과를 위해서 디버깅을 시작했다.

Panic이 뜨는 것을 보고 도대체 어떤 지점에서 터지기 시작했는지 다시 처음부터 뒤져보았다.

디버깅의 연속으로 process_cleanup() 함수에서 문제가 발생하는 것을 확인했는데, 이 함수 내부에서 VM에서부터 적용되는 spt_kill()함수에서 문제가 발생했던 것이었다. 이 함수는 프로세스를 실행하면서 spt_table을 init이 되어야 메모리가 할당되며 접근이 가능한데, 프로세스 실행 프로세스에 따르면 init 전에 실행하면서 hash_table에 접근하면서 Panic이 발생한 것.

그래서 if 문을 통해 선택적으로 실행하도록 수정해서 문제를 해결했다.

void supplemental_page_table_kill (struct supplemental_page_table *spt UNUSED){
	if (spt->hash_page_table){
    	hash_clear(spt->hash_page_table, page_destructor);
    }
    else
    	return;
}

Thread를 해결한 이후에 mmap()함수로 돌아갔다. 처음에 함수를 구성했을때는, 단순하게 maping이 될 것을 생각하고 코드를 구성했다.

처음에는 단순히 파일의 길이(length)만큼 loading을 실시했는데, 테스트 fail이 뜬 이후로, 페이지 size에 맞춰서 로딩하는게 필요한게 아닌가 하는 생각으로 while문으로 돌리면서 file loading을 실시했다.

load_segment 호출해서 사용하다가, vm_alloc_page_with_initializer()함수로 anon과 file 형식을 구분해서 load해줄 필요가 있어서, 직접 while문을 작성해서 실행해줬다.

void *
do_mmap(void *addr, size_t length, int writable,
        struct file *file, off_t offset) {

        struct file *mfile = file_reopen(file);
        struct thread *t_curr = thread_current();
        struct load_info *aux = (struct load_info *)calloc(1, sizeof(struct load_info));
        if (mfile == NULL)
                return NULL;

        uint32_t read_bytes = length > file_length(file) ? file_length(file) : length;
        uint32_t zero_bytes = PGSIZE - length % PGSIZE;

        while (read_bytes > 0 || zero_bytes > 0) {
                /* Do calculate how to fill this page.
                 * We will read PAGE_READ_BYTES bytes from FILE
                 * 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;

                struct load_info *mem_init_info = (struct load_info *)calloc(1, sizeof(struct load_info));
                mem_init_info->file = file;
                mem_init_info->ofs = offset;

                mem_init_info->page_read_bytes = page_read_bytes;
                mem_init_info->page_zero_bytes = page_zero_bytes;

                void *aux = mem_init_info;
                if (!vm_alloc_page_with_initializer(VM_FILE, addr,
                        writable, lazy_load_segment, aux))
                        return NULL;

                /* Advance. */
                read_bytes -= page_read_bytes;
                zero_bytes -= page_zero_bytes;
                addr += PGSIZE;

                /* 오프셋을 옮겨보자 */
                offset += page_read_bytes;
        }

        return addr;
}

문제점이 그런줄 알았는데 single_page 사이즈 만큼만 로딩하는 테스트가 fail해서 왜 실패하는지 다시 디버깅을 시작해야겠다.

구현하면서 헤맸던 함수들 몇가지 기억나는 사항들을 작성해두었다. 내일 벌써 WIL 공유날짜이지만, gitbook을 바탕으로 구현하는데 어려움이 많았다.

남은 기간동안 다시 Project3를 마저 진행해볼 예정이다.

0개의 댓글