Rename printk() to printf().
[pintos-anon] / src / threads / synch.c
index 08ba8f4b90cff42b698ab89a99f7c19d65ba45f6..169128d8ba62e84e3d6d738a9237988716023bb4 100644 (file)
@@ -1,14 +1,36 @@
-#include "synch.h"
-#include "interrupt.h"
-#include "lib.h"
-#include "thread.h"
-
-/* One thread in a list. */
-struct thread_elem
-  {
-    list_elem elem;
-    struct thread *thread;      
-  };
+/* This file is derived from source code for the Nachos
+   instructional operating system.  The Nachos copyright notice
+   is reproduced in full below. */
+
+/* Copyright (c) 1992-1996 The Regents of the University of California.
+   All rights reserved.
+
+   Permission to use, copy, modify, and distribute this software
+   and its documentation for any purpose, without fee, and
+   without written agreement is hereby granted, provided that the
+   above copyright notice and the following two paragraphs appear
+   in all copies of this software.
+
+   IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO
+   ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
+   CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE
+   AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA
+   HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+   THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY
+   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+   PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
+   BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+   PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+   MODIFICATIONS.
+*/
+
+#include "threads/synch.h"
+#include <stdio.h>
+#include <string.h>
+#include "threads/interrupt.h"
+#include "threads/thread.h"
 
 /* Initializes semaphore SEMA to VALUE and names it NAME (for
    debugging purposes only).  A semaphore is a nonnegative
 
 /* Initializes semaphore SEMA to VALUE and names it NAME (for
    debugging purposes only).  A semaphore is a nonnegative
@@ -30,8 +52,8 @@ sema_init (struct semaphore *sema, unsigned value, const char *name)
   list_init (&sema->waiters);
 }
 
   list_init (&sema->waiters);
 }
 
-/* Waits for SEMA's value to become positive and then
-   atomically decrements it.
+/* Down or "P" operation on a semaphore.  Waits for SEMA's value
+   to become positive and then atomically decrements it.
 
    This function may sleep, so it must not be called within an
    interrupt handler.  This function may be called with
 
    This function may sleep, so it must not be called within an
    interrupt handler.  This function may be called with
@@ -48,17 +70,15 @@ sema_down (struct semaphore *sema)
   old_level = intr_disable ();
   while (sema->value == 0) 
     {
   old_level = intr_disable ();
   while (sema->value == 0) 
     {
-      struct thread_elem te;
-      te.thread = thread_current ();
-      list_push_back (&sema->waiters, &te.elem);
+      list_push_back (&sema->waiters, &thread_current ()->elem);
       thread_block ();
     }
   sema->value--;
   intr_set_level (old_level);
 }
 
       thread_block ();
     }
   sema->value--;
   intr_set_level (old_level);
 }
 
-/* Increments SEMA's value.  Wakes up one thread of those waiting
-   for SEMA, if any. 
+/* Up or "V" operation on a semaphore.  Increments SEMA's value
+   and wakes up one thread of those waiting for SEMA, if any.
 
    This function may be called from an interrupt handler. */
 void
 
    This function may be called from an interrupt handler. */
 void
@@ -71,7 +91,7 @@ sema_up (struct semaphore *sema)
   old_level = intr_disable ();
   if (!list_empty (&sema->waiters)) 
     thread_unblock (list_entry (list_pop_front (&sema->waiters),
   old_level = intr_disable ();
   if (!list_empty (&sema->waiters)) 
     thread_unblock (list_entry (list_pop_front (&sema->waiters),
-                                struct thread_elem, elem)->thread);
+                                struct thread, elem));
   sema->value++;
   intr_set_level (old_level);
 }
   sema->value++;
   intr_set_level (old_level);
 }
@@ -83,21 +103,10 @@ sema_name (const struct semaphore *sema)
   return sema->name;
 }
 
   return sema->name;
 }
 
-static void
-sema_test_helper (void *sema_) 
-{
-  struct semaphore *sema = sema_;
-  int i;
-
-  for (i = 0; i < 10; i++) 
-    {
-      sema_down (&sema[0]);
-      sema_up (&sema[1]);
-    }
-}
+static void sema_test_helper (void *sema_);
 
 /* Self-test for semaphores that makes control "ping-pong"
 
 /* Self-test for semaphores that makes control "ping-pong"
-   between a pair of threads.  Insert calls to printk() to see
+   between a pair of threads.  Insert calls to printf() to see
    what's going on. */
 void
 sema_self_test (void) 
    what's going on. */
 void
 sema_self_test (void) 
@@ -106,6 +115,7 @@ sema_self_test (void)
   struct semaphore sema[2];
   int i;
 
   struct semaphore sema[2];
   int i;
 
+  printf ("Testing semaphores...");
   sema_init (&sema[0], 0, "ping");
   sema_init (&sema[1], 0, "pong");
   thread = thread_create ("sema-test", sema_test_helper, &sema);
   sema_init (&sema[0], 0, "ping");
   sema_init (&sema[1], 0, "pong");
   thread = thread_create ("sema-test", sema_test_helper, &sema);
@@ -114,6 +124,21 @@ sema_self_test (void)
       sema_up (&sema[0]);
       sema_down (&sema[1]);
     }
       sema_up (&sema[0]);
       sema_down (&sema[1]);
     }
+  printf ("done.\n");
+}
+
+/* Thread function used by sema_self_test(). */
+static void
+sema_test_helper (void *sema_) 
+{
+  struct semaphore *sema = sema_;
+  int i;
+
+  for (i = 0; i < 10; i++) 
+    {
+      sema_down (&sema[0]);
+      sema_up (&sema[1]);
+    }
 }
 \f
 /* Initializes LOCK and names it NAME (for debugging purposes).
 }
 \f
 /* Initializes LOCK and names it NAME (for debugging purposes).
@@ -208,8 +233,8 @@ lock_name (const struct lock *lock)
 /* One semaphore in a list. */
 struct semaphore_elem 
   {
 /* One semaphore in a list. */
 struct semaphore_elem 
   {
-    list_elem elem;
-    struct semaphore semaphore;
+    list_elem elem;                     /* List element. */
+    struct semaphore semaphore;         /* This semaphore. */
   };
 
 /* Initializes condition variable COND and names it NAME.  A
   };
 
 /* Initializes condition variable COND and names it NAME.  A
@@ -232,9 +257,9 @@ cond_init (struct condition *cond, const char *name)
    this function.
 
    The monitor implemented by this function is "Mesa" style, not
    this function.
 
    The monitor implemented by this function is "Mesa" style, not
-   "Hoare" style.  That is, sending a signal is not atomic with
-   delivering it.  Thus, typically the caller must recheck the
-   condition after the wait completes and, if necessary, wait
+   "Hoare" style, that is, sending and receiving a signal are not
+   an atomic operation.  Thus, typically the caller must recheck
+   the condition after the wait completes and, if necessary, wait
    again.
 
    A given condition variable is associated with only a single
    again.
 
    A given condition variable is associated with only a single