이어서 진행해보도록 하겠다.
이전 글에서는 비교적 쉬운(?) 시스템 콜들을 다루어보았는데, 이번 글에서는 wait()
, open()
, filesize()
등을 다루어 보겠다.
// userprog/syscall.c
int wait (tid_t tid)
{
/* 자식 프로세스가 종료 될 때까지 대기 */
/* process_wait() 사용 */
process_wait (tid);
}
// userprog/process.c
int process_wait (tid_t child_tid UNUSED)
{
/* 자식 프로세스의 프로세스 디스크립터 검색 */
/* 예외 처리 발생시 -1 리턴 */
/* 자식프로세스가 종료될 때까지 부모 프로세스 대기(세마포어 이용) */
/* 자식 프로세스 디스크립터 삭제 */
/* 자식 프로세스의 exit status 리턴 */
struct thread *curr = thread_current ();
struct thread *child_th = get_child_with_pid(child_tid);
if (child_th == NULL)
return -1;
sema_down(&child_th->wait_sema);
int exit_status = child_th->exit_status;
list_remove(&child_th->child_elem);
sema_up(&child_th->free_sema);
return exit_status;
}
프로세스의 정보를 알기 위해 프로세스 디스크립터 검색
자식 프로세스가 종료되지 않았으면 부모 프로세스 대기
유저 프로세스가 정상적으로 종료 시 exit status 반환, 아닐 시 -1 반환
// userprog/syscall.c
int open (const char *file)
{
check_address(file);
struct file *file_obj = filesys_open(file);
if (file_obj == NULL)
return -1;
int fd = process_add_file(file_obj);
if (fd == -1)
file_close(file_obj);
return fd;
}
파일을 open,
해당 파일 객체에 파일 디스크립터 부여
파일 디스크립터 리턴
해당 파일이 존재하지 않으면 -1 리턴
// userprog/syscall.c
int process_add_file (struct file *f)
{
struct thread *curr = thread_current();
struct file **fdt = curr->fdTable; // file descriptor table
while (curr->fdIdx < FDCOUNT_LIMIT && fdt[curr->fdIdx])
curr->fdIdx++;
if (curr->fdIdx >= FDCOUNT_LIMIT)
return -1;
fdt[curr->fdIdx] = f;
return curr->fdIdx;
}
fdTable
이 꽉 차면 넣을수 없기 때문에 -1을 반환해준다.
fdTable
: 프로세스가 현재 사용 중인 파일을 관리하기 위한 테이블이며, 프로세마다 하나씩 가지고 있다.fdIdx
: fdTable과 해당 테이블을 인덱싱할 때 사용하기 위해 추가해준다.// thread.h
struct thread {
struct file **fdTable;
int fdIdx;
};
thread_create()
: fdTable
과 fdIdx
를 초기화주어야한다.// userprog/syscall.c
int filesize (int fd)
{
struct file *file_obj = process_get_file(fd);
if (file_obj == NULL)
return -1;
return file_length(file_obj);
}
fd 로 열려 있는 파일의 크기(바이트)를 반환한다.
file.c
안에file_length
라는 wrapper function 이용
struct file *process_get_file (int fd)
{
struct thread *curr = thread_current ();
if (fd < 0 || fd >= FDCOUNT_LIMIT)
return NULL;
return curr->fdTable[fd];
}
프로세스의 파일 디스크립터 테이블을 검색하여 파일 객체의 주소를 리턴
안녕하세요, could you please share the slides?Thank u very much:)