diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index 04635159d30520fa11296dc922e622f2ad2553d5..d8ed9700f9cefd43434d867fb964d9c1c101930a 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -3,19 +3,170 @@ #include <syscall-nr.h> #include "threads/interrupt.h" #include "threads/thread.h" +#include "devices/shutdown.h" static void syscall_handler (struct intr_frame *); +void syscall_halt(void); +void syscall_exit(int status); +int syscall_wait(pid_t pid); +bool syscall_create(const char* file_name, unsigned initial_size); +bool syscall_remove(const char* file_name, unsigned initial_size); + +/*System call initializer*/ void -syscall_init (void) +syscall_init (void) { + //LOOK AT LOCK_INIT + lock_init (&filesys_lock); intr_register_int (0x30, 3, INTR_ON, syscall_handler, "syscall"); } - +/*Handler for system commands.*/ static void -syscall_handler (struct intr_frame *f UNUSED) +syscall_handler (struct intr_frame *f) { - printf ("system call!\n"); - thread_exit (); + //LOOK AGAIN UNTIL SWITCH-CASE + if (!FILE_LOCK_INIT) + { + lock_init(&file_system_lock); + FILE_LOCK_INIT = true; + } + + int syscall_number; + ASSERT( sizeof(syscall_number) == 4 ); // 4byte x86 + + read(f->esp, &syscall_number, sizeof(syscall_number)); + thread_current()->current_esp = f->esp; + + switch (syscall_number) { + case SYSCALL_HALT: // 0 + { + /*Terminate PintOS*/ + syscall_halt(); + break; + } + + case SYSCALL_EXIT: // 1 + { + int arg; + /*Get argument*/ + read(f->esp + 4, &arg, sizeof(arg)); + /*Terminate program*/ + syscall_exit(arg); + break; + } + + + case SYSCALL_WAIT: // 2 + { + pid_t pid; + /*Get argument*/ + read(f->esp + 4, &pid, sizeof(pid_t)); + /*Wait for child process*/ + f->eax = syscall_wait(pid); + break; + } + + case SYSCALL_CREATE: // 3 + { + const char* file_name; + unsigned initial_size; + + /*Get file name and size*/ + read(f->esp + 4, &file_name, sizeof(file_name)); + read(f->esp + 8, &initial_size, sizeof(initial_size)); + + /*Create file*/ + f->eax = syscall_create(file_name, initial_size); + break; + } + + case SYSCALL_REMOVE: // 4 + { + const char* file_name; + bool return_code; + + /*Get file name*/ + read(f->esp + 4, &file_name, sizeof(file_name)); + + /*Remove file*/ + f->eax = syscall_remove(file_name); + break; + } + + /* Unimplemented system calls */ + default: + printf("ERROR: system call ( %d ) has not implemented!\n", syscall_number); + + /* Terminate. */ + sys_exit(-1); + break; + } + +} + +/********SYSTEMCALLS********/ + +/* Halt */ +void syscall_halt(void) { + shutdown_power_off(); /* From shutdown.h */ +} + +/* Exit */ +void syscall_exit(int status) { + printf("%s: exit(%d)\n", thread_current()->name, status); + //LOOK AT PCB + struct process_control_block *pcb = thread_current()->pcb; + if(pcb != NULL) { + pcb->exitcode = status; + } + + thread_exit(); +} + +/* Wait */ +int syscall_wait(pid_t pid) +{ + return process_wait(pid); +} + +/* Create File */ +bool syscall_create(const char* file_name, unsigned initial_size) { + bool if_created = false; + //LOOK AT ACQUIRE AND RELEASE + lock_acquire (&filesys_lock); + if( filesys_create(file_name, initial_size)==true){ + if_created = true; + } + lock_release (&filesys_lock); + return if_created; +} + +/* Remove File */ +bool syscall_remove(const char* file_name, unsigned initial_size) { + bool if_removed = false; + //LOOK AT ACQUIRE AND RELEASE + lock_acquire (&filesys_lock); + if( filesys_remove(file_name, initial_size)==true){ + if_removed = true; + } + lock_release (&filesys_lock); + return if_removed; +} + +/****OTHER FUNCTIONS****/ +static int read(void *src, void *dst, size_t bytes) +{ + int32_t value; + size_t i; + for (i = 0; i < bytes; i++) + { + value = get_user(src + i); + if (value == -1) // segfault or invalid memory access + fail_invalid_access(); + + *(char *)(dst + i) = value & 0xff; + } + return (int)bytes; } diff --git a/src/userprog/syscall.h b/src/userprog/syscall.h index 90590967a9f96f9ea359d15c672b815dfb4379cb..0287064a1eb008f3ddc180c99a131cd463e17dc9 100644 --- a/src/userprog/syscall.h +++ b/src/userprog/syscall.h @@ -3,4 +3,11 @@ void syscall_init (void); +/*PROTOTYPES*/ +void syscall_halt(void); +void syscall_exit(int status); +int syscall_wait(pid_t pid); +bool syscall_create(const char* file_name, unsigned initial_size); +bool syscall_remove(const char* file_name, unsigned initial_size); + #endif /* userprog/syscall.h */