Remove runtime dependency on liburcu shared objects
[lttng-ust.git] / liblttng-ust / rculfhash-internal.h
1 #ifndef _LTTNG_UST_RCULFHASH_INTERNAL_H
2 #define _LTTNG_UST_RCULFHASH_INTERNAL_H
3
4 /*
5 * liblttng-ust/rculfhash-internal.h
6 *
7 * Internal header for Lock-Free RCU Hash Table
8 *
9 * Copyright 2011 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
10 * Copyright 2011 - Lai Jiangshan <laijs@cn.fujitsu.com>
11 *
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
16 *
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 */
26
27 #include "rculfhash.h"
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <assert.h>
31
32 #ifdef DEBUG
33 #define dbg_printf(fmt, args...) printf("[debug lttng-ust rculfhash] " fmt, ## args)
34 #else
35 #define dbg_printf(fmt, args...) \
36 do { \
37 /* do nothing but check printf format */ \
38 if (0) \
39 printf("[debug lttng-ust rculfhash] " fmt, ## args); \
40 } while (0)
41 #endif
42
43 #if (CAA_BITS_PER_LONG == 32)
44 #define MAX_TABLE_ORDER 32
45 #else
46 #define MAX_TABLE_ORDER 64
47 #endif
48
49 #define MAX_CHUNK_TABLE (1UL << 10)
50
51 #ifndef min
52 #define min(a, b) ((a) < (b) ? (a) : (b))
53 #endif
54
55 #ifndef max
56 #define max(a, b) ((a) > (b) ? (a) : (b))
57 #endif
58
59 /*
60 * lttng_ust_lfht: Top-level data structure representing a lock-free hash
61 * table. Defined in the implementation file to make it be an opaque
62 * cookie to users.
63 *
64 * The fields used in fast-paths are placed near the end of the
65 * structure, because we need to have a variable-sized union to contain
66 * the mm plugin fields, which are used in the fast path.
67 */
68 struct lttng_ust_lfht {
69 /* Initial configuration items */
70 unsigned long max_nr_buckets;
71 const struct lttng_ust_lfht_mm_type *mm; /* memory management plugin */
72 const struct rcu_flavor_struct *flavor; /* RCU flavor */
73
74 /*
75 * We need to put the work threads offline (QSBR) when taking this
76 * mutex, because we use synchronize_rcu within this mutex critical
77 * section, which waits on read-side critical sections, and could
78 * therefore cause grace-period deadlock if we hold off RCU G.P.
79 * completion.
80 */
81 pthread_mutex_t resize_mutex; /* resize mutex: add/del mutex */
82 unsigned int in_progress_destroy;
83 unsigned long resize_target;
84 int resize_initiated;
85
86 /*
87 * Variables needed for add and remove fast-paths.
88 */
89 int flags;
90 unsigned long min_alloc_buckets_order;
91 unsigned long min_nr_alloc_buckets;
92
93 /*
94 * Variables needed for the lookup, add and remove fast-paths.
95 */
96 unsigned long size; /* always a power of 2, shared (RCU) */
97 /*
98 * bucket_at pointer is kept here to skip the extra level of
99 * dereference needed to get to "mm" (this is a fast-path).
100 */
101 struct lttng_ust_lfht_node *(*bucket_at)(struct lttng_ust_lfht *ht,
102 unsigned long index);
103 /*
104 * Dynamic length "tbl_chunk" needs to be at the end of
105 * lttng_ust_lfht.
106 */
107 union {
108 /*
109 * Contains the per order-index-level bucket node table.
110 * The size of each bucket node table is half the number
111 * of hashes contained in this order (except for order 0).
112 * The minimum allocation buckets size parameter allows
113 * combining the bucket node arrays of the lowermost
114 * levels to improve cache locality for small index orders.
115 */
116 struct lttng_ust_lfht_node *tbl_order[MAX_TABLE_ORDER];
117
118 /*
119 * Contains the bucket node chunks. The size of each
120 * bucket node chunk is ->min_alloc_size (we avoid to
121 * allocate chunks with different size). Chunks improve
122 * cache locality for small index orders, and are more
123 * friendly with environments where allocation of large
124 * contiguous memory areas is challenging due to memory
125 * fragmentation concerns or inability to use virtual
126 * memory addressing.
127 */
128 struct lttng_ust_lfht_node *tbl_chunk[0];
129
130 /*
131 * Memory mapping with room for all possible buckets.
132 * Their memory is allocated when needed.
133 */
134 struct lttng_ust_lfht_node *tbl_mmap;
135 };
136 /*
137 * End of variables needed for the lookup, add and remove
138 * fast-paths.
139 */
140 };
141
142 extern unsigned int lttng_ust_lfht_fls_ulong(unsigned long x);
143 extern int lttng_ust_lfht_get_count_order_ulong(unsigned long x);
144
145 #ifdef POISON_FREE
146 #define poison_free(ptr) \
147 do { \
148 if (ptr) { \
149 memset(ptr, 0x42, sizeof(*(ptr))); \
150 free(ptr); \
151 } \
152 } while (0)
153 #else
154 #define poison_free(ptr) free(ptr)
155 #endif
156
157 static inline
158 struct lttng_ust_lfht *__default_alloc_lttng_ust_lfht(
159 const struct lttng_ust_lfht_mm_type *mm,
160 unsigned long lttng_ust_lfht_size,
161 unsigned long min_nr_alloc_buckets,
162 unsigned long max_nr_buckets)
163 {
164 struct lttng_ust_lfht *ht;
165
166 ht = calloc(1, lttng_ust_lfht_size);
167 assert(ht);
168
169 ht->mm = mm;
170 ht->bucket_at = mm->bucket_at;
171 ht->min_nr_alloc_buckets = min_nr_alloc_buckets;
172 ht->min_alloc_buckets_order =
173 lttng_ust_lfht_get_count_order_ulong(min_nr_alloc_buckets);
174 ht->max_nr_buckets = max_nr_buckets;
175
176 return ht;
177 }
178
179 #endif /* _LTTNG_UST_RCULFHASH_INTERNAL_H */
This page took 0.032101 seconds and 4 git commands to generate.