Refactor System Calls and Process for Readability; Change FD to local counter and use it as hash #47

Merged
sb3923 merged 9 commits from task2/refactoring/saleh into master 2024-11-15 16:41:13 +00:00
3 changed files with 115 additions and 36 deletions
Showing only changes of commit a7f1d519da - Show all commits

View File

@@ -211,6 +211,7 @@ process_init_stack (char *cmd_saveptr, void **esp, char *file_name)
split from the command line arguments. */ split from the command line arguments. */
push_to_stack (esp, arg, strlen (arg) + 1); push_to_stack (esp, arg, strlen (arg) + 1);
/* Try to allocate memory for the argument pointer. */
struct arg_elem *arg_elem = malloc (sizeof (struct arg_elem)); struct arg_elem *arg_elem = malloc (sizeof (struct arg_elem));
if (arg_elem == NULL) if (arg_elem == NULL)
{ {
@@ -219,9 +220,11 @@ process_init_stack (char *cmd_saveptr, void **esp, char *file_name)
return false; return false;
} }
/* Store the argument pointer in the linked list. */
arg_elem->arg = *esp; arg_elem->arg = *esp;
list_push_front (&arg_list, &arg_elem->elem); list_push_front (&arg_list, &arg_elem->elem);
/* Increment the argument count and get the next argument. */
arg_count++; arg_count++;
arg = strtok_r (NULL, " ", &cmd_saveptr); arg = strtok_r (NULL, " ", &cmd_saveptr);
} }
@@ -242,7 +245,10 @@ process_init_stack (char *cmd_saveptr, void **esp, char *file_name)
int overflow_bytes = (PHYS_BASE - *esp) + remaining_size - PGSIZE; int overflow_bytes = (PHYS_BASE - *esp) + remaining_size - PGSIZE;
if (overflow_bytes > 0) if (overflow_bytes > 0)
{ {
/* Calculate the number of pages needed to allocate. */
int pages_needed = DIV_CEIL (overflow_bytes, PGSIZE); int pages_needed = DIV_CEIL (overflow_bytes, PGSIZE);
/* Allocate the pages and map them to the user process. */
for (int i = 1; i < pages_needed + 1; i++) for (int i = 1; i < pages_needed + 1; i++)
{ {
uint8_t *kpage = palloc_get_page (PAL_USER | PAL_ZERO); uint8_t *kpage = palloc_get_page (PAL_USER | PAL_ZERO);
@@ -307,11 +313,12 @@ push_to_stack (void **esp, void *data, size_t data_size)
* This function will be implemented in task 2. * This function will be implemented in task 2.
* For now, it does nothing. */ * For now, it does nothing. */
int int
process_wait (tid_t child_tid UNUSED) process_wait (tid_t child_tid)
{ {
struct process_result *child_result = NULL; struct process_result *child_result = NULL;
struct list_elem *e; struct list_elem *e;
struct thread *cur = thread_current (); struct thread *cur = thread_current ();
for (e = list_begin (&cur->child_results); for (e = list_begin (&cur->child_results);
e != list_end (&cur->child_results); e = list_next (e)) e != list_end (&cur->child_results); e = list_next (e))
{ {
@@ -319,27 +326,40 @@ process_wait (tid_t child_tid UNUSED)
= list_entry (e, struct process_result, elem); = list_entry (e, struct process_result, elem);
if (result->tid == child_tid) if (result->tid == child_tid)
{ {
/* Found the child process. */
child_result = result; child_result = result;
break; break;
} }
/* List is ordered, allowing us to break early. */
/* List is ordered, allowing us to break early if the child_tid is
greater than the current result's tid. */
else if (result->tid > child_tid) else if (result->tid > child_tid)
break; break;
} }
/* If the child process was not found, return -1. */
if (child_result == NULL) if (child_result == NULL)
return -1; return -1;
/* Wait for child to die. */ /* Wait for child to die. */
sema_down (&child_result->sema); sema_down (&child_result->sema);
/* We need lock release in process_exit, so we need to acquire (and possibly /* We need lock release in process_exit, so we need to acquire (and possibly
wait) for it here to ensure we don't free the lock memory before it is wait) for it here to ensure we don't free the lock memory before it is
released in process_exit. */ released in process_exit. */
lock_acquire (&child_result->lock); lock_acquire (&child_result->lock);
/* To prevent waiting for child twice, remove it from the list. /* To prevent waiting for child twice, remove it from the list.
No need to use lock since this is the only thread with access to No need to use lock since this is the only thread with access to
the struct process_result now. */ the struct process_result now. */
list_remove (&child_result->elem); list_remove (&child_result->elem);
/* Get the exit status of the child */
int exit_status = child_result->exit_status; int exit_status = child_result->exit_status;
/* Release the lock */
lock_release (&child_result->lock); lock_release (&child_result->lock);
free (child_result); free (child_result);
return exit_status; return exit_status;
} }