All user programs are spawned from other user programs using the exec system call. So how is the first user program created? When the operating system starts up, it first runs
threads/init.c. If the command-line arguments to Pintos indicate that the user wants to start running user programs, the
run_task function is called, which has the main thread of Pintos (the one running the
threads/init.c code) call
process_wait(process_execute(task)). So, the first user program is created by the main thread of the OS.
Quick sidebar: it’s important to disambiguate between the “main” thread of the OS and the main thread of a user program. The main thread of Pintos is the thread that runs
threads/init.c – it is the thread that sets up the OS and starts running the first task, whether that is a user program or a kernel task. The type of task is dependent on the command-line arguments to Pintos. On the other hand, the main thread of a user program is the single thread that is running when that user program is first created. It should be clear from context which “main” thread we are referring to.
Because the first user program is created by the OS’s main thread, the OS’s main thread must have a PCB, even though it is not a process and will never run user-level code. This is because our implementation of
process_execute require the parent “process” to have access to a list of all child process’ completion statuses. So, in the
userprog_init function, we give the OS’s main thread a (minimal) PCB so that it can successfully execute those functions. Right now, it’s only possible that the main thread tries to access the
children list in those functions. However, if you modify those functions so that the main thread must access another member of struct process, you must initialize that member in
In the starter code, we define the process ID (PID) of a process to be the thread ID (TID) of its main thread. The following two functions in
userprog/process.c are related:
bool is_main_thread(struct thread* t, struct process* p)
Returns true if t is the main thread of p.
pid_t get_pid(struct process* p)
pid_tof the process p. The
pid_ttype is the same type as
tid_t, which is
typedef’d to be an