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