From e7a9b6d7c7246def3949f33771977bb9e3c2810a Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 12 Oct 2004 22:53:09 +0000 Subject: [PATCH] Add and refine FAQ answers. --- doc/threads.texi | 92 ++++++++++++++++++++++++++---------------------- 1 file changed, 50 insertions(+), 42 deletions(-) diff --git a/doc/threads.texi b/doc/threads.texi index 1e37971..9138daf 100644 --- a/doc/threads.texi +++ b/doc/threads.texi @@ -650,6 +650,7 @@ second should be good for almost 2,924,712,087 years. @item @b{The test program mostly works but reports a few out-of-order wake ups. I think it's a problem in the test program. What gives?} +@anchor{Out of Order 1-1} This test is inherently full of race conditions. On a real system it wouldn't work perfectly all the time either. However, you can help it @@ -670,10 +671,15 @@ modifying the call to @func{set_serial} in @func{serial_init_poll} in @file{devices/serial.c}. @end itemize -The former two changes are only desirable for testing problem 1-1. You -should revert them before working on other parts of the project or turn -in the project. The latter is harmless, so you can retain it or revert -it at your option. +The former two changes are only desirable for testing problem 1-1 and +possibly 1-3. You should revert them before working on other parts +of the project or turn in the project. The latter is harmless, so you +can retain it or revert it at your option. + +@item +@b{Should @file{p1-1.c} be expected to work with the MLFQS turned on?} + +No. The MLFQS will adjust priorities, changing thread ordering. @end enumerate @node Problem 1-2 Join FAQ @@ -763,44 +769,32 @@ Yes. Same scenario as above except L gets blocked waiting on a new lock when H restores its priority. @item -@b{Why is pubtest3's FIFO test skipping some threads! I know my scheduler -is round-robin'ing them like it's supposed to! Our output is like this:} - -@example -Thread 0 goes. -Thread 2 goes. -Thread 3 goes. -Thread 4 goes. -Thread 0 goes. -Thread 1 goes. -Thread 2 goes. -Thread 3 goes. -Thread 4 goes. -@end example - -@noindent @b{which repeats 5 times and then} - -@example -Thread 1 goes. -Thread 1 goes. -Thread 1 goes. -Thread 1 goes. -Thread 1 goes. -@end example - -This happens because context switches are being invoked by the test -when it explicitly calls @func{thread_yield}. However, the time -slice timer is still alive and so, every tick (by default), thread 1 -gets switched out (caused by @func{timer_interrupt} calling -@func{intr_yield_on_return}) before it gets a chance to run its -mainline. It is by coincidence that Thread 1 is the one that gets -skipped in our example. If we use a different jitter value, the same -behavior is seen where a thread gets started and switched out -completely. - -Solution: Increase the value of @code{TIME_SLICE} in -@file{devices/timer.c} to a very high value, such as 10000, to see -that the threads will round-robin if they aren't interrupted. +@b{Why is @file{p1-3.c}'s FIFO test skipping some threads? I know my +scheduler is round-robin'ing them like it's supposed to. Our output +starts out okay, but toward the end it starts getting out of order.} + +The usual problem is that the serial output buffer fills up. This is +causing serial_putc() to block in thread @var{A}, so that thread +@var{B} is scheduled. Thread @var{B} immediately tries to do output +of its own and blocks on the serial lock (which is held by thread +@var{A}). Now that we've wasted some time in scheduling and locking, +typically some characters have been drained out of the serial buffer +by the interrupt handler, so thread @var{A} can continue its output. +After it finishes, though, some other thread (not @var{B}) is +scheduled, because thread @var{B} was already scheduled while we +waited for the buffer to drain. + +There's at least one other possibility. Context switches are being +invoked by the test when it explicitly calls @func{thread_yield}. +However, the time slice timer is still alive and so, every tick (by +default), a thread gets switched out (caused by @func{timer_interrupt} +calling @func{intr_yield_on_return}) before it gets a chance to run +@func{printf}, effectively skipping it. If we use a different jitter +value, the same behavior is seen where a thread gets started and +switched out completely. + +Normally you can fix these problems using the same techniques +suggested on problem 1-1 (@pxref{Out of Order 1-1}). @item @b{What happens when a thread is added to the ready list which has @@ -814,6 +808,20 @@ solution must act this way. its priority has been increased by a donation?} The higher (donated) priority. + +@item +@b{Should @file{p1-3.c} be expected to work with the MLFQS turned on?} + +No. The MLFQS will adjust priorities, changing thread ordering. + +@item +@b{@func{printf} in @func{sema_up} or @func{sema_down} makes the +system reboot!} + +Yes. These functions are called before @func{printf} is ready to go. +You could add a global flag initialized to false and set it to true +just before the first @func{printf} in @func{main}. Then modify +@func{printf} itself to return immediately if the flag isn't set. @end enumerate @node Problem 1-4 Advanced Scheduler FAQ -- 2.30.2