From 4fd25765a593bb72940a1478446fd367a0ccef98 Mon Sep 17 00:00:00 2001 From: compudj Date: Mon, 18 Aug 2008 19:14:03 +0000 Subject: [PATCH] update rw test git-svn-id: http://ltt.polymtl.ca/svn@3031 04897980-b3bd-0310-b5e0-8ef037075253 --- trunk/tests/kernel/test-fair-rwlock.c | 159 ++++++++++++++++++++------ 1 file changed, 122 insertions(+), 37 deletions(-) diff --git a/trunk/tests/kernel/test-fair-rwlock.c b/trunk/tests/kernel/test-fair-rwlock.c index c1cec959..8098c03a 100644 --- a/trunk/tests/kernel/test-fair-rwlock.c +++ b/trunk/tests/kernel/test-fair-rwlock.c @@ -49,22 +49,45 @@ #define NR_TRYLOCK_WRITERS 2 #define NR_READERS 4 #define NR_TRYLOCK_READERS 2 + +/* + * 1 : test with thread and interrupt readers. + * 0 : test only with thread readers. + */ +#define TEST_INTERRUPTS 1 + +#if (TEST_INTERRUPTS) #define NR_INTERRUPT_READERS 1 #define NR_TRYLOCK_INTERRUPT_READERS 1 +#else +#define NR_INTERRUPT_READERS 0 +#define NR_TRYLOCK_INTERRUPT_READERS 0 +#endif /* * Writer iteration delay, in us. 0 for busy loop. Caution : writers can * starve readers. */ #define WRITER_DELAY 10 +#define TRYLOCK_WRITER_DELAY 1000 + +/* + * Number of iterations after which a trylock writer fails. + * -1 for infinite loop. + */ +#define TRYLOCK_WRITERS_FAIL_ITER 100 + +/* Thread and interrupt reader delay, in ms */ +#define THREAD_READER_DELAY 0 /* busy loop */ +#define INTERRUPT_READER_DELAY 100 static int var[NR_VARS]; static struct task_struct *reader_threads[NR_READERS]; static struct task_struct *trylock_reader_threads[NR_TRYLOCK_READERS]; static struct task_struct *writer_threads[NR_WRITERS]; static struct task_struct *trylock_writer_threads[NR_TRYLOCK_WRITERS]; -static struct task_struct *interrupt_reader; -static struct task_struct *trylock_interrupt_reader; +static struct task_struct *interrupt_reader[NR_INTERRUPT_READERS]; +static struct task_struct *trylock_interrupt_reader[NR_TRYLOCK_INTERRUPT_READERS]; static struct fair_rwlock frwlock = { .value = ATOMIC_LONG_INIT(0), @@ -116,15 +139,21 @@ static int reader_thread(void *data) } fair_read_unlock(&frwlock); preempt_enable(); /* for get_cycles accuracy */ - //msleep(100); + if (THREAD_READER_DELAY) + msleep(THREAD_READER_DELAY); } while (!kthread_should_stop()); - delayavg /= iter; - printk("reader_thread/%lu iterations : %lu, " - "lock delay [min,avg,max] %llu,%llu,%llu cycles\n", - (unsigned long)data, iter, - calibrate_cycles(delaymin), - calibrate_cycles(delayavg), - calibrate_cycles(delaymax)); + if (!iter) { + printk("reader_thread/%lu iterations : %lu", + (unsigned long)data, iter); + } else { + delayavg /= iter; + printk("reader_thread/%lu iterations : %lu, " + "lock delay [min,avg,max] %llu,%llu,%llu cycles\n", + (unsigned long)data, iter, + calibrate_cycles(delaymin), + calibrate_cycles(delayavg), + calibrate_cycles(delaymax)); + } return 0; } @@ -148,7 +177,8 @@ static int trylock_reader_thread(void *data) "in thread\n", cur, prev, i, iter); } fair_read_unlock(&frwlock); - //msleep(100); + if (THREAD_READER_DELAY) + msleep(THREAD_READER_DELAY); } while (!kthread_should_stop()); printk("trylock_reader_thread/%lu iterations : %lu, " "successful iterations : %lu\n", @@ -248,11 +278,14 @@ static int interrupt_reader_thread(void *data) do { iter++; on_each_cpu(interrupt_reader_ipi, NULL, 0); - msleep(100); + if (INTERRUPT_READER_DELAY) + msleep(INTERRUPT_READER_DELAY); } while (!kthread_should_stop()); printk("interrupt_reader_thread/%lu iterations : %lu\n", (unsigned long)data, iter); for_each_online_cpu(i) { + if (!per_cpu(int_ipi_nr, i)) + continue; per_cpu(int_delayavg, i) /= per_cpu(int_ipi_nr, i); printk("interrupt readers on CPU %i, " "lock delay [min,avg,max] %llu,%llu,%llu cycles\n", @@ -272,7 +305,8 @@ static int trylock_interrupt_reader_thread(void *data) do { iter++; on_each_cpu(trylock_interrupt_reader_ipi, NULL, 0); - msleep(100); + if (INTERRUPT_READER_DELAY) + msleep(INTERRUPT_READER_DELAY); } while (!kthread_should_stop()); printk("trylock_interrupt_reader_thread/%lu iterations : %lu\n", (unsigned long)data, iter); @@ -304,8 +338,11 @@ static int writer_thread(void *data) time1 = get_cycles(); rdtsc_barrier(); +#if (TEST_INTERRUPTS) fair_write_lock_irq(&frwlock); - //fair_write_lock(&frwlock); +#else + fair_write_lock(&frwlock); +#endif rdtsc_barrier(); time2 = get_cycles(); @@ -318,8 +355,11 @@ static int writer_thread(void *data) for (i = 0; i < NR_VARS; i++) { var[i] = new; } - //fair_write_unlock(&frwlock); +#if (TEST_INTERRUPTS) fair_write_unlock_irq(&frwlock); +#else + fair_write_unlock(&frwlock); +#endif preempt_enable(); /* for get_cycles accuracy */ if (WRITER_DELAY > 0) udelay(WRITER_DELAY); @@ -338,29 +378,61 @@ static int trylock_writer_thread(void *data) { int i; int new; - unsigned long iter = 0, success = 0; + unsigned long iter = 0, success = 0, fail = 0; printk("trylock_writer_thread/%lu runnning\n", (unsigned long)data); do { - fair_write_subscribe(&frwlock); - while (!fair_write_trylock_subscribed_irq(&frwlock)) { + iter++; +#if (TEST_INTERRUPTS) + if (fair_write_trylock_irq_else_subscribe(&frwlock)) +#else + if (fair_write_trylock_else_subscribe(&frwlock)) +#endif + goto locked; +#if (TRYLOCK_WRITERS_FAIL_ITER == -1) + for (;;) { iter++; - continue; +#if (TEST_INTERRUPTS) + if (fair_write_trylock_irq_subscribed(&frwlock)) +#else + if (fair_write_trylock_subscribed(&frwlock)) +#endif + goto locked; } +#else + for (i = 0; i < TRYLOCK_WRITERS_FAIL_ITER; i++) { + iter++; +#if (TEST_INTERRUPTS) + if (fair_write_trylock_irq_subscribed(&frwlock)) +#else + if (fair_write_trylock_subscribed(&frwlock)) +#endif + goto locked; + } +#endif + fail++; + fair_write_unsubscribe(&frwlock); + goto loop; +locked: success++; - //fair_write_lock(&frwlock); new = (int)get_cycles(); for (i = 0; i < NR_VARS; i++) { var[i] = new; } - //fair_write_unlock(&frwlock); +#if (TEST_INTERRUPTS) fair_write_unlock_irq(&frwlock); - if (WRITER_DELAY > 0) - udelay(WRITER_DELAY); +#else + fair_write_unlock(&frwlock); +#endif +loop: + if (TRYLOCK_WRITER_DELAY > 0) + udelay(TRYLOCK_WRITER_DELAY); } while (!kthread_should_stop()); - printk("trylock_writer_thread/%lu iterations : %lu, " - "successful iterations : %lu\n", - (unsigned long)data, iter, success); + printk("trylock_writer_thread/%lu iterations : " + "[try,success,fail after %d try], " + "%lu,%lu,%lu\n", + (unsigned long)data, TRYLOCK_WRITERS_FAIL_ITER, + iter, success, fail); return 0; } @@ -381,15 +453,18 @@ static void fair_rwlock_create(void) (void *)i, "frwlock_trylock_reader"); BUG_ON(!trylock_reader_threads[i]); } - - - printk("starting interrupt reader %lu\n", i); - interrupt_reader = kthread_run(interrupt_reader_thread, NULL, - "frwlock_interrupt_reader"); - printk("starting trylock interrupt reader %lu\n", i); - trylock_interrupt_reader = kthread_run(trylock_interrupt_reader_thread, - NULL, "frwlock_trylock_interrupt_reader"); - + for (i = 0; i < NR_INTERRUPT_READERS; i++) { + printk("starting interrupt reader %lu\n", i); + interrupt_reader[i] = kthread_run(interrupt_reader_thread, + (void *)i, + "frwlock_interrupt_reader"); + } + for (i = 0; i < NR_TRYLOCK_INTERRUPT_READERS; i++) { + printk("starting trylock interrupt reader %lu\n", i); + trylock_interrupt_reader[i] = + kthread_run(trylock_interrupt_reader_thread, + (void *)i, "frwlock_trylock_interrupt_reader"); + } for (i = 0; i < NR_WRITERS; i++) { printk("starting writer thread %lu\n", i); writer_threads[i] = kthread_run(writer_thread, (void *)i, @@ -416,8 +491,10 @@ static void fair_rwlock_stop(void) kthread_stop(reader_threads[i]); for (i = 0; i < NR_TRYLOCK_READERS; i++) kthread_stop(trylock_reader_threads[i]); - kthread_stop(interrupt_reader); - kthread_stop(trylock_interrupt_reader); + for (i = 0; i < NR_INTERRUPT_READERS; i++) + kthread_stop(interrupt_reader[i]); + for (i = 0; i < NR_TRYLOCK_INTERRUPT_READERS; i++) + kthread_stop(trylock_interrupt_reader[i]); } @@ -466,6 +543,14 @@ static int my_open(struct inode *inode, struct file *file) ssleep(SINGLE_WRITER_TEST_DURATION); kthread_stop(writer_threads[0]); + printk("** Single trylock writer test, no contention **\n"); + trylock_writer_threads[0] = kthread_run(trylock_writer_thread, + (void *)0, + "trylock_frwlock_writer"); + BUG_ON(!trylock_writer_threads[0]); + ssleep(SINGLE_WRITER_TEST_DURATION); + kthread_stop(trylock_writer_threads[0]); + printk("** Single reader test, no contention **\n"); reader_threads[0] = kthread_run(reader_thread, (void *)0, "frwlock_reader"); -- 2.34.1