-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathschedstress.c
executable file
·216 lines (188 loc) · 5.58 KB
/
schedstress.c
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
#ifdef CS333_P4
#include "types.h"
#include "user.h"
// Noah Zentzis, 2016
#define MAX_PRIORITY 7
// stress-test the MLFQ scheduler
//
// Note that this program doesn't necessarily do proper error-checking for all
// system calls, since it's not meant to test that. This is only intended to
// verify that MLFQ is behaving properly, and adding error-handling would make
// it more complicated than it really needs to be.
// wait for all children - just keep calling wait() until it fails due to not
// having any children.
void
waitall(void) {
while(wait() != -1);
}
// high-priority locking process. starts a process that locks itself into queue
// Q until it counts up to N.
void
queuebound(int q, unsigned int n) {
if(fork() == 0) {
int pid = getpid();
// busywait
for(unsigned int i = 0;i < n;i++) {
setpriority(pid, q);
}
exit();
}
}
// Test 1: queue priority. Start a few low-priority processes that print values
// on a delay, then start four CPU-bound processes that lock themselves into
// priority 0. Values should stop printing while the high-priority processes
// run.
void
test1(void) {
printf(1, "\n> starting test 1\n");
// start low-priority printing processes
for(int i = 0;i < 2;i++) {
if(fork() == 0) {
setpriority(getpid(), MAX_PRIORITY); // deprioritize ourselves
// lock ourselves into low priority
for(int n = 0;n < 5;n++) {
printf(1, "low-priority #%d\n", n);
setpriority(getpid(), MAX_PRIORITY);
sleep(10);
}
exit();
}
}
sleep(20); // wait for a few low priority values to print
// start high-priority processes
for(int i = 0;i < 4;i++) {
if(fork() == 0) {
int pid = getpid();
printf(1, "high-priority start\n");
// busywait
for(unsigned int i = 0;i < 0x100000;i++) {
setpriority(pid, 0); // lock into queue 0
}
printf(1, "high-priority end\n");
exit();
}
}
waitall();
printf(1, "\n> test 1 complete\n");
}
// Test 2: promotion. This makes it easy to check that promotion into queue 0
// functions as expected.
//
// This test functions by creating one processes for each priority level that
// waits for a short period of time before printing a value and exiting. Then,
// before the wait expires, it creates several high-priority processes that lock
// themselves into the highest-priority queue.
//
// The highest-priority process should run quickly and print its value. Each
// subsequent promotion delay, a new process will be moved into queue 0 and get
// a chance to run. This will manifest as an ascending sequence of numbers (one
// for each queue).
void
test2(void) {
printf(1, "\n> starting test 2\n");
// start processes for each queue
for(int i = 0;i <= MAX_PRIORITY;i++) {
int p = fork();
if(p == 0) {
sleep(10);
printf(1, "queue %d!\n", i);
exit();
} else {
setpriority(p, i);
}
}
// high-priority processes
for(int i = 0;i < 8;i++)
queuebound(0, 0x80000);
// wait for children
waitall();
printf(1, "\n> test 2 complete\n");
}
// Test 3: queue append.
//
// Verifies that queue 1 is appended to queue 0 during promotion. This test
// starts 4 busyloops in queue 0 and 4 in a lower-priority queue. Then, you can
// use C-L to show the different queues. Once promotion occurs, the
// lower-priority loops should be visible in queue 0 in the same order as they
// were in the lower-priority queue.
void
test3(void) {
printf(1, "\n> starting test 3\n");
if(MAX_PRIORITY < 2) {
printf(2, "! test 3 requires 3 queues!\n");
return;
}
// start low-priority loops
for(int i = 0;i < 4;i++) {
int p = fork();
if(p == 0) {
p = getpid();
// wait, so the other loops can start
sleep(10);
// lock to priority 0
for(int j = 0;j < 0x100000;j++)
setpriority(p, 0);
exit();
} else {
setpriority(p, 2);
}
}
// start high-priority loops
for(int i = 0;i < 4;i++)
queuebound(0, 0x800000);
// wait for children
waitall();
printf(1, "\n> test 3 complete\n");
}
// Test 3: demotion. This makes it easy to check that demotion into queue 0
// functions as expected.
//
// This test functions by creating one processes for each priority level that
// waits for a short period of time before printing a value and exiting. Then,
// before the wait expires, it creates several high-priority busyloops.
//
// The highest-priority process should run quickly and print its value. Each
// time the CPU-bound processes are demoted, a new process will be able to run
// and will display its value. This will manifest as an ascending sequence of
// numbers (one for each queue).
void
test4(void) {
printf(1, "\n> starting test 4\n");
// start processes for each queue
for(int i = 0;i <= MAX_PRIORITY;i++) {
int p = fork();
if(p == 0) {
sleep(10);
printf(1, "queue %d!\n", i);
exit();
} else {
setpriority(p, i);
}
}
// high-priority processes
for(int i = 0;i < 8;i++) {
if(fork() == 0) {
int p = getpid();
// let the others get established so we all move down at once
for(int j = 0;j < 0x100000;j++)
setpriority(p, 0);
for(int j = 0;j < 0x800000;j++);
exit();
}
}
// wait for children
waitall();
printf(1, "\n> test 4 complete\n");
}
int
main(int argc, char **argv) {
int test = 0;
if(argc == 2) test = atoi(argv[1]);
if(test == 0) printf(1, "stressing scheduler...\n");
if(test == 1 || test == 0) test1();
if(test == 2 || test == 0) test2();
if(test == 3 || test == 0) test3();
if(test == 4 || test == 0) test4();
exit();
}
#endif