hw5: mostly done
This commit is contained in:
parent
aa03d859f6
commit
de7abb4f0d
5 changed files with 47 additions and 37 deletions
6
.vscode/settings.json
vendored
6
.vscode/settings.json
vendored
|
@ -1,5 +1,9 @@
|
||||||
{
|
{
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"ratio": "c"
|
"ratio": "c",
|
||||||
|
"__functional_03": "c",
|
||||||
|
"functional": "c",
|
||||||
|
"locale": "c",
|
||||||
|
"*.inc": "c"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -440,7 +440,7 @@ thread_exit (void)
|
||||||
printf("%s: exit(%d)\n", t->name, t->exit_status);
|
printf("%s: exit(%d)\n", t->name, t->exit_status);
|
||||||
list_remove (&t->allelem);
|
list_remove (&t->allelem);
|
||||||
sema_up(&t->waiting_sem);
|
sema_up(&t->waiting_sem);
|
||||||
sema_down(&t->parent->parent_sem);
|
sema_down(&t->parent_sem);
|
||||||
t->status = THREAD_DYING;
|
t->status = THREAD_DYING;
|
||||||
list_remove(&t->child_elem);
|
list_remove(&t->child_elem);
|
||||||
schedule ();
|
schedule ();
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
#include "threads/thread.h"
|
#include "threads/thread.h"
|
||||||
#include "threads/vaddr.h"
|
#include "threads/vaddr.h"
|
||||||
#include "lib/kernel/list.h"
|
#include "lib/kernel/list.h"
|
||||||
|
#include "userprog/syscall.h"
|
||||||
|
#include "threads/synch.h"
|
||||||
|
|
||||||
static struct arg {
|
static struct arg {
|
||||||
struct list_elem elem;
|
struct list_elem elem;
|
||||||
|
@ -59,11 +61,13 @@ process_execute (const char *file_name)
|
||||||
}
|
}
|
||||||
strlcpy(program_name, file_name, i+1);
|
strlcpy(program_name, file_name, i+1);
|
||||||
|
|
||||||
|
lock_acquire(&filesys_lock);
|
||||||
struct file* f = filesys_open (program_name);
|
struct file* f = filesys_open (program_name);
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
return TID_ERROR;
|
return TID_ERROR;
|
||||||
}
|
}
|
||||||
file_close(f);
|
file_close(f);
|
||||||
|
lock_release(&filesys_lock);
|
||||||
|
|
||||||
/* Create a new thread to execute FILE_NAME. */
|
/* Create a new thread to execute FILE_NAME. */
|
||||||
tid = thread_create (program_name, PRI_DEFAULT, start_process, fn_copy);
|
tid = thread_create (program_name, PRI_DEFAULT, start_process, fn_copy);
|
||||||
|
@ -104,6 +108,7 @@ start_process (void *file_name_)
|
||||||
if_.gs = if_.fs = if_.es = if_.ds = if_.ss = SEL_UDSEG;
|
if_.gs = if_.fs = if_.es = if_.ds = if_.ss = SEL_UDSEG;
|
||||||
if_.cs = SEL_UCSEG;
|
if_.cs = SEL_UCSEG;
|
||||||
if_.eflags = FLAG_IF | FLAG_MBS;
|
if_.eflags = FLAG_IF | FLAG_MBS;
|
||||||
|
//printf("Loading %s\n", program_name);
|
||||||
success = load (program_name, &if_.eip, &if_.esp);
|
success = load (program_name, &if_.eip, &if_.esp);
|
||||||
|
|
||||||
list_reverse(&arg_list);
|
list_reverse(&arg_list);
|
||||||
|
@ -200,7 +205,7 @@ process_wait (tid_t child_tid)
|
||||||
int status = child->exit_status;
|
int status = child->exit_status;
|
||||||
//printf("Wait exit: %s %d\n",child->name, status);
|
//printf("Wait exit: %s %d\n",child->name, status);
|
||||||
child->waited_on_before = 1;
|
child->waited_on_before = 1;
|
||||||
sema_up(&(thread_current()->parent_sem));
|
sema_up(&(child->parent_sem));
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,6 +339,7 @@ load (const char *file_name, void (**eip) (void), void **esp)
|
||||||
goto done;
|
goto done;
|
||||||
process_activate ();
|
process_activate ();
|
||||||
|
|
||||||
|
lock_acquire(&filesys_lock);
|
||||||
/* Open executable file. */
|
/* Open executable file. */
|
||||||
file = filesys_open (file_name);
|
file = filesys_open (file_name);
|
||||||
if (file == NULL)
|
if (file == NULL)
|
||||||
|
@ -426,6 +432,7 @@ load (const char *file_name, void (**eip) (void), void **esp)
|
||||||
done:
|
done:
|
||||||
/* We arrive here whether the load is successful or not. */
|
/* We arrive here whether the load is successful or not. */
|
||||||
file_close (file);
|
file_close (file);
|
||||||
|
lock_release(&filesys_lock);
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ struct fd_item {
|
||||||
|
|
||||||
int next_fd = 3;
|
int next_fd = 3;
|
||||||
struct hash fd_table;
|
struct hash fd_table;
|
||||||
struct semaphore filesys_lock;
|
struct lock filesys_lock;
|
||||||
|
|
||||||
static unsigned item_hash (const struct hash_elem* e, void* aux) {
|
static unsigned item_hash (const struct hash_elem* e, void* aux) {
|
||||||
struct fd_item* i = hash_entry(e, struct fd_item, elem);
|
struct fd_item* i = hash_entry(e, struct fd_item, elem);
|
||||||
|
@ -72,7 +72,7 @@ syscall_init (void)
|
||||||
syscall_vec[SYS_READ] = (handler)sys_read;
|
syscall_vec[SYS_READ] = (handler)sys_read;
|
||||||
syscall_vec[SYS_WRITE] = (handler)sys_write;
|
syscall_vec[SYS_WRITE] = (handler)sys_write;
|
||||||
hash_init(&fd_table, item_hash, item_compare, NULL);
|
hash_init(&fd_table, item_hash, item_compare, NULL);
|
||||||
sema_init(&filesys_lock, 1);
|
lock_init(&filesys_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool check_ptr(const void* ptr) {
|
static bool check_ptr(const void* ptr) {
|
||||||
|
@ -90,17 +90,17 @@ void sys_halt(void) {
|
||||||
|
|
||||||
bool sys_create(const char* filename, unsigned initial_size) {
|
bool sys_create(const char* filename, unsigned initial_size) {
|
||||||
if (check_ptr(filename)) return 0;
|
if (check_ptr(filename)) return 0;
|
||||||
sema_down (&filesys_lock);
|
lock_acquire (&filesys_lock);
|
||||||
bool return_code = filesys_create(filename, initial_size);
|
bool return_code = filesys_create(filename, initial_size);
|
||||||
sema_up (&filesys_lock);
|
lock_release (&filesys_lock);
|
||||||
return return_code;
|
return return_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sys_remove(const char* filename) {
|
bool sys_remove(const char* filename) {
|
||||||
if (check_ptr(filename)) return 0;
|
if (check_ptr(filename)) return 0;
|
||||||
sema_down (&filesys_lock);
|
lock_acquire (&filesys_lock);
|
||||||
bool return_code = filesys_remove(filename);
|
bool return_code = filesys_remove(filename);
|
||||||
sema_up (&filesys_lock);
|
lock_release (&filesys_lock);
|
||||||
return return_code;
|
return return_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,40 +112,42 @@ int sys_open(const char* file) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sema_down (&filesys_lock);
|
lock_acquire (&filesys_lock);
|
||||||
file_opened = filesys_open(file);
|
file_opened = filesys_open(file);
|
||||||
|
//printf("File opened: %x\n", file_opened);
|
||||||
if (!file_opened) {
|
if (!file_opened) {
|
||||||
free(fd);
|
free(fd);
|
||||||
sema_up (&filesys_lock);
|
lock_release (&filesys_lock);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd->file = file_opened; //file save
|
fd->file = file_opened;
|
||||||
fd->fd = next_fd++;
|
fd->fd = next_fd++;
|
||||||
|
//printf("Hash put: %x %d\n", file_opened, fd->fd);
|
||||||
hash_insert(&fd_table, &fd->elem);
|
hash_insert(&fd_table, &fd->elem);
|
||||||
|
|
||||||
sema_up (&filesys_lock);
|
lock_release (&filesys_lock);
|
||||||
return fd->fd;
|
return fd->fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sys_filesize(int fd) {
|
int sys_filesize(int fd) {
|
||||||
sema_down (&filesys_lock);
|
lock_acquire (&filesys_lock);
|
||||||
struct fd_item i;
|
struct fd_item i;
|
||||||
i.fd = fd;
|
i.fd = fd;
|
||||||
struct fd_item* file_d = hash_entry(hash_find(&fd_table, &i.elem), struct fd_item, elem);
|
struct fd_item* file_d = hash_entry(hash_find(&fd_table, &i.elem), struct fd_item, elem);
|
||||||
|
|
||||||
if(file_d == NULL) {
|
if(file_d == NULL) {
|
||||||
sema_up (&filesys_lock);
|
lock_release (&filesys_lock);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret = file_length(file_d->file);
|
int ret = file_length(file_d->file);
|
||||||
sema_up (&filesys_lock);
|
lock_release (&filesys_lock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sys_seek(int fd, unsigned position) {
|
void sys_seek(int fd, unsigned position) {
|
||||||
sema_down (&filesys_lock);
|
lock_acquire (&filesys_lock);
|
||||||
struct fd_item i;
|
struct fd_item i;
|
||||||
i.fd = fd;
|
i.fd = fd;
|
||||||
struct fd_item* file_d = hash_entry(hash_find(&fd_table, &i.elem), struct fd_item, elem);
|
struct fd_item* file_d = hash_entry(hash_find(&fd_table, &i.elem), struct fd_item, elem);
|
||||||
|
@ -156,11 +158,11 @@ void sys_seek(int fd, unsigned position) {
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sema_up (&filesys_lock);
|
lock_release (&filesys_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned sys_tell(int fd) {
|
unsigned sys_tell(int fd) {
|
||||||
sema_down (&filesys_lock);
|
lock_acquire (&filesys_lock);
|
||||||
struct fd_item i;
|
struct fd_item i;
|
||||||
i.fd = fd;
|
i.fd = fd;
|
||||||
struct fd_item* file_d = hash_entry(hash_find(&fd_table, &i.elem), struct fd_item, elem);
|
struct fd_item* file_d = hash_entry(hash_find(&fd_table, &i.elem), struct fd_item, elem);
|
||||||
|
@ -172,29 +174,30 @@ unsigned sys_tell(int fd) {
|
||||||
else
|
else
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
|
||||||
sema_up (&filesys_lock);
|
lock_release (&filesys_lock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sys_close(int fd) {
|
void sys_close(int fd) {
|
||||||
sema_down (&filesys_lock);
|
lock_acquire (&filesys_lock);
|
||||||
struct fd_item i;
|
struct fd_item i;
|
||||||
i.fd = fd;
|
i.fd = fd;
|
||||||
struct hash_elem* h = hash_find(&fd_table, &i.elem);
|
struct hash_elem* h = hash_find(&fd_table, &i.elem);
|
||||||
if (h == NULL) sys_exit(-1);
|
if (h == NULL) sys_exit(-1);
|
||||||
struct fd_item* file_d = hash_entry(h, struct fd_item, elem);
|
struct fd_item* file_d = hash_entry(h, struct fd_item, elem);
|
||||||
|
//printf("File close id: %x\n", file_d);
|
||||||
if(file_d && file_d->file) {
|
if(file_d && file_d->file) {
|
||||||
|
//printf("File closed: %x\n", file_d->file);
|
||||||
file_close(file_d->file);
|
file_close(file_d->file);
|
||||||
hash_delete(&fd_table, &(file_d->elem));
|
hash_delete(&fd_table, &(file_d->elem));
|
||||||
free(file_d);
|
free(file_d);
|
||||||
}
|
}
|
||||||
sema_up (&filesys_lock);
|
lock_release (&filesys_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sys_read(int fd, void *buffer, unsigned size) {
|
int sys_read(int fd, void *buffer, unsigned size) {
|
||||||
if (check_ptr(buffer)||check_ptr(buffer+size)) return -1;
|
if (check_ptr(buffer)||check_ptr(buffer+size)) return -1;
|
||||||
sema_down (&filesys_lock);
|
lock_acquire (&filesys_lock);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if(fd == 0) {
|
if(fd == 0) {
|
||||||
|
@ -208,12 +211,10 @@ int sys_read(int fd, void *buffer, unsigned size) {
|
||||||
|
|
||||||
if (file_d && file_d->file) {
|
if (file_d && file_d->file) {
|
||||||
ret = file_read(file_d->file, buffer, size);
|
ret = file_read(file_d->file, buffer, size);
|
||||||
}
|
} else ret = -1;
|
||||||
else // no such file or can't open
|
|
||||||
ret = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sema_up (&filesys_lock);
|
lock_release (&filesys_lock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,11 +225,11 @@ int sys_write(int fd, const void *buffer, unsigned size) {
|
||||||
}
|
}
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if(fd == 1) { // write to stdout
|
if(fd == 1) {
|
||||||
putbuf(buffer, size);
|
putbuf(buffer, size);
|
||||||
ret = size;
|
ret = size;
|
||||||
} else {
|
} else {
|
||||||
sema_down (&filesys_lock);
|
lock_acquire (&filesys_lock);
|
||||||
struct fd_item i;
|
struct fd_item i;
|
||||||
i.fd = fd;
|
i.fd = fd;
|
||||||
struct hash_elem* h = hash_find(&fd_table, &i.elem);
|
struct hash_elem* h = hash_find(&fd_table, &i.elem);
|
||||||
|
@ -238,9 +239,8 @@ int sys_write(int fd, const void *buffer, unsigned size) {
|
||||||
if(file_d && file_d->file) {
|
if(file_d && file_d->file) {
|
||||||
ret = file_write(file_d->file, buffer, size);
|
ret = file_write(file_d->file, buffer, size);
|
||||||
}
|
}
|
||||||
else // no such file or can't open
|
else ret = -1;
|
||||||
ret = -1;
|
lock_release (&filesys_lock);
|
||||||
sema_up (&filesys_lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -277,9 +277,7 @@ sys_exit (int status)
|
||||||
int
|
int
|
||||||
sys_wait (tid_t tid)
|
sys_wait (tid_t tid)
|
||||||
{
|
{
|
||||||
//printf("system call wait\n");
|
|
||||||
int status = process_wait(tid);
|
int status = process_wait(tid);
|
||||||
//printf("wait has returned status(%d)\n", status);
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,6 +287,5 @@ sys_exec (const char* file_name) {
|
||||||
pagedir_get_page(thread_current()->pagedir, file_name) == NULL) {
|
pagedir_get_page(thread_current()->pagedir, file_name) == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return process_execute(file_name);
|
return process_execute(file_name);
|
||||||
}
|
}
|
|
@ -3,4 +3,6 @@
|
||||||
|
|
||||||
void syscall_init (void);
|
void syscall_init (void);
|
||||||
|
|
||||||
|
struct lock filesys_lock;
|
||||||
|
|
||||||
#endif /* userprog/syscall.h */
|
#endif /* userprog/syscall.h */
|
||||||
|
|
Reference in a new issue