src: use SPDX identifiers
[urcu.git] / src / rculfhash-internal.h
1 // SPDX-FileCopyrightText: 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
2 // SPDX-FileCopyrightText: 2011 Lai Jiangshan <laijs@cn.fujitsu.com>
3 //
4 // SPDX-License-Identifier: LGPL-2.1-or-later
5
6 #ifndef _URCU_RCULFHASH_INTERNAL_H
7 #define _URCU_RCULFHASH_INTERNAL_H
8
9 /*
10 * Internal header for Lock-Free RCU Hash Table
11 */
12
13 #include <urcu/assert.h>
14 #include <urcu/rculfhash.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17
18 #include "workqueue.h"
19
20 #ifdef DEBUG
21 #define dbg_printf(fmt, args...) printf("[debug rculfhash] " fmt, ## args)
22 #else
23 #define dbg_printf(fmt, args...) \
24 do { \
25 /* do nothing but check printf format */ \
26 if (0) \
27 printf("[debug rculfhash] " fmt, ## args); \
28 } while (0)
29 #endif
30
31 #if (CAA_BITS_PER_LONG == 32)
32 #define MAX_TABLE_ORDER 32
33 #else
34 #define MAX_TABLE_ORDER 64
35 #endif
36
37 #define MAX_CHUNK_TABLE (1UL << 10)
38
39 #ifndef min
40 #define min(a, b) ((a) < (b) ? (a) : (b))
41 #endif
42
43 #ifndef max
44 #define max(a, b) ((a) > (b) ? (a) : (b))
45 #endif
46
47 struct ht_items_count;
48
49 /*
50 * cds_lfht: Top-level data structure representing a lock-free hash
51 * table. Defined in the implementation file to make it be an opaque
52 * cookie to users.
53 *
54 * The fields used in fast-paths are placed near the end of the
55 * structure, because we need to have a variable-sized union to contain
56 * the mm plugin fields, which are used in the fast path.
57 */
58 struct cds_lfht {
59 /* Initial configuration items */
60 unsigned long max_nr_buckets;
61 const struct cds_lfht_mm_type *mm; /* memory management plugin */
62 const struct rcu_flavor_struct *flavor; /* RCU flavor */
63
64 long count; /* global approximate item count */
65
66 /*
67 * We need to put the work threads offline (QSBR) when taking this
68 * mutex, because we use synchronize_rcu within this mutex critical
69 * section, which waits on read-side critical sections, and could
70 * therefore cause grace-period deadlock if we hold off RCU G.P.
71 * completion.
72 */
73 pthread_mutex_t resize_mutex; /* resize mutex: add/del mutex */
74 pthread_attr_t *caller_resize_attr; /* resize threads attributes from lfht_new caller */
75 pthread_attr_t resize_attr;
76 unsigned int in_progress_destroy;
77 unsigned long resize_target;
78 int resize_initiated;
79 struct urcu_work destroy_work;
80
81 /*
82 * Variables needed for add and remove fast-paths.
83 */
84 int flags;
85 unsigned long min_alloc_buckets_order;
86 unsigned long min_nr_alloc_buckets;
87 struct ht_items_count *split_count; /* split item count */
88
89 /*
90 * Variables needed for the lookup, add and remove fast-paths.
91 */
92 unsigned long size; /* always a power of 2, shared (RCU) */
93 /*
94 * bucket_at pointer is kept here to skip the extra level of
95 * dereference needed to get to "mm" (this is a fast-path).
96 */
97 struct cds_lfht_node *(*bucket_at)(struct cds_lfht *ht,
98 unsigned long index);
99 /*
100 * Dynamic length "tbl_chunk" needs to be at the end of
101 * cds_lfht.
102 */
103 union {
104 /*
105 * Contains the per order-index-level bucket node table.
106 * The size of each bucket node table is half the number
107 * of hashes contained in this order (except for order 0).
108 * The minimum allocation buckets size parameter allows
109 * combining the bucket node arrays of the lowermost
110 * levels to improve cache locality for small index orders.
111 */
112 struct cds_lfht_node *tbl_order[MAX_TABLE_ORDER];
113
114 /*
115 * Contains the bucket node chunks. The size of each
116 * bucket node chunk is ->min_alloc_size (we avoid to
117 * allocate chunks with different size). Chunks improve
118 * cache locality for small index orders, and are more
119 * friendly with environments where allocation of large
120 * contiguous memory areas is challenging due to memory
121 * fragmentation concerns or inability to use virtual
122 * memory addressing.
123 */
124 struct cds_lfht_node *tbl_chunk[0];
125
126 /*
127 * Memory mapping with room for all possible buckets.
128 * Their memory is allocated when needed.
129 */
130 struct cds_lfht_node *tbl_mmap;
131 };
132 /*
133 * End of variables needed for the lookup, add and remove
134 * fast-paths.
135 */
136 };
137
138 extern unsigned int cds_lfht_fls_ulong(unsigned long x);
139 extern int cds_lfht_get_count_order_ulong(unsigned long x);
140
141 #ifdef POISON_FREE
142 #define poison_free(ptr) \
143 do { \
144 if (ptr) { \
145 memset(ptr, 0x42, sizeof(*(ptr))); \
146 free(ptr); \
147 } \
148 } while (0)
149 #else
150 #define poison_free(ptr) free(ptr)
151 #endif
152
153 static inline
154 struct cds_lfht *__default_alloc_cds_lfht(
155 const struct cds_lfht_mm_type *mm,
156 unsigned long cds_lfht_size,
157 unsigned long min_nr_alloc_buckets,
158 unsigned long max_nr_buckets)
159 {
160 struct cds_lfht *ht;
161
162 ht = calloc(1, cds_lfht_size);
163 urcu_posix_assert(ht);
164
165 ht->mm = mm;
166 ht->bucket_at = mm->bucket_at;
167 ht->min_nr_alloc_buckets = min_nr_alloc_buckets;
168 ht->min_alloc_buckets_order =
169 cds_lfht_get_count_order_ulong(min_nr_alloc_buckets);
170 ht->max_nr_buckets = max_nr_buckets;
171
172 return ht;
173 }
174
175 #endif /* _URCU_RCULFHASH_INTERNAL_H */
This page took 0.034251 seconds and 5 git commands to generate.