[Xenomai-git] Philippe Gerum : copperplate: fix synchronization with shared clusters

2015-03-24 Thread git repository hosting
Module: xenomai-3
Branch: master
Commit: 383e8ed5659076771c393a0f1aabb6da8c6b959b
URL:
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=383e8ed5659076771c393a0f1aabb6da8c6b959b

Author: Philippe Gerum r...@xenomai.org
Date:   Sun Mar 15 13:02:55 2015 +0100

copperplate: fix synchronization with shared clusters

The inter-process synchronization can only work if the syncobj is
shared between processes. Add a dictionary object type with an
embedded syncobj for implementing shared clusters.

---

 include/copperplate/cluster.h |9 -
 lib/copperplate/cluster.c |   87 ++---
 2 files changed, 63 insertions(+), 33 deletions(-)

diff --git a/include/copperplate/cluster.h b/include/copperplate/cluster.h
index 0f75690..9c76cbc 100644
--- a/include/copperplate/cluster.h
+++ b/include/copperplate/cluster.h
@@ -39,9 +39,14 @@ struct cluster {
struct dictionary *d;
 };
 
+struct syndictionary {
+   struct hash_table table;
+   struct syncobj sobj;
+   struct hashobj hobj;
+};
+
 struct syncluster {
-   struct cluster c;
-   struct syncobj *sobj;
+   struct syndictionary *d;
 };
 
 struct pvclusterobj {
diff --git a/lib/copperplate/cluster.c b/lib/copperplate/cluster.c
index 0dda986..7353aa8 100644
--- a/lib/copperplate/cluster.c
+++ b/lib/copperplate/cluster.c
@@ -139,20 +139,18 @@ redo:
}
 
d = xnmalloc(sizeof(*d));
-   if (d == NULL) {
-   ret = -ENOMEM;
-   goto out;
-   }
+   if (d == NULL)
+   return __bt(-ENOMEM);
 
hash_init(d-table);
ret = hash_enter(main_catalog, name, strlen(name), d-hobj,
 hash_operations);
+   /*
+* If someone managed to slip in, creating the cluster between
+* the table look up and indexing the new cluster, retry the
+* whole process.
+*/
if (ret == -EEXIST) {
-   /*
-* Someone seems to have slipped in, creating the
-* cluster right after we failed retrieving it: retry
-* the whole process.
-*/
hash_destroy(d-table);
xnfree(d);
goto redo;
@@ -249,17 +247,40 @@ int cluster_walk(struct cluster *c,
 
 int syncluster_init(struct syncluster *sc, const char *name)
 {
+   struct syndictionary *d;
+   struct hashobj *hobj;
int ret;
 
-   ret = __bt(cluster_init(sc-c, name));
-   if (ret)
-   return ret;
+redo:
+   hobj = hash_search(main_catalog, name, strlen(name),
+  hash_operations);
+   if (hobj) {
+   d = container_of(hobj, struct syndictionary, hobj);
+   ret = 0;
+   goto out;
+   }
 
-   sc-sobj = xnmalloc(sizeof(*sc-sobj));
-   if (sc-sobj == NULL)
+   d = xnmalloc(sizeof(*d));
+   if (d == NULL)
return -ENOMEM;
 
-   return syncobj_init(sc-sobj, CLOCK_COPPERPLATE,
+   hash_init(d-table);
+
+   ret = hash_enter(main_catalog, name, strlen(name), d-hobj,
+hash_operations);
+   /*
+* Same as cluster_init(), redo if someone slipped in,
+* creating the cluster.
+*/
+   if (ret == -EEXIST) {
+   hash_destroy(d-table);
+   xnfree(d);
+   goto redo;
+   }
+out:
+   sc-d = d;
+
+   return syncobj_init(d-sobj, CLOCK_COPPERPLATE,
SYNCOBJ_FIFO, fnref_null);
 }
 
@@ -271,26 +292,29 @@ int syncluster_addobj(struct syncluster *sc, const char 
*name,
struct syncstate syns;
int ret;
 
-   if (syncobj_lock(sc-sobj, syns))
+   if (syncobj_lock(sc-d-sobj, syns))
return __bt(-EINVAL);
 
-   ret = cluster_addobj(sc-c, name, cobj);
+   cobj-cnode = __node_id;
+
+   ret = hash_enter_probe(sc-d-table, name, strlen(name),
+  cobj-hobj, hash_operations);
if (ret)
goto out;
 
-   if (!syncobj_grant_wait_p(sc-sobj))
+   if (!syncobj_grant_wait_p(sc-d-sobj))
goto out;
/*
 * Wake up all threads waiting for this key to appear in the
 * dictionary.
 */
-   syncobj_for_each_grant_waiter_safe(sc-sobj, thobj, tmp) {
+   syncobj_for_each_grant_waiter_safe(sc-d-sobj, thobj, tmp) {
wait = threadobj_get_wait(thobj);
if (*wait-name == *name  strcmp(wait-name, name) == 0)
-   syncobj_grant_to(sc-sobj, thobj);
+   syncobj_grant_to(sc-d-sobj, thobj);
}
 out:
-   syncobj_unlock(sc-sobj, syns);
+   syncobj_unlock(sc-d-sobj, syns);
 
return ret;
 }
@@ -301,12 +325,12 @@ int syncluster_delobj(struct syncluster *sc,
struct syncstate syns;
int ret;
 
-   if (syncobj_lock(sc-sobj, syns))
+   if (syncobj_lock(sc-d-sobj, syns))
  

[Xenomai-git] Philippe Gerum : copperplate: fix synchronization with shared clusters

2015-03-15 Thread git repository hosting
Module: xenomai-3
Branch: next
Commit: 383e8ed5659076771c393a0f1aabb6da8c6b959b
URL:
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=383e8ed5659076771c393a0f1aabb6da8c6b959b

Author: Philippe Gerum r...@xenomai.org
Date:   Sun Mar 15 13:02:55 2015 +0100

copperplate: fix synchronization with shared clusters

The inter-process synchronization can only work if the syncobj is
shared between processes. Add a dictionary object type with an
embedded syncobj for implementing shared clusters.

---

 include/copperplate/cluster.h |9 -
 lib/copperplate/cluster.c |   87 ++---
 2 files changed, 63 insertions(+), 33 deletions(-)

diff --git a/include/copperplate/cluster.h b/include/copperplate/cluster.h
index 0f75690..9c76cbc 100644
--- a/include/copperplate/cluster.h
+++ b/include/copperplate/cluster.h
@@ -39,9 +39,14 @@ struct cluster {
struct dictionary *d;
 };
 
+struct syndictionary {
+   struct hash_table table;
+   struct syncobj sobj;
+   struct hashobj hobj;
+};
+
 struct syncluster {
-   struct cluster c;
-   struct syncobj *sobj;
+   struct syndictionary *d;
 };
 
 struct pvclusterobj {
diff --git a/lib/copperplate/cluster.c b/lib/copperplate/cluster.c
index 0dda986..7353aa8 100644
--- a/lib/copperplate/cluster.c
+++ b/lib/copperplate/cluster.c
@@ -139,20 +139,18 @@ redo:
}
 
d = xnmalloc(sizeof(*d));
-   if (d == NULL) {
-   ret = -ENOMEM;
-   goto out;
-   }
+   if (d == NULL)
+   return __bt(-ENOMEM);
 
hash_init(d-table);
ret = hash_enter(main_catalog, name, strlen(name), d-hobj,
 hash_operations);
+   /*
+* If someone managed to slip in, creating the cluster between
+* the table look up and indexing the new cluster, retry the
+* whole process.
+*/
if (ret == -EEXIST) {
-   /*
-* Someone seems to have slipped in, creating the
-* cluster right after we failed retrieving it: retry
-* the whole process.
-*/
hash_destroy(d-table);
xnfree(d);
goto redo;
@@ -249,17 +247,40 @@ int cluster_walk(struct cluster *c,
 
 int syncluster_init(struct syncluster *sc, const char *name)
 {
+   struct syndictionary *d;
+   struct hashobj *hobj;
int ret;
 
-   ret = __bt(cluster_init(sc-c, name));
-   if (ret)
-   return ret;
+redo:
+   hobj = hash_search(main_catalog, name, strlen(name),
+  hash_operations);
+   if (hobj) {
+   d = container_of(hobj, struct syndictionary, hobj);
+   ret = 0;
+   goto out;
+   }
 
-   sc-sobj = xnmalloc(sizeof(*sc-sobj));
-   if (sc-sobj == NULL)
+   d = xnmalloc(sizeof(*d));
+   if (d == NULL)
return -ENOMEM;
 
-   return syncobj_init(sc-sobj, CLOCK_COPPERPLATE,
+   hash_init(d-table);
+
+   ret = hash_enter(main_catalog, name, strlen(name), d-hobj,
+hash_operations);
+   /*
+* Same as cluster_init(), redo if someone slipped in,
+* creating the cluster.
+*/
+   if (ret == -EEXIST) {
+   hash_destroy(d-table);
+   xnfree(d);
+   goto redo;
+   }
+out:
+   sc-d = d;
+
+   return syncobj_init(d-sobj, CLOCK_COPPERPLATE,
SYNCOBJ_FIFO, fnref_null);
 }
 
@@ -271,26 +292,29 @@ int syncluster_addobj(struct syncluster *sc, const char 
*name,
struct syncstate syns;
int ret;
 
-   if (syncobj_lock(sc-sobj, syns))
+   if (syncobj_lock(sc-d-sobj, syns))
return __bt(-EINVAL);
 
-   ret = cluster_addobj(sc-c, name, cobj);
+   cobj-cnode = __node_id;
+
+   ret = hash_enter_probe(sc-d-table, name, strlen(name),
+  cobj-hobj, hash_operations);
if (ret)
goto out;
 
-   if (!syncobj_grant_wait_p(sc-sobj))
+   if (!syncobj_grant_wait_p(sc-d-sobj))
goto out;
/*
 * Wake up all threads waiting for this key to appear in the
 * dictionary.
 */
-   syncobj_for_each_grant_waiter_safe(sc-sobj, thobj, tmp) {
+   syncobj_for_each_grant_waiter_safe(sc-d-sobj, thobj, tmp) {
wait = threadobj_get_wait(thobj);
if (*wait-name == *name  strcmp(wait-name, name) == 0)
-   syncobj_grant_to(sc-sobj, thobj);
+   syncobj_grant_to(sc-d-sobj, thobj);
}
 out:
-   syncobj_unlock(sc-sobj, syns);
+   syncobj_unlock(sc-d-sobj, syns);
 
return ret;
 }
@@ -301,12 +325,12 @@ int syncluster_delobj(struct syncluster *sc,
struct syncstate syns;
int ret;
 
-   if (syncobj_lock(sc-sobj, syns))
+   if (syncobj_lock(sc-d-sobj, syns))