PintOS 2주차 - day6

솔다·2022년 12월 28일
0

thread 구조체 수정부터 시작하려고 했었던 계획은 실패했다.

코드 여러 구석을 뜯어보고 알게됐다.

이 부분은 userprogram 부분의 핵심인 fork() 함수와 wait()함수 작성이 필수인 부분이었다.

그리고 아직 작성되지 않은 시스템 콜을 작성해나가면서 인수를 하나하나 추가해가는 방식으로 해야 전체적인 그림을 잡을 수 있을 것으로 보였다.

몇일간의 노력이 허무했지만, 다시 가장 처음으로 돌아가 system_call을 작성하는 것 부터 시작했다.

void
syscall_handler (struct intr_frame *f UNUSED) {
	/* 유저 스택에 저장되어 있는 시스템 콜 넘버를 가져와야지 일단 */
	int sys_number = f->R.rax; // rax: 시스템 콜 넘버
    /* 
	인자 들어오는 순서:
	1번째 인자: %rdi
	2번째 인자: %rsi
	3번째 인자: %rdx
	4번째 인자: %r10
	5번째 인자: %r8
	6번째 인자: %r9 
	*/
	// TODO: Your implementation goes here.
	switch(sys_number) {
		case SYS_HALT:
			halt();
		case SYS_EXIT:
			exit(f->R.rdi);
		case SYS_FORK:
			fork(f->R.rdi);		
		case SYS_EXEC:
			exec(f->R.rdi);
		case SYS_WAIT:
			wait(f->R.rdi);
		case SYS_CREATE:
			create(f->R.rdi, f->R.rsi);		
		case SYS_REMOVE:
			remove(f->R.rdi);		
		case SYS_OPEN:
			open(f->R.rdi);		
		case SYS_FILESIZE:
			filesize(f->R.rdi);
		case SYS_READ:
			read(f->R.rdi, f->R.rsi, f->R.rdx);
		case SYS_WRITE:
			write(f->R.rdi, f->R.rsi, f->R.rdx);		
		case SYS_SEEK:
			seek(f->R.rdi, f->R.rdx);		
		case SYS_TELL:
			tell(f->R.rdi);		
		case SYS_CLOSE:
			close(f->R.rdi);	
	}
	printf ("system call!\n");
	thread_exit ();
}

시스템 콜 핸들러 자체는 어려운 함수가 아니었다. interrupt frame에서 레지스터의 정보를 저장하는 필드가 있고, 어떤 순서로 자료가 저장되는지만 파악하면 쉽게 인자를 넘겨줄 수 있었다.

이후에는 각 case 별로 실행되는 함수를 작성했다. 몇 개만 기록으로 남긴다.

/* 현재 프로세스를 종료시키는 시스템 콜 */
void exit(int status)
{
	struct thread *t = thread_current();
	printf("%s: exit%d\n", t->name, status); // Process Termination Message
	/* 정상적으로 종료됐다면 status는 0 */
	/* status: 프로그램이 정상적으로 종료됐는지 확인 */
	thread_exit();
}

현재 프로세스를 종료하는 시스템 콜인데 오늘 팀원들과 얘기하다가 이후에 나오는 fd_table 을 생성하고 이후에 thread를 종료할 때, 이 table을 free()를 해줘서 메모리 누수를 막아야 한다는 의견이 나왔고, 이 부분은 이후에 fd 부분을 작성할때 추가할 예정이다.

/* 파일 생성하는 시스템 콜 */
bool create (const char *file, unsigned initial_size) {
	/* 성공이면 true, 실패면 false */
	check_address(file);
	if (filesys_create(file, initial_size)) {
		return true;
	}
	else {
		return false;
	}
}

creat()함수는 파일을 생성하는 함수이다.

bool remove (const char *file) {
	check_address(file);
	if (filesys_remove(file)) {
		return true;
	} else {
		return false;
	}
}

remove 함수는 파일을 제거하는 함수이다. 이때, 파일을 제거하더라도 그 이전에 파일을 오픈했다면 해당 오픈 파일은 close되지 않고 그대로 켜진 상태로 남아있는다.

내일은 여기에 포스팅 안한 함수들을 마저 올리고, wait, fork 함수를 구현해볼 예정이다.

0개의 댓글