Set up a frame pointer on interrupt entry, to improve backtraces of
[pintos-anon] / doc / tour.texi
index ed1f92be1bad527cdc7574371dc917a16f7b603b..d1147dde6b0e91d891d5192cbf6bcc841781b920 100644 (file)
@@ -303,8 +303,8 @@ grows downward from the end of the page.  It looks like this:
              |              magic              |
              |                :                |
              |                :                |
              |              magic              |
              |                :                |
              |                :                |
-             |               name              |
              |              status             |
              |              status             |
+             |               tid               |
         0 kB +---------------------------------+
 @end group
 @end example
         0 kB +---------------------------------+
 @end group
 @end example
@@ -553,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
 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}.
 
 Pintos declared its semaphore type and operations on them in
 @file{threads/synch.h}.
@@ -665,22 +667,22 @@ struct condition not_full; /* @r{Signaled when the buffer is not full.} */
 
 void put (char ch) @{
   lock_acquire (&lock);
 
 void put (char ch) @{
   lock_acquire (&lock);
-  while (n == BUF_SIZE)         /* @r{Can't add to @var{buf} as long as it's full.} */
-    cond_wait (&not_full);
-  buf[head++ % BUF_SIZE] = ch;  /* @r{Add @var{ch} to @var{buf}.} */
+  while (n == BUF_SIZE)            /* @r{Can't add to @var{buf} as long as it's full.} */
+    cond_wait (&not_full, &lock);
+  buf[head++ % BUF_SIZE] = ch;     /* @r{Add @var{ch} to @var{buf}.} */
   n++;
   n++;
-  cond_signal (&not_empty);     /* @r{@var{buf} can't be empty anymore.} */
+  cond_signal (&not_empty, &lock); /* @r{@var{buf} can't be empty anymore.} */
   lock_release (&lock);
 @}
 
 char get (void) @{
   char ch;
   lock_acquire (&lock);
   lock_release (&lock);
 @}
 
 char get (void) @{
   char ch;
   lock_acquire (&lock);
-  while (n == 0)                /* @r{Can't read from @var{buf} as long as it's empty.} */
-    cond_wait (&not_empty);
-  ch = buf[tail++ % BUF_SIZE];  /* @r{Get @var{ch} from @var{buf}.} */
+  while (n == 0)                  /* @r{Can't read from @var{buf} as long as it's empty.} */
+    cond_wait (&not_empty, &lock);
+  ch = buf[tail++ % BUF_SIZE];    /* @r{Get @var{ch} from @var{buf}.} */
   n--;
   n--;
-  cond_signal (&not_full);      /* @r{@var{buf} can't be full anymore.} */
+  cond_signal (&not_full, &lock); /* @r{@var{buf} can't be full anymore.} */
   lock_release (&lock);
 @}
 @end example
   lock_release (&lock);
 @}
 @end example
@@ -780,11 +782,7 @@ In Pintos, @func{intr_init} in @file{threads/interrupt.c} sets up the
 IDT so that each entry points to a unique entry point in
 @file{threads/intr-stubs.S} named @func{intr@var{NN}_stub}, where
 @var{NN} is the interrupt number in
 IDT so that each entry points to a unique entry point in
 @file{threads/intr-stubs.S} named @func{intr@var{NN}_stub}, where
 @var{NN} is the interrupt number in
-hexadecimal.@footnote{@file{threads/intr-stubs.S} is so repetitive
-that it is actually generated by a Perl script,
-@file{threads/intr-stubs.pl}.  Thus, you will actually find
-@file{threads/intr-stubs.S} in your @file{threads/build/threads}
-directory, not in plain @file{threads}.}  Because the CPU doesn't give
+hexadecimal.  Because the CPU doesn't give
 us any other way to find out the interrupt number, this entry point
 pushes the interrupt number on the stack.  Then it jumps to
 @func{intr_entry}, which pushes all the registers that the processor
 us any other way to find out the interrupt number, this entry point
 pushes the interrupt number on the stack.  Then it jumps to
 @func{intr_entry}, which pushes all the registers that the processor