a7b919c90b276cf049bdab81598687e40a11f4e6
[pintos-anon] / src / tests / 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 Matt Franklin <startled@leland.stanford.edu>,
5    Greg Hutchins <gmh@leland.stanford.edu>, Yu Ping Hu
6    <yph@cs.stanford.edu>.  Modified by arens. */
7
8 #include <stdio.h>
9 #include "tests/threads/tests.h"
10 #include "threads/init.h"
11 #include "threads/synch.h"
12 #include "threads/thread.h"
13
14 struct locks 
15   {
16     struct lock *a;
17     struct lock *b;
18   };
19
20 static thread_func medium_thread_func;
21 static thread_func high_thread_func;
22
23 void
24 test_priority_donate_nest (void) 
25 {
26   struct lock a, b;
27   struct locks locks;
28
29   /* This test does not work with the MLFQS. */
30   ASSERT (!enable_mlfqs);
31
32   /* Make sure our priority is the default. */
33   ASSERT (thread_get_priority () == PRI_DEFAULT);
34
35   lock_init (&a);
36   lock_init (&b);
37
38   lock_acquire (&a);
39
40   locks.a = &a;
41   locks.b = &b;
42   thread_create ("medium", PRI_DEFAULT - 1, medium_thread_func, &locks);
43   thread_yield ();
44   msg ("Low thread should have priority %d.  Actual priority: %d.",
45        PRI_DEFAULT - 1, thread_get_priority ());
46
47   thread_create ("high", PRI_DEFAULT - 2, high_thread_func, &b);
48   thread_yield ();
49   msg ("Low thread should have priority %d.  Actual priority: %d.",
50        PRI_DEFAULT - 2, thread_get_priority ());
51
52   lock_release (&a);
53   thread_yield ();
54   msg ("Medium thread should just have finished.");
55   msg ("Low thread should have priority %d.  Actual priority: %d.",
56        PRI_DEFAULT, thread_get_priority ());
57 }
58
59 static void
60 medium_thread_func (void *locks_) 
61 {
62   struct locks *locks = locks_;
63
64   lock_acquire (locks->b);
65   lock_acquire (locks->a);
66
67   msg ("Medium thread should have priority %d.  Actual priority: %d.",
68        PRI_DEFAULT - 2, thread_get_priority ());
69   msg ("Medium thread got the lock.");
70
71   lock_release (locks->a);
72   thread_yield ();
73
74   lock_release (locks->b);
75   thread_yield ();
76
77   msg ("High thread should have just finished.");
78   msg ("Middle thread finished.");
79 }
80
81 static void
82 high_thread_func (void *lock_) 
83 {
84   struct lock *lock = lock_;
85
86   lock_acquire (lock);
87   msg ("High thread got the lock.");
88   lock_release (lock);
89   msg ("High thread finished.");
90 }