Clarification.
[pintos-anon] / doc / tour.texi
index ae9e74ebc177ee3c0cf28258a5d6d01e038d9faa..845a1c8b6f68904eb3289ed532e93b065832d853 100644 (file)
@@ -173,7 +173,8 @@ and @func{syscall_init}.
 Now that interrupts are set up, we can start preemptively scheduling
 threads with @func{thread_start}, which also enables interrupts.
 Interrupt-driven serial port I/O is also possible now, so we use
-@func{serial_init_queue} to switch to that mode.
+@func{serial_init_queue} to switch to that mode.  Finally,
+@func{timer_calibrate} calibrates the timer for accurate short delays.
 
 If the filesystem is compiled in, as it will be in project 2 and
 later, we now initialize the disks with @func{disk_init}, then the
@@ -204,7 +205,7 @@ threads to continue running.
 @end menu
 
 @node struct thread
-@subsection @struct{thread}
+@subsection @code{struct thread}
 
 The main Pintos data structure for threads is @struct{thread},
 declared in @file{threads/thread.h}.  @struct{thread} has these
@@ -283,6 +284,7 @@ memory.  The rest of the page is used for the thread's stack, which
 grows downward from the end of the page.  It looks like this:
 
 @example
+@group
         4 kB +---------------------------------+
              |          kernel stack           |
              |                |                |
@@ -304,6 +306,7 @@ grows downward from the end of the page.  It looks like this:
              |               name              |
              |              status             |
         0 kB +---------------------------------+
+@end group
 @end example
 
 The upshot of this is twofold.  First, @struct{thread} must not be
@@ -346,8 +349,8 @@ called early in Pintos initialization.
 Called by @func{main} to start the scheduler.  Creates the idle
 thread, that is, the thread that is scheduled when no other thread is
 ready.  Then enables interrupts, which enables the scheduler because
-processes are rescheduled in the return path from the timer
-interrupt.  FIXME
+processes are rescheduled on return from the timer interrupt, using
+@func{intr_yield_on_return} (@pxref{External Interrupt Handling}).
 @end deftypefun
 
 @deftypefun void thread_create (const char *@var{name}, int @var{priority}, thread_func *@var{func}, void *@var{aux})
@@ -492,7 +495,7 @@ is, kernel threads can be preempted at any time.  Traditional Unix
 systems are ``nonpreemptible,'' that is, kernel threads can only be
 preempted at points where they explicitly call into the scheduler.
 User programs can be preempted at any time in both models.  As you
-might imagine, preemptible kernels require more use of
+might imagine, preemptible kernels require more explicit
 synchronization.
 
 You should have little need to set the interrupt state directly.  Most
@@ -527,8 +530,8 @@ Turns interrupts off and returns the previous interrupt state.
 @node Semaphores
 @subsubsection Semaphores
 
-A semaphore is a nonnegative integer along with two atomic operators
-for manipulating it, which are:
+A semaphore is a nonnegative integer along with two operators
+for atomically manipulating it, which are:
 
 @itemize @bullet
 @item
@@ -550,8 +553,10 @@ A semaphore initialized to 0 can be useful for waiting for an event
 that will happen exactly once.  For example, suppose thread @var{A}
 starts another thread @var{B} and wants to wait for @var{B} to signal
 that some activity is complete.  @var{A} can create a semaphore
-initialized to 0, pass it to @var{B}, and then ``down'' the semaphore.
-When @var{B} finishes its activity, it ``ups'' the semaphore.
+initialized to 0, pass it to @var{B} as it starts it, and then
+``down'' the semaphore.  When @var{B} finishes its activity, it
+``ups'' the semaphore.  This works regardless of whether @var{A}
+``downs'' the semaphore or @var{B} ``ups'' it first.
 
 Pintos declared its semaphore type and operations on them in
 @file{threads/synch.h}.
@@ -591,7 +596,7 @@ semaphore is twofold.  First, a semaphore can have a value greater
 than 1, but a lock can only be owned by a single thread at a time.
 Second, a semaphore does not have an owner, meaning that one thread
 can ``down'' the semaphore and then another one ``up'' it, but with a
-lock the same thread must both acquire and release it.  When these
+lock a single thread must both acquire and release it.  When these
 restrictions prove onerous, it's a good sign that a semaphore should
 be used, instead of a lock.
 
@@ -630,8 +635,8 @@ A condition variable allows one piece of code to signal a condition
 and cooperating code to receive the signal and act upon it.  Each
 condition variable is associated with a lock.  A given condition
 variable is associated with only a single lock, but one lock may be
-associated with any number of condition variables.  A lock along with
-all of its condition variables is known as a ``monitor.''
+associated with any number of condition variables.  A set of condition
+variables taken together with their lock is called a ``monitor.''
 
 A thread that owns the monitor lock is said to be ``in the monitor.''
 The thread in the monitor has control over all the data protected with
@@ -733,7 +738,7 @@ timer, keyboard, serial ports, and disks.  External interrupts are
 @dfn{asynchronous}, meaning that they don't occur in a fashion
 synchronized with anything going on in the CPU.  External interrupts
 are what @func{intr_disable} and related functions can arrange to
-temporarily ignore (@pxref{Disabling Interrupts}).
+postpone (@pxref{Disabling Interrupts}).
 
 @item
 @dfn{Internal interrupts}, that is, interrupts caused by something