From 005791edd2dbd4e55688698e057ba38aa4619980 Mon Sep 17 00:00:00 2001 From: Gleb Koval Date: Wed, 13 Nov 2024 11:01:20 +0000 Subject: [PATCH] Synchronise process_execute return with child process load --- src/userprog/process.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/userprog/process.c b/src/userprog/process.c index 02adb34..b3140ad 100644 --- a/src/userprog/process.c +++ b/src/userprog/process.c @@ -47,6 +47,9 @@ struct process_start_data tokens while maintaining state. */ char file_name[FNAME_MAX_LEN + 1]; /* Name of the file of the process to be started. */ + bool success; /* Indicates whether the process was successfully loaded. */ + struct semaphore loaded; /* Semaphore used to signal that the process has + been loaded. */ }; static thread_func start_process NO_RETURN; @@ -67,6 +70,8 @@ process_execute (const char *cmd) { return TID_ERROR; } + sema_init (&data->loaded, 0); + data->success = false; /* Make a copy of command. Otherwise there's a race between the caller and load(). */ @@ -100,7 +105,14 @@ process_execute (const char *cmd) tid = thread_create (file_name, PRI_DEFAULT, start_process, data); if (tid == TID_ERROR) - palloc_free_page (cmd_copy); + palloc_free_page (cmd_copy); + else + { + sema_down (&data->loaded); + if (!data->success) + tid = TID_ERROR; + } + free (data); return tid; } @@ -132,6 +144,11 @@ start_process (void *proc_start_data) /* Prevent writing to the file being executed. */ struct file *exec_file = filesys_open (data->file_name); + if (exec_file == NULL) + { + lock_release (&filesys_lock); + goto fail; + } thread_current ()->exec_file = exec_file; file_deny_write (exec_file); lock_release (&filesys_lock); @@ -157,6 +174,8 @@ start_process (void *proc_start_data) goto fail; } + data->success = true; + sema_up (&data->loaded); /* Start the user process by simulating a return from an interrupt, implemented by intr_exit (in threads/intr-stubs.S). Because intr_exit takes all of its @@ -166,9 +185,10 @@ start_process (void *proc_start_data) asm volatile ("movl %0, %%esp; jmp intr_exit" : : "g" (&if_) : "memory"); NOT_REACHED (); -/* If starting the process failed, free its common resources and exit. */ - fail: - free (data); + /* If starting the process failed, exit. */ +fail: + data->success = false; + sema_up (&data->loaded); thread_exit (); } @@ -328,7 +348,6 @@ process_exit (void) if (cur->exec_file != NULL) { lock_acquire (&filesys_lock); - file_allow_write (cur->exec_file); file_close (cur->exec_file); lock_release (&filesys_lock); }