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