update test
[lttv.git] / trunk / tests / kernel / test-wbias-rwlock.c
1 /* test-wbias-rwlock.c
2 *
3 */
4
5 #include <linux/module.h>
6 #include <linux/proc_fs.h>
7 #include <linux/sched.h>
8 #include <linux/timex.h>
9 #include <linux/kthread.h>
10 #include <linux/delay.h>
11 #include <linux/hardirq.h>
12 #include <linux/module.h>
13 #include <linux/percpu.h>
14 #include <linux/spinlock.h>
15 #include <asm/ptrace.h>
16 #include <linux/wbias-rwlock.h>
17
18 /* Test with no contention duration, in seconds */
19 #define SINGLE_WRITER_TEST_DURATION 10
20 #define SINGLE_READER_TEST_DURATION 10
21 #define MULTIPLE_READERS_TEST_DURATION 10
22
23 /* Test duration, in seconds */
24 #define TEST_DURATION 60
25
26 #define NR_VARS 100
27 #define NR_WRITERS 2
28 #define NR_TRYLOCK_WRITERS 1
29 #define NR_NPREADERS 2
30 #define NR_TRYLOCK_READERS 1
31
32 /*
33 * 1 : test standard rwlock
34 * 0 : test wbiasrwlock
35 */
36 #define TEST_STD_RWLOCK 0
37
38 /*
39 * 1 : test with thread and interrupt readers.
40 * 0 : test only with thread readers.
41 */
42 #define TEST_INTERRUPTS 1
43
44 #if (TEST_INTERRUPTS)
45 #define NR_INTERRUPT_READERS 1
46 #define NR_TRYLOCK_INTERRUPT_READERS 1
47 #else
48 #define NR_INTERRUPT_READERS 0
49 #define NR_TRYLOCK_INTERRUPT_READERS 0
50 #endif
51
52 /*
53 * 1 : test with thread preemption readers.
54 * 0 : test only with non-preemptable thread readers.
55 */
56 #define TEST_PREEMPT 0
57
58 #if (TEST_PREEMPT)
59 #define NR_PREADERS 2
60 #else
61 #define NR_PREADERS 0
62 #endif
63
64
65 /*
66 * Writer iteration delay, in us. 0 for busy loop. Caution : writers can
67 * starve readers.
68 */
69 #define WRITER_DELAY 100
70 #define TRYLOCK_WRITER_DELAY 1000
71
72 /*
73 * Number of iterations after which a trylock writer fails.
74 * -1 for infinite loop.
75 */
76 #define TRYLOCK_WRITERS_FAIL_ITER 100
77
78 /* Thread and interrupt reader delay, in ms */
79 #define THREAD_READER_DELAY 0 /* busy loop */
80 #define INTERRUPT_READER_DELAY 100
81
82 static int var[NR_VARS];
83 static struct task_struct *preader_threads[NR_PREADERS];
84 static struct task_struct *npreader_threads[NR_NPREADERS];
85 static struct task_struct *trylock_reader_threads[NR_TRYLOCK_READERS];
86 static struct task_struct *writer_threads[NR_WRITERS];
87 static struct task_struct *trylock_writer_threads[NR_TRYLOCK_WRITERS];
88 static struct task_struct *interrupt_reader[NR_INTERRUPT_READERS];
89 static struct task_struct *trylock_interrupt_reader[NR_TRYLOCK_INTERRUPT_READERS];
90
91 #if (TEST_STD_RWLOCK)
92
93 static DEFINE_RWLOCK(std_rw_lock);
94
95 #define wrap_read_lock() read_lock(&std_rw_lock)
96 #define wrap_read_trylock() read_trylock(&std_rw_lock)
97 #define wrap_read_unlock() read_unlock(&std_rw_lock)
98
99 #define wrap_read_lock_inatomic() read_lock(&std_rw_lock)
100 #define wrap_read_trylock_inatomic() read_trylock(&std_rw_lock)
101 #define wrap_read_unlock_inatomic() read_unlock(&std_rw_lock)
102
103 #define wrap_read_lock_irq() read_lock(&std_rw_lock)
104 #define wrap_read_trylock_irq() read_trylock(&std_rw_lock)
105 #define wrap_read_unlock_irq() read_unlock(&std_rw_lock)
106
107 #if (TEST_INTERRUPTS)
108 #define wrap_write_lock() write_lock_irq(&std_rw_lock)
109 #define wrap_write_unlock() write_unlock_irq(&std_rw_lock)
110 #else
111 #define wrap_write_lock() write_lock(&std_rw_lock)
112 #define wrap_write_unlock() write_unlock(&std_rw_lock)
113 #endif
114
115 #else
116
117 static DEFINE_WBIAS_RWLOCK(wbiasrwlock);
118
119 #define wrap_read_lock() wbias_read_lock(&wbiasrwlock)
120 #define wrap_read_trylock() wbias_read_trylock(&wbiasrwlock)
121 #define wrap_read_unlock() wbias_read_unlock(&wbiasrwlock)
122
123 #define wrap_read_lock_inatomic() wbias_read_lock_inatomic(&wbiasrwlock)
124 #define wrap_read_trylock_inatomic() \
125 wbias_read_trylock_inatomic(&wbiasrwlock)
126 #define wrap_read_unlock_inatomic() \
127 wbias_read_unlock_inatomic(&wbiasrwlock)
128
129 #define wrap_read_lock_irq() wbias_read_lock_irq(&wbiasrwlock)
130 #define wrap_read_trylock_irq() wbias_read_trylock_irq(&wbiasrwlock)
131 #define wrap_read_unlock_irq() wbias_read_unlock_irq(&wbiasrwlock)
132
133 #if (TEST_INTERRUPTS)
134 #define wrap_write_lock() wbias_write_lock_irq(&wbiasrwlock)
135 #define wrap_write_unlock() wbias_write_unlock_irq(&wbiasrwlock)
136 #define wrap_write_trylock_else_subscribe() \
137 wbias_write_trylock_irq_else_subscribe(&wbiasrwlock)
138 #define wrap_write_trylock_subscribed() \
139 wbias_write_trylock_irq_subscribed(&wbiasrwlock)
140 #else
141 #if (TEST_PREEMPT)
142 #define wrap_write_lock() wbias_write_lock(&wbiasrwlock)
143 #define wrap_write_unlock() wbias_write_unlock(&wbiasrwlock)
144 #define wrap_write_trylock_else_subscribe() \
145 wbias_write_trylock_else_subscribe(&wbiasrwlock)
146 #define wrap_write_trylock_subscribed() \
147 wbias_write_trylock_subscribed(&wbiasrwlock)
148 #else
149 #define wrap_write_lock() wbias_write_lock_atomic(&wbiasrwlock)
150 #define wrap_write_unlock() wbias_write_unlock_atomic(&wbiasrwlock)
151 #define wrap_write_trylock_else_subscribe() \
152 wbias_write_trylock_atomic_else_subscribe(&wbiasrwlock)
153 #define wrap_write_trylock_subscribed() \
154 wbias_write_trylock_atomic_subscribed(&wbiasrwlock)
155 #endif
156 #endif
157
158 #endif
159
160 static cycles_t cycles_calibration_min,
161 cycles_calibration_avg,
162 cycles_calibration_max;
163
164 static inline cycles_t calibrate_cycles(cycles_t cycles)
165 {
166 return cycles - cycles_calibration_avg;
167 }
168
169 struct proc_dir_entry *pentry = NULL;
170
171 static int p_or_np_reader_thread(const char *typename,
172 void *data, int preemptable)
173 {
174 int i;
175 int prev, cur;
176 unsigned long iter = 0;
177 cycles_t time1, time2, delay, delaymax = 0, delaymin = ULLONG_MAX,
178 delayavg = 0;
179
180 printk("%s/%lu runnning\n", typename, (unsigned long)data);
181 do {
182 iter++;
183 if (!preemptable)
184 preempt_disable();
185 rdtsc_barrier();
186 time1 = get_cycles();
187 rdtsc_barrier();
188
189 if (!preemptable)
190 wrap_read_lock_inatomic();
191 else
192 wrap_read_lock();
193
194 rdtsc_barrier();
195 time2 = get_cycles();
196 rdtsc_barrier();
197 delay = time2 - time1;
198 delaymax = max(delaymax, delay);
199 delaymin = min(delaymin, delay);
200 delayavg += delay;
201 prev = var[0];
202 for (i = 1; i < NR_VARS; i++) {
203 cur = var[i];
204 if (cur != prev)
205 printk(KERN_ALERT
206 "Unequal cur %d/prev %d at i %d, iter %lu "
207 "in thread\n", cur, prev, i, iter);
208 }
209
210 if (!preemptable)
211 wrap_read_unlock_inatomic();
212 else
213 wrap_read_unlock();
214 if (!preemptable)
215 preempt_enable();
216 if (THREAD_READER_DELAY)
217 msleep(THREAD_READER_DELAY);
218 } while (!kthread_should_stop());
219 if (!iter) {
220 printk("%s/%lu iterations : %lu", typename,
221 (unsigned long)data, iter);
222 } else {
223 delayavg /= iter;
224 printk("%s/%lu iterations : %lu, "
225 "lock delay [min,avg,max] %llu,%llu,%llu cycles\n",
226 typename,
227 (unsigned long)data, iter,
228 calibrate_cycles(delaymin),
229 calibrate_cycles(delayavg),
230 calibrate_cycles(delaymax));
231 }
232 return 0;
233 }
234
235 static int preader_thread(void *data)
236 {
237 return p_or_np_reader_thread("preader_thread", data, 1);
238 }
239
240 static int npreader_thread(void *data)
241 {
242 return p_or_np_reader_thread("npreader_thread", data, 0);
243 }
244
245 static int trylock_reader_thread(void *data)
246 {
247 int i;
248 int prev, cur;
249 unsigned long iter = 0, success_iter = 0;
250
251 printk("trylock_reader_thread/%lu runnning\n", (unsigned long)data);
252 do {
253 while (!wrap_read_trylock())
254 iter++;
255 success_iter++;
256 prev = var[0];
257 for (i = 1; i < NR_VARS; i++) {
258 cur = var[i];
259 if (cur != prev)
260 printk(KERN_ALERT
261 "Unequal cur %d/prev %d at i %d, iter %lu "
262 "in thread\n", cur, prev, i, iter);
263 }
264 wrap_read_unlock();
265 if (THREAD_READER_DELAY)
266 msleep(THREAD_READER_DELAY);
267 } while (!kthread_should_stop());
268 printk("trylock_reader_thread/%lu iterations : %lu, "
269 "successful iterations : %lu\n",
270 (unsigned long)data, iter, success_iter);
271 return 0;
272 }
273
274 DEFINE_PER_CPU(cycles_t, int_delaymin);
275 DEFINE_PER_CPU(cycles_t, int_delayavg);
276 DEFINE_PER_CPU(cycles_t, int_delaymax);
277 DEFINE_PER_CPU(cycles_t, int_ipi_nr);
278
279 static void interrupt_reader_ipi(void *data)
280 {
281 int i;
282 int prev, cur;
283 cycles_t time1, time2;
284 cycles_t *delaymax, *delaymin, *delayavg, *ipi_nr, delay;
285
286 /*
287 * Skip the ipi caller, not in irq context.
288 */
289 if (!in_irq())
290 return;
291
292 delaymax = &per_cpu(int_delaymax, smp_processor_id());
293 delaymin = &per_cpu(int_delaymin, smp_processor_id());
294 delayavg = &per_cpu(int_delayavg, smp_processor_id());
295 ipi_nr = &per_cpu(int_ipi_nr, smp_processor_id());
296
297 rdtsc_barrier();
298 time1 = get_cycles();
299 rdtsc_barrier();
300
301 wrap_read_lock_irq();
302
303 rdtsc_barrier();
304 time2 = get_cycles();
305 rdtsc_barrier();
306 delay = time2 - time1;
307 *delaymax = max(*delaymax, delay);
308 *delaymin = min(*delaymin, delay);
309 *delayavg += delay;
310 (*ipi_nr)++;
311 prev = var[0];
312 for (i = 1; i < NR_VARS; i++) {
313 cur = var[i];
314 if (cur != prev)
315 printk(KERN_ALERT
316 "Unequal cur %d/prev %d at i %d in interrupt\n",
317 cur, prev, i);
318 }
319 wrap_read_unlock_irq();
320 }
321
322 DEFINE_PER_CPU(unsigned long, trylock_int_iter);
323 DEFINE_PER_CPU(unsigned long, trylock_int_success);
324
325 static void trylock_interrupt_reader_ipi(void *data)
326 {
327 int i;
328 int prev, cur;
329
330 /*
331 * Skip the ipi caller, not in irq context.
332 */
333 if (!in_irq())
334 return;
335
336 per_cpu(trylock_int_iter, smp_processor_id())++;
337 while (!wrap_read_trylock_irq())
338 per_cpu(trylock_int_iter, smp_processor_id())++;
339 per_cpu(trylock_int_success, smp_processor_id())++;
340 prev = var[0];
341 for (i = 1; i < NR_VARS; i++) {
342 cur = var[i];
343 if (cur != prev)
344 printk(KERN_ALERT
345 "Unequal cur %d/prev %d at i %d in interrupt\n",
346 cur, prev, i);
347 }
348 wrap_read_unlock_irq();
349 }
350
351
352 static int interrupt_reader_thread(void *data)
353 {
354 unsigned long iter = 0;
355 int i;
356
357 for_each_online_cpu(i) {
358 per_cpu(int_delaymax, i) = 0;
359 per_cpu(int_delaymin, i) = ULLONG_MAX;
360 per_cpu(int_delayavg, i) = 0;
361 per_cpu(int_ipi_nr, i) = 0;
362 }
363 do {
364 iter++;
365 on_each_cpu(interrupt_reader_ipi, NULL, 0);
366 if (INTERRUPT_READER_DELAY)
367 msleep(INTERRUPT_READER_DELAY);
368 } while (!kthread_should_stop());
369 printk("interrupt_reader_thread/%lu iterations : %lu\n",
370 (unsigned long)data, iter);
371 for_each_online_cpu(i) {
372 if (!per_cpu(int_ipi_nr, i))
373 continue;
374 per_cpu(int_delayavg, i) /= per_cpu(int_ipi_nr, i);
375 printk("interrupt readers on CPU %i, "
376 "lock delay [min,avg,max] %llu,%llu,%llu cycles\n",
377 i,
378 calibrate_cycles(per_cpu(int_delaymin, i)),
379 calibrate_cycles(per_cpu(int_delayavg, i)),
380 calibrate_cycles(per_cpu(int_delaymax, i)));
381 }
382 return 0;
383 }
384
385 static int trylock_interrupt_reader_thread(void *data)
386 {
387 unsigned long iter = 0;
388 int i;
389
390 do {
391 iter++;
392 on_each_cpu(trylock_interrupt_reader_ipi, NULL, 0);
393 if (INTERRUPT_READER_DELAY)
394 msleep(INTERRUPT_READER_DELAY);
395 } while (!kthread_should_stop());
396 printk("trylock_interrupt_reader_thread/%lu iterations : %lu\n",
397 (unsigned long)data, iter);
398 for_each_online_cpu(i) {
399 printk("trylock interrupt readers on CPU %i, "
400 "iterations %lu, "
401 "successful iterations : %lu\n",
402 i, per_cpu(trylock_int_iter, i),
403 per_cpu(trylock_int_success, i));
404 per_cpu(trylock_int_iter, i) = 0;
405 per_cpu(trylock_int_success, i) = 0;
406 }
407 return 0;
408 }
409
410 static int writer_thread(void *data)
411 {
412 int i;
413 int new;
414 unsigned long iter = 0;
415 cycles_t time1, time2, delay, delaymax = 0, delaymin = ULLONG_MAX,
416 delayavg = 0;
417
418 printk("writer_thread/%lu runnning\n", (unsigned long)data);
419 do {
420 iter++;
421 //preempt_disable(); /* for get_cycles accuracy */
422 rdtsc_barrier();
423 time1 = get_cycles();
424 rdtsc_barrier();
425
426 wrap_write_lock();
427
428 rdtsc_barrier();
429 time2 = get_cycles();
430 rdtsc_barrier();
431 delay = time2 - time1;
432 delaymax = max(delaymax, delay);
433 delaymin = min(delaymin, delay);
434 delayavg += delay;
435 new = (int)get_cycles();
436 for (i = 0; i < NR_VARS; i++) {
437 var[i] = new;
438 }
439
440 wrap_write_unlock();
441
442 //preempt_enable(); /* for get_cycles accuracy */
443 if (WRITER_DELAY > 0)
444 udelay(WRITER_DELAY);
445 } while (!kthread_should_stop());
446 delayavg /= iter;
447 printk("writer_thread/%lu iterations : %lu, "
448 "lock delay [min,avg,max] %llu,%llu,%llu cycles\n",
449 (unsigned long)data, iter,
450 calibrate_cycles(delaymin),
451 calibrate_cycles(delayavg),
452 calibrate_cycles(delaymax));
453 return 0;
454 }
455
456 #if (TEST_STD_RWLOCK)
457 static int trylock_writer_thread(void *data)
458 {
459 int i;
460 int new;
461 unsigned long iter = 0, success = 0, fail = 0;
462
463 printk("trylock_writer_thread/%lu runnning\n", (unsigned long)data);
464 do {
465 #if (TEST_INTERRUPTS)
466 /* std write trylock cannot disable interrupts. */
467 local_irq_disable();
468 #endif
469
470 #if (TRYLOCK_WRITERS_FAIL_ITER == -1)
471 for (;;) {
472 iter++;
473 if (write_trylock(&std_rw_lock))
474 goto locked;
475 }
476 #else
477 for (i = 0; i < TRYLOCK_WRITERS_FAIL_ITER; i++) {
478 iter++;
479 if (write_trylock(&std_rw_lock))
480 goto locked;
481 }
482 #endif
483 fail++;
484 #if (TEST_INTERRUPTS)
485 local_irq_enable();
486 #endif
487 goto loop;
488 locked:
489 success++;
490 new = (int)get_cycles();
491 for (i = 0; i < NR_VARS; i++) {
492 var[i] = new;
493 }
494 #if (TEST_INTERRUPTS)
495 write_unlock_irq(&std_rw_lock);
496 #else
497 write_unlock(&std_rw_lock);
498 #endif
499 loop:
500 if (TRYLOCK_WRITER_DELAY > 0)
501 udelay(TRYLOCK_WRITER_DELAY);
502 } while (!kthread_should_stop());
503 printk("trylock_writer_thread/%lu iterations : "
504 "[try,success,fail after %d try], "
505 "%lu,%lu,%lu\n",
506 (unsigned long)data, TRYLOCK_WRITERS_FAIL_ITER,
507 iter, success, fail);
508 return 0;
509 }
510
511 #else /* !TEST_STD_RWLOCK */
512
513 static int trylock_writer_thread(void *data)
514 {
515 int i;
516 int new;
517 unsigned long iter = 0, success = 0, fail = 0;
518
519 printk("trylock_writer_thread/%lu runnning\n", (unsigned long)data);
520 do {
521 iter++;
522 if (wrap_write_trylock_else_subscribe())
523 goto locked;
524
525 #if (TRYLOCK_WRITERS_FAIL_ITER == -1)
526 for (;;) {
527 iter++;
528 if (wrap_write_trylock_subscribed())
529 goto locked;
530 }
531 #else
532 for (i = 0; i < TRYLOCK_WRITERS_FAIL_ITER - 1; i++) {
533 iter++;
534 if (wrap_write_trylock_subscribed())
535 goto locked;
536 }
537 #endif
538 fail++;
539 wbias_write_unsubscribe(&wbiasrwlock);
540 goto loop;
541 locked:
542 success++;
543 new = (int)get_cycles();
544 for (i = 0; i < NR_VARS; i++) {
545 var[i] = new;
546 }
547 wrap_write_unlock();
548 loop:
549 if (TRYLOCK_WRITER_DELAY > 0)
550 udelay(TRYLOCK_WRITER_DELAY);
551 } while (!kthread_should_stop());
552 printk("trylock_writer_thread/%lu iterations : "
553 "[try,success,fail after %d try], "
554 "%lu,%lu,%lu\n",
555 (unsigned long)data, TRYLOCK_WRITERS_FAIL_ITER,
556 iter, success, fail);
557 return 0;
558 }
559
560 #endif /* TEST_STD_RWLOCK */
561
562 static void wbias_rwlock_create(void)
563 {
564 unsigned long i;
565
566 for (i = 0; i < NR_PREADERS; i++) {
567 printk("starting preemptable reader thread %lu\n", i);
568 preader_threads[i] = kthread_run(preader_thread, (void *)i,
569 "wbiasrwlock_preader");
570 BUG_ON(!preader_threads[i]);
571 }
572
573 for (i = 0; i < NR_NPREADERS; i++) {
574 printk("starting non-preemptable reader thread %lu\n", i);
575 npreader_threads[i] = kthread_run(npreader_thread, (void *)i,
576 "wbiasrwlock_npreader");
577 BUG_ON(!npreader_threads[i]);
578 }
579
580 for (i = 0; i < NR_TRYLOCK_READERS; i++) {
581 printk("starting trylock reader thread %lu\n", i);
582 trylock_reader_threads[i] = kthread_run(trylock_reader_thread,
583 (void *)i, "wbiasrwlock_trylock_reader");
584 BUG_ON(!trylock_reader_threads[i]);
585 }
586 for (i = 0; i < NR_INTERRUPT_READERS; i++) {
587 printk("starting interrupt reader %lu\n", i);
588 interrupt_reader[i] = kthread_run(interrupt_reader_thread,
589 (void *)i,
590 "wbiasrwlock_interrupt_reader");
591 }
592 for (i = 0; i < NR_TRYLOCK_INTERRUPT_READERS; i++) {
593 printk("starting trylock interrupt reader %lu\n", i);
594 trylock_interrupt_reader[i] =
595 kthread_run(trylock_interrupt_reader_thread,
596 (void *)i, "wbiasrwlock_trylock_interrupt_reader");
597 }
598 for (i = 0; i < NR_WRITERS; i++) {
599 printk("starting writer thread %lu\n", i);
600 writer_threads[i] = kthread_run(writer_thread, (void *)i,
601 "wbiasrwlock_writer");
602 BUG_ON(!writer_threads[i]);
603 }
604 for (i = 0; i < NR_TRYLOCK_WRITERS; i++) {
605 printk("starting trylock writer thread %lu\n", i);
606 trylock_writer_threads[i] = kthread_run(trylock_writer_thread,
607 (void *)i, "wbiasrwlock_trylock_writer");
608 BUG_ON(!trylock_writer_threads[i]);
609 }
610 }
611
612 static void wbias_rwlock_stop(void)
613 {
614 unsigned long i;
615
616 for (i = 0; i < NR_WRITERS; i++)
617 kthread_stop(writer_threads[i]);
618 for (i = 0; i < NR_TRYLOCK_WRITERS; i++)
619 kthread_stop(trylock_writer_threads[i]);
620 for (i = 0; i < NR_NPREADERS; i++)
621 kthread_stop(npreader_threads[i]);
622 for (i = 0; i < NR_PREADERS; i++)
623 kthread_stop(preader_threads[i]);
624 for (i = 0; i < NR_TRYLOCK_READERS; i++)
625 kthread_stop(trylock_reader_threads[i]);
626 for (i = 0; i < NR_INTERRUPT_READERS; i++)
627 kthread_stop(interrupt_reader[i]);
628 for (i = 0; i < NR_TRYLOCK_INTERRUPT_READERS; i++)
629 kthread_stop(trylock_interrupt_reader[i]);
630 }
631
632
633 static void perform_test(const char *name, void (*callback)(void))
634 {
635 printk("%s\n", name);
636 callback();
637 }
638
639 static int my_open(struct inode *inode, struct file *file)
640 {
641 unsigned long i;
642 cycles_t time1, time2, delay;
643
644 printk("** get_cycles calibration **\n");
645 cycles_calibration_min = ULLONG_MAX;
646 cycles_calibration_avg = 0;
647 cycles_calibration_max = 0;
648
649 local_irq_disable();
650 for (i = 0; i < 10; i++) {
651 rdtsc_barrier();
652 time1 = get_cycles();
653 rdtsc_barrier();
654 rdtsc_barrier();
655 time2 = get_cycles();
656 rdtsc_barrier();
657 delay = time2 - time1;
658 cycles_calibration_min = min(cycles_calibration_min, delay);
659 cycles_calibration_avg += delay;
660 cycles_calibration_max = max(cycles_calibration_max, delay);
661 }
662 cycles_calibration_avg /= 10;
663 local_irq_enable();
664
665 printk("get_cycles takes [min,avg,max] %llu,%llu,%llu cycles, "
666 "results calibrated on avg\n",
667 cycles_calibration_min,
668 cycles_calibration_avg,
669 cycles_calibration_max);
670 printk("\n");
671
672 printk("** Single writer test, no contention **\n");
673 wbias_rwlock_profile_latency_reset();
674 writer_threads[0] = kthread_run(writer_thread, (void *)0,
675 "wbiasrwlock_writer");
676 BUG_ON(!writer_threads[0]);
677 ssleep(SINGLE_WRITER_TEST_DURATION);
678 kthread_stop(writer_threads[0]);
679 printk("\n");
680
681 wbias_rwlock_profile_latency_print();
682
683 printk("** Single trylock writer test, no contention **\n");
684 wbias_rwlock_profile_latency_reset();
685 trylock_writer_threads[0] = kthread_run(trylock_writer_thread,
686 (void *)0,
687 "trylock_wbiasrwlock_writer");
688 BUG_ON(!trylock_writer_threads[0]);
689 ssleep(SINGLE_WRITER_TEST_DURATION);
690 kthread_stop(trylock_writer_threads[0]);
691 printk("\n");
692
693 wbias_rwlock_profile_latency_print();
694
695 printk("** Single preemptable reader test, no contention **\n");
696 wbias_rwlock_profile_latency_reset();
697 preader_threads[0] = kthread_run(preader_thread, (void *)0,
698 "wbiasrwlock_preader");
699 BUG_ON(!preader_threads[0]);
700 ssleep(SINGLE_READER_TEST_DURATION);
701 kthread_stop(preader_threads[0]);
702 printk("\n");
703
704 wbias_rwlock_profile_latency_print();
705
706 printk("** Single non-preemptable reader test, no contention **\n");
707 wbias_rwlock_profile_latency_reset();
708 npreader_threads[0] = kthread_run(npreader_thread, (void *)0,
709 "wbiasrwlock_npreader");
710 BUG_ON(!npreader_threads[0]);
711 ssleep(SINGLE_READER_TEST_DURATION);
712 kthread_stop(npreader_threads[0]);
713 printk("\n");
714
715 wbias_rwlock_profile_latency_print();
716
717 printk("** Multiple p/non-p readers test, no contention **\n");
718 wbias_rwlock_profile_latency_reset();
719 for (i = 0; i < NR_PREADERS; i++) {
720 printk("starting preader thread %lu\n", i);
721 preader_threads[i] = kthread_run(preader_thread, (void *)i,
722 "wbiasrwlock_preader");
723 BUG_ON(!preader_threads[i]);
724 }
725 for (i = 0; i < NR_NPREADERS; i++) {
726 printk("starting npreader thread %lu\n", i);
727 npreader_threads[i] = kthread_run(npreader_thread, (void *)i,
728 "wbiasrwlock_npreader");
729 BUG_ON(!npreader_threads[i]);
730 }
731 ssleep(SINGLE_READER_TEST_DURATION);
732 for (i = 0; i < NR_NPREADERS; i++)
733 kthread_stop(npreader_threads[i]);
734 for (i = 0; i < NR_PREADERS; i++)
735 kthread_stop(preader_threads[i]);
736 printk("\n");
737
738 wbias_rwlock_profile_latency_print();
739
740 printk("** High contention test **\n");
741 wbias_rwlock_profile_latency_reset();
742 perform_test("wbias-rwlock-create", wbias_rwlock_create);
743 ssleep(TEST_DURATION);
744 perform_test("wbias-rwlock-stop", wbias_rwlock_stop);
745 printk("\n");
746 wbias_rwlock_profile_latency_print();
747
748 return -EPERM;
749 }
750
751
752 static struct file_operations my_operations = {
753 .open = my_open,
754 };
755
756 int init_module(void)
757 {
758 pentry = create_proc_entry("testwbiasrwlock", 0444, NULL);
759 if (pentry)
760 pentry->proc_fops = &my_operations;
761
762 printk("PTHREAD_ROFFSET : %016lX\n", PTHREAD_ROFFSET);
763 printk("PTHREAD_RMASK : %016lX\n", PTHREAD_RMASK);
764 printk("NPTHREAD_ROFFSET : %016lX\n", NPTHREAD_ROFFSET);
765 printk("NPTHREAD_RMASK : %016lX\n", NPTHREAD_RMASK);
766 printk("SOFTIRQ_ROFFSET : %016lX\n", SOFTIRQ_ROFFSET);
767 printk("SOFTIRQ_RMASK : %016lX\n", SOFTIRQ_RMASK);
768 printk("HARDIRQ_ROFFSET : %016lX\n", HARDIRQ_ROFFSET);
769 printk("HARDIRQ_RMASK : %016lX\n", HARDIRQ_RMASK);
770 printk("PTHREAD_WOFFSET : %016lX\n", PTHREAD_WOFFSET);
771 printk("PTHREAD_WMASK : %016lX\n", PTHREAD_WMASK);
772 printk("NPTHREAD_WOFFSET : %016lX\n", NPTHREAD_WOFFSET);
773 printk("NPTHREAD_WMASK : %016lX\n", NPTHREAD_WMASK);
774 printk("WRITER_MUTEX : %016lX\n", WRITER_MUTEX);
775 printk("SOFTIRQ_WMASK : %016lX\n", SOFTIRQ_WMASK);
776 printk("HARDIRQ_WMASK : %016lX\n", HARDIRQ_WMASK);
777
778 return 0;
779 }
780
781 void cleanup_module(void)
782 {
783 remove_proc_entry("testwbiasrwlock", NULL);
784 }
785
786 MODULE_LICENSE("GPL");
787 MODULE_AUTHOR("Mathieu Desnoyers");
788 MODULE_DESCRIPTION("wbias rwlock test");
This page took 0.054526 seconds and 5 git commands to generate.