Android: add a compat layer for 'syscall.h'
[urcu.git] / rculfhash-internal.h
... / ...
CommitLineData
1#ifndef _URCU_RCULFHASH_INTERNAL_H
2#define _URCU_RCULFHASH_INTERNAL_H
3
4/*
5 * urcu/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 <urcu/rculfhash.h>
28#include <stdio.h>
29
30#ifdef DEBUG
31#define dbg_printf(fmt, args...) printf("[debug rculfhash] " fmt, ## args)
32#else
33#define dbg_printf(fmt, args...) \
34do { \
35 /* do nothing but check printf format */ \
36 if (0) \
37 printf("[debug rculfhash] " fmt, ## args); \
38} while (0)
39#endif
40
41#if (CAA_BITS_PER_LONG == 32)
42#define MAX_TABLE_ORDER 32
43#else
44#define MAX_TABLE_ORDER 64
45#endif
46
47#define MAX_CHUNK_TABLE (1UL << 10)
48
49#ifndef min
50#define min(a, b) ((a) < (b) ? (a) : (b))
51#endif
52
53#ifndef max
54#define max(a, b) ((a) > (b) ? (a) : (b))
55#endif
56
57struct ht_items_count;
58
59/*
60 * cds_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 */
68struct cds_lfht {
69 /* Initial configuration items */
70 unsigned long max_nr_buckets;
71 const struct cds_lfht_mm_type *mm; /* memory management plugin */
72 const struct rcu_flavor_struct *flavor; /* RCU flavor */
73
74 long count; /* global approximate item count */
75
76 /*
77 * We need to put the work threads offline (QSBR) when taking this
78 * mutex, because we use synchronize_rcu within this mutex critical
79 * section, which waits on read-side critical sections, and could
80 * therefore cause grace-period deadlock if we hold off RCU G.P.
81 * completion.
82 */
83 pthread_mutex_t resize_mutex; /* resize mutex: add/del mutex */
84 pthread_attr_t *resize_attr; /* Resize threads attributes */
85 unsigned int in_progress_resize, in_progress_destroy;
86 unsigned long resize_target;
87 int resize_initiated;
88
89 /*
90 * Variables needed for add and remove fast-paths.
91 */
92 int flags;
93 unsigned long min_alloc_buckets_order;
94 unsigned long min_nr_alloc_buckets;
95 struct ht_items_count *split_count; /* split item count */
96
97 /*
98 * Variables needed for the lookup, add and remove fast-paths.
99 */
100 unsigned long size; /* always a power of 2, shared (RCU) */
101 /*
102 * bucket_at pointer is kept here to skip the extra level of
103 * dereference needed to get to "mm" (this is a fast-path).
104 */
105 struct cds_lfht_node *(*bucket_at)(struct cds_lfht *ht,
106 unsigned long index);
107 /*
108 * Dynamic length "tbl_chunk" needs to be at the end of
109 * cds_lfht.
110 */
111 union {
112 /*
113 * Contains the per order-index-level bucket node table.
114 * The size of each bucket node table is half the number
115 * of hashes contained in this order (except for order 0).
116 * The minimum allocation buckets size parameter allows
117 * combining the bucket node arrays of the lowermost
118 * levels to improve cache locality for small index orders.
119 */
120 struct cds_lfht_node *tbl_order[MAX_TABLE_ORDER];
121
122 /*
123 * Contains the bucket node chunks. The size of each
124 * bucket node chunk is ->min_alloc_size (we avoid to
125 * allocate chunks with different size). Chunks improve
126 * cache locality for small index orders, and are more
127 * friendly with environments where allocation of large
128 * contiguous memory areas is challenging due to memory
129 * fragmentation concerns or inability to use virtual
130 * memory addressing.
131 */
132 struct cds_lfht_node *tbl_chunk[0];
133
134 /*
135 * Memory mapping with room for all possible buckets.
136 * Their memory is allocated when needed.
137 */
138 struct cds_lfht_node *tbl_mmap;
139 };
140 /*
141 * End of variables needed for the lookup, add and remove
142 * fast-paths.
143 */
144};
145
146extern unsigned int cds_lfht_fls_ulong(unsigned long x);
147extern int cds_lfht_get_count_order_ulong(unsigned long x);
148
149#ifdef POISON_FREE
150#define poison_free(ptr) \
151 do { \
152 if (ptr) { \
153 memset(ptr, 0x42, sizeof(*(ptr))); \
154 free(ptr); \
155 } \
156 } while (0)
157#else
158#define poison_free(ptr) free(ptr)
159#endif
160
161static inline
162struct cds_lfht *__default_alloc_cds_lfht(
163 const struct cds_lfht_mm_type *mm,
164 unsigned long cds_lfht_size,
165 unsigned long min_nr_alloc_buckets,
166 unsigned long max_nr_buckets)
167{
168 struct cds_lfht *ht;
169
170 ht = calloc(1, cds_lfht_size);
171 assert(ht);
172
173 ht->mm = mm;
174 ht->bucket_at = mm->bucket_at;
175 ht->min_nr_alloc_buckets = min_nr_alloc_buckets;
176 ht->min_alloc_buckets_order =
177 cds_lfht_get_count_order_ulong(min_nr_alloc_buckets);
178 ht->max_nr_buckets = max_nr_buckets;
179
180 return ht;
181}
182
183#endif /* _URCU_RCULFHASH_INTERNAL_H */
This page took 0.022574 seconds and 4 git commands to generate.