앞의 포스팅에서 말했듯, project2에서 구현할 14개의 시스템콜 중에서 7개를 먼저 확인해보자.
pintOS를 종료시키는 명령으로, 간단하게 아래와 같이 나타낸다.
void halt(void) {
power_off();
}
현재 thread(process)를 종료시키는 명령이다. status가 0인 경우가 정상종료 되는 경우다.
void exit(int status) {
printf("%s: exit(%d)\n", thread_name(), status);
thread_current()->exit_code = status;
thread_exit();
}
현재 프로세스를 cmd_line에서 지정된 인수를 전달하여 이름이 지정된 실행 파일로 변경한다. 중간에 에러가 나면 status가 -1로 반환된다.
int exec(const char *cmd_line) {
char *file_name = cmd_line;
char file_static_name[64] = {0,};
memcpy(file_static_name, file_name, strlen(file_name)+1);
bool success;
char *next_ptr;
char *save_ptr = NULL;
char *save_arg[64];
int token_cnt = 1;
save_ptr = strtok_r(file_static_name, " ", &next_ptr);
save_arg[0] = save_ptr;
while (save_ptr != NULL)
{
token_cnt++;
save_ptr = strtok_r(NULL, " ", &next_ptr);
save_arg[token_cnt - 1] = save_ptr;
}
/* We cannot use the intr_frame in the thread structure.
* This is because when current thread rescheduled,
* it stores the execution information to the member. */
struct intr_frame _if;
_if.ds = _if.es = _if.ss = SEL_UDSEG;
_if.cs = SEL_UCSEG;
_if.eflags = FLAG_IF | FLAG_MBS;
/* We first kill the current context */
process_cleanup();
/* And then load the binary */
success = load(file_static_name, &_if);
/* If load failed, quit. */
// lock 반환
thread_current()->load_status = success;
if (!success)
return -1;
argument_stack(save_arg, token_cnt, &_if.rsp);
_if.R.rdi = token_cnt - 1;
_if.R.rsi = (uintptr_t *)_if.rsp + 1;
/* Start switched process. */
if (is_kernel_vaddr(file_name))
palloc_free_page(file_name);
do_iret(&_if);
NOT_REACHED();
}
자식 스레드가 실행될 때까지 기다렸다가, 자식 스레드의 status를 return한다.
int wait(tid_t child_tid) {
/* XXX: Hint) The pintos exit if process_wait (initd), we recommend you
* XXX: to add infinite loop here before
* XXX: implementing the process_wait. */
// struct thread *child_t = list_entry(child_tid, struct thread, elem);
struct thread *tmp_child = get_child_process(child_tid);
if (tmp_child == NULL)
{
return -1;
}
sema_down(&tmp_child->child_lock);
int child_exitcode = tmp_child->exit_code;
list_remove(&tmp_child->child_elem);
sema_up(&tmp_child->memory_lock); //!
return child_exitcode;
}
initial_size 바이트 크기의 새 파일을 만듭니다. 성공하면 true를 반환하고 그렇지 않으면 false를 반환한다. 새 파일을 생성해도 파일이 열리지 않는다.(open 시스템 콜이 있다.)
bool create(const char *file, unsigned initial_size){
bool result;
if (file == NULL){
exit(-1);
}
result = filesys_create(file, initial_size);
return result;
}
인자로 받은 파일을 삭제한다. 성공하면 true를 반환하고 그렇지 않으면 false를 반환한다. (열린 파일인지 닫힌 파일인지 여부에 관계없이 파일을 제거할 수 있으며 열려 있는 파일을 제거해도 파일이 닫히지 않는다.)
bool remove(const char *file){
bool result;
if (file == NULL){
exit(-1);
}
lock_acquire(&filesys_lock);
result = filesys_remove(file);
lock_release(&filesys_lock);
return result;
}
파일을 open한다. open할 수 없는 경우 -1을 리턴한다. 파일이 없는 경우 exit(-1)한다.
int open(const char *file)
{
int open_result;
if (file == NULL){
exit(-1);
}
lock_acquire(&filesys_lock);
struct file *new_file = filesys_open(file);
if (new_file != NULL) {
struct thread *curr = thread_current();
open_result = process_add_file(new_file);
}
else {
open_result = -1;
}
lock_release(&filesys_lock);
return open_result;
}