summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Triplett <josh@joshtriplett.org>2011-01-06 23:20:35 -0800
committerJosh Triplett <josh@joshtriplett.org>2011-01-06 23:20:35 -0800
commitc0208be53ab9565f1694587c25db51afa6a1956d (patch)
tree77196ee4926d67561091a4837c9f6dfef52d2685
parent4cffb831f30c82c15d6a0c7427989ca7a1dcee0c (diff)
downloadrcuhashbash-master.tar.gz
Add rwlock-based hash-table resizeHEADmaster
-rw-r--r--rcuhashbash-resize.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/rcuhashbash-resize.c b/rcuhashbash-resize.c
index de6663b..95d785e 100644
--- a/rcuhashbash-resize.c
+++ b/rcuhashbash-resize.c
@@ -63,6 +63,7 @@ static struct rcuhashbash_table *table;
static struct rcuhashbash_table *table2;
static seqcount_t seqcount;
+static DEFINE_RWLOCK(rwlock);
struct rcuhashbash_entry {
struct hlist_node node;
@@ -312,6 +313,47 @@ static int rcuhashbash_resize_ddds(u8 new_buckets_shift, struct stats *stats)
return 0;
}
+static int rcuhashbash_read_rwlock(u32 value, struct stats *stats)
+{
+ read_lock(&rwlock);
+ if (rcuhashbash_try_lookup(table, value))
+ stats->read_hits++;
+ else
+ stats->read_misses++;
+ read_unlock(&rwlock);
+
+ return 0;
+}
+
+static int rcuhashbash_resize_rwlock(u8 new_buckets_shift, struct stats *stats)
+{
+ struct rcuhashbash_table *new;
+ unsigned long i;
+
+ new = kzalloc(sizeof(*table) + (1UL << new_buckets_shift) * sizeof(table->buckets[0]), GFP_KERNEL);
+ if (!new)
+ return -ENOMEM;
+ new->mask = (1UL << new_buckets_shift) - 1;
+
+ write_lock(&rwlock);
+ for (i = 0; i <= table->mask; i++) {
+ struct hlist_head *head = &table->buckets[i];
+
+ while (!hlist_empty(head)) {
+ struct rcuhashbash_entry *entry = hlist_entry(head->first, struct rcuhashbash_entry, node);
+ hlist_del_rcu(&entry->node);
+ hlist_add_head_rcu(&entry->node, &new->buckets[entry->value & new->mask]);
+ }
+ }
+ kfree(table);
+ table = new;
+ write_unlock(&rwlock);
+
+ stats->resizes++;
+
+ return 0;
+}
+
static int rcuhashbash_read_thread(void *arg)
{
int err;
@@ -364,6 +406,11 @@ static struct rcuhashbash_ops all_ops[] = {
.read = rcuhashbash_read_ddds,
.resize = rcuhashbash_resize_ddds,
},
+ {
+ .test = "rwlock",
+ .read = rcuhashbash_read_rwlock,
+ .resize = rcuhashbash_resize_rwlock,
+ },
};
static struct rcuhashbash_ops *ops;