73c78664e70da3cfb129588a9cfa763eac86fe2f
[pintos-anon] / grading / threads / priority-donate-nest.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 #ifdef MLFQS
10 #error This test not applicable with MLFQS enabled.
11 #endif
12
13 #include "threads/test.h"
14 #include <stdio.h>
15 #include "threads/synch.h"
16 #include "threads/thread.h"
17
18 static void test_donate_nest (void);
19
20 void
21 test (void) 
22 {
23   /* Make sure our priority is the default. */
24   ASSERT (thread_get_priority () == PRI_DEFAULT);
25
26   test_donate_nest ();
27 }
28 \f
29 static thread_func medium_thread_func;
30 static thread_func high_thread_func;
31
32 struct locks 
33   {
34     struct lock *a;
35     struct lock *b;
36   };
37
38 static void
39 test_donate_nest (void) 
40 {
41   struct lock a, b;
42   struct locks locks;
43
44   printf ("\n"
45           "Testing nested priority donation.\n"
46           "If the statements printed below are all true, you pass.\n");
47
48   lock_init (&a, "a");
49   lock_init (&b, "b");
50
51   lock_acquire (&a);
52
53   locks.a = &a;
54   locks.b = &b;
55   thread_create ("medium", PRI_DEFAULT + 1, medium_thread_func, &locks);
56   thread_yield ();
57   printf ("Low thread should have priority %d.  Actual priority: %d.\n",
58           PRI_DEFAULT + 1, thread_get_priority ());
59
60   thread_create ("high", PRI_DEFAULT + 2, high_thread_func, &b);
61   thread_yield ();
62   printf ("Low thread should have priority %d.  Actual priority: %d.\n",
63           PRI_DEFAULT + 2, thread_get_priority ());
64
65   lock_release (&a);
66   thread_yield ();
67   printf ("Medium thread should just have finished.\n");
68   printf ("Low thread should have priority %d.  Actual priority: %d.\n",
69           PRI_DEFAULT, thread_get_priority ());
70   printf ("Nested priority priority donation test finished.\n");
71 }
72
73 static void
74 medium_thread_func (void *locks_) 
75 {
76   struct locks *locks = locks_;
77
78   lock_acquire (locks->b);
79   lock_acquire (locks->a);
80
81   printf ("Medium thread should have priority %d.  Actual priority: %d.\n",
82           PRI_DEFAULT + 2, thread_get_priority ());
83   printf ("Medium thread got the lock.\n");
84
85   lock_release (locks->a);
86   thread_yield ();
87
88   lock_release (locks->b);
89   thread_yield ();
90
91   printf ("High thread should have just finished.\n");
92   printf ("Middle thread finished.\n");
93 }
94
95 static void
96 high_thread_func (void *lock_) 
97 {
98   struct lock *lock = lock_;
99
100   lock_acquire (lock);
101   printf ("High thread got the lock.\n");
102   lock_release (lock);
103   printf ("High thread finished.\n");
104 }