2. For this assignment, you will be working in the "threads" directory. Edit threadtest.cc to run the code listed below. For each procedure call/return, give the name of the thread doing the call/return, the procedure name, and the values of any significant arguments. You only have to list calls and returns to routines defined in thread.cc, scheduler.cc, and switch.s, calls to Interrupt:SetLevel(), and calls to the functions defined below. In other words, you can ignore ASSERT statements, DEBUG statements, calls to list routines, calls made internal to the interrupt simulation, and any trivial inline functions. You should also assume that timer interrupts are disabled, so there is no preemption. You should also assume that there are no threads on the ready list when SelfTest is called. For example, you solution should begin: readylist = NULL; running "main" In "main" calling SelfTest In "main" calling Thread::Thread("child 1") In "main" returning from Thread::Thread("child 1") The readylist will list all threads currently in the ready list. "main" here refers to the thread that is running, not the function that is currently being executed. You should generate your solution automatically by modifying the Nachos source files. Here is the code to add to threadtest.cc: void ChildFunction(int arg) { currentThread->Yield(); } void SelfTest() { Thread *t1 = new Thread("child 1"); Thread *t2 = new Thread("child 2"); t1->Fork(&ChildFunction, 1); t2->Fork(&ChildFunction, 2); currentThread->Yield(); } Remember to pay close attention to when interrupts are enabled and disabled and to understand what is going on in switch.s, particularly in ThreadRoot.