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