Exercise

In this exercise, we finish tracing KThread.selfTest() to study the thread package and the default FIFO scheduler.

Recall that KThread.selfTest() is called by AutoGrader.run() during the boot process.

1   public static void selfTest() {
2   Lib.debug(dbgThread, "Enter KThread.selfTest");
3  
4   new KThread(new PingTest(1)).setName("forked thread").fork();
5   new PingTest(0).run();
6   }

By the time KThread.selfTest() is called in Line 4, the main kernel and idle threads have been created.

Question: In Eclipse Debug mode, what are the values of the name and the status fields of the currentThread object? What about the idleThread object?

Now after executing Line 4, a new KThread object is created and is put to the ready queue. In the debug mode, you should see that the size of waitQueue of readyQueue increases by 1. In Line 5, a new runnable object PingTest(0) is created and its run() method is executed. Since no KThread is created for this object, it runs in the main thread. As closer look at the run() method of PingTest, we find that it just yields the execution of the current thread and put it to the ready queue (Line 7) (to make clear which thread is the current thread, we made a slight change to the source code).

1   private static class PingTest implements Runnable {
2   ...
3   public void run() {
4   for (int i = 0; i < 5; i++) {
5   System.out.println("⋆⋆⋆ thread " + which + " looped " + i
6   + " times" + " " + currentThread.name);
7   currentThread.yield();
8   }
9   }
10  
11   ...
12   }

If we trace into KThread.runNextThread, we find that readyQueue.nextThread(). Since there is only one thread, the FIFO scheduler simply return that thread. The first time currentThread.yield() is called, the main thread will yield to the forked thread corresponding to PingTest(1), which in turn yields in its run() method to the main thread. Thus, the two threads will take turns in their execution until they finish.

Question:
  1. Provide the output of the program with the modified source code.
  2. Modify KThread.selfTest() to create 5 KThreads for PingTest and trace the order of execution (you can name the threads accordingly to see things more clearly).