[Xenomai-git] Philippe Gerum : copperplate: fix synchronization with shared clusters
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
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))