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개의 댓글

Powered by GraphCDN, the GraphQL CDN