[Pintos] - User Program(System call) - 3

Junyeong Fred Kim·2022년 1월 6일
0

운영체제

목록 보기
14/27

과제 설명 참고

동기화 관련 API

// threads/synch.h

void lock_init (struct lock *) // lock을 초기화
void lock_acquire (struct lock *) // 다른 프로세스가 접근하지 못하도록 lock을 잠금
void lock_release (struct lock *) // 다른 프로세스가 접근할 수 있도록 lock을 해제

📟 int read (int fd , void *buffer unsigned size);

  • 열린 파일의 데이터를 읽는 시스템 콜

구현 설명

  • 열린 파일의 데이터를 읽는 시스템 콜
  • 성공 시 읽은 바이트 수를 반환, 실패 시 -1 반환
  • buffer : 읽은 데이터를 저장할 버퍼의 주소 값
  • size : 읽을 데이터 크기
  • fd 값이 0일 때 키보드의 데이터를 읽어 버퍼에 저장. (input_getc() 이용)
// userpog/syscall.c

int read (int fd, void *buffer, unsigned size)
{
    /* 파일에 동시 접근이 일어날 수 있으므로 Lock 사용 */
    /* 파일 디스크립터를 이용하여 파일 객체 검색 */
    /* 파일 디스크립터가 0일 경우 키보드에 입력을 버퍼에 저장 후 버퍼의 저장한 크기를 리턴 (input_getc() 이용) */
    /* 파일 디스크립터가 0이 아닐 경우 파일의 데이터를 크기만큼 저장 후 읽은 바이트 수를 리턴 */
  
    check_address(buffer);  /* page fault를 피하기 위해 */
    int ret;
    struct thread *curr = thread_current ();

    struct file *file_obj = process_get_file(fd);
    if (file_obj == NULL)
        return -1;

    if (file_obj == 1) {
        if (curr->stdin_count == 0) {
            NOT_REACHED();
        }
        int i;
        unsigned char *buf = buffer;
        for (i = 0; i < size; i++) {
            char c = input_getc();
            *buf++ = c;
            if (c == '\0')
                break;
        }
        return i;
    }

    if (file_obj == 2) {
        return -1;
    }
    
    lock_acquire (&filesys_lock);
    ret = file_read(file_obj, buffer, size);
    lock_release (&filesys_lock);

    return ret;
}

file_read: 파일에 데이터를 읽는 함수
NOT_REACHED() : schedule 이후 run이었던 thread의 context는 실행되지 않는다.

#define NOT_REACHED() PANIC ("executed an unreachable statement");

📟 int write (int fd, const void *buffer, unsigned size);

  • 열린 파일의 데이터를 기록 시스템
  • buffer가 read와 달리 const인 이유는 memory에 적는게 목적이 아닌, disk에 쓰는 것이 목적이기 때문에 memory에서의 수정을 방지하기 위해 const void *buffer를 사용한다.

구현 설명

  • 열린 파일의 데이터를 기록 시스템 콜
  • 성공 시 기록한 데이터의 바이트 수를 반환, 실패시 -1 반환
  • buffer : 기록 할 데이터를 저장한 버퍼의 주소 값
  • size : 기록할 데이터 크기
  • fd 값이 1일 때 버퍼에 저장된 데이터를 화면에 출력. (putbuf() 이용)
// userpog/syscall.c


int write (int fd, const void *buffer, unsigned size)
{
    /* 파일에 동시 접근이 일어날 수 있으므로 Lock 사용 */
    /* 파일 디스크립터를 이용하여 파일 객체 검색 */
    /* 파일 디스크립터가 1일 경우 버퍼에 저장된 값을 화면에 출력 후 버퍼의 크기 리턴 (putbuf() 이용) */
    /* 파일 디스크립터가 1이 아닐 경우 버퍼에 저장된 데이터를 크기만큼 파일에 기록후 기록한 바이트 수를 리턴 */
    
    check_address(buffer);  /* page fault를 피하기 위해 */
    int ret;
    struct thread *curr = thread_current ();

    struct file *file_obj = process_get_file(fd);
    if (file_obj == NULL)
        return -1;

    if (file_obj == 2) {
        if (curr->stdout_count == 0) {
            NOT_REACHED();
            process_close_file(fd);
            return -1;
        }

        putbuf(buffer, size);
        return size;
    }

    if (file_obj == 1) {
        return -1;
    }
	
    lock_acquire (&filesys_lock);
    ret = file_write(file_obj, buffer, size);
    lock_release (&filesys_lock);
	
    return ret;
}

file_write: 파일에 데이터를 기록하는 함수


📟 void seek (int fd, unsigned position);

  • 열린 파일의 위치(offset)를 이동하는 시스템 콜

구현 설명

  • 열린 파일의 위치(offset)를 이동하는 시스템 콜
  • Position : 현재 위치(offset)를 기준으로 이동할 거리
// userpog/syscall.c


void seek (int fd, unsigned position)
{
    /* 파일 디스크립터를 이용하여 파일 객체 검색 */
    /* 해당 열린 파일의 위치(offset)를 position만큼 이동 */
    
    struct file *file_obj = process_get_file(fd);
	
    if (file_obj <= 2)
        return ;

    file_obj->pos = position;
}

📟 unsigned tell (int fd);

  • 열린 파일의 위치(offset)를 이동하는 시스템 콜

구현 설명

  • 열린 파일의 위치(offset)를 알려주는 시스템 콜
  • 성공 시 파일의 위치(offset)를 반환, 실패 시 -1 반환
// userpog/syscall.c


unsigned tell (int fd)
{
    /* 파일 디스크립터를 이용하여 파일 객체 검색 */
    /* 해당 열린 파일의 위치를 반환 */
    
    struct file *file_obj = process_get_file(fd);

    if (file_obj <= 2)
        return ;

    return file_tell(file_obj);
}
profile
기억보다 기록

3개의 댓글

comment-user-thumbnail
2022년 1월 7일

어후 블로그가 굉장히 복잡하게 생겼군여

답글 달기
comment-user-thumbnail
2022년 1월 10일

다음꺼 연재해주세요 빨리~

1개의 답글