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