From 0bf5fdb0e564213159ece8aa9682866d509d6998 Mon Sep 17 00:00:00 2001 From: sBubshait Date: Sun, 3 Nov 2024 22:28:17 +0000 Subject: [PATCH 01/25] Add syscall_function type definition for the different syscall handlers, w/ E --- src/userprog/syscall.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index 370c89b..6f8f660 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -6,6 +6,11 @@ static void syscall_handler (struct intr_frame *); +/* A syscall_function is a function that receives up to 3 arguments, the + arguments to the functions are either ints or pointers taking up to 32 bits + in size. */ +typedef uintptr_t syscall_function (uintptr_t, uintptr_t, uintptr_t); + void syscall_init (void) { From fa6dac21089676b48b3a4433e55ffa3b022b0f6e Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Sun, 3 Nov 2024 22:34:50 +0000 Subject: [PATCH 02/25] Implement halt system call w/ S. --- src/userprog/syscall.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index 6f8f660..1d3ef62 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -1,4 +1,5 @@ #include "userprog/syscall.h" +#include "devices/shutdown.h" #include #include #include "threads/interrupt.h" @@ -11,6 +12,9 @@ static void syscall_handler (struct intr_frame *); in size. */ typedef uintptr_t syscall_function (uintptr_t, uintptr_t, uintptr_t); +/* System Call Functions */ +static void halt (void); + void syscall_init (void) { @@ -23,3 +27,9 @@ syscall_handler (struct intr_frame *f UNUSED) printf ("system call!\n"); thread_exit (); } + +static void +halt (void) +{ + shutdown_power_off (); +} From c0f85a6bccd74349293151038bbed222b6782a7c Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Sun, 3 Nov 2024 22:36:22 +0000 Subject: [PATCH 03/25] Implement skeleton for exit command w/ S. --- src/userprog/syscall.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index 1d3ef62..5fec7d3 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -14,6 +14,7 @@ typedef uintptr_t syscall_function (uintptr_t, uintptr_t, uintptr_t); /* System Call Functions */ static void halt (void); +static void exit (int status); void syscall_init (void) @@ -33,3 +34,9 @@ halt (void) { shutdown_power_off (); } + +static void +exit (int status) +{ + //TODO +} \ No newline at end of file From 62453ef432877ec31ea8b72b810d321260301982 Mon Sep 17 00:00:00 2001 From: sBubshait Date: Sun, 3 Nov 2024 22:54:03 +0000 Subject: [PATCH 04/25] Add a look up table from system call numbers to their handler functions, w/ E --- src/userprog/syscall.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index 5fec7d3..6e7fb17 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -10,12 +10,24 @@ static void syscall_handler (struct intr_frame *); /* A syscall_function is a function that receives up to 3 arguments, the arguments to the functions are either ints or pointers taking up to 32 bits in size. */ -typedef uintptr_t syscall_function (uintptr_t, uintptr_t, uintptr_t); +typedef uintptr_t (*syscall_function) (uintptr_t, uintptr_t, uintptr_t); /* System Call Functions */ static void halt (void); static void exit (int status); +/* A struct defining a pair of a syscall_function along with its arity. */ +typedef struct { + syscall_function function; + int arity; +} syscall_arguments; + +/* A look-up table for system call functions mapped using their numbers. */ +static const syscall_arguments syscall_lookup[] = { + [SYS_HALT] = {(syscall_function) halt, 0}, + [SYS_EXIT] = {(syscall_function) exit, 1}, +}; + void syscall_init (void) { From 87126237ad7ac56cac1062982d05b13c4179690f Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Sun, 3 Nov 2024 23:20:42 +0000 Subject: [PATCH 05/25] Implement function to validate user memory pointers w/ S. --- src/userprog/syscall.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index 6e7fb17..9164142 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -1,5 +1,6 @@ #include "userprog/syscall.h" #include "devices/shutdown.h" +#include "threads/vaddr.h" #include #include #include "threads/interrupt.h" @@ -51,4 +52,15 @@ static void exit (int status) { //TODO +} + +/* A function to validate if a block of memory starting at PTR and of + size SIZE bytes is fully contained within user virtual memory. */ +static void * +validate_user_pointer (void *ptr, size_t size) +{ + if (ptr == NULL || !is_user_vaddr (ptr) || !is_user_vaddr (ptr + size - 1)) + thread_exit (); + + return ptr; } \ No newline at end of file From d626b7a392aca74c5327daf493d5183a24571106 Mon Sep 17 00:00:00 2001 From: sBubshait Date: Sun, 3 Nov 2024 23:47:22 +0000 Subject: [PATCH 06/25] Implement basic syscall_handler using the lookup table, w/ E --- src/userprog/syscall.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index 9164142..5e53cd3 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -17,6 +17,8 @@ typedef uintptr_t (*syscall_function) (uintptr_t, uintptr_t, uintptr_t); static void halt (void); static void exit (int status); +static void *validate_user_pointer(void *ptr, size_t size); + /* A struct defining a pair of a syscall_function along with its arity. */ typedef struct { syscall_function function; @@ -29,6 +31,9 @@ static const syscall_arguments syscall_lookup[] = { [SYS_EXIT] = {(syscall_function) exit, 1}, }; +static const int lookup_size + = sizeof (syscall_lookup) / sizeof (syscall_arguments); + void syscall_init (void) { @@ -36,10 +41,23 @@ syscall_init (void) } static void -syscall_handler (struct intr_frame *f UNUSED) +syscall_handler (struct intr_frame *f) { - printf ("system call!\n"); - thread_exit (); + validate_user_pointer(f->esp, 1); + int syscall_number = *(int *) f->esp; + + if (syscall_number < 0 || syscall_number >= lookup_size) + thread_exit (); + + syscall_arguments syscall = syscall_lookup[syscall_number]; + + validate_user_pointer (f->esp, syscall.arity); + uintptr_t args[3]; + + for (int i=0; i < syscall.arity; i++) + args[i] = *(uintptr_t *) (f->esp + 1 + i); + + f->eax = syscall.function(args[0], args[1], args[2]); } static void From ade8faf0f4abe285c103f8085dd2d8fe22c58197 Mon Sep 17 00:00:00 2001 From: sBubshait Date: Mon, 4 Nov 2024 00:20:09 +0000 Subject: [PATCH 07/25] Update syscall to add more comments explaining the basic handler --- src/userprog/syscall.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index 5e53cd3..2926bbd 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -13,24 +13,27 @@ static void syscall_handler (struct intr_frame *); in size. */ typedef uintptr_t (*syscall_function) (uintptr_t, uintptr_t, uintptr_t); -/* System Call Functions */ +/* System call function prototypes */ static void halt (void); static void exit (int status); static void *validate_user_pointer(void *ptr, size_t size); -/* A struct defining a pair of a syscall_function along with its arity. */ +/* A struct defining a syscall_function pointer along with its arity. */ typedef struct { - syscall_function function; - int arity; + syscall_function function; /* Function pointer. */ + int arity; /* Number of arguments of the function. */ } syscall_arguments; -/* A look-up table for system call functions mapped using their numbers. */ +/* A look-up table mapping numbers to system call functions with their number of + arguments. */ static const syscall_arguments syscall_lookup[] = { [SYS_HALT] = {(syscall_function) halt, 0}, [SYS_EXIT] = {(syscall_function) exit, 1}, }; +/* The number of syscall functions (i.e, number of elements) within the + syscall_lookup table. */ static const int lookup_size = sizeof (syscall_lookup) / sizeof (syscall_arguments); @@ -43,20 +46,24 @@ syscall_init (void) static void syscall_handler (struct intr_frame *f) { + /* First, read the system call number from the stack. */ validate_user_pointer(f->esp, 1); int syscall_number = *(int *) f->esp; + /* Ensures the number corresponds to a system call that can be handled. */ if (syscall_number < 0 || syscall_number >= lookup_size) thread_exit (); syscall_arguments syscall = syscall_lookup[syscall_number]; + /* Next, read and copy the arguments from the stack pointer. */ validate_user_pointer (f->esp, syscall.arity); uintptr_t args[3]; - for (int i=0; i < syscall.arity; i++) args[i] = *(uintptr_t *) (f->esp + 1 + i); + /* Call the function that handles this system call with the arguments. When + there is a return value it is stored in f->eax. */ f->eax = syscall.function(args[0], args[1], args[2]); } @@ -67,13 +74,13 @@ halt (void) } static void -exit (int status) +exit (int status UNUSED) { //TODO } -/* A function to validate if a block of memory starting at PTR and of - size SIZE bytes is fully contained within user virtual memory. */ +/* Validates if a block of memory starting at PTR and of size SIZE bytes is + fully contained within user virtual memory. */ static void * validate_user_pointer (void *ptr, size_t size) { From e718159ed89acf205213caf4cb218a52bb5312d0 Mon Sep 17 00:00:00 2001 From: sBubshait Date: Mon, 4 Nov 2024 00:29:07 +0000 Subject: [PATCH 08/25] Update syscall to use screaming uppercase casing for a constant --- src/userprog/syscall.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index 2926bbd..ddbbd39 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -34,7 +34,7 @@ static const syscall_arguments syscall_lookup[] = { /* The number of syscall functions (i.e, number of elements) within the syscall_lookup table. */ -static const int lookup_size +static const int LOOKUP_SIZE = sizeof (syscall_lookup) / sizeof (syscall_arguments); void @@ -51,7 +51,7 @@ syscall_handler (struct intr_frame *f) int syscall_number = *(int *) f->esp; /* Ensures the number corresponds to a system call that can be handled. */ - if (syscall_number < 0 || syscall_number >= lookup_size) + if (syscall_number < 0 || syscall_number >= LOOKUP_SIZE) thread_exit (); syscall_arguments syscall = syscall_lookup[syscall_number]; From 3a258cf064c51f6f69df48a5bf37de9097f337c7 Mon Sep 17 00:00:00 2001 From: sBubshait Date: Mon, 4 Nov 2024 00:38:58 +0000 Subject: [PATCH 09/25] Update validate_user_pointer to perform no memory checks when size is 0 --- src/userprog/syscall.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index ddbbd39..fc8c28e 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -80,11 +80,15 @@ exit (int status UNUSED) } /* Validates if a block of memory starting at PTR and of size SIZE bytes is - fully contained within user virtual memory. */ + fully contained within user virtual memory. Kills the thread (by calling + thread_exit) if the memory is invalid. Otherwise, returns the PTR given. + If the size is 0, the function does no checks and returns PTR.*/ static void * validate_user_pointer (void *ptr, size_t size) { - if (ptr == NULL || !is_user_vaddr (ptr) || !is_user_vaddr (ptr + size - 1)) + if (size > 0 && (ptr == NULL || + !is_user_vaddr (ptr) || + !is_user_vaddr (ptr + size - 1))) thread_exit (); return ptr; From 79f6a8e8080dfd2fc15fd9bd31dc0365600c4600 Mon Sep 17 00:00:00 2001 From: sBubshait Date: Mon, 4 Nov 2024 00:44:55 +0000 Subject: [PATCH 10/25] Fix Bug in syscall handler related to pointer arithmetic: add sizeof uintptr_t instead of 1 --- src/userprog/syscall.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index fc8c28e..e2f0163 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -57,10 +57,11 @@ syscall_handler (struct intr_frame *f) syscall_arguments syscall = syscall_lookup[syscall_number]; /* Next, read and copy the arguments from the stack pointer. */ - validate_user_pointer (f->esp, syscall.arity); - uintptr_t args[3]; + validate_user_pointer (f->esp + sizeof (uintptr_t), + syscall.arity * sizeof (uintptr_t)); + uintptr_t args[3] = {0}; for (int i=0; i < syscall.arity; i++) - args[i] = *(uintptr_t *) (f->esp + 1 + i); + args[i] = *(uintptr_t *) (f->esp + sizeof (uintptr_t) * (i + 1)); /* Call the function that handles this system call with the arguments. When there is a return value it is stored in f->eax. */ From 0d057da3dc56dd90fa487df96daf3410ac5ae65d Mon Sep 17 00:00:00 2001 From: sBubshait Date: Mon, 4 Nov 2024 00:48:36 +0000 Subject: [PATCH 11/25] Refactor syscall to follow PintOS style in adding space after after function name in calls --- src/userprog/syscall.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index e2f0163..f225b41 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -17,17 +17,19 @@ typedef uintptr_t (*syscall_function) (uintptr_t, uintptr_t, uintptr_t); static void halt (void); static void exit (int status); -static void *validate_user_pointer(void *ptr, size_t size); +static void *validate_user_pointer (void *ptr, size_t size); /* A struct defining a syscall_function pointer along with its arity. */ -typedef struct { - syscall_function function; /* Function pointer. */ - int arity; /* Number of arguments of the function. */ -} syscall_arguments; +typedef struct + { + syscall_function function; /* Function pointer. */ + int arity; /* Number of arguments of the function. */ + } syscall_arguments; /* A look-up table mapping numbers to system call functions with their number of arguments. */ -static const syscall_arguments syscall_lookup[] = { +static const syscall_arguments syscall_lookup[] = +{ [SYS_HALT] = {(syscall_function) halt, 0}, [SYS_EXIT] = {(syscall_function) exit, 1}, }; @@ -47,7 +49,7 @@ static void syscall_handler (struct intr_frame *f) { /* First, read the system call number from the stack. */ - validate_user_pointer(f->esp, 1); + validate_user_pointer (f->esp, 1); int syscall_number = *(int *) f->esp; /* Ensures the number corresponds to a system call that can be handled. */ @@ -65,7 +67,7 @@ syscall_handler (struct intr_frame *f) /* Call the function that handles this system call with the arguments. When there is a return value it is stored in f->eax. */ - f->eax = syscall.function(args[0], args[1], args[2]); + f->eax = syscall.function (args[0], args[1], args[2]); } static void From 5e2342fad781a75a70bf6f7bda65d8b2b3d71e1a Mon Sep 17 00:00:00 2001 From: sBubshait Date: Mon, 4 Nov 2024 00:49:47 +0000 Subject: [PATCH 12/25] Update syscall to make syscall_number an unsigned integer instead of an int --- src/userprog/syscall.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index f225b41..2b504ec 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -50,10 +50,10 @@ syscall_handler (struct intr_frame *f) { /* First, read the system call number from the stack. */ validate_user_pointer (f->esp, 1); - int syscall_number = *(int *) f->esp; + unsigned syscall_number = *(int *) f->esp; /* Ensures the number corresponds to a system call that can be handled. */ - if (syscall_number < 0 || syscall_number >= LOOKUP_SIZE) + if (syscall_number >= LOOKUP_SIZE) thread_exit (); syscall_arguments syscall = syscall_lookup[syscall_number]; From 4c27aa020309f756de85b39b9879dfe2f544b123 Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Mon, 4 Nov 2024 00:57:19 +0000 Subject: [PATCH 13/25] Complete syscall lookup table, and syscall stubs and skeletons w/ S. --- src/userprog/syscall.c | 97 ++++++++++++++++++++++++++++++++++++++++++ src/userprog/syscall.h | 2 + 2 files changed, 99 insertions(+) diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index 5e53cd3..0e0a050 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -16,6 +16,17 @@ typedef uintptr_t (*syscall_function) (uintptr_t, uintptr_t, uintptr_t); /* System Call Functions */ static void halt (void); static void exit (int status); +static pid_t exec (const char *cmd_line); +static int wait (pid_t pid); +static bool file_create (const char *file, unsigned initial_size); +static bool file_remove (const char *file); +static int open (const char *file); +static int filesize (int fd); +static int read (int fd, void *buffer, unsigned size); +static int write (int fd, const void *buffer, unsigned size); +static void seek (int fd, unsigned position); +static unsigned tell (int fd); +static void close (int fd); static void *validate_user_pointer(void *ptr, size_t size); @@ -29,6 +40,17 @@ typedef struct { static const syscall_arguments syscall_lookup[] = { [SYS_HALT] = {(syscall_function) halt, 0}, [SYS_EXIT] = {(syscall_function) exit, 1}, + [SYS_EXEC] = {(syscall_function) exec, 1}, + [SYS_WAIT] = {(syscall_function) wait, 1}, + [SYS_CREATE] = {(syscall_function) file_create, 2}, + [SYS_REMOVE] = {(syscall_function) file_remove, 1}, + [SYS_OPEN] = {(syscall_function) open, 1}, + [SYS_FILESIZE] = {(syscall_function) filesize, 1}, + [SYS_READ] = {(syscall_function) read, 3}, + [SYS_WRITE] = {(syscall_function) write, 3}, + [SYS_SEEK] = {(syscall_function) seek, 2}, + [SYS_TELL] = {(syscall_function) tell, 1}, + [SYS_CLOSE] = {(syscall_function) close, 1}, }; static const int lookup_size @@ -72,6 +94,81 @@ exit (int status) //TODO } +static pid_t +exec (const char *cmd_line) +{ + //TODO + return 0; +} + +static int +wait (pid_t pid) +{ + //TODO + return 0; +} + +static bool +file_create (const char *file, unsigned initial_size) +{ + //TODO + return 0; +} + +static bool +file_remove (const char *file) +{ + //TODO + return 0; +} + +static int +open (const char *file) +{ + //TODO + return 0; +} + +static int +filesize (int fd) +{ + //TODO + return 0; +} + +static int +read (int fd, void *buffer, unsigned size) +{ + //TODO + return 0; +} + +static int +write (int fd, const void *buffer, unsigned size) +{ + //TODO + return 0; +} + +static void +seek (int fd, unsigned position) +{ + //TODO +} + +static unsigned +tell (int fd) +{ + //TODO + return 0; +} + +static void +close (int fd) +{ + //TODO +} + /* A function to validate if a block of memory starting at PTR and of size SIZE bytes is fully contained within user virtual memory. */ static void * diff --git a/src/userprog/syscall.h b/src/userprog/syscall.h index 9059096..702a6c7 100644 --- a/src/userprog/syscall.h +++ b/src/userprog/syscall.h @@ -1,6 +1,8 @@ #ifndef USERPROG_SYSCALL_H #define USERPROG_SYSCALL_H +typedef int pid_t; + void syscall_init (void); #endif /* userprog/syscall.h */ From f8e529e87748ae9c0a9c69544259425ca3fbe59b Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Mon, 4 Nov 2024 01:02:04 +0000 Subject: [PATCH 14/25] Add UNUSED tag to system call function skeletons w/ S. --- src/userprog/syscall.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index 61682aa..fedd1a4 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -105,76 +105,76 @@ exit (int status UNUSED) } static pid_t -exec (const char *cmd_line) +exec (const char *cmd_line UNUSED) { //TODO return 0; } static int -wait (pid_t pid) +wait (pid_t pid UNUSED) { //TODO return 0; } static bool -file_create (const char *file, unsigned initial_size) +file_create (const char *file UNUSED, unsigned initial_size UNUSED) { //TODO return 0; } static bool -file_remove (const char *file) +file_remove (const char *file UNUSED) { //TODO return 0; } static int -open (const char *file) +open (const char *file UNUSED) { //TODO return 0; } static int -filesize (int fd) +filesize (int fd UNUSED) { //TODO return 0; } static int -read (int fd, void *buffer, unsigned size) +read (int fd UNUSED, void *buffer UNUSED, unsigned size UNUSED) { //TODO return 0; } static int -write (int fd, const void *buffer, unsigned size) +write (int fd UNUSED, const void *buffer UNUSED, unsigned size UNUSED) { //TODO return 0; } static void -seek (int fd, unsigned position) +seek (int fd UNUSED, unsigned position UNUSED) { //TODO } static unsigned -tell (int fd) +tell (int fd UNUSED) { //TODO return 0; } static void -close (int fd) +close (int fd UNUSED) { //TODO } From 2dccd87a76992159c2540604d5f8bd4ec8527982 Mon Sep 17 00:00:00 2001 From: sBubshait Date: Tue, 5 Nov 2024 22:38:09 +0000 Subject: [PATCH 15/25] Update thread to add exit_status, intialised to -1, into the thread structure, w/ E --- src/threads/thread.c | 2 ++ src/threads/thread.h | 1 + 2 files changed, 3 insertions(+) diff --git a/src/threads/thread.c b/src/threads/thread.c index 7102ad2..457f7b9 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -659,6 +659,8 @@ init_thread (struct thread *t, const char *name, int nice, int priority, t->recent_cpu = recent_cpu; t->priority = t->base_priority; + t->exit_status = -1; + old_level = intr_disable (); list_push_back (&all_list, &t->allelem); intr_set_level (old_level); diff --git a/src/threads/thread.h b/src/threads/thread.h index c7cc364..1c05030 100644 --- a/src/threads/thread.h +++ b/src/threads/thread.h @@ -111,6 +111,7 @@ struct thread /* Shared between thread.c and synch.c. */ struct list_elem elem; /* List element. */ + int exit_status; /* Exit Status: 0 = successful exit. */ #ifdef USERPROG /* Owned by userprog/process.c. */ From e9c4061531a26621b24e04eac0280384cd509182 Mon Sep 17 00:00:00 2001 From: sBubshait Date: Tue, 5 Nov 2024 22:38:45 +0000 Subject: [PATCH 16/25] Implement the exit system call, w/ E --- src/userprog/syscall.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index fedd1a4..5113292 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -99,9 +99,12 @@ halt (void) } static void -exit (int status UNUSED) +exit (int status) { - //TODO + /* Sets exit_status of the thread to status. thread_exit () will call + process_exit () if user programs are allowed. */ + thread_current ()->exit_status = status; + thread_exit (); } static pid_t From 421f2c1206933624a58e9ad82bcf51c24e3ffcc4 Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Tue, 5 Nov 2024 22:46:21 +0000 Subject: [PATCH 17/25] Refactor function names and includes in syscall.c to avoid conflicts w/ S. --- src/userprog/syscall.c | 82 +++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index 5113292..3cb3d69 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -1,10 +1,10 @@ #include "userprog/syscall.h" #include "devices/shutdown.h" #include "threads/vaddr.h" -#include -#include #include "threads/interrupt.h" #include "threads/thread.h" +#include +#include static void syscall_handler (struct intr_frame *); @@ -14,19 +14,19 @@ static void syscall_handler (struct intr_frame *); typedef uintptr_t (*syscall_function) (uintptr_t, uintptr_t, uintptr_t); /* System call function prototypes */ -static void halt (void); -static void exit (int status); -static pid_t exec (const char *cmd_line); -static int wait (pid_t pid); -static bool file_create (const char *file, unsigned initial_size); -static bool file_remove (const char *file); -static int open (const char *file); -static int filesize (int fd); -static int read (int fd, void *buffer, unsigned size); -static int write (int fd, const void *buffer, unsigned size); -static void seek (int fd, unsigned position); -static unsigned tell (int fd); -static void close (int fd); +static void syscall_halt (void); +static void syscall_exit (int status); +static pid_t syscall_exec (const char *cmd_line); +static int syscall_wait (pid_t pid); +static bool syscall_create (const char *file, unsigned initial_size); +static bool syscall_remove (const char *file); +static int syscall_open (const char *file); +static int syscall_filesize (int fd); +static int syscall_read (int fd, void *buffer, unsigned size); +static int syscall_write (int fd, const void *buffer, unsigned size); +static void syscall_seek (int fd, unsigned position); +static unsigned syscall_tell (int fd); +static void syscall_close (int fd); static void *validate_user_pointer (void *ptr, size_t size); @@ -41,19 +41,19 @@ typedef struct arguments. */ static const syscall_arguments syscall_lookup[] = { - [SYS_HALT] = {(syscall_function) halt, 0}, - [SYS_EXIT] = {(syscall_function) exit, 1}, - [SYS_EXEC] = {(syscall_function) exec, 1}, - [SYS_WAIT] = {(syscall_function) wait, 1}, - [SYS_CREATE] = {(syscall_function) file_create, 2}, - [SYS_REMOVE] = {(syscall_function) file_remove, 1}, - [SYS_OPEN] = {(syscall_function) open, 1}, - [SYS_FILESIZE] = {(syscall_function) filesize, 1}, - [SYS_READ] = {(syscall_function) read, 3}, - [SYS_WRITE] = {(syscall_function) write, 3}, - [SYS_SEEK] = {(syscall_function) seek, 2}, - [SYS_TELL] = {(syscall_function) tell, 1}, - [SYS_CLOSE] = {(syscall_function) close, 1}, + [SYS_HALT] = {(syscall_function) syscall_halt, 0}, + [SYS_EXIT] = {(syscall_function) syscall_exit, 1}, + [SYS_EXEC] = {(syscall_function) syscall_exec, 1}, + [SYS_WAIT] = {(syscall_function) syscall_wait, 1}, + [SYS_CREATE] = {(syscall_function) syscall_create, 2}, + [SYS_REMOVE] = {(syscall_function) syscall_remove, 1}, + [SYS_OPEN] = {(syscall_function) syscall_open, 1}, + [SYS_FILESIZE] = {(syscall_function) syscall_filesize, 1}, + [SYS_READ] = {(syscall_function) syscall_read, 3}, + [SYS_WRITE] = {(syscall_function) syscall_write, 3}, + [SYS_SEEK] = {(syscall_function) syscall_seek, 2}, + [SYS_TELL] = {(syscall_function) syscall_tell, 1}, + [SYS_CLOSE] = {(syscall_function) syscall_close, 1}, }; /* The number of syscall functions (i.e, number of elements) within the @@ -93,13 +93,13 @@ syscall_handler (struct intr_frame *f) } static void -halt (void) +syscall_halt (void) { shutdown_power_off (); } static void -exit (int status) +syscall_exit (int status) { /* Sets exit_status of the thread to status. thread_exit () will call process_exit () if user programs are allowed. */ @@ -108,76 +108,76 @@ exit (int status) } static pid_t -exec (const char *cmd_line UNUSED) +syscall_exec (const char *cmd_line UNUSED) { //TODO return 0; } static int -wait (pid_t pid UNUSED) +syscall_wait (pid_t pid UNUSED) { //TODO return 0; } static bool -file_create (const char *file UNUSED, unsigned initial_size UNUSED) +syscall_create (const char *file UNUSED, unsigned initial_size UNUSED) { //TODO return 0; } static bool -file_remove (const char *file UNUSED) +syscall_remove (const char *file UNUSED) { //TODO return 0; } static int -open (const char *file UNUSED) +syscall_open (const char *file UNUSED) { //TODO return 0; } static int -filesize (int fd UNUSED) +syscall_filesize (int fd UNUSED) { //TODO return 0; } static int -read (int fd UNUSED, void *buffer UNUSED, unsigned size UNUSED) +syscall_read (int fd UNUSED, void *buffer UNUSED, unsigned size UNUSED) { //TODO return 0; } static int -write (int fd UNUSED, const void *buffer UNUSED, unsigned size UNUSED) +syscall_write (int fd UNUSED, const void *buffer UNUSED, unsigned size UNUSED) { //TODO return 0; } static void -seek (int fd UNUSED, unsigned position UNUSED) +syscall_seek (int fd UNUSED, unsigned position UNUSED) { //TODO } static unsigned -tell (int fd UNUSED) +syscall_tell (int fd UNUSED) { //TODO return 0; } static void -close (int fd UNUSED) +syscall_close (int fd UNUSED) { //TODO } From b3e23eb1ccf68a828175db9cbf1f32f870a652ef Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Tue, 5 Nov 2024 22:48:35 +0000 Subject: [PATCH 18/25] Implement system call wait w/ S. --- src/userprog/syscall.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index 3cb3d69..6eb1bce 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -3,6 +3,7 @@ #include "threads/vaddr.h" #include "threads/interrupt.h" #include "threads/thread.h" +#include "userprog/process.h" #include #include @@ -115,10 +116,9 @@ syscall_exec (const char *cmd_line UNUSED) } static int -syscall_wait (pid_t pid UNUSED) +syscall_wait (pid_t pid) { - //TODO - return 0; + return process_wait (pid); } static bool From 01933cb5de852bcb14b1b225c7512eb0aa8c2255 Mon Sep 17 00:00:00 2001 From: sBubshait Date: Tue, 5 Nov 2024 23:07:07 +0000 Subject: [PATCH 19/25] Implement the write system call, w/ E --- src/userprog/syscall.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index 6eb1bce..dbcd3b8 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -29,7 +29,7 @@ static void syscall_seek (int fd, unsigned position); static unsigned syscall_tell (int fd); static void syscall_close (int fd); -static void *validate_user_pointer (void *ptr, size_t size); +static void *validate_user_pointer (const void *ptr, size_t size); /* A struct defining a syscall_function pointer along with its arity. */ typedef struct @@ -157,10 +157,26 @@ syscall_read (int fd UNUSED, void *buffer UNUSED, unsigned size UNUSED) } static int -syscall_write (int fd UNUSED, const void *buffer UNUSED, unsigned size UNUSED) +syscall_write (int fd, const void *buffer, unsigned size) { - //TODO - return 0; + /* Only console (fd = 1) or other files, not including STDIN, (fd > 1) are + allowed. */ + if (fd <= 0) + return 0; + + validate_user_pointer (buffer, size); + + if (fd == STDOUT_FILENO) + { + /* Writing to the console. */ + putbuf (buffer, size); + return size; + } + else + { + /* Writing to a file. */ + return 0; // TODO: Implement Write to Files + } } static void @@ -187,7 +203,7 @@ syscall_close (int fd UNUSED) thread_exit) if the memory is invalid. Otherwise, returns the PTR given. If the size is 0, the function does no checks and returns PTR.*/ static void * -validate_user_pointer (void *ptr, size_t size) +validate_user_pointer (const void *ptr, size_t size) { if (size > 0 && (ptr == NULL || !is_user_vaddr (ptr) || From f4290c31f325b734b0d1acca1df44b048746b99f Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Tue, 5 Nov 2024 23:20:18 +0000 Subject: [PATCH 20/25] Implement syscall_read for console input w/ S. --- src/userprog/syscall.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index dbcd3b8..6027de2 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -1,5 +1,6 @@ #include "userprog/syscall.h" #include "devices/shutdown.h" +#include "devices/input.h" #include "threads/vaddr.h" #include "threads/interrupt.h" #include "threads/thread.h" @@ -150,10 +151,29 @@ syscall_filesize (int fd UNUSED) } static int -syscall_read (int fd UNUSED, void *buffer UNUSED, unsigned size UNUSED) +syscall_read (int fd, void *buffer, unsigned size) { - //TODO - return 0; + /* Only console (fd = 0) or other files, not including STDOUT, (fd > 1) are + allowed. */ + if (fd < 0 && fd != STDOUT_FILENO) + return -1; + + validate_user_pointer (buffer, size); + + if (fd == STDIN_FILENO) + { + /* Reading from the console. */ + char *write_buffer = buffer; + for (int i = 0; i < size; i++) + write_buffer[i] = input_getc (); + + return size; + } + else + { + /* Reading from a file. */ + return 0; // TODO: Implement Write to Files + } } static int From 02fff62ca2dd77af8f59a9630337a0200dae040b Mon Sep 17 00:00:00 2001 From: sBubshait Date: Tue, 5 Nov 2024 23:24:41 +0000 Subject: [PATCH 21/25] Refactor syscall.c to follow PintOS styling, w/ E --- src/userprog/syscall.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index 6027de2..1dbe73b 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -161,19 +161,19 @@ syscall_read (int fd, void *buffer, unsigned size) validate_user_pointer (buffer, size); if (fd == STDIN_FILENO) - { - /* Reading from the console. */ - char *write_buffer = buffer; - for (int i = 0; i < size; i++) - write_buffer[i] = input_getc (); + { + /* Reading from the console. */ + char *write_buffer = buffer; + for (int i = 0; i < size; i++) + write_buffer[i] = input_getc (); - return size; - } + return size; + } else - { - /* Reading from a file. */ - return 0; // TODO: Implement Write to Files - } + { + /* Reading from a file. */ + return 0; // TODO: Implement Write to Files + } } static int @@ -231,4 +231,4 @@ validate_user_pointer (const void *ptr, size_t size) thread_exit (); return ptr; -} \ No newline at end of file +} From 5aac37d1674dfc5b3b32ea5c53b5d80376283914 Mon Sep 17 00:00:00 2001 From: sBubshait Date: Tue, 5 Nov 2024 23:28:17 +0000 Subject: [PATCH 22/25] Add temporary fixes to process_wait and setup stack, w/ E --- src/userprog/process.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/userprog/process.c b/src/userprog/process.c index 49b9bd5..c9f6339 100644 --- a/src/userprog/process.c +++ b/src/userprog/process.c @@ -14,6 +14,7 @@ #include "threads/flags.h" #include "threads/init.h" #include "threads/interrupt.h" +#include "threads/synch.h" #include "threads/palloc.h" #include "threads/thread.h" #include "threads/vaddr.h" @@ -88,7 +89,8 @@ start_process (void *file_name_) int process_wait (tid_t child_tid UNUSED) { - return -1; + for (;;) + barrier (); } /* Free the current process's resources. */ @@ -451,7 +453,7 @@ setup_stack (void **esp) { success = install_page (((uint8_t *) PHYS_BASE) - PGSIZE, kpage, true); if (success) - *esp = PHYS_BASE; + *esp = PHYS_BASE - 12; else palloc_free_page (kpage); } From 91cef4d650922cc341b7d40fdd7038cde333039e Mon Sep 17 00:00:00 2001 From: sBubshait Date: Wed, 6 Nov 2024 15:36:56 +0000 Subject: [PATCH 23/25] Refactor lock release and sema up to remove unnecessary code --- src/threads/synch.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/threads/synch.c b/src/threads/synch.c index 09fc71f..d706d19 100644 --- a/src/threads/synch.c +++ b/src/threads/synch.c @@ -113,28 +113,33 @@ void sema_up (struct semaphore *sema) { enum intr_level old_level; + bool thread_unblocked = false; /* Flag to track if any thread was woken up. */ ASSERT (sema != NULL); old_level = intr_disable (); if (!list_empty (&sema->waiters)) - { - /* Enforces wake-up of the highest priority thread waiting for the - semaphore. */ - struct list_elem *e = list_max (&sema->waiters, priority_less, NULL); - list_remove (e); - thread_unblock (list_entry (e, struct thread, elem)); - } + { + /* Enforces wake-up of the highest priority thread waiting for the + semaphore. */ + struct list_elem *e = list_max (&sema->waiters, priority_less, NULL); + list_remove (e); + thread_unblock (list_entry (e, struct thread, elem)); + thread_unblocked = true; + } sema->value++; intr_set_level (old_level); /* Yields the CPU in case the thread that has been woken up has a higher priority that the current running thread, including the case when called within an interrupt handler. */ - if (intr_context ()) - intr_yield_on_return (); - else - thread_yield (); + if (thread_unblocked) + { + if (intr_context ()) + intr_yield_on_return (); + else + thread_yield (); + } } static void sema_test_helper (void *sema_); @@ -347,7 +352,6 @@ lock_release (struct lock *lock) lock->holder = NULL; sema_up (&lock->semaphore); - thread_yield (); } /* Returns true if the current thread holds LOCK, false From ab716de0a6ed8dcb7b2f880dd3466d14fd727c11 Mon Sep 17 00:00:00 2001 From: sBubshait Date: Wed, 6 Nov 2024 15:46:47 +0000 Subject: [PATCH 24/25] Update process_wait to temporarily sleep for 1 second to allow user programs to run --- src/userprog/process.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/userprog/process.c b/src/userprog/process.c index 49b9bd5..017e14b 100644 --- a/src/userprog/process.c +++ b/src/userprog/process.c @@ -17,6 +17,7 @@ #include "threads/palloc.h" #include "threads/thread.h" #include "threads/vaddr.h" +#include "devices/timer.h" static thread_func start_process NO_RETURN; static bool load (const char *cmdline, void (**eip) (void), void **esp); @@ -88,7 +89,12 @@ start_process (void *file_name_) int process_wait (tid_t child_tid UNUSED) { - return -1; + /* As a temporary wait, waiting will just put the thread to sleep for one + second (TIMER_FREQ = 100 ticks ~ 1 second). */ + /* TODO: Implement process_wait () correctly. Remove the next line. */ + timer_sleep (TIMER_FREQ); + + return 0; /* TODO: Change this too */ } /* Free the current process's resources. */ From fcb7e9e4414d320bef117be95326c81f69d35b98 Mon Sep 17 00:00:00 2001 From: sBubshait Date: Wed, 6 Nov 2024 15:48:27 +0000 Subject: [PATCH 25/25] Update setup_stack to temporarily fake set-up for a stack to prevent page faults in no arg user programs --- src/userprog/process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/userprog/process.c b/src/userprog/process.c index 017e14b..cde4b4a 100644 --- a/src/userprog/process.c +++ b/src/userprog/process.c @@ -457,7 +457,7 @@ setup_stack (void **esp) { success = install_page (((uint8_t *) PHYS_BASE) - PGSIZE, kpage, true); if (success) - *esp = PHYS_BASE; + *esp = PHYS_BASE - 12; else palloc_free_page (kpage); }