[TIL/크래프톤 정글] DAY 78

배재준·2025년 5월 26일

크래프톤 정글 - TIL

목록 보기
70/93
post-thumbnail

2025.05.26

TIL(TODAY I LEARN)


  • 오늘한 내용 : PintOS - Project2: UserProgram - System calls
    파일 디스크립터 구현 및 자잘한 예외처리 구현 중
  • WEEK 11 : 정글 끝까지(PintOS) - UserProgram

FD 구현

  • 스레드 구조체에 fd 변수 추가 및 초기화
thread.h 
------------------------------
#define MAX_FD 128
struct thread {struct file *fd_table[MAX_FD];   /* 프로세스별 열린 파일 포인터 */
  int next_fd;                     /* 다음 할당할 FD 번호 */
};

thread.c
------------------------------
static void init_thread(struct thread *t,) {for (int i = 0; i < MAX_FD; i++)
    t->fd_table[i] = NULL;
  t->next_fd = 2;   /* 0: stdin, 1: stdout 예약 */}
  • fork 시 fd 복제 추가
__do_fork()
-------------------------------
for (int fd = 2; fd < MAX_FD; fd++)
	{
		struct file *f = parent->fd_table[fd];
		if (f != NULL)
			current->fd_table[fd] = file_duplicate(f);
	}
	current->next_fd = parent->next_fd;
  • process_exit 시 fd 디스크립터 삭제 추가
// fd_table 순회하여 file_close()
		for (int fd = 2; fd < MAX_FD; fd++)
		{
			if (curr->fd_table[fd])
			{
				file_close(curr->fd_table[fd]);
				curr->fd_table[fd] = NULL;
			}
		}
  • int open(const char file); 호출 시
    • 파일 시스템에서 file 이름의 파일을 열고, 성공하면 새 파일 디스크립터(fd)를 반환. 실패하면 –1 반환.
    • open(file) 호출 → 레지스터에 SYS_OPENfile 포인터를 담고 syscall 실행
    • 구현
      1. check_user_address() / check_user_buffer()file 문자열 검사
      2. filesys_open(file)struct file* 얻음
      3. allocate_fd(fptr)thread_current()->fd_table[fd] = fptr
      4. 실패 시 file_close(fptr) 후 –1, 성공 시 fd 반환
  • int read(int fd, void buffer, unsigned size); 호출 시
    • 열린 파일 디스크립터 fd로부터 최대 size 바이트를 buffer에 읽어서 실제 읽은 바이트 수를 반환. stdin(fd=0)은 키보드 입력. 오류 시 –1.
    • read(fd, buffer, size) 호출 → 레지스터에 SYS_READ, fd, buffer, size 담고 syscall 실행
    • sys_read() 구현
      1. check_user_address() / check_user_buffer()buffer 검사
      2. fd==0input_getc() 반복 호출
      3. fd>1file_read(fd_table[fd], buffer, size)
      4. 유효치 않으면 –1 반환
  • int write(int fd, const void buffer, unsigned size); 호출 시
    • 열린 파일 디스크립터 fdbuffer의 내용을 size 바이트만큼 기록하고, 성공하면 기록한 바이트 수 반환. stdout(fd=1)은 콘솔 출력. 오류 시 –1.
    • write(fd, buffer, size) 호출 → 레지스터에 SYS_WRITE, fd, buffer, size 담고 syscall 실행
    • sys_write() 구현
      1. check_user_address() / check_user_buffer()buffer 검사
      2. fd==1putbuf(buffer, size) (콘솔)
      3. fd>1file_write(fd_table[fd], buffer, size)
      4. 유효치 않으면 –1 반환
  • void close(int fd); 호출 시
    • 파일 디스크립터 fd가 가리키는 파일을 닫고, 해당 엔트리를 해제(free_fd).
    • close(fd) 호출 → 레지스터에 SYS_CLOSE, fd 담고 syscall 실행
    • 구현
      1. 유효한 fd (>1 && < MAX_FD)인지 검사
      2. file_close(fd_table[fd]), free_fd(fd)
  • bool create(const char file, unsigned initial_size); 호출 시
    • 새 파일 file을 크기 initial_size로 생성. 성공 시 true, 실패 시 false.
    • create(file, size) 호출 → 레지스터에 SYS_CREATE, file, size 담고 syscall 실행
    • 구현
      1. check_user_address() / check_user_buffer()file 검사
      2. filesys_create(file, initial_size) 호출
      3. 반환값 그대로 리턴
  • bool remove(const char file); 호출 시
    • 파일 시스템에서 file을 삭제. 성공 시 true, 실패 시 false.
    • remove(file) 호출 → 레지스터에 SYS_REMOVE, file 담고 syscall 실행
    • 구현
      1. check_user_address() / check_user_buffer()file 검사
      2. filesys_remove(file) 호출
      3. 반환값 그대로 리턴
  • int filesize(int fd); 호출 시
    • 열린 파일 디스크립터 fd가 가리키는 파일의 크기를 바이트 단위로 반환. 오류 시 –1.
    • filesize(fd) 호출 → 레지스터에 SYS_FILESIZE, fd 담고 syscall 실행
    • 구현
      1. 유효한 fd인지 검사
      2. file_length(fd_table[fd]) 호출 후 반환
  • void seek(int fd, unsigned position); 호출 시
    • 열린 파일 디스크립터 fd의 읽기/쓰기 위치(offset)를 position으로 설정.
    • seek(fd, pos) 호출 → 레지스터에 SYS_SEEK, fd, position 담고 syscall 실행
    • 구현
      1. 유효한 fd인지 검사
      2. file_seek(fd_table[fd], position) 호출
  • unsigned tell(int fd); 호출 시
    • 열린 파일 디스크립터 fd의 현재 읽기/쓰기 위치(offset)를 반환. 오류 시 0.
    • tell(fd) 호출 → 레지스터에 SYS_TELL, fd 담고 syscall 실행
    • 구현
      1. 유효한 fd인지 검사
      2. file_tell(fd_table[fd]) 호출 후 반환

원자적 수행을 위해 lock을 inode에 추가

  • struct inode
inode.c
----------------------
struct inode {
    struct list_elem elem;
    disk_sector_t sector;
    int open_cnt;
    bool removed;
    int deny_write_cnt;
    struct inode_disk data;

    struct lock inode_lock;    /* ← 여기 추가 */
};

struct inode *inode_open(disk_sector_t sector){}
/* inode가 새로 생성되었으니 락도 초기화 */
lock_init(&inode->inode_lock);
  • inode_read_at(), inode_write_at(), inode_deny_write(), inode_allow_write(), inode_remove() , innode_reopen()에 락 설정
lock_acquire(&inode->inode_lock);;
lock_release(&inode->inode_lock);

0개의 댓글