X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=urcu-ht.c;h=7213c39ce1414d788149dc864f9114bcb814acb0;hb=3df2df75972d2ccaa1a1fa01bad06b0eda7f76f2;hp=500b8d36fff51dffaa3d2b8548b70f83be60518e;hpb=e0ba718a906a70053d699a25c1d59b5bbdbf8715;p=urcu.git diff --git a/urcu-ht.c b/urcu-ht.c index 500b8d3..7213c39 100644 --- a/urcu-ht.c +++ b/urcu-ht.c @@ -17,13 +17,16 @@ #include #include +/* node flags */ +#define NODE_STOLEN (1 << 0) + struct rcu_ht_node; struct rcu_ht_node { struct rcu_ht_node *next; void *key; void *data; - int stolen; + unsigned int flags; }; struct rcu_ht { @@ -95,7 +98,7 @@ int ht_add(struct rcu_ht *ht, void *key, void *data) new_head = calloc(1, sizeof(struct rcu_ht_node)); new_head->key = key; new_head->data = data; - new_head->stolen = 0; + new_head->flags = 0; /* here comes the fun and tricky part. * Add at the beginning with a cmpxchg. * Hold a read lock between the moment the first element is read @@ -174,9 +177,15 @@ retry: node = rcu_dereference(*prev); } - /* Another concurrent thread stole it ? If so, let it deal with this. */ - if (cmpxchg(&node->stolen, 0, 1) != 0) - goto error; + if (!del_node) { + /* + * Another concurrent thread stole it ? If so, let it deal with + * this. Assume NODE_STOLEN is the only flag. If this changes, + * read flags before cmpxchg. + */ + if (cmpxchg(&node->flags, 0, NODE_STOLEN) != 0) + goto error; + } /* Found it ! pointer to object is in "prev" */ if (rcu_cmpxchg_pointer(prev, node, node->next) == node)