Module: xenomai-3
Branch: master
Commit: 1fe66f3a2bc0b74767d7b13110b6426c31018c06
URL:    
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=1fe66f3a2bc0b74767d7b13110b6426c31018c06

Author: Philippe Gerum <r...@xenomai.org>
Date:   Fri Mar  6 17:47:16 2015 +0100

boilerplate/hash: no dependency on address space in shared h-table

---

 include/boilerplate/hash.h        |  122 +++++++++++++++-----------
 lib/boilerplate/hash.c            |  169 ++++++++++++++++++++++++-------------
 lib/copperplate/cluster.c         |   49 ++++++++---
 lib/copperplate/heapobj-pshared.c |    2 +-
 lib/copperplate/registry.c        |   44 ++++++----
 5 files changed, 252 insertions(+), 134 deletions(-)

diff --git a/include/boilerplate/hash.h b/include/boilerplate/hash.h
index fca9c49..081aefe 100644
--- a/include/boilerplate/hash.h
+++ b/include/boilerplate/hash.h
@@ -25,7 +25,10 @@
 #define HASHSLOTS  (1<<8)
 
 struct hashobj {
-       const void *key;
+       dref_type(const void *) key;
+#ifdef CONFIG_XENO_PSHARED
+       char static_key[16];
+#endif
        size_t len;
        struct holder link;
 };
@@ -36,13 +39,27 @@ struct hash_bucket {
 
 struct hash_table {
        struct hash_bucket table[HASHSLOTS];
-       int (*compare)(const struct hashobj *l,
-                      const struct hashobj *r);
        pthread_mutex_t lock;
 };
 
+struct hash_operations {
+       int (*compare)(const void *l,
+                      const void *r,
+                      size_t len);
+#ifdef CONFIG_XENO_PSHARED
+       int (*probe)(struct hashobj *oldobj);
+       void *(*alloc)(size_t len);
+       void (*free)(void *key);
+#endif
+};
+
+typedef int (*hash_walk_op)(struct hash_table *t,
+                           struct hashobj *obj);
+       
 #ifdef CONFIG_XENO_PSHARED
-/* Private version - not shareable between processes. */
+
+/* Private version - h-table is not shareable between processes. */
+
 struct pvhashobj {
        const void *key;
        size_t len;
@@ -55,14 +72,23 @@ struct pvhash_bucket {
 
 struct pvhash_table {
        struct pvhash_bucket table[HASHSLOTS];
-       int (*compare)(const struct pvhashobj *l,
-                      const struct pvhashobj *r);
        pthread_mutex_t lock;
 };
+
+struct pvhash_operations {
+       int (*compare)(const void *l,
+                      const void *r,
+                      size_t len);
+};
+
+typedef int (*pvhash_walk_op)(struct pvhash_table *t,
+                             struct pvhashobj *obj);
+       
 #else /* !CONFIG_XENO_PSHARED */
-#define pvhashobj      hashobj
-#define pvhash_bucket  hash_bucket
-#define pvhash_table   hash_table
+#define pvhashobj              hashobj
+#define pvhash_bucket          hash_bucket
+#define pvhash_table           hash_table
+#define pvhash_walk_op         hash_walk_op
 #endif /* !CONFIG_XENO_PSHARED */
 
 #ifdef __cplusplus
@@ -72,112 +98,112 @@ extern "C" {
 unsigned int __hash_key(const void *key,
                        size_t length, unsigned int c);
 
-void __hash_init(void *heap, struct hash_table *t,
-                int (*compare)(const struct hashobj *l,
-                               const struct hashobj *r));
+void __hash_init(void *heap, struct hash_table *t);
 
 int __hash_enter(struct hash_table *t,
                 const void *key, size_t len,
-                struct hashobj *newobj, int nodup);
+                struct hashobj *newobj,
+                const struct hash_operations *hops,
+                int nodup);
 
-static inline void hash_init(struct hash_table *t,
-                            int (*compare)(const struct hashobj *l,
-                                           const struct hashobj *r))
+static inline void hash_init(struct hash_table *t)
 {
-       __hash_init(__main_heap, t, compare);
+       __hash_init(__main_heap, t);
 }
 
 void hash_destroy(struct hash_table *t);
 
 static inline int hash_enter(struct hash_table *t,
                             const void *key, size_t len,
-                            struct hashobj *newobj)
+                            struct hashobj *newobj,
+                            const struct hash_operations *hops)
 {
-       return __hash_enter(t, key, len, newobj, 1);
+       return __hash_enter(t, key, len, newobj, hops, 1);
 }
 
 static inline int hash_enter_dup(struct hash_table *t,
                                 const void *key, size_t len,
-                                struct hashobj *newobj)
+                                struct hashobj *newobj,
+                                const struct hash_operations *hops)
 {
-       return __hash_enter(t, key, len, newobj, 0);
+       return __hash_enter(t, key, len, newobj, hops, 0);
 }
 
-int hash_remove(struct hash_table *t, struct hashobj *delobj);
+int hash_remove(struct hash_table *t, struct hashobj *delobj,
+               const struct hash_operations *hops);
 
 struct hashobj *hash_search(struct hash_table *t,
-                           const void *key, size_t len);
+                           const void *key, size_t len,
+                           const struct hash_operations *hops);
 
 int hash_walk(struct hash_table *t,
-               int (*walk)(struct hash_table *t, struct hashobj *obj));
-
-int hash_compare_strings(const struct hashobj *l,
-                        const struct hashobj *r);
+             hash_walk_op walk);
 
 #ifdef CONFIG_XENO_PSHARED
 
 int __hash_enter_probe(struct hash_table *t,
                       const void *key, size_t len,
                       struct hashobj *newobj,
-                      int (*probefn)(struct hashobj *oldobj),
+                      const struct hash_operations *hops,
                       int nodup);
 
 int __pvhash_enter(struct pvhash_table *t,
                   const void *key, size_t len,
-                  struct pvhashobj *newobj, int nodup);
+                  struct pvhashobj *newobj,
+                  const struct pvhash_operations *hops,
+                  int nodup);
 
 static inline
 int hash_enter_probe(struct hash_table *t,
                     const void *key, size_t len,
                     struct hashobj *newobj,
-                    int (*probefn)(struct hashobj *oldobj))
+                    const struct hash_operations *hops)
 {
-       return __hash_enter_probe(t, key, len, newobj, probefn, 1);
+       return __hash_enter_probe(t, key, len, newobj, hops, 1);
 }
 
 static inline
 int hash_enter_probe_dup(struct hash_table *t,
                         const void *key, size_t len,
                         struct hashobj *newobj,
-                        int (*probefn)(struct hashobj *oldobj))
+                        const struct hash_operations *hops)
 {
-       return __hash_enter_probe(t, key, len, newobj, probefn, 0);
+       return __hash_enter_probe(t, key, len, newobj, hops, 0);
 }
 
 struct hashobj *hash_search_probe(struct hash_table *t,
                                  const void *key, size_t len,
-                                 int (*probefn)(struct hashobj *obj));
+                                 const struct hash_operations *hops);
 
-void pvhash_init(struct pvhash_table *t,
-                int (*compare)(const struct pvhashobj *l,
-                               const struct pvhashobj *r));
+void pvhash_init(struct pvhash_table *t);
 
 static inline
 int pvhash_enter(struct pvhash_table *t,
                 const void *key, size_t len,
-                struct pvhashobj *newobj)
+                struct pvhashobj *newobj,
+                const struct pvhash_operations *hops)
 {
-       return __pvhash_enter(t, key, len, newobj, 1);
+       return __pvhash_enter(t, key, len, newobj, hops, 1);
 }
 
 static inline
 int pvhash_enter_dup(struct pvhash_table *t,
                     const void *key, size_t len,
-                    struct pvhashobj *newobj)
+                    struct pvhashobj *newobj,
+                    const struct pvhash_operations *hops)
 {
-       return __pvhash_enter(t, key, len, newobj, 0);
+       return __pvhash_enter(t, key, len, newobj, hops, 0);
 }
 
-int pvhash_remove(struct pvhash_table *t, struct pvhashobj *delobj);
+int pvhash_remove(struct pvhash_table *t, struct pvhashobj *delobj,
+                 const struct pvhash_operations *hops);
 
 struct pvhashobj *pvhash_search(struct pvhash_table *t,
-                               const void *key, size_t len);
+                               const void *key, size_t len,
+                               const struct pvhash_operations *hops);
 
 int pvhash_walk(struct pvhash_table *t,
-               int (*walk)(struct pvhash_table *t, struct pvhashobj *obj));
-
-int pvhash_compare_strings(const struct pvhashobj *l,
-                          const struct pvhashobj *r);
+               pvhash_walk_op walk);
 
 #else /* !CONFIG_XENO_PSHARED */
 #define pvhash_init            hash_init
@@ -186,7 +212,7 @@ int pvhash_compare_strings(const struct pvhashobj *l,
 #define pvhash_remove          hash_remove
 #define pvhash_search          hash_search
 #define pvhash_walk            hash_walk
-#define pvhash_compare_strings hash_compare_strings
+#define pvhash_operations      hash_operations
 #endif /* !CONFIG_XENO_PSHARED */
 
 #ifdef __cplusplus
diff --git a/lib/boilerplate/hash.c b/lib/boilerplate/hash.c
index d7a11bd..c7f5a50 100644
--- a/lib/boilerplate/hash.c
+++ b/lib/boilerplate/hash.c
@@ -16,11 +16,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
  */
 
-/*
- * We need hash table management with a removal op, so we can't rely
- * on <search.h>.
- */
-
 #include <string.h>
 #include <errno.h>
 #include "boilerplate/lock.h"
@@ -49,6 +44,17 @@
        c -= a; c -= b; c ^= (b>>15);           \
 }
 
+#define __moff(__p)    __memoff(__main_heap, __p)
+#define __mptr(__p)    __memptr(__main_heap, __p)
+#define __mchk(__p)    __memchk(__main_heap, __p)
+
+static inline int store_key(struct hashobj *obj,
+                           const void *key, size_t len,
+                           const struct hash_operations *hops);
+
+static inline void drop_key(struct hashobj *obj,
+                           const struct hash_operations *hops);
+
 #define GOLDEN_HASH_RATIO  0x9e3779b9  /* Arbitrary value. */
 
 unsigned int __hash_key(const void *key, size_t length, unsigned int c)
@@ -89,9 +95,7 @@ unsigned int __hash_key(const void *key, size_t length, 
unsigned int c)
        return c;
 }
 
-void __hash_init(void *heap, struct hash_table *t,
-                int (*compare)(const struct hashobj *l,
-                               const struct hashobj *r))
+void __hash_init(void *heap, struct hash_table *t)
 {
        pthread_mutexattr_t mattr;
        int n;
@@ -99,7 +103,6 @@ void __hash_init(void *heap, struct hash_table *t,
        for (n = 0; n < HASHSLOTS; n++)
                __list_init(heap, &t->table[n].obj_list);
 
-       t->compare = compare;
        pthread_mutexattr_init(&mattr);
        pthread_mutexattr_settype(&mattr, mutex_type_attribute);
        pthread_mutexattr_setpshared(&mattr, mutex_scope_attribute);
@@ -122,22 +125,28 @@ static struct hash_bucket *do_hash(struct hash_table *t,
 int __hash_enter(struct hash_table *t,
                 const void *key, size_t len,
                 struct hashobj *newobj,
+                const struct hash_operations *hops,
                 int nodup)
 {
        struct hash_bucket *bucket;
        struct hashobj *obj;
-       int ret = 0;
+       int ret;
 
        holder_init(&newobj->link);
-       newobj->key = key;
-       newobj->len = len;
-       bucket = do_hash(t, key, len);
+       ret = store_key(newobj, key, len, hops);
+       if (ret)
+               return ret;
 
+       bucket = do_hash(t, key, len);
        write_lock_nocancel(&t->lock);
 
        if (nodup && !list_empty(&bucket->obj_list)) {
                list_for_each_entry(obj, &bucket->obj_list, link) {
-                       if (t->compare(obj, newobj) == 0) {
+                       if (obj->len != newobj->len)
+                               continue;
+                       if (hops->compare(__mptr(obj->key), __mptr(newobj->key),
+                                         obj->len) == 0) {
+                               drop_key(newobj, hops);
                                ret = -EEXIST;
                                goto out;
                        }
@@ -151,13 +160,14 @@ out:
        return ret;
 }
 
-int hash_remove(struct hash_table *t, struct hashobj *delobj)
+int hash_remove(struct hash_table *t, struct hashobj *delobj,
+               const struct hash_operations *hops)
 {
        struct hash_bucket *bucket;
        struct hashobj *obj;
        int ret = -ESRCH;
 
-       bucket = do_hash(t, delobj->key, delobj->len);
+       bucket = do_hash(t, __mptr(delobj->key), delobj->len);
 
        write_lock_nocancel(&t->lock);
 
@@ -165,6 +175,7 @@ int hash_remove(struct hash_table *t, struct hashobj 
*delobj)
                list_for_each_entry(obj, &bucket->obj_list, link) {
                        if (obj == delobj) {
                                list_remove_init(&obj->link);
+                               drop_key(obj, hops);
                                ret = 0;
                                goto out;
                        }
@@ -177,20 +188,20 @@ out:
 }
 
 struct hashobj *hash_search(struct hash_table *t, const void *key,
-                           size_t len)
+                           size_t len, const struct hash_operations *hops)
 {
        struct hash_bucket *bucket;
-       struct hashobj *obj, _obj;
+       struct hashobj *obj;
 
        bucket = do_hash(t, key, len);
 
        read_lock_nocancel(&t->lock);
 
        if (!list_empty(&bucket->obj_list)) {
-               _obj.key = key;
-               _obj.len = len;
                list_for_each_entry(obj, &bucket->obj_list, link) {
-                       if (t->compare(obj, &_obj) == 0)
+                       if (obj->len != len)
+                               continue;
+                       if (hops->compare(__mptr(obj->key), key, len) == 0)
                                goto out;
                }
        }
@@ -201,8 +212,7 @@ out:
        return obj;
 }
 
-int hash_walk(struct hash_table *t,
-             int (*walk)(struct hash_table *t, struct hashobj *obj))
+int hash_walk(struct hash_table *t, hash_walk_op walk)
 {
        struct hash_bucket *bucket;
        struct hashobj *obj, *tmp;
@@ -228,43 +238,73 @@ int hash_walk(struct hash_table *t,
        return 0;
 }
 
-int hash_compare_strings(const struct hashobj *l,
-                        const struct hashobj *r)
+#ifdef CONFIG_XENO_PSHARED
+
+static inline int store_key(struct hashobj *obj,
+                           const void *key, size_t len,
+                           const struct hash_operations *hops)
 {
-       return strcmp(l->key, r->key);
+       void *p;
+       
+       assert(__mchk(obj));
+
+       if (len > sizeof(obj->static_key)) {
+               p = hops->alloc(len);
+               if (p == NULL)
+                       return -ENOMEM;
+               assert(__mchk(p));
+       } else
+               p = obj->static_key;
+
+       memcpy(p, key, len);
+       obj->key = __moff(p);
+       obj->len = len;
+
+       return 0;
 }
 
-#ifdef CONFIG_XENO_PSHARED
+static inline void drop_key(struct hashobj *obj,
+                           const struct hash_operations *hops)
+{
+       if (obj->key != __moff(obj->static_key))
+               hops->free((void *)__mptr(obj->key));
+}
 
 int __hash_enter_probe(struct hash_table *t,
                       const void *key, size_t len,
                       struct hashobj *newobj,
-                      int (*probefn)(struct hashobj *oldobj),
+                      const struct hash_operations *hops,
                       int nodup)
 {
        struct hash_bucket *bucket;
        struct hashobj *obj, *tmp;
-       int ret = 0;
+       int ret;
 
        holder_init(&newobj->link);
-       newobj->key = key;
-       newobj->len = len;
-       bucket = do_hash(t, key, len);
+       ret = store_key(newobj, key, len, hops);
+       if (ret)
+               return ret;
 
+       bucket = do_hash(t, key, len);
        push_cleanup_lock(&t->lock);
        write_lock(&t->lock);
 
        if (!list_empty(&bucket->obj_list)) {
                list_for_each_entry_safe(obj, tmp, &bucket->obj_list, link) {
-                       if (t->compare(obj, newobj) == 0) {
-                               if (probefn(obj)) {
+                       if (obj->len != newobj->len)
+                               continue;
+                       if (hops->compare(__mptr(obj->key),
+                                         __mptr(newobj->key), obj->len) == 0) {
+                               if (hops->probe(obj)) {
                                        if (nodup) {
+                                               drop_key(newobj, hops);
                                                ret = -EEXIST;
                                                goto out;
                                        }
                                        continue;
                                }
                                list_remove_init(&obj->link);
+                               drop_key(obj, hops);
                        }
                }
        }
@@ -279,10 +319,10 @@ out:
 
 struct hashobj *hash_search_probe(struct hash_table *t,
                                  const void *key, size_t len,
-                                 int (*probefn)(struct hashobj *obj))
+                                 const struct hash_operations *hops)
 {
-       struct hashobj *obj, *tmp, _obj;
        struct hash_bucket *bucket;
+       struct hashobj *obj, *tmp;
 
        bucket = do_hash(t, key, len);
 
@@ -290,12 +330,13 @@ struct hashobj *hash_search_probe(struct hash_table *t,
        write_lock(&t->lock);
 
        if (!list_empty(&bucket->obj_list)) {
-               _obj.key = key;
-               _obj.len = len;
                list_for_each_entry_safe(obj, tmp, &bucket->obj_list, link) {
-                       if (t->compare(obj, &_obj) == 0) {
-                               if (!probefn(obj)) {
+                       if (obj->len != len)
+                               continue;
+                       if (hops->compare(__mptr(obj->key), key, len) == 0) {
+                               if (!hops->probe(obj)) {
                                        list_remove_init(&obj->link);
+                                       drop_key(obj, hops);
                                        continue;
                                }
                                goto out;
@@ -310,9 +351,7 @@ out:
        return obj;
 }
 
-void pvhash_init(struct pvhash_table *t,
-                int (*compare)(const struct pvhashobj *l,
-                               const struct pvhashobj *r))
+void pvhash_init(struct pvhash_table *t)
 {
        pthread_mutexattr_t mattr;
        int n;
@@ -320,7 +359,6 @@ void pvhash_init(struct pvhash_table *t,
        for (n = 0; n < HASHSLOTS; n++)
                pvlist_init(&t->table[n].obj_list);
 
-       t->compare = compare;
        pthread_mutexattr_init(&mattr);
        pthread_mutexattr_settype(&mattr, mutex_type_attribute);
        pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT);
@@ -338,7 +376,9 @@ static struct pvhash_bucket *do_pvhash(struct pvhash_table 
*t,
 
 int __pvhash_enter(struct pvhash_table *t,
                   const void *key, size_t len,
-                  struct pvhashobj *newobj, int nodup)
+                  struct pvhashobj *newobj,
+                  const struct pvhash_operations *hops,
+                  int nodup)
 {
        struct pvhash_bucket *bucket;
        struct pvhashobj *obj;
@@ -353,7 +393,9 @@ int __pvhash_enter(struct pvhash_table *t,
 
        if (nodup && !pvlist_empty(&bucket->obj_list)) {
                pvlist_for_each_entry(obj, &bucket->obj_list, link) {
-                       if (t->compare(obj, newobj) == 0) {
+                       if (obj->len != newobj->len)
+                               continue;
+                       if (hops->compare(obj->key, newobj->key, len) == 0) {
                                ret = -EEXIST;
                                goto out;
                        }
@@ -367,7 +409,8 @@ out:
        return ret;
 }
 
-int pvhash_remove(struct pvhash_table *t, struct pvhashobj *delobj)
+int pvhash_remove(struct pvhash_table *t, struct pvhashobj *delobj,
+                 const struct pvhash_operations *hops)
 {
        struct pvhash_bucket *bucket;
        struct pvhashobj *obj;
@@ -393,20 +436,21 @@ out:
 }
 
 struct pvhashobj *pvhash_search(struct pvhash_table *t,
-                               const void *key, size_t len)
+                               const void *key, size_t len,
+                               const struct pvhash_operations *hops)
 {
        struct pvhash_bucket *bucket;
-       struct pvhashobj *obj, _obj;
+       struct pvhashobj *obj;
 
        bucket = do_pvhash(t, key, len);
 
        read_lock_nocancel(&t->lock);
 
        if (!pvlist_empty(&bucket->obj_list)) {
-               _obj.key = key;
-               _obj.len = len;
                pvlist_for_each_entry(obj, &bucket->obj_list, link) {
-                       if (t->compare(obj, &_obj) == 0)
+                       if (obj->len != len)
+                               continue;
+                       if (hops->compare(obj->key, key, len) == 0)
                                goto out;
                }
        }
@@ -417,8 +461,7 @@ out:
        return obj;
 }
 
-int pvhash_walk(struct pvhash_table *t,
-               int (*walk)(struct pvhash_table *t, struct pvhashobj *obj))
+int pvhash_walk(struct pvhash_table *t,        pvhash_walk_op walk)
 {
        struct pvhash_bucket *bucket;
        struct pvhashobj *obj, *tmp;
@@ -444,10 +487,20 @@ int pvhash_walk(struct pvhash_table *t,
        return 0;
 }
 
-int pvhash_compare_strings(const struct pvhashobj *l,
-                          const struct pvhashobj *r)
+#else /* !CONFIG_XENO_PSHARED */
+
+static inline int store_key(struct hashobj *obj,
+                           const void *key, size_t len,
+                           const struct hash_operations *hops)
 {
-       return strcmp(l->key, r->key);
+       obj->key = key;
+       obj->len = len;
+
+       return 0;
 }
 
-#endif /* CONFIG_XENO_PSHARED */
+static inline void drop_key(struct hashobj *obj,
+                           const struct hash_operations *hops)
+{ }
+
+#endif /* !CONFIG_XENO_PSHARED */
diff --git a/lib/copperplate/cluster.c b/lib/copperplate/cluster.c
index c6bec97..28e24c8 100644
--- a/lib/copperplate/cluster.c
+++ b/lib/copperplate/cluster.c
@@ -90,6 +90,7 @@
 
 #include <errno.h>
 #include <string.h>
+#include <memory.h>
 #include "copperplate/heapobj.h"
 #include "copperplate/cluster.h"
 #include "copperplate/syncobj.h"
@@ -97,6 +98,8 @@
 #include "copperplate/debug.h"
 #include "internal.h"
 
+const static struct hash_operations hash_operations;
+
 #ifdef CONFIG_XENO_PSHARED
 
 int cluster_init(struct cluster *c, const char *name)
@@ -115,7 +118,8 @@ int cluster_init(struct cluster *c, const char *name)
         * clusters.
         */
 redo:
-       hobj = hash_search(&main_catalog, name, strlen(name));
+       hobj = hash_search(&main_catalog, name, strlen(name),
+                          &hash_operations);
        if (hobj) {
                d = container_of(hobj, struct dictionary, hobj);
                goto out;
@@ -127,8 +131,9 @@ redo:
                goto out;
        }
 
-       hash_init(&d->table, hash_compare_strings);
-       ret = hash_enter(&main_catalog, name, strlen(name), &d->hobj);
+       hash_init(&d->table);
+       ret = hash_enter(&main_catalog, name, strlen(name), &d->hobj,
+                        &hash_operations);
        if (ret == -EEXIST) {
                /*
                 * Someone seems to have slipped in, creating the
@@ -171,7 +176,7 @@ int cluster_addobj(struct cluster *c, const char *name,
         * fly.
         */
        return hash_enter_probe(&c->d->table, name, strlen(name),
-                               &cobj->hobj, cluster_probe);
+                               &cobj->hobj, &hash_operations);
 }
 
 int cluster_addobj_dup(struct cluster *c, const char *name,
@@ -183,12 +188,12 @@ int cluster_addobj_dup(struct cluster *c, const char 
*name,
         * live objects.
         */
        return hash_enter_probe_dup(&c->d->table, name, strlen(name),
-                                   &cobj->hobj, cluster_probe);
+                                   &cobj->hobj, &hash_operations);
 }
 
 int cluster_delobj(struct cluster *c, struct clusterobj *cobj)
 {
-       return __bt(hash_remove(&c->d->table, &cobj->hobj));
+       return __bt(hash_remove(&c->d->table, &cobj->hobj, &hash_operations));
 }
 
 struct clusterobj *cluster_findobj(struct cluster *c, const char *name)
@@ -200,7 +205,7 @@ struct clusterobj *cluster_findobj(struct cluster *c, const 
char *name)
         * discarding dead instances on the fly.
         */
        hobj = hash_search_probe(&c->d->table, name, strlen(name),
-                                cluster_probe);
+                                &hash_operations);
        if (hobj == NULL)
                return NULL;
 
@@ -319,11 +324,28 @@ out:
        return ret;
 }
 
+const static struct hash_operations hash_operations = {
+       .compare = memcmp,
+       .probe = cluster_probe,
+       .alloc = xnmalloc,
+       .free = xnfree,
+};
+
+const static struct pvhash_operations pvhash_operations = {
+       .compare = memcmp,
+};
+
+#else /* !CONFIG_XENO_PSHARED */
+
+const static struct hash_operations hash_operations = {
+       .compare = memcmp,
+};
+
 #endif /* !CONFIG_XENO_PSHARED */
 
 int pvcluster_init(struct pvcluster *c, const char *name)
 {
-       pvhash_init(&c->table, pvhash_compare_strings);
+       pvhash_init(&c->table);
        return 0;
 }
 
@@ -335,25 +357,28 @@ void pvcluster_destroy(struct pvcluster *c)
 int pvcluster_addobj(struct pvcluster *c, const char *name,
                     struct pvclusterobj *cobj)
 {
-       return pvhash_enter(&c->table, name, strlen(name), &cobj->hobj);
+       return pvhash_enter(&c->table, name, strlen(name), &cobj->hobj,
+                           &pvhash_operations);
 }
 
 int pvcluster_addobj_dup(struct pvcluster *c, const char *name,
                         struct pvclusterobj *cobj)
 {
-       return pvhash_enter_dup(&c->table, name, strlen(name), &cobj->hobj);
+       return pvhash_enter_dup(&c->table, name, strlen(name), &cobj->hobj,
+                               &pvhash_operations);
 }
 
 int pvcluster_delobj(struct pvcluster *c, struct pvclusterobj *cobj)
 {
-       return __bt(pvhash_remove(&c->table, &cobj->hobj));
+       return __bt(pvhash_remove(&c->table, &cobj->hobj, &pvhash_operations));
 }
 
 struct pvclusterobj *pvcluster_findobj(struct pvcluster *c, const char *name)
 {
        struct pvhashobj *hobj;
 
-       hobj = pvhash_search(&c->table, name, strlen(name));
+       hobj = pvhash_search(&c->table, name, strlen(name),
+                            &pvhash_operations);
        if (hobj == NULL)
                return NULL;
 
diff --git a/lib/copperplate/heapobj-pshared.c 
b/lib/copperplate/heapobj-pshared.c
index 9e50047..29a1a29 100644
--- a/lib/copperplate/heapobj-pshared.c
+++ b/lib/copperplate/heapobj-pshared.c
@@ -211,7 +211,7 @@ static int init_main_heap(struct session_heap *m_heap, void 
*mem, size_t size)
        if (ret)
                return ret;
 
-       __hash_init(m_heap, &m_heap->catalog, hash_compare_strings);
+       __hash_init(m_heap, &m_heap->catalog);
        m_heap->sysgroup.thread_count = 0;
        __list_init(m_heap, &m_heap->sysgroup.thread_list);
        m_heap->sysgroup.heap_count = 0;
diff --git a/lib/copperplate/registry.c b/lib/copperplate/registry.c
index 6d038f3..3053d0d 100644
--- a/lib/copperplate/registry.c
+++ b/lib/copperplate/registry.c
@@ -87,6 +87,10 @@ struct regfs_dir {
        struct pvholder link;
 };
 
+const static struct pvhash_operations pvhash_operations = {
+       .compare = memcmp,
+};
+
 int registry_add_dir(const char *fmt, ...)
 {
        struct regfs_data *p = regfs_get_context();
@@ -125,7 +129,8 @@ int registry_add_dir(const char *fmt, ...)
                if (path == basename)
                        basename++;
                *basename = '\0';
-               hobj = pvhash_search(&p->dirs, path, strlen(path));
+               hobj = pvhash_search(&p->dirs, path, strlen(path),
+                                    &pvhash_operations);
                if (hobj == NULL) {
                        ret = -ENOENT;
                        goto fail;
@@ -140,7 +145,8 @@ int registry_add_dir(const char *fmt, ...)
        pvlist_init(&d->dir_list);
        d->ndirs = d->nfiles = 0;
        d->ctime = now;
-       ret = pvhash_enter(&p->dirs, d->path, strlen(d->path), &d->hobj);
+       ret = pvhash_enter(&p->dirs, d->path, strlen(d->path), &d->hobj,
+                          &pvhash_operations);
        if (ret) {
        fail:
                pvfree(d->path);
@@ -206,17 +212,18 @@ int registry_add_file(struct fsobj *fsobj, int mode, 
const char *fmt, ...)
        write_lock_safe(&p->lock, state);
 
        ret = pvhash_enter(&p->files, fsobj->path, strlen(fsobj->path),
-                          &fsobj->hobj);
+                          &fsobj->hobj, &pvhash_operations);
        if (ret)
                goto fail;
 
        *basename = '\0';
        dir = basename == path ? "/" : path;
-       hobj = pvhash_search(&p->dirs, dir, strlen(dir));
+       hobj = pvhash_search(&p->dirs, dir, strlen(dir),
+                            &pvhash_operations);
        if (hobj == NULL) {
                ret = -ENOENT;
        fail:
-               pvhash_remove(&p->files, &fsobj->hobj);
+               pvhash_remove(&p->files, &fsobj->hobj, &pvhash_operations);
                pvfree(fsobj->path);
                fsobj->path = NULL;
                goto done;
@@ -246,7 +253,7 @@ void registry_destroy_file(struct fsobj *fsobj)
        if (fsobj->path == NULL)
                goto out;       /* Not registered. */
 
-       pvhash_remove(&p->files, &fsobj->hobj);
+       pvhash_remove(&p->files, &fsobj->hobj, &pvhash_operations);
        /*
         * We are covered by a previous call to write_lock_safe(), so
         * we may nest pthread_mutex_lock() directly.
@@ -283,7 +290,8 @@ static int regfs_getattr(const char *path, struct stat 
*sbuf)
 
        read_lock_nocancel(&p->lock);
 
-       hobj = pvhash_search(&p->dirs, path, strlen(path));
+       hobj = pvhash_search(&p->dirs, path, strlen(path),
+                            &pvhash_operations);
        if (hobj) {
                d = container_of(hobj, struct regfs_dir, hobj);
                sbuf->st_mode = S_IFDIR | 0755;
@@ -294,7 +302,8 @@ static int regfs_getattr(const char *path, struct stat 
*sbuf)
                goto done;
        }
 
-       hobj = pvhash_search(&p->files, path, strlen(path));
+       hobj = pvhash_search(&p->files, path, strlen(path),
+                            &pvhash_operations);
        if (hobj) {
                fsobj = container_of(hobj, struct fsobj, hobj);
                sbuf->st_mode = S_IFREG;
@@ -332,7 +341,8 @@ static int regfs_readdir(const char *path, void *buf, 
fuse_fill_dir_t filler,
 
        read_lock_nocancel(&p->lock);
 
-       hobj = pvhash_search(&p->dirs, path, strlen(path));
+       hobj = pvhash_search(&p->dirs, path, strlen(path),
+                            &pvhash_operations);
        if (hobj == NULL) {
                read_unlock(&p->lock);
                return __bt(-ENOENT);
@@ -376,7 +386,8 @@ static int regfs_open(const char *path, struct 
fuse_file_info *fi)
        push_cleanup_lock(&p->lock);
        read_lock(&p->lock);
 
-       hobj = pvhash_search(&p->files, path, strlen(path));
+       hobj = pvhash_search(&p->files, path, strlen(path),
+                            &pvhash_operations);
        if (hobj == NULL) {
                ret = -ENOENT;
                goto done;
@@ -422,7 +433,8 @@ static int regfs_release(const char *path, struct 
fuse_file_info *fi)
        push_cleanup_lock(&p->lock);
        read_lock(&p->lock);
 
-       hobj = pvhash_search(&p->files, path, strlen(path));
+       hobj = pvhash_search(&p->files, path, strlen(path),
+                            &pvhash_operations);
        if (hobj == NULL) {
                ret = -ENOENT;
                goto done;
@@ -456,7 +468,8 @@ static int regfs_read(const char *path, char *buf, size_t 
size, off_t offset,
 
        read_lock_nocancel(&p->lock);
 
-       hobj = pvhash_search(&p->files, path, strlen(path));
+       hobj = pvhash_search(&p->files, path, strlen(path),
+                            &pvhash_operations);
        if (hobj == NULL) {
                read_unlock(&p->lock);
                return __bt(-EIO);
@@ -493,7 +506,8 @@ static int regfs_write(const char *path, const char *buf, 
size_t size, off_t off
 
        read_lock_nocancel(&p->lock);
 
-       hobj = pvhash_search(&p->files, path, strlen(path));
+       hobj = pvhash_search(&p->files, path, strlen(path),
+                            &pvhash_operations);
        if (hobj == NULL) {
                read_unlock(&p->lock);
                return __bt(-EIO);
@@ -738,8 +752,8 @@ int __registry_pkg_init(const char *arg0, char *mountpt, 
int shared_registry)
        if (ret)
                return ret;
 
-       pvhash_init(&p->files, pvhash_compare_strings);
-       pvhash_init(&p->dirs, pvhash_compare_strings);
+       pvhash_init(&p->files);
+       pvhash_init(&p->dirs);
 
        registry_add_dir("/");  /* Create the fs root. */
 


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://www.xenomai.org/mailman/listinfo/xenomai-git

Reply via email to