50a4fcfa803de0416a86f1e0433096b745df278f
[pintos-anon] / src / tests / threads / p1-2.c
1 /* Problem 1-2: 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_preempt (void);
19 static void test_fifo (void);
20 static void test_donate_return (void);
21
22 void
23 test (void) 
24 {
25   /* Make sure our priority is the default. */
26   ASSERT (thread_get_priority () == PRI_DEFAULT);
27
28   test_preempt ();
29   test_fifo ();
30   test_donate_return ();
31 }
32 \f
33 static thread_func simple_thread_func;
34 static thread_func acquire_thread_func;
35
36 static void
37 test_preempt (void) 
38 {
39   printf ("\n"
40           "Testing priority preemption.\n");
41   thread_create ("high-priority", PRI_DEFAULT + 1, simple_thread_func, NULL);
42   printf ("The high-priority thread should have already completed.\n"
43           "Priority preemption test done.\n");
44 }
45
46 static void
47 test_fifo (void) 
48 {
49   int i;
50   
51   printf ("\n"
52           "Testing FIFO preemption.\n"
53           "5 threads will iterate 10 times in the same order each time.\n"
54           "If the order varies then there is a bug.\n");
55
56   thread_set_priority (PRI_DEFAULT + 2);
57   for (i = 0; i < 10; i++) 
58     {
59       char name[16];
60       snprintf (name, sizeof name, "%d", i);
61       thread_create (name, PRI_DEFAULT + 1, simple_thread_func, NULL);
62     }
63   thread_set_priority (PRI_DEFAULT);
64
65   printf ("FIFO preemption test done.\n");
66 }
67
68 static void
69 test_donate_return (void) 
70 {
71   struct lock lock;
72
73   printf ("\n"
74           "Testing priority donation.\n"
75           "If the statements printed below are all true, you pass.\n");
76
77   lock_init (&lock, "donor");
78   lock_acquire (&lock);
79   thread_create ("acquire1", PRI_DEFAULT + 1, acquire_thread_func, &lock);
80   printf ("This thread should have priority %d.  Actual priority: %d.\n",
81           PRI_DEFAULT + 1, thread_get_priority ());
82   thread_create ("acquire2", PRI_DEFAULT + 2, acquire_thread_func, &lock);
83   printf ("This thread should have priority %d.  Actual priority: %d.\n",
84           PRI_DEFAULT + 2, thread_get_priority ());
85   lock_release (&lock);
86   printf ("acquire2 and acquire1 must already have finished, in that order.\n"
87           "This should be the last line before finishing this test.\n"
88           "Priority donation test done.\n");
89 }
90
91 static void 
92 simple_thread_func (void *aux UNUSED) 
93 {
94   int i;
95   
96   for (i = 0; i < 5; i++) 
97     {
98       printf ("Thread %s iteration %d\n", thread_name (), i);
99       thread_yield ();
100     }
101   printf ("Thread %s done!\n", thread_name ());
102 }
103
104 static void
105 acquire_thread_func (void *lock_) 
106 {
107   struct lock *lock = lock_;
108
109   lock_acquire (lock);
110   printf ("%s: got the lock\n", thread_name ());
111   lock_release (lock);
112   printf ("%s: done\n", thread_name ());
113 }