Add more tests.
[pintos-anon] / grading / threads / priority-fifo.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 #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/malloc.h"
16 #include "threads/synch.h"
17 #include "threads/thread.h"
18
19 static void test_fifo (void);
20
21 void
22 test (void) 
23 {
24   /* Make sure our priority is the default. */
25   ASSERT (thread_get_priority () == PRI_DEFAULT);
26
27   test_fifo ();
28 }
29 \f
30 static thread_func simple_thread_func;
31
32 struct simple_thread_data 
33   {
34     struct lock *lock;          /* Lock on output. */
35     char **out;                 /* Output pointer. */
36   };
37
38 static void
39 test_fifo (void) 
40 {
41   struct simple_thread_data data;
42   struct lock lock;
43   char *output, *cp;
44   int i;
45   
46   printf ("\n"
47           "Testing FIFO preemption.\n"
48           "10 threads will iterate 5 times in the same order each time.\n"
49           "If the order varies then there is a bug.\n");
50
51   output = cp = malloc (5 * 10 * 128);
52   ASSERT (output != NULL);
53   lock_init (&lock, "output");
54
55   data.lock = &lock;
56   data.out = &cp;
57
58   thread_set_priority (PRI_DEFAULT + 2);
59   for (i = 0; i < 10; i++) 
60     {
61       char name[16];
62       snprintf (name, sizeof name, "%d", i);
63       thread_create (name, PRI_DEFAULT + 1, simple_thread_func, &data);
64     }
65   thread_set_priority (PRI_DEFAULT);
66
67   lock_acquire (&lock);
68   *cp = '\0';
69   printf ("%sFIFO preemption test done.\n", output);
70   lock_release (&lock);
71 }
72
73 static void 
74 simple_thread_func (void *data_) 
75 {
76   struct simple_thread_data *data = data_;
77   int i;
78   
79   for (i = 0; i < 5; i++) 
80     {
81       lock_acquire (data->lock);
82       *data->out += snprintf (*data->out, 128, "Thread %s iteration %d\n",
83                               thread_name (), i);
84       lock_release (data->lock);
85       thread_yield ();
86     }
87
88   lock_acquire (data->lock);
89   *data->out += snprintf (*data->out, 128,
90                           "Thread %s done!\n", thread_name ());
91   lock_release (data->lock);
92 }