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