Skip to main content Link Menu Expand (external link) Document Search Copy Copied

Process details

The first user program

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_wait and 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 userprog_init in userprog/process.c.

TIDs and PIDs

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)

Returns the pid_t of the process p. The pid_t type is the same type as tid_t, which is typedef’d to be an int.