thread.h : thread 구조체 수정
#include "threads/synch.h" // synch.h 추가
/* 자식 프로세스 순회용 리스트 */
struct list child_list;
struct list_elem child;
/* wait_sema 를 이용하여 자식 프로세스가 종료할때까지 대기함. 종료 상태를 저장 */
struct semaphore wait_sema;
int exit_status;
/* 자식에게 넘겨줄 intr_frame
* fork가 완료될때 까지 부모가 기다리게 하는 forksema
* 자식 프로세스 종료상태를 부모가 받을때까지 종료를 대기하게 하는 free_sema
*/
struct intr_frame parent_if;
struct semaphore fork_sema;
struct semaphore free_sema;
/* fd table 파일 구조체와 fd index
* 각 프로세스는 자신의 File Descriptor 테이블을 가지고 있음 (파일 객체 포인터의 배열)
*/
struct file **fdTable;
int fdIdx;
/* stdin_count와 stdout_count?
* 표준입출력인 fd가 여러 개인 경우를 고려하여 만든 변수.
* 즉, 입출력 fd가 0이 될 때까지 close를 닫으면 안 된다.
*/
int stdin_count;
int stdout_count;
/* 현재 실행 중인 파일 */
struct file *running;
thread.c : init_thread() 초기화
/* 자식 리스트 및 세마포어 초기화 */
/* project - user programs */
t->exit_status = 0;
exeception.c : page_fault() 수정
static void
page_fault (struct intr_frame *f) {
...
exit(-1);
...
}
```
syscall.c : 함수 선언
int open(const char *file);
int filesize(int fd);
int read(int fd, void *buffer, unsigned size);
int write(int fd, void *buffer, unsigned size);
void seek(int fd, unsigned position);
unsigned tell (int fd);
void close(int fd);
static struct file *find_file_by_fd(int fd);
int add_file_to_fdt(struct file *file);
void remove_file_from_fdt(int fd);
```
- 스레드 생성 시 File Descriptor를 초기화하도록 수정 pintos/src/threads/thread.c tid_t thread_create(const char name, int priority, thread_func function, void *aux)
struct thread에 추가된 필드 초기화
File Descriptor 테이블 메모리 할당
프로세스 종료 시 열린파일을 모두 닫도록 수정
pintos/src/userprog/process.c
void process_exit(void)
프로세스 종료가 일어날 경우 프로세스에 열려있는 모든 파일을 닫음
File Descriptor 사용을 위한 함수 추가
pintos/src/userprog/process.c
int process_add_file(struct file *f)
- 파일 객체에 대한 파일 디스크립터 생성
struct file *process_get_file(intfd)
- 프로세스의 파일 디스크립터 테이블을 검색하여 파일객체의 주소를 리턴
void process_close_file(intfd)
- 파일 디스크립터에 해당하는 파일을 닫고 해당 엔트리 초기화
File Descriptor 테이블 추가
pintos/src/threads/thread.h
struct thread
파일 객체 포인터의 배열 // **fdTable
현재 테이블에 할당된 파일 fd + 1 // fdIdx
File Descriptor 초기화
pintos/src/threads/thread.c
tid_t thread_create(constcharname, intpriority, thread_funcfunction, void*aux)
- fd 초기값 : 2
- fd 테이블 메모리 할당
File Descriptor 생성
pintos/src/userprog/process.c
int process_add_file(structfile *f)
- 파일객체(structfile)를 File Descriptor 테이블에 추가
- 프로세스의 File Descriptor의 최대값1 증가
- 파일객체의 File Descriptor반환
파일 객체(struct file) 검색
pintos/src/userprog/process.c
struct file *process_get_file(intfd)
- File Descriptor 값에 해당하는 파일 객체 반환(fd 테이블 이용)
- 해당 테이블에 파일 객체가 없을 시 NULL 반환
모든 열린 파일 닫기
pintos/src/userprog/process.c
void process_exit(void)
- 프로세스가 종료될 때 메모리누수를 방지하기 위해 프로세스에 열린 모든 파일을 닫음
- File Descriptor 테이블 메모리 해제
- 동시 접근이 일어날 수 있으므로 lock 사용 pintos/src/threads/synch.h struct lock filesys_lock 생성
- userprog/syscall.h 헤더파일에 전역변수로 추가
- read(), write() 시스템콜에서 파일에 접근하기전에 lock을 획득하도록 구현
- 파일에 대한 접근이 끝난 뒤 lock 해제
- syscall_init() 함수에서 filesys_lock 초기화 코드 추가
pintos/src/userprog/syscall.c
- lock_init(structlock*) 인터페이스사용
#include <filesys/filesys.h>
struct file *filesys_open(constchar *name)
// 파일 이름에 해당하는 파일을 여는 함수
/*----------*/
#include <filesys/file.h>
void file_close(structfile *)
// 파일을 닫는 함수
off_t file_read(structfile *, void*, off_t)
// 파일에 데이터를 읽는 함수
off_t file_write(structfile *, constvoid *, off_t);
// 파일에 데이터를 기록하는 함수
void file_seek(structfile *, off_t);
// 파일의 위치(offset)를 이동하는 함수
off_t file_tell(structfile *);
// 파일의 위치(offset)를 알려주는 함수
off_t file_length(structfile *);
// 파일의 크기를 알려주는 함수
/*----------*/
#include <devices/input.h>
uint8_t input_getc(void)
// 키보드로 입력받은 문자를 반환하는 함수
/*----------*/
#include <stdio.h>
void putbuf(constchar *, size_t)
// 문자열을 화면에 출력해주는 함수
pintos/src/threads/synch.h
void lock_init(structlock *)
// lock을초기화
void lock_acquire(structlock *)
// 다른프로세스가접근하지못하도록lock을잠금
void lock_release(structlock *)
// 다른프로세스가접근할수있도록lock을해제
#include "threads/synch.h"
...
/* 자식 프로세스 순회용 리스트 */
struct list child_list;
struct list_elem child;
/* wait_sema 를 이용하여 자식 프로세스가 종료할때까지 대기함. 종료 상태를 저장 */
struct semaphore wait_sema;
int exit_status;
/* 자식에게 넘겨줄 intr_frame
* fork가 완료될때 까지 부모가 기다리게 하는 forksema
* 자식 프로세스 종료상태를 부모가 받을때까지 종료를 대기하게 하는 free_sema
*/
struct intr_frame parent_if;
struct semaphore fork_sema;
struct semaphore free_sema;
/* fd table 파일 구조체와 fd index
* 각 프로세스는 자신의 File Descriptor 테이블을 가지고 있음 (파일 객체 포인터의 배열)
*/
struct file **fdTable;
int fdIdx;
/* stdin_count와 stdout_count?
* 표준입출력인 fd가 여러 개인 경우를 고려하여 만든 변수.
* 즉, 입출력 fd가 0이 될 때까지 close를 닫으면 안 된다.
*/
int stdin_count;
int stdout_count;
/* 현재 실행 중인 파일 */
struct file *running;
```
/* 자식 리스트 및 세마포어 초기화 */
/* project - user programs */
t->exit_status = 0;
list_init(&t->child_list);
sema_init(&t->wait_sema, 0);
sema_init(&t->fork_sema, 0);
sema_init(&t->free_sema, 0);
```
/* 부모프로세스저장*/
/* 프로그램이로드되지않음*/
/* 프로세스가종료되지않음*/
/* exit 세마포어0으로초기화*/
/* load 세마포어0으로초기화*/
/* 자식리스트에추가*/
/* Add to run queue. */
/* project2 - user programs */
/* parent-child */
struct thread *parent = aux;
sema_init(&t->wait_sema, 0);
sema_init(&t->free_sema, 0);
sema_init(&t->fork_sema, 0);
**// 이게 어디드가야해??**
list_push_back(&parent->child_list, &t->child);
thread_unblock(t);
```
/* 자식리스트에접근하여프로세스디스크립터검색*/
/* 해당pid가존재하면프로세스디스크립터반환*/
/* 리스트에존재하지않으면NULL 리턴*/
struct thread *get_child_process(tid_t tid){
struct thread *curr = thread_current();
struct list_elem *child;
struct thread *t;
for(child=list_begin(&curr->child_list); child!=list_end(&curr->child_list); child=list_next(child)){
t = list_entry(child, struct thread, child);
if(tid == t->tid){
break;
}
}
if(!child){
return NULL;
}
return t;
}
```
/* 자식리스트에서제거*/
/* 프로세스디스크립터메모리해제*/
void remove_child_process(tid){
struct thread *curr = thread_current();
struct list_elem *child;
struct thread *t;
for(child=list_begin(&curr->child_list); child!=list_end(&curr->child_list); child=list_next(child)){
t = list_entry(child, struct thread, child);
if(tid == t->tid){
list_remove(child);
return;
}
}
if(!child){
return;
}
return;
}
```
static void
page_fault (struct intr_frame *f) {
...
exit(-1);
...
}int exec (const char *cmd_line);
int wait (pid_t pid);
pid_t fork (const char *thread_name);


공유자원에 접근할 수 있는 프로세스의 수를 제한
- 초과하면 대기해야함
- value : 현재 공유자원에 접근할 수 있는 프로세스의 수
- waiters : 공유 자원에 접근대기중인 프로세스 리스트
pintos/src/threads/synch.h
struct semaphore{
unsignedvalue;
structlist waiters;
};
void sema_init(struct semaphore *, unsignedvalue)
// 세마포어의 value 값을 초기화
void sema_down(struct semaphore *)
// 세마포어의 value가 0일 경우 현재 스레드를 THREAD_BLOCK 상태로 변경 후 schedule() 호출
void sema_up(struct semaphore *sema)
// ready_list에 스레드가 있으면 맨앞(head)에 위치한 스레드를 THREAD_READY 상태로 변경 후 schedule()호출