diff options
author | Josh Triplett <josh@freedesktop.org> | 2007-12-10 05:32:17 -0800 |
---|---|---|
committer | Josh Triplett <josh@freedesktop.org> | 2007-12-10 05:32:17 -0800 |
commit | 075e734caa89ddff02df1c65e49258f3ff254058 (patch) | |
tree | 9511918b3a2cd81085f5b741d51360404c038449 | |
parent | 50621841b9d25b22658b715deb2f2a141f6e0168 (diff) | |
download | rcuhashbash-075e734caa89ddff02df1c65e49258f3ff254058.tar.gz |
Support multiple writers
-rw-r--r-- | rcuhashbash.c | 75 |
1 files changed, 52 insertions, 23 deletions
diff --git a/rcuhashbash.c b/rcuhashbash.c index c5b02f3..0ac8b1e 100644 --- a/rcuhashbash.c +++ b/rcuhashbash.c @@ -21,8 +21,9 @@ MODULE_DESCRIPTION("RCU hash algorithm test module."); MODULE_LICENSE("GPL"); static char *reader_type = "rcu"; /* Reader implementation to benchmark */ -static char *writer_type = "single"; /* Writer implementation to benchmark */ +static char *writer_type = "spinlock"; /* Writer implementation to benchmark */ static int readers = -1; /* Number of reader tasks; defaults to online CPUs */ +static int writers = -1; /* Number of writer tasks; defaults to online CPUs */ static unsigned long buckets = 1024; /* Number of hash table buckets */ static unsigned long entries = 4096; /* Number of entries initially added */ @@ -32,6 +33,8 @@ module_param(writer_type, charp, 0444); MODULE_PARM_DESC(writer_type, "Hash table writer implementation"); module_param(readers, int, 0444); MODULE_PARM_DESC(readers, "Number of reader threads"); +module_param(writers, int, 0444); +MODULE_PARM_DESC(writers, "Number of writer threads"); module_param(buckets, ulong, 0444); MODULE_PARM_DESC(buckets, "Number of hash buckets"); module_param(entries, ulong, 0444); @@ -72,7 +75,7 @@ struct rcuhashbash_entry { static struct kmem_cache *entry_cache; static struct task_struct **reader_tasks; -static struct task_struct *writer_task; +static struct task_struct **writer_tasks; struct reader_stats { u64 hits; @@ -86,7 +89,7 @@ struct writer_stats { } ____cacheline_aligned_in_smp; struct reader_stats *reader_stats; -struct writer_stats writer_stats; +struct writer_stats *writer_stats; struct rcu_random_state { unsigned long rrs_state; @@ -444,13 +447,17 @@ static void rcuhashbash_print_stats(void) rs.misses += reader_stats[i].misses; } - ws = writer_stats; + for (i = 0; i < writers; i++) { + ws.moves += writer_stats[i].moves; + ws.dests_in_use += writer_stats[i].dests_in_use; + ws.misses += writer_stats[i].misses; + } - printk(KERN_ALERT "rcuhashbash summary: %d %s readers, %s writer\n" - KERN_ALERT "rcuhashbash summary: %lu buckets, %lu entries\n" - KERN_ALERT "rcuhashbash summary: writer %llu moves %llu dests in use %llu misses\n" - KERN_ALERT "rcuhashbash summary: readers %llu hits %llu misses\n", - readers, reader_type, writer_type, + printk(KERN_ALERT "rcuhashbash summary: readers=%d reader_type=%s writers=%d writer_type=%s\n" + KERN_ALERT "rcuhashbash summary: buckets=%lu entries=%lu\n" + KERN_ALERT "rcuhashbash summary: writers: %llu moves, %llu dests in use, %llu misses\n" + KERN_ALERT "rcuhashbash summary: readers: %llu hits, %llu misses\n", + readers, reader_type, writers, writer_type, buckets, entries, ws.moves, ws.dests_in_use, ws.misses, rs.hits, rs.misses); @@ -461,11 +468,14 @@ static void rcuhashbash_exit(void) unsigned long i; int ret; - if (writer_task) { - ret = kthread_stop(writer_task); - if(ret) - printk(KERN_ALERT "rcuhashbash writer returned error %d\n", ret); - writer_task = NULL; + if (writer_tasks) { + for (i = 0; i < writers; i++) + if (writer_tasks[i]) { + ret = kthread_stop(writer_tasks[i]); + if(ret) + printk(KERN_ALERT "rcuhashbash writer returned error %d\n", ret); + } + kfree(writer_tasks); } if (reader_tasks) { @@ -499,6 +509,7 @@ static void rcuhashbash_exit(void) rcuhashbash_print_stats(); + kfree(writer_stats); kfree(reader_stats); printk(KERN_ALERT "rcuhashbash done\n"); @@ -520,6 +531,16 @@ static __init int rcuhashbash_init(void) return -EINVAL; } + if (readers < 0) + readers = num_online_cpus(); + if (writers < 0) + writers = num_online_cpus(); + if (ops->max_writers && writers > ops->max_writers) { + printk(KERN_ALERT "rcuhashbash: %s writer implementation supports at most %d writers\n", + writer_type, ops->max_writers); + return -EINVAL; + } + entry_cache = KMEM_CACHE(rcuhashbash_entry, 0); if (!entry_cache) goto enomem; @@ -541,9 +562,6 @@ static __init int rcuhashbash_init(void) hlist_add_head(&entry->node, &hash_table[entry->value % buckets].head); } - if (readers < 0) - readers = num_online_cpus(); - reader_stats = kcalloc(readers, sizeof(reader_stats[0]), GFP_KERNEL); if (!reader_stats) goto enomem; @@ -552,6 +570,14 @@ static __init int rcuhashbash_init(void) if (!reader_tasks) goto enomem; + writer_stats = kcalloc(writers, sizeof(writer_stats[0]), GFP_KERNEL); + if (!writer_stats) + goto enomem; + + writer_tasks = kcalloc(writers, sizeof(writer_tasks[0]), GFP_KERNEL); + if (!writer_tasks) + goto enomem; + printk(KERN_ALERT "rcuhashbash starting threads\n"); for (i = 0; i < readers; i++) { @@ -565,12 +591,15 @@ static __init int rcuhashbash_init(void) reader_tasks[i] = task; } - writer_task = kthread_run(rcuhashbash_writer, &writer_stats, - "rcuhashbash_writer"); - if (IS_ERR(writer_task)) { - ret = PTR_ERR(writer_task); - writer_task = NULL; - goto error; + for (i = 0; i < writers; i++) { + struct task_struct *task; + task = kthread_run(rcuhashbash_writer, &writer_stats[i], + "rcuhashbash_writer"); + if (IS_ERR(task)) { + ret = PTR_ERR(task); + goto error; + } + writer_tasks[i] = task; } return 0; |