From: Ben Pfaff Date: Thu, 14 Oct 2004 00:41:53 +0000 (+0000) Subject: Add some grading test programs. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=24747933efc4ebdc3bac0329d7dded41ad96c5d4;p=pintos-anon Add some grading test programs. --- diff --git a/grading/threads/alarm-negative.c b/grading/threads/alarm-negative.c new file mode 100644 index 0000000..a627b9b --- /dev/null +++ b/grading/threads/alarm-negative.c @@ -0,0 +1,19 @@ +/* Problem 1-1: Alarm Clock tests. + + Tests timer_sleep(-100). Only requirement is that it not crash. */ + +#include "threads/test.h" +#include +#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"); +} diff --git a/grading/threads/alarm-simple.c b/grading/threads/alarm-simple.c new file mode 100644 index 0000000..65f1ae8 --- /dev/null +++ b/grading/threads/alarm-simple.c @@ -0,0 +1,117 @@ +/* Problem 1-1: Alarm Clock tests. + + Based on a test originally submitted for Stanford's CS 140 in + winter 1998 by Rob Baesman , Ben + Taskar , and Toli Kuznets + . */ + +#include "threads/test.h" +#include +#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); +} diff --git a/grading/threads/alarm-zero.c b/grading/threads/alarm-zero.c new file mode 100644 index 0000000..f1ac775 --- /dev/null +++ b/grading/threads/alarm-zero.c @@ -0,0 +1,19 @@ +/* Problem 1-1: Alarm Clock tests. + + Tests timer_sleep(0). Only requirement is that it not crash. */ + +#include "threads/test.h" +#include +#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"); +} diff --git a/grading/threads/join-dummy.c b/grading/threads/join-dummy.c new file mode 100644 index 0000000..202b6e4 --- /dev/null +++ b/grading/threads/join-dummy.c @@ -0,0 +1,52 @@ +/* Problem 1-2: Join tests. + + Based on a test originally submitted for Stanford's CS 140 in + winter 1998 by Rob Baesman , Ben + Taskar , and Toli Kuznets + . Later modified by shiangc, yph, and + arens. */ +#include "threads/test.h" +#include +#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); +} diff --git a/grading/threads/join-invalid.c b/grading/threads/join-invalid.c new file mode 100644 index 0000000..05decb4 --- /dev/null +++ b/grading/threads/join-invalid.c @@ -0,0 +1,50 @@ +/* Problem 1-2: Join tests. + + Based on a test originally submitted for Stanford's CS 140 in + winter 1998 by Rob Baesman , Ben + Taskar , and Toli Kuznets + . Later modified by shiangc, yph, and + arens. */ +#include "threads/test.h" +#include +#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); +} diff --git a/grading/threads/join-multiple.c b/grading/threads/join-multiple.c new file mode 100644 index 0000000..c903a25 --- /dev/null +++ b/grading/threads/join-multiple.c @@ -0,0 +1,53 @@ +/* Problem 1-2: Join tests. + + Based on a test originally submitted for Stanford's CS 140 in + winter 1998 by Rob Baesman , Ben + Taskar , and Toli Kuznets + . Later modified by shiangc, yph, and + arens. */ +#include "threads/test.h" +#include +#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); +} diff --git a/grading/threads/join-nested.c b/grading/threads/join-nested.c new file mode 100644 index 0000000..18970f0 --- /dev/null +++ b/grading/threads/join-nested.c @@ -0,0 +1,58 @@ +/* Problem 1-2: Join tests. + + Based on a test originally submitted for Stanford's CS 140 in + winter 1998 by Rob Baesman , Ben + Taskar , and Toli Kuznets + . Later modified by shiangc, yph, and + arens. */ +#include "threads/test.h" +#include +#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); +} diff --git a/grading/threads/join-no.c b/grading/threads/join-no.c new file mode 100644 index 0000000..32623e3 --- /dev/null +++ b/grading/threads/join-no.c @@ -0,0 +1,49 @@ +/* Problem 1-2: Join tests. + + Based on a test originally submitted for Stanford's CS 140 in + winter 1998 by Rob Baesman , Ben + Taskar , and Toli Kuznets + . Later modified by shiangc, yph, and + arens. */ + +#include "threads/test.h" +#include +#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); +} diff --git a/grading/threads/join-quick.c b/grading/threads/join-quick.c new file mode 100644 index 0000000..78f1e3f --- /dev/null +++ b/grading/threads/join-quick.c @@ -0,0 +1,68 @@ +/* Problem 1-2: Join tests. + + Based on a test originally submitted for Stanford's CS 140 in + winter 1998 by Rob Baesman , Ben + Taskar , and Toli Kuznets + . Later modified by shiangc, yph, and + arens. */ +#include "threads/test.h" +#include +#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); +} diff --git a/grading/threads/join-simple.c b/grading/threads/join-simple.c new file mode 100644 index 0000000..3407f56 --- /dev/null +++ b/grading/threads/join-simple.c @@ -0,0 +1,50 @@ +/* Problem 1-2: Join tests. + + Based on a test originally submitted for Stanford's CS 140 in + winter 1998 by Rob Baesman , Ben + Taskar , and Toli Kuznets + . Later modified by shiangc, yph, and + arens. */ +#include "threads/test.h" +#include +#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); +}