[WEEK 09] PintOS - Project 2: User Programs (Extend File Descriptor)

신호정 벨로그·2021년 10월 12일
1

Today I Learned

목록 보기
52/89

Extend File Descriptor 과제의 목표는 파일 디스크립터 및 관련 시스템 콜을 구현하는 것이다.

기존의 PintOS는 파일 디스크립터 부분이 누락되어 있기 때문에, 파일을 입출력 하기 위해서는 파일 디스크립터를 구현해야 한다.

프로세스 디스크립터(struct thread)로부터 파일 디스크립터의 정보를 포함해야 한다.

파일 디스크립터 테이블(fd_table)을 추가한다.

파일 객체 포인터의 배열을 추가한다.

파일 디스크립터 등록 시 2부터 순차적으로 1씩 증가(fd_idx)시킨다. (fd_idx = 2; fd_idx 0과 1은 STDIN과 STDOUT이기 때문이다.)

open() 시 파일 디스크립터를 리턴한다. (return fd;)

close() 파일 디스크립터 테이블에 해당 엔트리를 초기화한다. (remove_file_from_fdt(fd);)

각 프로세스는 자신의 파일 디스크립터 테이블을 가진다.

thread_create() 함수를 쓰레드를 생성할 시 파일 디스크립터를 초기화 하도록 수정한다.

process_exit() 함수를 수정하여 프로세스를 종료할 시 열린 파일을 모두 닫도록 수정한다. (file_close(curr -> running);)

파일 디스크립터를 사용하기 위한 함수를 추가한다.

process_add_file() 함수는 파일 객체에 대한 파일 디스크립터를 생성한다.

process_get_file() 함수는 프로세스의 파일 디스크립터 테이블을 검색하여 파일 객체의 주소를 리턴한다.

process_close_file() 함수는 파일 디스크립터에 해당하는 파일을 닫고 해당 엔트리를 초기화한다.

쓰레드 구조체 struct thread에 파일 디스크립터 테이블을 추가한다.

파일 객체 포인터의 배열과 현재 테이블에 할당된 파일의 파일 디스크립터의 최대값 + 1

파일 디스크립터 테이블에 메모리 할당 (t -> fd_table = palloc_get_multiple(PAL_ZERO, FDT_PAGES);)

파일 디스크립터를 생성하는 process_add_file() 함수를 추가한다.

인자로 입력 받은 파일 구조체 struct file를 파일 디스크립터 테이블에 추가한다.

프로세스의 파일 디스크립터의 최대값을 1만큼 증가시킨다.

파일 객체의 파일 디스크립터를 반환한다.

인자로 입력 받은 파일 식별자로 파일 객체를 검색하는 process_get_file() 함수를 추가한다.

파일 디스크립터 테이블을 이용하여 파일 디스크립터 값에 해당하는 파일 객체를 반환한다.

파일 디스크립터에 해당하는 파일 객체의 파일을 닫는 process_close_file() 함수를 추가한다.

파일 디스크립터 테이블에 해당 엔트리를 초기화한다.

프로세스가 종료될 때 메모리 누수를 방지하기 위해 프로세스에 열린 모든 파일을 닫도록 process_exit() 함수를 수정한다.

파일 디스크립터 테이블 메모리를 해제한다. (for (int i = 0; i < FDCOUNT_LIMIT; i++ {close(i)};)

*filesys_open() 함수는 인자로 입력 받은 파일 이름에 해당하는 파일을 연다.

file_close() 함수는 인자로 입력 받은 파일을 닫는다.

file_read() 함수는 인자로 입력 받은 파일에 저장된 데이터를 읽는다.

file_write() 함수는 인자로 입력 받은 파일에 데이터를 저장한다.

file_seek() 함수는 인자로 입력 받은 파일의 위치(offset)를 이동한다.

file_tell() 함수는 인자로 입력 받은 파일의 위치(offset)를 알려준다.

file_length() 함수는 인자로 입력 받은 파일의 크기를 알려준다.

read(), write() 시스템 콜을 구현할 시 File Descriptor 0(표준 입력), File Descriptor 1(표준 출력)에 사용되는 함수.

input_getc() 함수는 키보드로 입력 받은 문자를 반환한다.

putbuf() 함수는 문자열을 화면에 출력한다.

파일에 대한 동시 접근이 일어날 수 있으므로 lock을 사용한다.

락 구조체 struct lock은 holder 구조체와 semaphore 구조체로 멤버가 구성된다.

struct lock filesys_lock을 멤버로 추가한다.

syscall_init() 함수에서 lock_init() 함수를 이용해 filesys_lock을 초기화하도록 한다.

lock_init() 함수는 lock을 초기화한다.

lock_acquire() 함수는 다른 프로세스가 접근하지 못하도록 lock을 잠근다.

lock_release() 함수는 다른 프로세스가 접근할 수 있도록 lock을 해제한다.

open() 시스템 콜은 인자로 입력 받은 파일을 열고 성공 시 fd를 생성하여 반환한다.

filesize() 시스템 콜은 인자로 입력 받은 파일의 크기를 반환한다.

read() 시스템 콜은 인자로 입력 받은 파일의 데이터를 읽고 성공 시 읽은 바이트 수를 반환한다.

인자 buffer은 읽은 데이터를 저장할 버퍼의 주소 값을 의미한다.

인자 size은 읽을 데이터의 크기를 의미한다.

fd 값이 STDIN을 의미하는 0일 경우 input_getc()를 이용해 키보드의 데이터를 읽어 버퍼에 저장한다.

write() 시스템 콜은 열린 파일의 데이터를 기록하고 성공 시 기록한 데이터의 바이트 수를 반환한다.

인자 buffer은 기록 할 데이터를 저장한 버퍼의 주소 값을 의미한다.

인자 size는 기록할 데이터의 크기를 의미한다.

fd 값이 STDOUT을 의미하는 1일 경우 putbuf()를 이용해 버퍼에 저장된 데이터를 화면에 출력한다.

seek() 시스템 콜은 열린 파일의 위치(offset)를 이동한다.

인자 position은 현재 위치(offset)를 기준으로 이동할 거리를 의미한다.

tell() 시스템 콜은 열린 파일의 위치(offset)를 알려주고 성공 시 파일의 위치(offset)를 반환한다.

close() 시스템 콜은 열린 파일을 닫고 파일 디스크립터를 제거한다.

스택 포인터(%esp)가 가리키는 주소에서 페이지 폴트가 발생할 경우 exit(-1) 시스템 콜을 호출하도록 수정한다.

유저 영역의 주소이지만 물리 메모리에 존재하지 않으므로 페이지 폴트가 발생한다.

0개의 댓글