Make tests public. Rewrite most tests. Add tests.
[pintos-anon] / src / tests / 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 #include <stdio.h>
10 #include "tests/threads/tests.h"
11 #include "threads/init.h"
12 #include "devices/timer.h"
13 #include "threads/malloc.h"
14 #include "threads/synch.h"
15 #include "threads/thread.h"
16
17 struct simple_thread_data 
18   {
19     int id;                     /* Sleeper ID. */
20     int iterations;             /* Iterations so far. */
21     struct lock *lock;          /* Lock on output. */
22     int **op;                   /* Output buffer position. */
23   };
24
25 #define THREAD_CNT 16
26 #define ITER_CNT 16
27
28 static thread_func simple_thread_func;
29
30 void
31 test_priority_fifo (void) 
32 {
33   struct simple_thread_data data[THREAD_CNT];
34   struct lock lock;
35   int *output, *op;
36   int i, cnt;
37
38   /* This test does not work with the MLFQS. */
39   ASSERT (!enable_mlfqs);
40
41   /* Make sure our priority is the default. */
42   ASSERT (thread_get_priority () == PRI_DEFAULT);
43
44   msg ("%d threads will iterate %d times in the same order each time.",
45        THREAD_CNT, ITER_CNT);
46   msg ("If the order varies then there is a bug.");
47
48   output = op = malloc (sizeof *output * THREAD_CNT * ITER_CNT * 2);
49   ASSERT (output != NULL);
50   lock_init (&lock);
51
52   thread_set_priority (PRI_DEFAULT - 2);
53   for (i = 0; i < THREAD_CNT; i++) 
54     {
55       char name[16];
56       struct simple_thread_data *d = data + i;
57       snprintf (name, sizeof name, "%d", i);
58       d->id = i;
59       d->iterations = 0;
60       d->lock = &lock;
61       d->op = &op;
62       thread_create (name, PRI_DEFAULT - 1, simple_thread_func, d);
63     }
64
65   thread_set_priority (PRI_DEFAULT);
66   /* All the other threads now run to termination here. */
67   ASSERT (lock.holder == NULL);
68
69   cnt = 0;
70   for (; output < op; output++) 
71     {
72       struct simple_thread_data *d;
73
74       ASSERT (*output >= 0 && *output < THREAD_CNT);
75       d = data + *output;
76       if (cnt % THREAD_CNT == 0)
77         printf ("(priority-fifo) iteration:");
78       printf (" %d", d->id);
79       if (++cnt % THREAD_CNT == 0)
80         printf ("\n");
81       d->iterations++;
82     }
83 }
84
85 static void 
86 simple_thread_func (void *data_) 
87 {
88   struct simple_thread_data *data = data_;
89   int i;
90   
91   for (i = 0; i < ITER_CNT; i++) 
92     {
93       lock_acquire (data->lock);
94       *(*data->op)++ = data->id;
95       lock_release (data->lock);
96       thread_yield ();
97     }
98 }