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