From f0a36bb1de4aff951669733fac825e2a8d74ef92 Mon Sep 17 00:00:00 2001 From: compudj Date: Sat, 16 Aug 2008 21:06:03 +0000 Subject: [PATCH] update test fair rwlock git-svn-id: http://ltt.polymtl.ca/svn@3023 04897980-b3bd-0310-b5e0-8ef037075253 --- trunk/tests/kernel/Makefile | 4 +- trunk/tests/kernel/test-fair-rwlock.c | 215 +++++++++++++++++++++++++ trunk/tests/kernel/test-prefix-speed.c | 4 + 3 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 trunk/tests/kernel/test-fair-rwlock.c diff --git a/trunk/tests/kernel/Makefile b/trunk/tests/kernel/Makefile index d7c78963..c4566e45 100644 --- a/trunk/tests/kernel/Makefile +++ b/trunk/tests/kernel/Makefile @@ -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 index 00000000..ec751a10 --- /dev/null +++ b/trunk/tests/kernel/test-fair-rwlock.c @@ -0,0 +1,215 @@ +/* test-fair-rwlock.c + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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"); diff --git a/trunk/tests/kernel/test-prefix-speed.c b/trunk/tests/kernel/test-prefix-speed.c index d2e0de9d..55518b25 100644 --- a/trunk/tests/kernel/test-prefix-speed.c +++ b/trunk/tests/kernel/test-prefix-speed.c @@ -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; } -- 2.34.1