summaryrefslogtreecommitdiffstats
path: root/pintos-progos/tests/threads/priority-fifo.c
diff options
context:
space:
mode:
Diffstat (limited to 'pintos-progos/tests/threads/priority-fifo.c')
-rw-r--r--pintos-progos/tests/threads/priority-fifo.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/pintos-progos/tests/threads/priority-fifo.c b/pintos-progos/tests/threads/priority-fifo.c
new file mode 100644
index 0000000..3af98a3
--- /dev/null
+++ b/pintos-progos/tests/threads/priority-fifo.c
@@ -0,0 +1,99 @@
1/* Creates several threads all at the same priority and ensures
2 that they consistently run in the same round-robin order.
3
4 Based on a test originally submitted for Stanford's CS 140 in
5 winter 1999 by by Matt Franklin
6 <startled@leland.stanford.edu>, Greg Hutchins
7 <gmh@leland.stanford.edu>, Yu Ping Hu <yph@cs.stanford.edu>.
8 Modified by arens. */
9
10#include <stdio.h>
11#include "tests/threads/tests.h"
12#include "threads/init.h"
13#include "devices/timer.h"
14#include "threads/malloc.h"
15#include "threads/synch.h"
16#include "threads/thread.h"
17
18struct simple_thread_data
19 {
20 int id; /* Sleeper ID. */
21 int iterations; /* Iterations so far. */
22 struct lock *lock; /* Lock on output. */
23 int **op; /* Output buffer position. */
24 };
25
26#define THREAD_CNT 16
27#define ITER_CNT 16
28
29static thread_func simple_thread_func;
30
31void
32test_priority_fifo (void)
33{
34 struct simple_thread_data data[THREAD_CNT];
35 struct lock lock;
36 int *output, *op;
37 int i, cnt;
38
39 /* This test does not work with the MLFQS. */
40 ASSERT (!thread_mlfqs);
41
42 /* Make sure our priority is the default. */
43 ASSERT (thread_get_priority () == PRI_DEFAULT);
44
45 msg ("%d threads will iterate %d times in the same order each time.",
46 THREAD_CNT, ITER_CNT);
47 msg ("If the order varies then there is a bug.");
48
49 output = op = malloc (sizeof *output * THREAD_CNT * ITER_CNT * 2);
50 ASSERT (output != NULL);
51 lock_init (&lock);
52
53 thread_set_priority (PRI_DEFAULT + 2);
54 for (i = 0; i < THREAD_CNT; i++)
55 {
56 char name[16];
57 struct simple_thread_data *d = data + i;
58 snprintf (name, sizeof name, "%d", i);
59 d->id = i;
60 d->iterations = 0;
61 d->lock = &lock;
62 d->op = &op;
63 thread_create (name, PRI_DEFAULT + 1, simple_thread_func, d);
64 }
65
66 thread_set_priority (PRI_DEFAULT);
67 /* All the other threads now run to termination here. */
68 ASSERT (lock.holder == NULL);
69
70 cnt = 0;
71 for (; output < op; output++)
72 {
73 struct simple_thread_data *d;
74
75 ASSERT (*output >= 0 && *output < THREAD_CNT);
76 d = data + *output;
77 if (cnt % THREAD_CNT == 0)
78 printf ("(priority-fifo) iteration:");
79 printf (" %d", d->id);
80 if (++cnt % THREAD_CNT == 0)
81 printf ("\n");
82 d->iterations++;
83 }
84}
85
86static void
87simple_thread_func (void *data_)
88{
89 struct simple_thread_data *data = data_;
90 int i;
91
92 for (i = 0; i < ITER_CNT; i++)
93 {
94 lock_acquire (data->lock);
95 *(*data->op)++ = data->id;
96 lock_release (data->lock);
97 thread_yield ();
98 }
99}