Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
script3r
GitHub Repository: script3r/os161
Path: blob/master/user/testbin/parallelvm/parallelvm.c
734 views
1
/*
2
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
3
* The President and Fellows of Harvard College.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
* 3. Neither the name of the University nor the names of its contributors
14
* may be used to endorse or promote products derived from this software
15
* without specific prior written permission.
16
*
17
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
18
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
21
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
* SUCH DAMAGE.
28
*/
29
30
/*
31
* parallelvm.c: highly parallelized VM stress test.
32
*
33
* This test probably won't run with only 512k of physical memory
34
* (unless maybe if you have a *really* gonzo VM system) because each
35
* of its processes needs to allocate a kernel stack, and those add up
36
* quickly.
37
*/
38
39
#include <sys/types.h>
40
#include <sys/wait.h>
41
#include <stdarg.h>
42
#include <stdio.h>
43
#include <string.h>
44
#include <stdlib.h>
45
#include <unistd.h>
46
#include <err.h>
47
48
#define NJOBS 24
49
50
#define DIM 35
51
#define NMATS 11
52
#define JOBSIZE ((NMATS+1)*DIM*DIM*sizeof(int))
53
54
static const int right_answers[NJOBS] = {
55
-1337312809,
56
356204544,
57
-537881911,
58
-65406976,
59
1952063315,
60
-843894784,
61
1597000869,
62
-993925120,
63
838840559,
64
-1616928768,
65
-182386335,
66
-364554240,
67
251084843,
68
-61403136,
69
295326333,
70
1488013312,
71
1901440647,
72
0,
73
-1901440647,
74
-1488013312,
75
-295326333,
76
61403136,
77
-251084843,
78
364554240,
79
};
80
81
////////////////////////////////////////////////////////////
82
83
struct matrix {
84
int m_data[DIM][DIM];
85
};
86
87
////////////////////////////////////////////////////////////
88
89
/*
90
* Use this instead of just calling printf so we know each printout
91
* is atomic; this prevents the lines from getting intermingled.
92
*/
93
static
94
void
95
say(const char *fmt, ...)
96
{
97
char buf[256];
98
va_list ap;
99
va_start(ap, fmt);
100
vsnprintf(buf, sizeof(buf), fmt, ap);
101
va_end(ap);
102
write(STDOUT_FILENO, buf, strlen(buf));
103
}
104
105
////////////////////////////////////////////////////////////
106
107
static
108
void
109
multiply(struct matrix *res, const struct matrix *m1, const struct matrix *m2)
110
{
111
int i, j, k;
112
113
for (i=0; i<DIM; i++) {
114
for (j=0; j<DIM; j++) {
115
int val=0;
116
for (k=0; k<DIM; k++) {
117
val += m1->m_data[i][k]*m2->m_data[k][j];
118
}
119
res->m_data[i][j] = val;
120
}
121
}
122
}
123
124
static
125
void
126
addeq(struct matrix *m1, const struct matrix *m2)
127
{
128
int i, j;
129
for (i=0; i<DIM; i++) {
130
for (j=0; j<DIM; j++) {
131
m1->m_data[i][j] += m2->m_data[i][j];
132
}
133
}
134
}
135
136
static
137
int
138
trace(const struct matrix *m1)
139
{
140
int i, t=0;
141
for (i=0; i<DIM; i++) {
142
t += m1->m_data[i][i];
143
}
144
return t;
145
}
146
147
////////////////////////////////////////////////////////////
148
149
static struct matrix mats[NMATS];
150
151
static
152
void
153
populate_initial_matrixes(int mynum)
154
{
155
int i,j;
156
struct matrix *m = &mats[0];
157
for (i=0; i<DIM; i++) {
158
for (j=0; j<DIM; j++) {
159
m->m_data[i][j] = mynum+i-2*j;
160
}
161
}
162
163
multiply(&mats[1], &mats[0], &mats[0]);
164
}
165
166
static
167
void
168
compute(int n)
169
{
170
struct matrix tmp;
171
int i, j;
172
173
for (i=0,j=n-1; i<j; i++,j--) {
174
multiply(&tmp, &mats[i], &mats[j]);
175
addeq(&mats[n], &tmp);
176
}
177
}
178
179
static
180
void
181
computeall(int mynum)
182
{
183
int i;
184
populate_initial_matrixes(mynum);
185
for (i=2; i<NMATS; i++) {
186
compute(i);
187
}
188
}
189
190
static
191
int
192
answer(void)
193
{
194
return trace(&mats[NMATS-1]);
195
}
196
197
static
198
void
199
go(int mynum)
200
{
201
int r;
202
203
say("Process %d (pid %d) starting computation...\n", mynum,
204
(int) getpid());
205
206
computeall(mynum);
207
r = answer();
208
209
if (r != right_answers[mynum]) {
210
say("Process %d answer %d: FAILED, should be %d\n",
211
mynum, r, right_answers[mynum]);
212
exit(1);
213
}
214
say("Process %d answer %d: passed\n", mynum, r);
215
exit(0);
216
}
217
218
////////////////////////////////////////////////////////////
219
220
static
221
int
222
status_is_failure(int status)
223
{
224
/* Proper interpretation of Unix exit status */
225
if (WIFSIGNALED(status)) {
226
return 1;
227
}
228
if (!WIFEXITED(status)) {
229
/* ? */
230
return 1;
231
}
232
status = WEXITSTATUS(status);
233
return status != 0;
234
}
235
236
static
237
void
238
makeprocs(void)
239
{
240
int i, status, failcount;
241
pid_t pids[NJOBS];
242
243
printf("Job size approximately %lu bytes\n", (unsigned long) JOBSIZE);
244
printf("Forking %d jobs; total load %luk\n", NJOBS,
245
(unsigned long) (NJOBS * JOBSIZE)/1024);
246
247
for (i=0; i<NJOBS; i++) {
248
pids[i] = fork();
249
if (pids[i]<0) {
250
warn("fork");
251
}
252
if (pids[i]==0) {
253
/* child */
254
go(i);
255
}
256
}
257
258
failcount=0;
259
for (i=0; i<NJOBS; i++) {
260
if (pids[i]<0) {
261
failcount++;
262
}
263
else {
264
if (waitpid(pids[i], &status, 0)<0) {
265
err(1, "waitpid");
266
}
267
if (status_is_failure(status)) {
268
failcount++;
269
}
270
}
271
}
272
273
if (failcount>0) {
274
printf("%d subprocesses failed\n", failcount);
275
exit(1);
276
}
277
printf("Test complete\n");
278
}
279
280
int
281
main()
282
{
283
makeprocs();
284
return 0;
285
}
286
287