Add threads tests.
[pintos-anon] / src / tests / threads / p1-3.c
1 /* Problem 1-3: Priority Scheduling tests.
2
3    Based on a test originally submitted for Stanford's CS 140 in
4    winter 1999 by by Matt Franklin
5    <startled@leland.stanford.edu>, Greg Hutchins
6    <gmh@leland.stanford.edu>, Yu Ping Hu <yph@cs.stanford.edu>.
7    Modified by arens. */
8
9 #include "threads/test.h"
10 #include <stdio.h>
11 #include "threads/thread.h"
12
13 static void test_preempt (void);
14 static void test_fifo (void);
15 static void test_donate_return (void);
16
17 void
18 test (void) 
19 {
20   /* Make sure our prority is the default. */
21   ASSERT (thread_get_priority () == PRI_DEFAULT);
22
23   test_preempt ();
24   test_fifo ();
25   test_donate_return ();
26 }
27 \f
28 static thread_func simple_thread_func;
29 static thread_func acquire_thread_func;
30
31 static void
32 test_preempt (void) 
33 {
34   printf ("\n"
35           "Testing priority preemption.\n");
36   thread_create ("high-priority", PRI_DEFAULT + 1, simple_thread_func, NULL);
37   printf ("The high-priority thread should have already completed.\n"
38           "Priority preemption test done.\n");
39 }
40
41 static void
42 test_fifo (void) 
43 {
44   int i;
45   
46   printf ("\n"
47           "Testing FIFO preemption.\n"
48           "5 threads will iterate 10 times in the same order each time.\n"
49           "If the order varies then there is a bug.\n");
50
51   thread_set_priority (PRI_DEFAULT + 2);
52   for (i = 0; i < 5; i++) 
53     {
54       char name[16];
55       snprintf (name, sizeof name, "%d", i);
56       thread_create (name, PRI_DEFAULT + 1, simple_thread_func, NULL);
57     }
58   thread_set_priority (PRI_DEFAULT);
59
60   printf ("FIFO preemption test done.\n");
61 }
62
63 static void
64 test_donate_return (void) 
65 {
66   struct lock lock;
67
68   printf ("\n"
69           "Testing priority donation.\n"
70           "If the statements printed below are all true, you pass.\n");
71
72   lock_init (&lock, "donor");
73   lock_acquire (&lock);
74   thread_create ("acquire1", PRI_DEFAULT + 1, acquire_thread_func, &lock);
75   printf ("This thread should have priority %d.  Actual priority: %d.\n",
76           PRI_DEFAULT + 1, thread_get_priority ());
77   thread_create ("acquire2", PRI_DEFAULT + 2, acquire_thread_func, &lock);
78   printf ("This thread should have priority %d.  Actual priority: %d.\n",
79           PRI_DEFAULT + 2, thread_get_priority ());
80   lock_release ();
81   printf ("acquire1 and acquire2 must already have finished, in that order.\n"
82           "This should be the last line before finishing this test.\n"
83           "Priority donation test done.\n");
84 }
85
86 static void 
87 simple_thread_func (void *aux UNUSED) 
88 {
89   int i;
90   
91   for (i = 0; i < 5; i++) 
92     {
93       printf ("Thread %s iteration %d\n", thread_name (), i);
94       thread_yield ();
95     }
96   printf ("Thread %s done!\n", thread_name ());
97 }
98
99 static void
100 acquire_thread_func (void *lock_) 
101 {
102   struct lock *lock = lock_;
103
104   lock_acquire (lock);
105   printf ("%s: got the lock\n", thread_name ());
106   lock_release (lock);
107   printf ("%s: done\n", thread_name ());
108 }