Move problem 1-2 (join) into project 2 as the "wait" system call.
[pintos-anon] / src / tests / threads / p1-2.c
index fb39bb1d2d1df45263bd652595ad80b1bf04674b..50a4fcfa803de0416a86f1e0433096b745df278f 100644 (file)
-/* Problem 1-2: Join tests.
+/* Problem 1-2: Priority Scheduling tests.
 
    Based on a test originally submitted for Stanford's CS 140 in
-   winter 1998 by Rob Baesman <rbaesman@cs.stanford.edu>, Ben
-   Taskar <btaskar@cs.stanford.edu>, and Toli Kuznets
-   <tolik@cs.stanford.edu>.  Later modified by shiangc, yph, and
-   arens. */
+   winter 1999 by by Matt Franklin
+   <startled@leland.stanford.edu>, Greg Hutchins
+   <gmh@leland.stanford.edu>, Yu Ping Hu <yph@cs.stanford.edu>.
+   Modified by arens. */
+
+#ifdef MLFQS
+#error This test not applicable with MLFQS enabled.
+#endif
+
 #include "threads/test.h"
 #include <stdio.h>
-#include "threads/interrupt.h"
+#include "threads/synch.h"
 #include "threads/thread.h"
 
-static void simple_test (void);
-static void quick_test (void);
-static void multiple_test (void);
+static void test_preempt (void);
+static void test_fifo (void);
+static void test_donate_return (void);
 
 void
 test (void) 
 {
-  simple_test ();
-  quick_test ();
-  multiple_test ();
-}
+  /* Make sure our priority is the default. */
+  ASSERT (thread_get_priority () == PRI_DEFAULT);
 
+  test_preempt ();
+  test_fifo ();
+  test_donate_return ();
+}
+\f
 static thread_func simple_thread_func;
-static thread_func quick_thread_func;
+static thread_func acquire_thread_func;
 
 static void
-simple_test (void) 
+test_preempt (void) 
 {
-  tid_t tid0;
-  
   printf ("\n"
-          "Testing simple join.\n"
-          "Thread 0 should finish before thread 1 starts.\n");
-  tid0 = thread_create ("0", PRI_DEFAULT, simple_thread_func, "0");
-  thread_yield ();
-  thread_join (tid0);
-  simple_thread_func ("1");
-  printf ("Simple join test done.\n");
+          "Testing priority preemption.\n");
+  thread_create ("high-priority", PRI_DEFAULT + 1, simple_thread_func, NULL);
+  printf ("The high-priority thread should have already completed.\n"
+          "Priority preemption test done.\n");
 }
 
 static void
-quick_test (void) 
+test_fifo (void) 
 {
-  tid_t tid2;
+  int i;
   
   printf ("\n"
-          "Testing quick join.\n"
-          "Thread 2 should finish before thread 3 starts.\n");
-
-  tid2 = thread_create ("2", PRI_DEFAULT, quick_thread_func, "2");
-  thread_yield ();
-  thread_join (tid2);
-  simple_thread_func ("3");
-  printf ("Quick join test done.\n");
+          "Testing FIFO preemption.\n"
+          "5 threads will iterate 10 times in the same order each time.\n"
+          "If the order varies then there is a bug.\n");
+
+  thread_set_priority (PRI_DEFAULT + 2);
+  for (i = 0; i < 10; i++) 
+    {
+      char name[16];
+      snprintf (name, sizeof name, "%d", i);
+      thread_create (name, PRI_DEFAULT + 1, simple_thread_func, NULL);
+    }
+  thread_set_priority (PRI_DEFAULT);
+
+  printf ("FIFO preemption test done.\n");
 }
 
 static void
-multiple_test (void) 
+test_donate_return (void) 
 {
-  tid_t tid4, tid5;
-  
+  struct lock lock;
+
   printf ("\n"
-          "Testing multiple join.\n"
-          "Threads 4 and 5 should finish before thread 6 starts.\n");
-
-  tid4 = thread_create ("4", PRI_DEFAULT, simple_thread_func, "4");
-  tid5 = thread_create ("5", PRI_DEFAULT, simple_thread_func, "5");
-  thread_yield ();
-  thread_join (tid4);
-  thread_join (tid5);
-  simple_thread_func ("6");
-  printf ("Multiple join test done.\n");
+          "Testing priority donation.\n"
+          "If the statements printed below are all true, you pass.\n");
+
+  lock_init (&lock, "donor");
+  lock_acquire (&lock);
+  thread_create ("acquire1", PRI_DEFAULT + 1, acquire_thread_func, &lock);
+  printf ("This thread should have priority %d.  Actual priority: %d.\n",
+          PRI_DEFAULT + 1, thread_get_priority ());
+  thread_create ("acquire2", PRI_DEFAULT + 2, acquire_thread_func, &lock);
+  printf ("This thread should have priority %d.  Actual priority: %d.\n",
+          PRI_DEFAULT + 2, thread_get_priority ());
+  lock_release (&lock);
+  printf ("acquire2 and acquire1 must already have finished, in that order.\n"
+          "This should be the last line before finishing this test.\n"
+          "Priority donation test done.\n");
 }
 
-void 
-simple_thread_func (void *name_
+static void 
+simple_thread_func (void *aux UNUSED
 {
-  const char *name = name_;
   int i;
   
   for (i = 0; i < 5; i++) 
     {
-      printf ("Thread %s iteration %d\n", name, i);
+      printf ("Thread %s iteration %d\n", thread_name (), i);
       thread_yield ();
     }
-  printf ("Thread %s done!\n", name);
+  printf ("Thread %s done!\n", thread_name ());
 }
 
-void 
-quick_thread_func (void *name_) 
+static void
+acquire_thread_func (void *lock_) 
 {
-  const char *name = name_;
-  int i;
+  struct lock *lock = lock_;
 
-  intr_disable ();
-
-  for (i = 0; i < 5; i++) 
-    {
-      printf ("Thread %s iteration %d\n", name, i);
-      thread_yield ();
-    }
-  printf ("Thread %s done!\n", name);
+  lock_acquire (lock);
+  printf ("%s: got the lock\n", thread_name ());
+  lock_release (lock);
+  printf ("%s: done\n", thread_name ());
 }