--- /dev/null
+/* Problem 1-1: Alarm Clock tests.
+
+ Tests timer_sleep(-100). Only requirement is that it not crash. */
+
+#include "threads/test.h"
+#include <stdio.h>
+#include "threads/malloc.h"
+#include "threads/synch.h"
+#include "threads/thread.h"
+#include "devices/timer.h"
+
+void
+test (void)
+{
+ printf ("\n"
+ "Testing timer_sleep(-100).\n");
+ timer_sleep (-100);
+ printf ("Success.\n");
+}
--- /dev/null
+/* Problem 1-1: Alarm Clock 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>. */
+
+#include "threads/test.h"
+#include <stdio.h>
+#include "threads/malloc.h"
+#include "threads/synch.h"
+#include "threads/thread.h"
+#include "devices/timer.h"
+
+/* Number of iterations. */
+#define ITERATION_CNT 1
+
+static void test_sleep (int iterations);
+
+void
+test (void)
+{
+ test_sleep (ITERATION_CNT);
+}
+
+struct sleep_thread_data
+ {
+ int64_t start; /* Start time. */
+ int duration; /* Number of ticks to sleep. */
+ int iterations; /* Number of iterations to run. */
+ struct semaphore done; /* Completion semaphore. */
+ tid_t tid; /* Thread ID. */
+
+ struct lock *lock; /* Lock on access to remaining members. */
+ int *product; /* Largest product so far. */
+ char **out; /* Output pointer. */
+ };
+
+static void sleeper (void *);
+
+static void
+test_sleep (int iterations)
+{
+ struct sleep_thread_data threads[5];
+ const int thread_cnt = sizeof threads / sizeof *threads;
+ char *output, *cp;
+ struct lock lock;
+ int64_t start;
+ int product;
+ int i;
+
+ printf ("\n"
+ "Testing %d sleeps per thread.\n"
+ "If successful, product of iteration count and\n"
+ "sleep duration will appear in nondescending order.\n",
+ iterations);
+
+ /* Start all the threads. */
+ product = 0;
+ lock_init (&lock, "product");
+ cp = output = malloc (128 * iterations * thread_cnt);
+ ASSERT (output != NULL);
+ start = timer_ticks ();
+ for (i = 0; i < thread_cnt; i++)
+ {
+ struct sleep_thread_data *t;
+ char name[16];
+
+ snprintf (name, sizeof name, "thread %d", i);
+ t = threads + i;
+ t->start = start;
+ t->duration = (i + 1) * 10;
+ t->iterations = iterations;
+ sema_init (&t->done, 0, name);
+ t->tid = thread_create (name, PRI_DEFAULT, sleeper, t);
+
+ t->lock = &lock;
+ t->product = &product;
+ t->out = &cp;
+ }
+
+ /* Wait for all the threads to finish. */
+ for (i = 0; i < thread_cnt; i++)
+ sema_down (&threads[i].done);
+
+ printf ("%s...done\n", output);
+}
+
+static void
+sleeper (void *t_)
+{
+ struct sleep_thread_data *t = t_;
+ int i;
+
+ for (i = 1; i <= t->iterations; i++)
+ {
+ int old_product;
+ int new_product = i * t->duration;
+
+ timer_sleep ((t->start + new_product) - timer_ticks ());
+
+ lock_acquire (t->lock);
+ old_product = *t->product;
+ *t->product = new_product;
+ *t->out += snprintf (*t->out, 128,
+ "%s: duration=%d, iteration=%d, product=%d\n",
+ thread_name (), t->duration, i, new_product);
+ if (old_product > new_product)
+ *t->out += snprintf (*t->out, 128,
+ "%s: Out of order sleep completion (%d > %d)!\n",
+ thread_name (), old_product, new_product);
+ lock_release (t->lock);
+ }
+
+ /* Signal completion. */
+ sema_up (&t->done);
+}
--- /dev/null
+/* Problem 1-1: Alarm Clock tests.
+
+ Tests timer_sleep(0). Only requirement is that it not crash. */
+
+#include "threads/test.h"
+#include <stdio.h>
+#include "threads/malloc.h"
+#include "threads/synch.h"
+#include "threads/thread.h"
+#include "devices/timer.h"
+
+void
+test (void)
+{
+ printf ("\n"
+ "Testing timer_sleep(0).\n");
+ timer_sleep (0);
+ printf ("Success.\n");
+}
--- /dev/null
+/* Problem 1-2: Join 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. */
+#include "threads/test.h"
+#include <stdio.h>
+#include "threads/interrupt.h"
+#include "threads/thread.h"
+
+static void dummy_test (void);
+
+void
+test (void)
+{
+ dummy_test ();
+}
+
+static thread_func simple_thread_func;
+
+static void
+dummy_test (void)
+{
+ tid_t tid0;
+
+ printf ("\n"
+ "Testing dummy 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);
+ thread_join (tid0);
+ simple_thread_func ("1");
+ thread_join (tid0);
+ printf ("Simple join test done.\n");
+}
+
+void
+simple_thread_func (void *name_)
+{
+ const char *name = name_;
+ int i;
+
+ for (i = 0; i < 5; i++)
+ {
+ printf ("Thread %s iteration %d\n", name, i);
+ thread_yield ();
+ }
+ printf ("Thread %s done!\n", name);
+}
--- /dev/null
+/* Problem 1-2: Join 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. */
+#include "threads/test.h"
+#include <stdio.h>
+#include "threads/interrupt.h"
+#include "threads/thread.h"
+
+static void invalid_test (void);
+
+void
+test (void)
+{
+ invalid_test ();
+}
+
+static thread_func simple_thread_func;
+
+static void
+invalid_test (void)
+{
+ tid_t tid0;
+
+ printf ("\n"
+ "Testing invalid join.\n"
+ "Should just not crash.\n");
+ tid0 = thread_create ("0", PRI_DEFAULT, simple_thread_func, "0");
+ thread_yield ();
+ thread_join (1234);
+ simple_thread_func ("1");
+ printf ("Invalid join test done.\n");
+}
+
+void
+simple_thread_func (void *name_)
+{
+ const char *name = name_;
+ int i;
+
+ for (i = 0; i < 5; i++)
+ {
+ printf ("Thread %s iteration %d\n", name, i);
+ thread_yield ();
+ }
+ printf ("Thread %s done!\n", name);
+}
--- /dev/null
+/* Problem 1-2: Join 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. */
+#include "threads/test.h"
+#include <stdio.h>
+#include "threads/interrupt.h"
+#include "threads/thread.h"
+
+static void multiple_test (void);
+
+void
+test (void)
+{
+ multiple_test ();
+}
+
+static thread_func simple_thread_func;
+
+static void
+multiple_test (void)
+{
+ tid_t tid4, tid5;
+
+ 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");
+}
+
+void
+simple_thread_func (void *name_)
+{
+ const char *name = name_;
+ int i;
+
+ for (i = 0; i < 5; i++)
+ {
+ printf ("Thread %s iteration %d\n", name, i);
+ thread_yield ();
+ }
+ printf ("Thread %s done!\n", name);
+}
--- /dev/null
+/* Problem 1-2: Join 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. */
+#include "threads/test.h"
+#include <stdio.h>
+#include "threads/interrupt.h"
+#include "threads/thread.h"
+
+static void nested_test (void);
+
+void
+test (void)
+{
+ nested_test ();
+}
+
+static thread_func nested_thread_func;
+
+static void
+nested_test (void)
+{
+ tid_t tid0;
+ int zero = 0;
+
+ printf ("\n"
+ "Testing nested join.\n"
+ "Threads 0 to 7 should start in numerical order\n"
+ "and finish in reverse order.");
+ tid0 = thread_create ("0", PRI_DEFAULT, nested_thread_func, &zero);
+ thread_join (tid0);
+ printf ("Simple join test done.\n");
+}
+
+void
+nested_thread_func (void *valuep_)
+{
+ int *valuep = valuep_;
+ int value = *valuep;
+
+ printf ("Thread %d starting.\n", value);
+ if (value < 7)
+ {
+ int next = value + 1;
+ tid_t tid_next;
+ char name_next[8];
+ snprintf (name_next, sizeof name_next, "%d", next);
+
+ tid_next = thread_create (name_next, PRI_DEFAULT,
+ nested_thread_func, &next);
+
+ thread_join (tid_next);
+ }
+ printf ("Thread %d done.\n", value);
+}
--- /dev/null
+/* Problem 1-2: Join 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. */
+
+#include "threads/test.h"
+#include <stdio.h>
+#include "threads/interrupt.h"
+#include "threads/thread.h"
+
+static void no_test (void);
+
+void
+test (void)
+{
+ no_test ();
+}
+
+static thread_func simple_thread_func;
+
+static void
+no_test (void)
+{
+ tid_t tid0;
+
+ printf ("\n"
+ "Testing no join.\n"
+ "Should just not crash.\n");
+ tid0 = thread_create ("0", PRI_DEFAULT, simple_thread_func, "0");
+ simple_thread_func ("1");
+ printf ("Simple join test done.\n");
+}
+
+void
+simple_thread_func (void *name_)
+{
+ const char *name = name_;
+ int i;
+
+ for (i = 0; i < 5; i++)
+ {
+ printf ("Thread %s iteration %d\n", name, i);
+ thread_yield ();
+ }
+ printf ("Thread %s done!\n", name);
+}
--- /dev/null
+/* Problem 1-2: Join 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. */
+#include "threads/test.h"
+#include <stdio.h>
+#include "threads/interrupt.h"
+#include "threads/thread.h"
+
+static void quick_test (void);
+
+void
+test (void)
+{
+ quick_test ();
+}
+
+static thread_func quick_thread_func;
+static thread_func simple_thread_func;
+
+static void
+quick_test (void)
+{
+ tid_t tid2;
+
+ 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");
+}
+
+void
+quick_thread_func (void *name_)
+{
+ const char *name = name_;
+ int i;
+
+ intr_disable ();
+
+ for (i = 0; i < 5; i++)
+ {
+ printf ("Thread %s iteration %d\n", name, i);
+ thread_yield ();
+ }
+ printf ("Thread %s done!\n", name);
+}
+
+void
+simple_thread_func (void *name_)
+{
+ const char *name = name_;
+ int i;
+
+ for (i = 0; i < 5; i++)
+ {
+ printf ("Thread %s iteration %d\n", name, i);
+ thread_yield ();
+ }
+ printf ("Thread %s done!\n", name);
+}
--- /dev/null
+/* Problem 1-2: Join 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. */
+#include "threads/test.h"
+#include <stdio.h>
+#include "threads/interrupt.h"
+#include "threads/thread.h"
+
+static void simple_test (void);
+
+void
+test (void)
+{
+ simple_test ();
+}
+
+static thread_func simple_thread_func;
+
+static void
+simple_test (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");
+}
+
+void
+simple_thread_func (void *name_)
+{
+ const char *name = name_;
+ int i;
+
+ for (i = 0; i < 5; i++)
+ {
+ printf ("Thread %s iteration %d\n", name, i);
+ thread_yield ();
+ }
+ printf ("Thread %s done!\n", name);
+}