X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=trunk%2Ftests%2Fkernel%2Ftest-wbias-rwlock.c;h=5c7dde65f797d635b9568833f3f39e1d27eaf25a;hb=292f011035a22f3751aea1bed027158e395510bf;hp=1cbfadb2fbe396ebd77d4dbe7c4db3aff8d52aee;hpb=ae4a4ebf4c6be7a4793b94e04ad84cf13bd8e917;p=lttv.git diff --git a/trunk/tests/kernel/test-wbias-rwlock.c b/trunk/tests/kernel/test-wbias-rwlock.c index 1cbfadb2..5c7dde65 100644 --- a/trunk/tests/kernel/test-wbias-rwlock.c +++ b/trunk/tests/kernel/test-wbias-rwlock.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -14,6 +13,7 @@ #include #include #include +#include /* Test with no contention duration, in seconds */ #define SINGLE_WRITER_TEST_DURATION 10 @@ -26,7 +26,7 @@ #define NR_VARS 100 #define NR_WRITERS 2 #define NR_TRYLOCK_WRITERS 1 -#define NR_READERS 4 +#define NR_NPREADERS 2 #define NR_TRYLOCK_READERS 1 /* @@ -49,6 +49,19 @@ #define NR_TRYLOCK_INTERRUPT_READERS 0 #endif +/* + * 1 : test with thread preemption readers. + * 0 : test only with non-preemptable thread readers. + */ +#define TEST_PREEMPT 1 + +#if (TEST_PREEMPT) +#define NR_PREADERS 2 +#else +#define NR_PREADERS 0 +#endif + + /* * Writer iteration delay, in us. 0 for busy loop. Caution : writers can * starve readers. @@ -67,7 +80,8 @@ #define INTERRUPT_READER_DELAY 100 static int var[NR_VARS]; -static struct task_struct *reader_threads[NR_READERS]; +static struct task_struct *preader_threads[NR_PREADERS]; +static struct task_struct *npreader_threads[NR_NPREADERS]; 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]; @@ -82,6 +96,10 @@ static DEFINE_RWLOCK(std_rw_lock); #define wrap_read_trylock() read_trylock(&std_rw_lock) #define wrap_read_unlock() read_unlock(&std_rw_lock) +#define wrap_read_lock_inatomic() read_lock(&std_rw_lock) +#define wrap_read_trylock_inatomic() read_trylock(&std_rw_lock) +#define wrap_read_unlock_inatomic() read_unlock(&std_rw_lock) + #define wrap_read_lock_irq() read_lock(&std_rw_lock) #define wrap_read_trylock_irq() read_trylock(&std_rw_lock) #define wrap_read_unlock_irq() read_unlock(&std_rw_lock) @@ -102,6 +120,12 @@ static DEFINE_WBIAS_RWLOCK(wbiasrwlock); #define wrap_read_trylock() wbias_read_trylock(&wbiasrwlock) #define wrap_read_unlock() wbias_read_unlock(&wbiasrwlock) +#define wrap_read_lock_inatomic() wbias_read_lock_inatomic(&wbiasrwlock) +#define wrap_read_trylock_inatomic() \ + wbias_read_trylock_inatomic(&wbiasrwlock) +#define wrap_read_unlock_inatomic() \ + wbias_read_unlock_inatomic(&wbiasrwlock) + #define wrap_read_lock_irq() wbias_read_lock_irq(&wbiasrwlock) #define wrap_read_trylock_irq() wbias_read_trylock_irq(&wbiasrwlock) #define wrap_read_unlock_irq() wbias_read_unlock_irq(&wbiasrwlock) @@ -109,9 +133,26 @@ static DEFINE_WBIAS_RWLOCK(wbiasrwlock); #if (TEST_INTERRUPTS) #define wrap_write_lock() wbias_write_lock_irq(&wbiasrwlock) #define wrap_write_unlock() wbias_write_unlock_irq(&wbiasrwlock) +#define wrap_write_trylock_else_subscribe() \ + wbias_write_trylock_irq_else_subscribe(&wbiasrwlock) +#define wrap_write_trylock_subscribed() \ + wbias_write_trylock_irq_subscribed(&wbiasrwlock) #else +#if (TEST_PREEMPT) #define wrap_write_lock() wbias_write_lock(&wbiasrwlock) #define wrap_write_unlock() wbias_write_unlock(&wbiasrwlock) +#define wrap_write_trylock_else_subscribe() \ + wbias_write_trylock_else_subscribe(&wbiasrwlock) +#define wrap_write_trylock_subscribed() \ + wbias_write_trylock_subscribed(&wbiasrwlock) +#else +#define wrap_write_lock() wbias_write_lock_atomic(&wbiasrwlock) +#define wrap_write_unlock() wbias_write_unlock_atomic(&wbiasrwlock) +#define wrap_write_trylock_else_subscribe() \ + wbias_write_trylock_atomic_else_subscribe(&wbiasrwlock) +#define wrap_write_trylock_subscribed() \ + wbias_write_trylock_atomic_subscribed(&wbiasrwlock) +#endif #endif #endif @@ -127,7 +168,8 @@ static inline cycles_t calibrate_cycles(cycles_t cycles) struct proc_dir_entry *pentry = NULL; -static int reader_thread(void *data) +static int p_or_np_reader_thread(const char *typename, + void *data, int preemptable) { int i; int prev, cur; @@ -135,15 +177,19 @@ static int reader_thread(void *data) cycles_t time1, time2, delay, delaymax = 0, delaymin = ULLONG_MAX, delayavg = 0; - printk("reader_thread/%lu runnning\n", (unsigned long)data); + printk("%s/%lu runnning\n", typename, (unsigned long)data); do { iter++; - //preempt_disable(); /* for get_cycles accuracy */ + if (!preemptable) + preempt_disable(); rdtsc_barrier(); time1 = get_cycles(); rdtsc_barrier(); - wrap_read_lock(); + if (!preemptable) + wrap_read_lock_inatomic(); + else + wrap_read_lock(); rdtsc_barrier(); time2 = get_cycles(); @@ -161,19 +207,23 @@ static int reader_thread(void *data) "in thread\n", cur, prev, i, iter); } - wrap_read_unlock(); - - //preempt_enable(); /* for get_cycles accuracy */ + if (!preemptable) + wrap_read_unlock_inatomic(); + else + wrap_read_unlock(); + if (!preemptable) + preempt_enable(); if (THREAD_READER_DELAY) msleep(THREAD_READER_DELAY); } while (!kthread_should_stop()); if (!iter) { - printk("reader_thread/%lu iterations : %lu", + printk("%s/%lu iterations : %lu", typename, (unsigned long)data, iter); } else { delayavg /= iter; - printk("reader_thread/%lu iterations : %lu, " + printk("%s/%lu iterations : %lu, " "lock delay [min,avg,max] %llu,%llu,%llu cycles\n", + typename, (unsigned long)data, iter, calibrate_cycles(delaymin), calibrate_cycles(delayavg), @@ -182,6 +232,16 @@ static int reader_thread(void *data) return 0; } +static int preader_thread(void *data) +{ + return p_or_np_reader_thread("preader_thread", data, 1); +} + +static int npreader_thread(void *data) +{ + return p_or_np_reader_thread("npreader_thread", data, 0); +} + static int trylock_reader_thread(void *data) { int i; @@ -459,31 +519,19 @@ static int trylock_writer_thread(void *data) printk("trylock_writer_thread/%lu runnning\n", (unsigned long)data); do { iter++; -#if (TEST_INTERRUPTS) - if (wbias_write_trylock_irq_else_subscribe(&wbiasrwlock)) -#else - if (wbias_write_trylock_else_subscribe(&wbiasrwlock)) -#endif + if (wrap_write_trylock_else_subscribe()) goto locked; #if (TRYLOCK_WRITERS_FAIL_ITER == -1) for (;;) { iter++; -#if (TEST_INTERRUPTS) - if (wbias_write_trylock_irq_subscribed(&wbiasrwlock)) -#else - if (wbias_write_trylock_subscribed(&wbiasrwlock)) -#endif + if (wrap_write_trylock_subscribed()) goto locked; } #else for (i = 0; i < TRYLOCK_WRITERS_FAIL_ITER - 1; i++) { iter++; -#if (TEST_INTERRUPTS) - if (wbias_write_trylock_irq_subscribed(&wbiasrwlock)) -#else - if (wbias_write_trylock_subscribed(&wbiasrwlock)) -#endif + if (wrap_write_trylock_subscribed()) goto locked; } #endif @@ -496,11 +544,7 @@ locked: for (i = 0; i < NR_VARS; i++) { var[i] = new; } -#if (TEST_INTERRUPTS) - wbias_write_unlock_irq(&wbiasrwlock); -#else - wbias_write_unlock(&wbiasrwlock); -#endif + wrap_write_unlock(); loop: if (TRYLOCK_WRITER_DELAY > 0) udelay(TRYLOCK_WRITER_DELAY); @@ -519,11 +563,18 @@ static void wbias_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, - "wbiasrwlock_reader"); - BUG_ON(!reader_threads[i]); + for (i = 0; i < NR_PREADERS; i++) { + printk("starting preemptable reader thread %lu\n", i); + preader_threads[i] = kthread_run(preader_thread, (void *)i, + "wbiasrwlock_preader"); + BUG_ON(!preader_threads[i]); + } + + for (i = 0; i < NR_NPREADERS; i++) { + printk("starting non-preemptable reader thread %lu\n", i); + npreader_threads[i] = kthread_run(npreader_thread, (void *)i, + "wbiasrwlock_npreader"); + BUG_ON(!npreader_threads[i]); } for (i = 0; i < NR_TRYLOCK_READERS; i++) { @@ -566,8 +617,10 @@ static void wbias_rwlock_stop(void) kthread_stop(writer_threads[i]); for (i = 0; i < NR_TRYLOCK_WRITERS; i++) kthread_stop(trylock_writer_threads[i]); - for (i = 0; i < NR_READERS; i++) - kthread_stop(reader_threads[i]); + for (i = 0; i < NR_NPREADERS; i++) + kthread_stop(npreader_threads[i]); + for (i = 0; i < NR_PREADERS; i++) + kthread_stop(preader_threads[i]); for (i = 0; i < NR_TRYLOCK_READERS; i++) kthread_stop(trylock_reader_threads[i]); for (i = 0; i < NR_INTERRUPT_READERS; i++) @@ -639,28 +692,49 @@ static int my_open(struct inode *inode, struct file *file) wbias_rwlock_profile_latency_print(); - printk("** Single reader test, no contention **\n"); + printk("** Single preemptable reader test, no contention **\n"); wbias_rwlock_profile_latency_reset(); - reader_threads[0] = kthread_run(reader_thread, (void *)0, - "wbiasrwlock_reader"); - BUG_ON(!reader_threads[0]); + preader_threads[0] = kthread_run(preader_thread, (void *)0, + "wbiasrwlock_preader"); + BUG_ON(!preader_threads[0]); ssleep(SINGLE_READER_TEST_DURATION); - kthread_stop(reader_threads[0]); + kthread_stop(preader_threads[0]); printk("\n"); wbias_rwlock_profile_latency_print(); - printk("** Multiple readers test, no contention **\n"); +#if (TEST_PREEMPT) + printk("** Single non-preemptable reader test, no contention **\n"); wbias_rwlock_profile_latency_reset(); - for (i = 0; i < NR_READERS; i++) { - printk("starting reader thread %lu\n", i); - reader_threads[i] = kthread_run(reader_thread, (void *)i, - "wbiasrwlock_reader"); - BUG_ON(!reader_threads[i]); + npreader_threads[0] = kthread_run(npreader_thread, (void *)0, + "wbiasrwlock_npreader"); + BUG_ON(!npreader_threads[0]); + ssleep(SINGLE_READER_TEST_DURATION); + kthread_stop(npreader_threads[0]); + printk("\n"); + + wbias_rwlock_profile_latency_print(); +#endif + + printk("** Multiple p/non-p readers test, no contention **\n"); + wbias_rwlock_profile_latency_reset(); + for (i = 0; i < NR_PREADERS; i++) { + printk("starting preader thread %lu\n", i); + preader_threads[i] = kthread_run(preader_thread, (void *)i, + "wbiasrwlock_preader"); + BUG_ON(!preader_threads[i]); + } + for (i = 0; i < NR_NPREADERS; i++) { + printk("starting npreader thread %lu\n", i); + npreader_threads[i] = kthread_run(npreader_thread, (void *)i, + "wbiasrwlock_npreader"); + BUG_ON(!npreader_threads[i]); } ssleep(SINGLE_READER_TEST_DURATION); - for (i = 0; i < NR_READERS; i++) - kthread_stop(reader_threads[i]); + for (i = 0; i < NR_NPREADERS; i++) + kthread_stop(npreader_threads[i]); + for (i = 0; i < NR_PREADERS; i++) + kthread_stop(preader_threads[i]); printk("\n"); wbias_rwlock_profile_latency_print(); @@ -687,20 +761,21 @@ int init_module(void) if (pentry) pentry->proc_fops = &my_operations; - printk("PTHREAD_ROFFSET : %lX\n", PTHREAD_ROFFSET); - printk("PTHREAD_RMASK : %lX\n", PTHREAD_RMASK); - printk("NPTHREAD_ROFFSET : %lX\n", THREAD_ROFFSET); - printk("NPTHREAD_RMASK : %lX\n", THREAD_RMASK); - printk("SOFTIRQ_ROFFSET : %lX\n", SOFTIRQ_ROFFSET); - printk("SOFTIRQ_RMASK : %lX\n", SOFTIRQ_RMASK); - printk("HARDIRQ_ROFFSET : %lX\n", HARDIRQ_ROFFSET); - printk("HARDIRQ_RMASK : %lX\n", HARDIRQ_RMASK); - printk("SUBSCRIBERS_WOFFSET : %lX\n", SUBSCRIBERS_WOFFSET); - printk("SUBSCRIBERS_WMASK : %lX\n", SUBSCRIBERS_WMASK); - printk("WRITER_MUTEX : %lX\n", WRITER_MUTEX); - printk("NPTHREAD_WMASK : %lX\n", SOFTIRQ_WMASK); - printk("SOFTIRQ_WMASK : %lX\n", SOFTIRQ_WMASK); - printk("HARDIRQ_WMASK : %lX\n", HARDIRQ_WMASK); + printk("PTHREAD_ROFFSET : %016lX\n", PTHREAD_ROFFSET); + printk("PTHREAD_RMASK : %016lX\n", PTHREAD_RMASK); + printk("NPTHREAD_ROFFSET : %016lX\n", NPTHREAD_ROFFSET); + printk("NPTHREAD_RMASK : %016lX\n", NPTHREAD_RMASK); + printk("SOFTIRQ_ROFFSET : %016lX\n", SOFTIRQ_ROFFSET); + printk("SOFTIRQ_RMASK : %016lX\n", SOFTIRQ_RMASK); + printk("HARDIRQ_ROFFSET : %016lX\n", HARDIRQ_ROFFSET); + printk("HARDIRQ_RMASK : %016lX\n", HARDIRQ_RMASK); + printk("PTHREAD_WOFFSET : %016lX\n", PTHREAD_WOFFSET); + printk("PTHREAD_WMASK : %016lX\n", PTHREAD_WMASK); + printk("NPTHREAD_WOFFSET : %016lX\n", NPTHREAD_WOFFSET); + printk("NPTHREAD_WMASK : %016lX\n", NPTHREAD_WMASK); + printk("WRITER_MUTEX : %016lX\n", WRITER_MUTEX); + printk("SOFTIRQ_WMASK : %016lX\n", SOFTIRQ_WMASK); + printk("HARDIRQ_WMASK : %016lX\n", HARDIRQ_WMASK); return 0; }