

The close-write test tests if we can write to a file that has been created / opened and then immediately closed.
#QEMU SYSTEM I386 EXIT CODE#
Perhaps we could have switched off the task of actually writing the code more often in the pair-programming task, but that requires more time pulling from the repository and getting set-up properly in Pintos. This worked really well in that everyone was always on the same page on the project-it was really good that we didn't split off tasks. No one was "in charge" of any specific part of the project. We pair-programmed the entire project-no one did any work except for the time we spent together in a room with the code on a projector and everybody calling out what to write. We also did not create a `open_file` struct-we only needed the index and the file from the array. We did change how we allocated new file descriptors, by keeping space to hold file pointers, and returning the first index in the list that is available. We didn't change much from our original scheme for this task. is about to die in `thread_schedule_tail`) With this design, we're able to accomplish `exec`, because we have the exit code of the process, and properly and efficiently deallocate threads because the parent deletes children only when it is sure that the child has fully finished (i.e. Call sema_up on children_threads_finished In `thread_schedule_tail` (called just before a thread is deallocated, so after `process_exit` has been called) Wait for each child to finish: we accomplish this by calling sema_down on the children_threads_finished semaphore (# of children) times Remove the child from the parent's list Try to sema_down the running semaphore (waits till it is sema_up'd in `process_exit`) Add child to parent's child list (+ increment number of children) In `start_process`, if `load` succeeds: Pass a reference to the parent into `start_process` along with the arguments Our original scheme was very underdeveloped, and didn't properly cover how we would implement the wait cases, so here is the final scheme:

#QEMU SYSTEM I386 EXIT DRIVER#
Our `exec/wait` scheme was the main driver for these changes. The load status variable was stored along with the other arguments, because it is set in start_process-we used an extra semaphore to wait until the executable is loaded, so we could return -1 if load fails.

A semaphore to indicate whether the children threads are finished A semaphore that indicates whether the thread has finished

A pointer to the thread struct of the parent A file pointer to the loaded current program (we call `file_deny_write` on this at the start and `file_allow_write` in `process_exit`)-we didn't address this in our first design doc A list of file pointers of the current open files (covered in the next section) A load status variable that says whether the program executable is loaded properly A semaphore that indicates whether thread has finished running or not Our original thread struct design (storing the TCB) called for: running `is_user_vaddr` and `pagedir_get_page`), and validating the pointer and the actual content if it is a string. We validated user arguments to the kernel very similarly to how we described in the design doc (i.e. Pointers to the command tokens (with an null pointer to end the array) The command chars, tokenized (4-byte aligned)ġ. Pass this struct as an argument to `start_process`ġ. Parse/tokenize arguments using `strtok_r` Create a struct in `process_execute` that has `argc` and pointers to the parsed arguments from the original command After a conversation with our TA, the final process was: Our original design for this was incomplete, it did not go into detail about how exactly the arguments were to be pushed onto the stack.
