update rw test
authorcompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Mon, 18 Aug 2008 19:14:03 +0000 (19:14 +0000)
committercompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Mon, 18 Aug 2008 19:14:03 +0000 (19:14 +0000)
git-svn-id: http://ltt.polymtl.ca/svn@3031 04897980-b3bd-0310-b5e0-8ef037075253

trunk/tests/kernel/test-fair-rwlock.c

index c1cec959b1afbeb7ce0a05799a76dea371c7f920..8098c03a97d1d61dfeb768245b47be599e4c0b15 100644 (file)
 #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");
This page took 0.027078 seconds and 4 git commands to generate.