__attribute__((visibility("protected")))
void rcuja_free_all_children(struct cds_ja_shadow_node *shadow_node,
struct cds_ja_inode_flag *node_flag,
- void (*free_node_cb)(struct rcu_head *head));
+ void (*rcu_free_node)(struct cds_ja_node *node));
__attribute__((visibility("protected")))
struct cds_ja_shadow_node *rcuja_shadow_lookup_lock(struct cds_lfht *ht,
__attribute__((visibility("protected")))
void rcuja_shadow_prune(struct cds_lfht *ht,
unsigned int flags,
- void (*free_node_cb)(struct rcu_head *head));
+ void (*rcu_free_node)(struct cds_ja_node *node));
__attribute__((visibility("protected")))
struct cds_lfht *rcuja_create_ht(const struct rcu_flavor_struct *flavor);
__attribute__((visibility("protected")))
void rcuja_shadow_prune(struct cds_lfht *ht,
unsigned int flags,
- void (*free_node_cb)(struct rcu_head *head))
+ void (*rcu_free_node)(struct cds_ja_node *node))
{
const struct rcu_flavor_struct *flavor;
struct cds_ja_shadow_node *shadow_node;
if (shadow_node->level == shadow_node->ja->tree_depth - 1) {
rcuja_free_all_children(shadow_node,
shadow_node->node_flag,
- free_node_cb);
+ rcu_free_node);
}
if (flags & RCUJA_SHADOW_CLEAR_FREE_LOCK) {
flavor->update_call_rcu(&shadow_node->head,
__attribute__((visibility("protected")))
void rcuja_free_all_children(struct cds_ja_shadow_node *shadow_node,
struct cds_ja_inode_flag *node_flag,
- void (*free_node_cb)(struct rcu_head *head))
+ void (*rcu_free_node)(struct cds_ja_node *node))
{
- const struct rcu_flavor_struct *flavor;
unsigned int type_index;
struct cds_ja_inode *node;
const struct cds_ja_type *type;
- flavor = cds_lfht_rcu_flavor(shadow_node->ja->ht);
node = ja_node_ptr(node_flag);
assert(node != NULL);
type_index = ja_node_type(node_flag);
continue;
head.next = (struct cds_hlist_node *) iter;
cds_hlist_for_each_entry_safe(entry, pos, tmp, &head, list) {
- flavor->update_call_rcu(&entry->head, free_node_cb);
+ rcu_free_node(entry);
}
}
break;
continue;
head.next = (struct cds_hlist_node *) iter;
cds_hlist_for_each_entry_safe(entry, pos, tmp, &head, list) {
- flavor->update_call_rcu(&entry->head, free_node_cb);
+ rcu_free_node(entry);
}
}
}
continue;
head.next = (struct cds_hlist_node *) iter;
cds_hlist_for_each_entry_safe(entry, pos, tmp, &head, list) {
- flavor->update_call_rcu(&entry->head, free_node_cb);
+ rcu_free_node(entry);
}
}
break;
* being destroyed (ensured by the caller).
*/
int cds_ja_destroy(struct cds_ja *ja,
- void (*free_node_cb)(struct rcu_head *head))
+ void (*rcu_free_node)(struct cds_ja_node *node))
{
const struct rcu_flavor_struct *flavor;
int ret;
flavor = cds_lfht_rcu_flavor(ja->ht);
rcuja_shadow_prune(ja->ht,
RCUJA_SHADOW_CLEAR_FREE_NODE | RCUJA_SHADOW_CLEAR_FREE_LOCK,
- free_node_cb);
+ rcu_free_node);
flavor->thread_offline();
ret = rcuja_delete_ht(ja->ht);
if (ret)
void free_node_cb(struct rcu_head *head)
{
struct ja_test_node *node =
- caa_container_of(head, struct ja_test_node, node.head);
+ caa_container_of(head, struct ja_test_node, head);
free_node(node);
}
+static
+void rcu_free_test_node(struct ja_test_node *test_node)
+{
+ call_rcu(&test_node->head, free_node_cb);
+}
+
+static
+void rcu_free_node(struct cds_ja_node *node)
+{
+ struct ja_test_node *test_node = to_test_node(node);
+
+ rcu_free_test_node(test_node);
+}
+
#if 0
static
void test_delete_all_nodes(struct cds_lfht *ht)
fprintf(stderr, "Error (%d) removing node %" PRIu64 "\n", ret, key);
assert(0);
}
- call_rcu(&node->node.head, free_node_cb);
+ rcu_free_test_node(node);
head = cds_ja_lookup(test_ja, key);
if (!cds_hlist_empty(&head)) {
fprintf(stderr, "Error lookup %" PRIu64 ": %p (after delete) failed. Node is not expected.\n", key, head.next);
printf("OK\n");
- ret = cds_ja_destroy(test_ja, free_node_cb);
+ ret = cds_ja_destroy(test_ja, rcu_free_node);
if (ret) {
fprintf(stderr, "Error destroying judy array\n");
return -1;
fprintf(stderr, "Error (%d) removing node %" PRIu64 "\n", ret, key);
assert(0);
}
- call_rcu(&node->node.head, free_node_cb);
+ rcu_free_test_node(node);
head = cds_ja_lookup(test_ja, key);
if (!cds_hlist_empty(&head)) {
fprintf(stderr, "Error lookup %" PRIu64 ": %p (after delete) failed. Node is not expected.\n", key, head.next);
printf("OK\n");
- ret = cds_ja_destroy(test_ja, free_node_cb);
+ ret = cds_ja_destroy(test_ja, rcu_free_node);
if (ret) {
fprintf(stderr, "Error destroying judy array\n");
return -1;
fprintf(stderr, "Error (%d) removing node %" PRIu64 "\n", ret, key);
assert(0);
}
- call_rcu(&node->node.head, free_node_cb);
+ rcu_free_test_node(node);
testhead = cds_ja_lookup(test_ja, key);
if (count < nr_dup && cds_hlist_empty(&testhead)) {
fprintf(stderr, "Error: no node found after deletion of some nodes of a key\n");
}
printf("OK\n");
- ret = cds_ja_destroy(test_ja, free_node_cb);
+ ret = cds_ja_destroy(test_ja, rcu_free_node);
if (ret) {
fprintf(stderr, "Error destroying judy array\n");
return -1;
if (node) {
ret = cds_ja_del(test_ja, key, &node->node);
if (!ret) {
- call_rcu(&node->node.head, free_node_cb);
+ rcu_free_test_node(node);
URCU_TLS(nr_del)++;
} else {
URCU_TLS(nr_delnoent)++;
}
rcu_thread_online_qsbr();
- ret = cds_ja_destroy(test_ja, free_node_cb);
+ ret = cds_ja_destroy(test_ja, rcu_free_node);
if (ret) {
fprintf(stderr, "Error destroying judy array\n");
goto end;
struct ja_test_node {
struct cds_ja_node node;
- uint64_t key; /* for testing */
+ uint64_t key; /* for testing */
+ struct rcu_head head; /* delayed reclaim */
};
static inline struct ja_test_node *
struct cds_ja_node {
/* Linked list of nodes with same key */
struct cds_hlist_node list;
- /* delayed reclaim */
- struct rcu_head head;
};
struct cds_ja;
}
int cds_ja_destroy(struct cds_ja *ja,
- void (*free_node_cb)(struct rcu_head *head));
+ void (*rcu_free_node_cb)(struct cds_ja_node *node));
#ifdef __cplusplus
}