2 * SPDX-License-Identifier: LGPL-2.1-or-later
4 * Copyright 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 * Copyright 2011 Lai Jiangshan <laijs@cn.fujitsu.com>
7 * Internal header for Lock-Free RCU Hash Table
10 #ifndef _LTTNG_UST_RCULFHASH_INTERNAL_H
11 #define _LTTNG_UST_RCULFHASH_INTERNAL_H
13 #include "rculfhash.h"
19 #define dbg_printf(fmt, args...) printf("[debug lttng-ust rculfhash] " fmt, ## args)
21 #define dbg_printf(fmt, args...) \
23 /* do nothing but check printf format */ \
25 printf("[debug lttng-ust rculfhash] " fmt, ## args); \
29 #if (CAA_BITS_PER_LONG == 32)
30 #define MAX_TABLE_ORDER 32
32 #define MAX_TABLE_ORDER 64
35 #define MAX_CHUNK_TABLE (1UL << 10)
38 #define min(a, b) ((a) < (b) ? (a) : (b))
42 #define max(a, b) ((a) > (b) ? (a) : (b))
46 * lttng_ust_lfht: Top-level data structure representing a lock-free hash
47 * table. Defined in the implementation file to make it be an opaque
50 * The fields used in fast-paths are placed near the end of the
51 * structure, because we need to have a variable-sized union to contain
52 * the mm plugin fields, which are used in the fast path.
54 struct lttng_ust_lfht
{
55 /* Initial configuration items */
56 unsigned long max_nr_buckets
;
57 const struct lttng_ust_lfht_mm_type
*mm
; /* memory management plugin */
58 const struct rcu_flavor_struct
*flavor
; /* RCU flavor */
61 * We need to put the work threads offline (QSBR) when taking this
62 * mutex, because we use synchronize_rcu within this mutex critical
63 * section, which waits on read-side critical sections, and could
64 * therefore cause grace-period deadlock if we hold off RCU G.P.
67 pthread_mutex_t resize_mutex
; /* resize mutex: add/del mutex */
68 unsigned int in_progress_destroy
;
69 unsigned long resize_target
;
73 * Variables needed for add and remove fast-paths.
76 unsigned long min_alloc_buckets_order
;
77 unsigned long min_nr_alloc_buckets
;
80 * Variables needed for the lookup, add and remove fast-paths.
82 unsigned long size
; /* always a power of 2, shared (RCU) */
84 * bucket_at pointer is kept here to skip the extra level of
85 * dereference needed to get to "mm" (this is a fast-path).
87 struct lttng_ust_lfht_node
*(*bucket_at
)(struct lttng_ust_lfht
*ht
,
90 * Dynamic length "tbl_chunk" needs to be at the end of
95 * Contains the per order-index-level bucket node table.
96 * The size of each bucket node table is half the number
97 * of hashes contained in this order (except for order 0).
98 * The minimum allocation buckets size parameter allows
99 * combining the bucket node arrays of the lowermost
100 * levels to improve cache locality for small index orders.
102 struct lttng_ust_lfht_node
*tbl_order
[MAX_TABLE_ORDER
];
105 * Contains the bucket node chunks. The size of each
106 * bucket node chunk is ->min_alloc_size (we avoid to
107 * allocate chunks with different size). Chunks improve
108 * cache locality for small index orders, and are more
109 * friendly with environments where allocation of large
110 * contiguous memory areas is challenging due to memory
111 * fragmentation concerns or inability to use virtual
114 struct lttng_ust_lfht_node
*tbl_chunk
[0];
117 * Memory mapping with room for all possible buckets.
118 * Their memory is allocated when needed.
120 struct lttng_ust_lfht_node
*tbl_mmap
;
123 * End of variables needed for the lookup, add and remove
128 extern unsigned int lttng_ust_lfht_fls_ulong(unsigned long x
)
129 __attribute__((visibility("hidden")));
131 extern int lttng_ust_lfht_get_count_order_u32(uint32_t x
)
132 __attribute__((visibility("hidden")));
134 extern int lttng_ust_lfht_get_count_order_ulong(unsigned long x
)
135 __attribute__((visibility("hidden")));
138 #define poison_free(ptr) \
141 memset(ptr, 0x42, sizeof(*(ptr))); \
146 #define poison_free(ptr) free(ptr)
150 struct lttng_ust_lfht
*__default_alloc_lttng_ust_lfht(
151 const struct lttng_ust_lfht_mm_type
*mm
,
152 unsigned long lttng_ust_lfht_size
,
153 unsigned long min_nr_alloc_buckets
,
154 unsigned long max_nr_buckets
)
156 struct lttng_ust_lfht
*ht
;
158 ht
= calloc(1, lttng_ust_lfht_size
);
162 ht
->bucket_at
= mm
->bucket_at
;
163 ht
->min_nr_alloc_buckets
= min_nr_alloc_buckets
;
164 ht
->min_alloc_buckets_order
=
165 lttng_ust_lfht_get_count_order_ulong(min_nr_alloc_buckets
);
166 ht
->max_nr_buckets
= max_nr_buckets
;
171 #endif /* _LTTNG_UST_RCULFHASH_INTERNAL_H */