e1bccbdb4b567baef5c1767173ff9271aeda74c9
[pintos-anon] / src / tests / threads / priority-donate-multiple.c
1 /* The main thread acquires locks A and B, then it creates two
2    higher-priority threads.  Each of these threads blocks
3    acquiring one of the locks and thus donate their priority to
4    the main thread.  The main thread releases the locks in turn
5    and relinquishes its donated priorities.
6    
7    Based on a test originally submitted for Stanford's CS 140 in
8    winter 1999 by Matt Franklin <startled@leland.stanford.edu>,
9    Greg Hutchins <gmh@leland.stanford.edu>, Yu Ping Hu
10    <yph@cs.stanford.edu>.  Modified by arens. */
11
12 #include <stdio.h>
13 #include "tests/threads/tests.h"
14 #include "threads/init.h"
15 #include "threads/synch.h"
16 #include "threads/thread.h"
17
18 static thread_func a_thread_func;
19 static thread_func b_thread_func;
20
21 void
22 test_priority_donate_multiple (void) 
23 {
24   struct lock a, b;
25
26   /* This test does not work with the MLFQS. */
27   ASSERT (!enable_mlfqs);
28
29   /* Make sure our priority is the default. */
30   ASSERT (thread_get_priority () == PRI_DEFAULT);
31
32   lock_init (&a);
33   lock_init (&b);
34
35   lock_acquire (&a);
36   lock_acquire (&b);
37
38   thread_create ("a", PRI_DEFAULT + 1, a_thread_func, &a);
39   msg ("Main thread should have priority %d.  Actual priority: %d.",
40        PRI_DEFAULT + 1, thread_get_priority ());
41
42   thread_create ("b", PRI_DEFAULT + 2, b_thread_func, &b);
43   msg ("Main thread should have priority %d.  Actual priority: %d.",
44        PRI_DEFAULT + 2, thread_get_priority ());
45
46   lock_release (&b);
47   msg ("Thread b should have just finished.");
48   msg ("Main thread should have priority %d.  Actual priority: %d.",
49        PRI_DEFAULT + 1, thread_get_priority ());
50
51   lock_release (&a);
52   msg ("Thread a should have just finished.");
53   msg ("Main thread should have priority %d.  Actual priority: %d.",
54        PRI_DEFAULT, thread_get_priority ());
55 }
56
57 static void
58 a_thread_func (void *lock_) 
59 {
60   struct lock *lock = lock_;
61
62   lock_acquire (lock);
63   msg ("Thread a acquired lock a.");
64   lock_release (lock);
65   msg ("Thread a finished.");
66 }
67
68 static void
69 b_thread_func (void *lock_) 
70 {
71   struct lock *lock = lock_;
72
73   lock_acquire (lock);
74   msg ("Thread b acquired lock b.");
75   lock_release (lock);
76   msg ("Thread b finished.");
77 }