update test fair rwlock
authorcompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Sat, 16 Aug 2008 21:06:03 +0000 (21:06 +0000)
committercompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Sat, 16 Aug 2008 21:06:03 +0000 (21:06 +0000)
git-svn-id: http://ltt.polymtl.ca/svn@3023 04897980-b3bd-0310-b5e0-8ef037075253

trunk/tests/kernel/Makefile
trunk/tests/kernel/test-fair-rwlock.c [new file with mode: 0644]
trunk/tests/kernel/test-prefix-speed.c

index d7c78963c7b6a80e2c5e0f939f2547e714985f00..c4566e45729b450e30515bc92d30e8a3481a6dbb 100644 (file)
@@ -15,7 +15,9 @@ endif
        #obj-m += test-sys_call.o
 #      obj-m += test-bug.o
        obj-m += test-nop-speed.o
-       obj-m += test-prefix-speed-32.o
+#      obj-m += test-prefix-speed-32.o
+       obj-m += test-prefix-speed.o
+       obj-m += test-fair-rwlock.o
 #      obj-m += test-cmpxchg-nolock2.o
 #      obj-m += test-trace-speed.o
 #      obj-m += test-rcu-speed.o
diff --git a/trunk/tests/kernel/test-fair-rwlock.c b/trunk/tests/kernel/test-fair-rwlock.c
new file mode 100644 (file)
index 0000000..ec751a1
--- /dev/null
@@ -0,0 +1,215 @@
+/* test-fair-rwlock.c
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/sched.h>
+#include <linux/timex.h>
+#include <linux/fair-rwlock.h>
+#include <linux/kthread.h>
+#include <linux/delay.h>
+#include <linux/hardirq.h>
+#include <linux/module.h>
+#include <asm/ptrace.h>
+
+#if (NR_CPUS > 512 && (BITS_PER_LONG == 32 || NR_CPUS > 1048576))
+#error "fair rwlock needs more bits per long to deal with that many CPUs"
+#endif
+
+#define THREAD_ROFFSET 1UL
+#define THREAD_RMASK   ((NR_CPUS - 1) * THREAD_ROFFSET)
+#define SOFTIRQ_ROFFSET        (THREAD_RMASK + 1)
+#define SOFTIRQ_RMASK  ((NR_CPUS - 1) * SOFTIRQ_ROFFSET)
+#define HARDIRQ_ROFFSET        ((SOFTIRQ_RMASK | THREAD_RMASK) + 1)
+#define HARDIRQ_RMASK  ((NR_CPUS - 1) * HARDIRQ_ROFFSET)
+
+#define THREAD_WMASK   (1UL << (BITS_PER_LONG - 3))
+#define SOFTIRQ_WMASK  (1UL << (BITS_PER_LONG - 2))
+#define HARDIRQ_WMASK  (1UL << (BITS_PER_LONG - 1))
+
+
+#define NR_VARS 100
+#define NR_WRITERS 3
+#define NR_READERS 6
+#define NR_INTERRUPT_READERS 2
+
+static int var[NR_VARS];
+static struct task_struct *reader_threads[NR_READERS];
+static struct task_struct *writer_threads[NR_WRITERS];
+static struct task_struct *interrupt_reader;
+
+static struct fair_rwlock frwlock = {
+       .value = ATOMIC_LONG_INIT(0),
+       .wlock = __SPIN_LOCK_UNLOCKED(&frwlock.wlock),
+};
+
+struct proc_dir_entry *pentry = NULL;
+
+static int reader_thread(void *data)
+{
+       int i;
+       int prev, cur;
+       unsigned long iter = 0;
+
+       printk("reader_thread/%lu runnning\n", (unsigned long)data);
+       do {
+               iter++;
+               fair_read_lock(&frwlock);
+               prev = var[0];
+               for (i = 1; i < NR_VARS; i++) {
+                       cur = var[i];
+                       if (cur != prev)
+                               printk(KERN_ALERT
+                               "Unequal cur %d/prev %d at i %d, iter %lu "
+                               "in thread\n", cur, prev, i, iter);
+               }
+               fair_read_unlock(&frwlock);
+               //msleep(100);
+       } while (!kthread_should_stop());
+       printk("reader_thread/%lu iterations : %lu\n",
+                       (unsigned long)data, iter);
+       return 0;
+}
+
+static void interrupt_reader_ipi(void *data)
+{
+       int i;
+       int prev, cur;
+
+       fair_read_lock(&frwlock);
+       prev = var[0];
+       for (i = 1; i < NR_VARS; i++) {
+               cur = var[i];
+               if (cur != prev)
+                       printk(KERN_ALERT
+                       "Unequal cur %d/prev %d at i %d in interrupt\n",
+                               cur, prev, i);
+       }
+       fair_read_unlock(&frwlock);
+}
+
+static int interrupt_reader_thread(void *data)
+{
+       unsigned long iter = 0;
+       do {
+               iter++;
+               on_each_cpu(interrupt_reader_ipi, NULL, 0);
+               msleep(100);
+       } while (!kthread_should_stop());
+       printk("interrupt_reader_thread/%lu iterations : %lu\n",
+                       (unsigned long)data, iter);
+       return 0;
+}
+
+static int writer_thread(void *data)
+{
+       int i;
+       int new;
+       unsigned long iter = 0;
+
+       printk("writer_thread/%lu runnning\n", (unsigned long)data);
+       do {
+               iter++;
+               fair_write_lock_irq(&frwlock);
+               //fair_write_lock(&frwlock);
+               new = (int)get_cycles();
+               for (i = 0; i < NR_VARS; i++) {
+                       var[i] = new;
+               }
+               //fair_write_unlock(&frwlock);
+               fair_write_unlock_irq(&frwlock);
+               //msleep(100);
+       } while (!kthread_should_stop());
+       printk("writer_thread/%lu iterations : %lu\n",
+                       (unsigned long)data, iter);
+       return 0;
+}
+
+static void fair_rwlock_create(void)
+{
+       unsigned long i;
+
+       for (i = 0; i < NR_READERS; i++) {
+               printk("starting reader thread %lu\n", i);
+               reader_threads[i] = kthread_run(reader_thread, (void *)i,
+                       "frwlock_reader");
+               BUG_ON(!reader_threads[i]);
+       }
+
+       printk("starting interrupt reader %lu\n", i);
+       interrupt_reader = kthread_run(interrupt_reader_thread, NULL,
+               "frwlock_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,
+                       "frwlock_writer");
+               BUG_ON(!writer_threads[i]);
+       }
+}
+
+static void fair_rwlock_stop(void)
+{
+       unsigned long i;
+
+       for (i = 0; i < NR_READERS; i++) {
+               kthread_stop(reader_threads[i]);
+       }
+
+       //kthread_stop(interrupt_reader);
+
+       for (i = 0; i < NR_WRITERS; i++) {
+               kthread_stop(writer_threads[i]);
+       }
+}
+
+
+static void perform_test(const char *name, void (*callback)(void))
+{
+       printk("%s\n", name);
+       callback();
+}
+
+static int my_open(struct inode *inode, struct file *file)
+{
+       perform_test("fair-rwlock-create", fair_rwlock_create);
+       ssleep(30);
+       perform_test("fair-rwlock-stop", fair_rwlock_stop);
+
+       return -EPERM;
+}
+
+
+static struct file_operations my_operations = {
+       .open = my_open,
+};
+
+int init_module(void)
+{
+       pentry = create_proc_entry("testfrwlock", 0444, NULL);
+       if (pentry)
+               pentry->proc_fops = &my_operations;
+
+       printk("NR_CPUS : %d\n", NR_CPUS);
+       printk("THREAD_ROFFSET : %lX\n", THREAD_ROFFSET);
+       printk("THREAD_RMASK : %lX\n", THREAD_RMASK);
+       printk("THREAD_WMASK : %lX\n", THREAD_WMASK);
+       printk("SOFTIRQ_ROFFSET : %lX\n", SOFTIRQ_ROFFSET);
+       printk("SOFTIRQ_RMASK : %lX\n", SOFTIRQ_RMASK);
+       printk("SOFTIRQ_WMASK : %lX\n", SOFTIRQ_WMASK);
+       printk("HARDIRQ_ROFFSET : %lX\n", HARDIRQ_ROFFSET);
+       printk("HARDIRQ_RMASK : %lX\n", HARDIRQ_RMASK);
+       printk("HARDIRQ_WMASK : %lX\n", HARDIRQ_WMASK);
+
+       return 0;
+}
+
+void cleanup_module(void)
+{
+       remove_proc_entry("testfrwlock", NULL);
+}
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Fair rwlock test");
index d2e0de9dc22107e6391cc7399e2461397b3dfca2..55518b258e9cccc229a556b5517316e3f3e6b378 100644 (file)
@@ -108,9 +108,13 @@ static int my_open(struct inode *inode, struct file *file)
        printk("NR_TESTS %d\n", NR_TESTS);
 
        perform_test("empty", empty);
+       printk("value : %ld\n", atomic64_read(&atomicval));
        perform_test("test 1-byte nop xadd", testnop);
+       printk("value : %ld\n", atomic64_read(&atomicval));
        perform_test("test DS override prefix xadd", testprefix);
+       printk("value : %ld\n", atomic64_read(&atomicval));
        perform_test("test LOCK xadd", testlock);
+       printk("value : %ld\n", atomic64_read(&atomicval));
 
        return -EPERM;
 }
This page took 0.026515 seconds and 4 git commands to generate.