/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- cleanitems
- inititems
- add_thread
- sub_thread
- uwlocktest1
- vmstats_thread
- uwvmstatstest
1
2 /*
3 * UW - Synchronization test code.
4 * Tim Brecht July, 2013
5 * UW - uwvmstats tests code.
6 * Tim Brecht January, 2014
7 */
8
9 #include <types.h>
10 #include <synch.h>
11 #include <thread.h>
12 #include <test.h>
13 #include <uw-vmstats.h>
14
15 #define NAME_LEN (30)
16
17 static struct lock *testlock = NULL;
18 static struct semaphore *donesem = NULL;
19
20 #define NTESTLOOPS (5000) /* Needs to be evenly divisible by 8 */
21 #define NTESTTHREADS (8)
22 #define START_VALUE (0)
23 static volatile int test_value = START_VALUE;
24 static int use_locks = 1;
25
26 static
27 void
28 cleanitems(void)
29 {
30 kprintf("cleanitems: Destroying sems and locks\n");
31 lock_destroy(testlock);
32 testlock = NULL;
33 sem_destroy(donesem);
34 donesem = NULL;
35 test_value = START_VALUE;
36 }
37
38 static
39 void
40 inititems(void)
41 {
42 if (testlock==NULL) {
43 testlock = lock_create("testlock");
44 if (testlock == NULL) {
45 panic("synchtest: lock_create failed\n");
46 }
47 }
48
49 if (donesem==NULL) {
50 donesem = sem_create("donesem", 0);
51 if (donesem == NULL) {
52 panic("synchtest: sem_create failed\n");
53 }
54 }
55 }
56
57 /* This thread adds values to a global variable. */
58 static
59 void
60 add_thread(void *junk, unsigned long num)
61 {
62 int i;
63 (void) num;
64 (void) junk;
65
66 for (i=0; i<NTESTLOOPS; i++) {
67 if (use_locks) {
68 lock_acquire(testlock);
69 }
70
71 /* This loop is unrolled to possibly avoid optimizations
72 * and to provide more instructions that could be interrupted.
73 * This may or may not be necessary.
74 */
75 test_value = test_value + 1;
76 test_value = test_value + 1;
77 test_value = test_value + 1;
78 test_value = test_value + 1;
79 test_value = test_value + 1;
80
81 if (use_locks) {
82 lock_release(testlock);
83 }
84
85 }
86 V(donesem);
87 thread_exit();
88 }
89
90 /* This thread substract values from a global variable. */
91 static
92 void
93 sub_thread(void *junk, unsigned long num)
94 {
95 int i;
96 (void)num;
97 (void)junk;
98
99 for (i=0; i<NTESTLOOPS; i++) {
100 if (use_locks) {
101 lock_acquire(testlock);
102 }
103
104 /* This loop is unrolled to avoid optimizations
105 * and to provide more instructions that could be interrupted.
106 * This may or may not be necessary.
107 */
108 test_value = test_value - 1;
109 test_value = test_value - 1;
110 test_value = test_value - 1;
111 test_value = test_value - 1;
112 test_value = test_value - 1;
113
114 if (use_locks) {
115 lock_release(testlock);
116 }
117
118 }
119 V(donesem);
120 thread_exit();
121 }
122
123 int
124 uwlocktest1(int nargs, char **args)
125 {
126 int i, result;
127 char name[NAME_LEN];
128
129 (void)nargs;
130 (void)args;
131
132 inititems();
133 kprintf("Starting uwlocktest1...\n");
134
135 for (i=0; i<NTESTTHREADS; i++) {
136 snprintf(name, NAME_LEN, "add_thread %d", i);
137 result = thread_fork(name, NULL, add_thread, NULL, i);
138 if (result) {
139 panic("uwlocktest1: thread_fork failed: %s\n",
140 strerror(result));
141 }
142 }
143
144 for (i=0; i<NTESTTHREADS; i++) {
145 snprintf(name, NAME_LEN, "sub_thread %d", i);
146 result = thread_fork(name, NULL, sub_thread, NULL, i);
147 if (result) {
148 panic("uwlocktest1: thread_fork failed: %s\n",
149 strerror(result));
150 }
151 }
152
153 for (i=0; i<NTESTTHREADS*2; i++) {
154 P(donesem);
155 }
156
157 kprintf("value of test_value = %d should be %d\n", test_value, START_VALUE);
158 if (test_value == START_VALUE) {
159 kprintf("TEST SUCCEEDED\n");
160 } else {
161 kprintf("TEST FAILED\n");
162 }
163 KASSERT(test_value == START_VALUE);
164
165 cleanitems();
166 kprintf("uwlocktest1 done.\n");
167
168 return 0;
169 }
170
171 /*-----------------------------------------------------------------------*/
172
173 /* Each thread makes some calls to vmstats functions */
174 static
175 void
176 vmstats_thread(void *junk, unsigned long num)
177 {
178 int i;
179 int j;
180 (void)num;
181 (void)junk;
182
183 for (i=0; i<NTESTLOOPS; i++) {
184 for (j=0; j<VMSTAT_COUNT; j++) {
185 /* NOTE: The number of calls to vmstats_inc below have been manipulated
186 * so the checks during printing add up properly and pass the various tests
187 */
188 switch(j) {
189 /* Need twice as many TLB faults */
190 case VMSTAT_TLB_FAULT:
191 vmstats_inc(j);
192 vmstats_inc(j);
193 break;
194
195 case VMSTAT_TLB_FAULT_FREE:
196 vmstats_inc(j);
197 break;
198
199 case VMSTAT_TLB_FAULT_REPLACE:
200 vmstats_inc(j);
201 break;
202
203 /* Just reduce these to compare (not necessary) */
204 case VMSTAT_TLB_INVALIDATE:
205 if (i % 2 == 0) {
206 vmstats_inc(j);
207 }
208 break;
209
210 case VMSTAT_TLB_RELOAD:
211 vmstats_inc(j);
212 break;
213
214 /* VMSTAT_TLB_FAULT = VMSTAT_TLB_RELOAD + VMSTAT_PAGE_FAULT_DISK + VMSTAT_SWAP_FILE_ZERO */
215 case VMSTAT_PAGE_FAULT_ZERO:
216 if (i % 2 == 0) {
217 vmstats_inc(j);
218 }
219 break;
220
221 /* VMSTAT_PAGE_FAULT_DISK = VMSTAT_ELF_FILE_READ + VMSTAT_SWAP_FILE_READ */
222 case VMSTAT_PAGE_FAULT_DISK:
223 if (i % 2 == 0) {
224 vmstats_inc(j);
225 }
226 break;
227
228 case VMSTAT_ELF_FILE_READ:
229 if (i % 4 == 0) {
230 vmstats_inc(j);
231 }
232 break;
233
234 case VMSTAT_SWAP_FILE_READ:
235 if (i % 4 == 0) {
236 vmstats_inc(j);
237 }
238 break;
239
240 case VMSTAT_SWAP_FILE_WRITE:
241 if (i % 8 == 0) {
242 vmstats_inc(j);
243 }
244 break;
245
246 default:
247 kprintf("Unknown stat %d\n", j);
248 break;
249 }
250 }
251 }
252
253 V(donesem);
254 thread_exit();
255 }
256
257 int
258 uwvmstatstest(int nargs, char **args)
259 {
260 int i, result;
261 char name[NAME_LEN];
262
263 (void)nargs;
264 (void)args;
265
266 inititems();
267 kprintf("Starting uwvmstatstest...\n");
268
269 kprintf("Initializing vmstats\n");
270 vmstats_init();
271
272 for (i=0; i<NTESTTHREADS; i++) {
273 snprintf(name, NAME_LEN, "vmstatsthread %d", i);
274 result = thread_fork(name, NULL, vmstats_thread, NULL, i);
275 if (result) {
276 panic("uwvmstatstest: thread_fork failed: %s\n",
277 strerror(result));
278 }
279 }
280
281 for (i=0; i<NTESTTHREADS; i++) {
282 P(donesem);
283 }
284
285 vmstats_print();
286
287 cleanitems();
288 kprintf("uwvmstatstest done.\n");
289
290 return 0;
291 }
292
293