uatomic/x86: Remove redundant memory barriers
[urcu.git] / doc / examples / rculfhash / cds_lfht_del.c
CommitLineData
1c87adb3
MJ
1// SPDX-FileCopyrightText: 2013 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
2//
3// SPDX-License-Identifier: MIT
4
f7e7a1b8 5/*
f7e7a1b8
MD
6 * This example shows how to remove nodes from a RCU lock-free hash table.
7 * This hash table requires using a RCU scheme.
8 */
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <time.h>
13
b9050d91 14#include <urcu/urcu-memb.h> /* RCU flavor */
f7e7a1b8
MD
15#include <urcu/rculfhash.h> /* RCU Lock-free hash table */
16#include <urcu/compiler.h> /* For CAA_ARRAY_SIZE */
17#include "jhash.h" /* Example hash function */
18
19/*
20 * Nodes populated into the hash table.
21 */
22struct mynode {
23 int value; /* Node content */
24 struct cds_lfht_node node; /* Chaining in hash table */
25 struct rcu_head rcu_head; /* For call_rcu() */
26};
27
34b3f359 28static
f7e7a1b8
MD
29int match(struct cds_lfht_node *ht_node, const void *_key)
30{
31 struct mynode *node =
32 caa_container_of(ht_node, struct mynode, node);
83e334d0 33 const int *key = _key;
f7e7a1b8
MD
34
35 return *key == node->value;
36}
37
34b3f359
MD
38static
39void free_node(struct rcu_head *head)
40{
41 struct mynode *node = caa_container_of(head, struct mynode, rcu_head);
42
43 free(node);
44}
45
70469b43 46int main(void)
f7e7a1b8
MD
47{
48 int values[] = { -5, 42, 42, 36, 24, }; /* 42 is duplicated */
49 int remove_values[] = { 42, 36, 24, 123, };
50 struct cds_lfht *ht; /* Hash table */
51 unsigned int i;
52 int ret = 0;
53 uint32_t seed;
54 struct cds_lfht_iter iter; /* For iteration on hash table */
55 struct cds_lfht_node *ht_node;
56 struct mynode *node;
57
58 /*
59 * Each thread need using RCU read-side need to be explicitly
60 * registered.
61 */
b9050d91 62 urcu_memb_register_thread();
f7e7a1b8
MD
63
64 /* Use time as seed for hash table hashing. */
65 seed = (uint32_t) time(NULL);
66
67 /*
68 * Allocate hash table.
69 */
b9050d91 70 ht = cds_lfht_new_flavor(1, 1, 0,
f7e7a1b8 71 CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING,
b9050d91 72 &urcu_memb_flavor, NULL);
f7e7a1b8
MD
73 if (!ht) {
74 printf("Error allocating hash table\n");
75 ret = -1;
76 goto end;
77 }
78
79 /*
80 * Add nodes to hash table.
81 */
82 for (i = 0; i < CAA_ARRAY_SIZE(values); i++) {
83 unsigned long hash;
84 int value;
85
86 node = malloc(sizeof(*node));
87 if (!node) {
88 ret = -1;
89 goto end;
90 }
91
92 cds_lfht_node_init(&node->node);
93 value = values[i];
94 node->value = value;
95 hash = jhash(&value, sizeof(value), seed);
96
97 /*
98 * cds_lfht_add() needs to be called from RCU read-side
99 * critical section.
100 */
b9050d91 101 urcu_memb_read_lock();
f7e7a1b8 102 cds_lfht_add(ht, hash, &node->node);
b9050d91 103 urcu_memb_read_unlock();
f7e7a1b8
MD
104 }
105
106 /*
107 * Iterate over each hash table node. Those will appear in
108 * random order, depending on the hash seed. Iteration needs to
109 * be performed within RCU read-side critical section.
110 */
111 printf("hash table content (random order):");
b9050d91 112 urcu_memb_read_lock();
f7e7a1b8
MD
113 cds_lfht_for_each_entry(ht, &iter, node, node) {
114 printf(" %d", node->value);
115 }
b9050d91 116 urcu_memb_read_unlock();
f7e7a1b8
MD
117 printf("\n");
118
119 /*
120 * Remove one node for each key, if such a node is present.
121 */
122 printf("removing keys (single key, not duplicates):");
123 for (i = 0; i < CAA_ARRAY_SIZE(remove_values); i++) {
124 unsigned long hash;
125 int value;
126
127 value = remove_values[i];
128 hash = jhash(&value, sizeof(value), seed);
129 printf(" %d", value);
b9050d91 130 urcu_memb_read_lock();
f7e7a1b8
MD
131 cds_lfht_lookup(ht, hash, match, &value, &iter);
132 ht_node = cds_lfht_iter_get_node(&iter);
133 if (ht_node) {
134 ret = cds_lfht_del(ht, ht_node);
135 if (ret) {
136 printf(" (concurrently deleted)");
34b3f359
MD
137 } else {
138 struct mynode *del_node =
139 caa_container_of(ht_node,
140 struct mynode, node);
b9050d91 141 urcu_memb_call_rcu(&del_node->rcu_head, free_node);
f7e7a1b8
MD
142 }
143 } else {
144 printf(" (not found)");
145 }
b9050d91 146 urcu_memb_read_unlock();
f7e7a1b8
MD
147 }
148 printf("\n");
149
150 printf("hash table content (random order):");
b9050d91 151 urcu_memb_read_lock();
f7e7a1b8
MD
152 cds_lfht_for_each_entry(ht, &iter, node, node) {
153 printf(" %d", node->value);
154 }
b9050d91 155 urcu_memb_read_unlock();
f7e7a1b8
MD
156 printf("\n");
157
158end:
b9050d91 159 urcu_memb_unregister_thread();
f7e7a1b8
MD
160 return ret;
161}
This page took 0.042601 seconds and 4 git commands to generate.