@item serial.c
@itemx serial.h
Serial port driver. Again, @func{printf} calls this code for you,
-so you don't need to do so yourself. Feel free to look through it if
-you're curious.
+so you don't need to do so yourself.
+It handles serial input by passing it to the input layer (see below).
@item disk.c
@itemx disk.h
Supports reading and writing sectors on up to 4 IDE disks. This won't
actually be used until project 2.
+@item kbd.c
+@itemx kbd.h
+Keyboard driver. Handles keystrokes passing them to the input layer
+(see below).
+
+@item input.c
+@itemx input.h
+Input layer. Queues input characters passed along by the keyboard or
+serial drivers.
+
@item intq.c
@itemx intq.h
Interrupt queue, for managing a circular queue that both kernel
to be @func{pass}.
@xref{Backtraces}, for more information.
+
+@item How do interrupts get re-enabled in the new thread following @func{schedule}?
+
+Every path into @func{schedule} disables interrupts. They eventually
+get re-enabled by the next thread to be scheduled. Consider the
+possibilities: the new thread is running in @func{switch_thread} (but
+see below), which is called by @func{schedule}, which is called by one
+of a few possible functions:
+
+@itemize @bullet
+@item
+@func{thread_exit}, but we'll never switch back into such a thread, so
+it's uninteresting.
+
+@item
+@func{thread_yield}, which immediately restores the interrupt level upon
+return from @func{schedule}.
+
+@item
+@func{thread_block}, which is called from multiple places:
+
+@itemize @minus
+@item
+@func{sema_down}, which restores the interrupt level before returning.
+
+@item
+@func{idle}, which enables interrupts with an explicit assembly STI
+instruction.
+
+@item
+@func{wait} in @file{devices/intq.c}, whose callers are responsible for
+re-enabling interrupts.
+@end itemize
+@end itemize
+
+There is a special case when a newly created thread runs for the first
+time. Such a thread calls @func{intr_enable} as the first action in
+@func{kernel_thread}, which is at the bottom of the call stack for every
+kernel thread but the first.
@end table
@menu
thus loses the CPU and is moved to the ready queue. Now @var{L}'s
old priority is restored while it is in the ready queue.
+@item Can a thread's priority change while it is blocked?
+
+Yes. While a thread that has acquired lock @var{L} is blocked for any
+reason, its priority can increase by priority donation if a
+higher-priority thread attempts to acquire @var{L}. This case is
+checked by the @code{priority-donate-sema} test.
+
@item Can a thread added to the ready list preempt the processor?
Yes. If a thread added to the ready list has higher priority than the
@item How does @func{thread_set_priority} affect a thread receiving donations?
-It should do something sensible, but no particular behavior is
-required. None of the test cases call @func{thread_set_priority} from a
-thread while it is receiving a priority donation.
+It sets the thread's base priority. The thread's effective priority
+becomes the higher of the newly set priority or the highest donated
+priority. When the donations are released, the thread's priority
+becomes the one set through the function call. This behavior is checked
+by the @code{priority-donate-lower} test.
@item Calling @func{printf} in @func{sema_up} or @func{sema_down} reboots!