xref: /OK3568_Linux_fs/external/mpp/osal/inc/mpp_hash.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright 2021 Rockchip Electronics Co. LTD
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Licensed under the Apache License, Version 2.0 (the "License");
5*4882a593Smuzhiyun  * you may not use this file except in compliance with the License.
6*4882a593Smuzhiyun  * You may obtain a copy of the License at
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  *      http://www.apache.org/licenses/LICENSE-2.0
9*4882a593Smuzhiyun  *
10*4882a593Smuzhiyun  * Unless required by applicable law or agreed to in writing, software
11*4882a593Smuzhiyun  * distributed under the License is distributed on an "AS IS" BASIS,
12*4882a593Smuzhiyun  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4882a593Smuzhiyun  * See the License for the specific language governing permissions and
14*4882a593Smuzhiyun  * limitations under the License.
15*4882a593Smuzhiyun  */
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #ifndef __MPP_HASH_H__
18*4882a593Smuzhiyun #define __MPP_HASH_H__
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #include <stdbool.h>
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #include "rk_type.h"
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun #ifdef __cplusplus
25*4882a593Smuzhiyun extern "C" {
26*4882a593Smuzhiyun #endif
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun #define GOLDEN_RATIO_32 0x61C88647
29*4882a593Smuzhiyun #define GOLDEN_RATIO_64 0x61C8864680B583EBull
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun #if __SIZEOF_POINTER__ == 4
32*4882a593Smuzhiyun #define GOLDEN_RATIO_PRIME GOLDEN_RATIO_32
33*4882a593Smuzhiyun #define hash_long(val, bits) hash_32(val, bits)
34*4882a593Smuzhiyun #elif __SIZEOF_POINTER__ == 8
35*4882a593Smuzhiyun #define GOLDEN_RATIO_PRIME GOLDEN_RATIO_64
36*4882a593Smuzhiyun #define hash_long(val, bits) hash_64(val, bits)
37*4882a593Smuzhiyun #else
38*4882a593Smuzhiyun #error __SIZEOF_POINTER__ not 4 or 8
39*4882a593Smuzhiyun #endif
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun struct hlist_node {
42*4882a593Smuzhiyun     struct hlist_node *next, **pprev;
43*4882a593Smuzhiyun };
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun struct hlist_head {
46*4882a593Smuzhiyun     struct hlist_node *first;
47*4882a593Smuzhiyun };
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun #define HLIST_HEAD_INIT { .first = NULL }
50*4882a593Smuzhiyun #define HLIST_HEAD(name) struct hlist_head name = {  .first = NULL }
51*4882a593Smuzhiyun #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun #define LIST_POISON1  ((void *) 0x100)
54*4882a593Smuzhiyun #define LIST_POISON2  ((void *) 0x200)
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun #define WRITE_ONCE(var, val) \
57*4882a593Smuzhiyun     (*((volatile typeof(val) *)(&(var))) = (val))
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun #define READ_ONCE(var) (*((volatile typeof(var) *)(&(var))))
60*4882a593Smuzhiyun 
INIT_HLIST_NODE(struct hlist_node * h)61*4882a593Smuzhiyun static inline void INIT_HLIST_NODE(struct hlist_node *h)
62*4882a593Smuzhiyun {
63*4882a593Smuzhiyun     h->next = NULL;
64*4882a593Smuzhiyun     h->pprev = NULL;
65*4882a593Smuzhiyun }
66*4882a593Smuzhiyun 
hlist_unhashed(const struct hlist_node * h)67*4882a593Smuzhiyun static inline int hlist_unhashed(const struct hlist_node *h)
68*4882a593Smuzhiyun {
69*4882a593Smuzhiyun     return !h->pprev;
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun 
hlist_empty(const struct hlist_head * h)72*4882a593Smuzhiyun static inline int hlist_empty(const struct hlist_head *h)
73*4882a593Smuzhiyun {
74*4882a593Smuzhiyun     return !READ_ONCE(h->first);
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun 
__hlist_del(struct hlist_node * n)77*4882a593Smuzhiyun static inline void __hlist_del(struct hlist_node *n)
78*4882a593Smuzhiyun {
79*4882a593Smuzhiyun     struct hlist_node *next = n->next;
80*4882a593Smuzhiyun     struct hlist_node **pprev = n->pprev;
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun     WRITE_ONCE(*pprev, next);
83*4882a593Smuzhiyun     if (next)
84*4882a593Smuzhiyun         next->pprev = pprev;
85*4882a593Smuzhiyun }
86*4882a593Smuzhiyun 
hlist_del(struct hlist_node * n)87*4882a593Smuzhiyun static inline void hlist_del(struct hlist_node *n)
88*4882a593Smuzhiyun {
89*4882a593Smuzhiyun     __hlist_del(n);
90*4882a593Smuzhiyun     n->next = (struct hlist_node*)LIST_POISON1;
91*4882a593Smuzhiyun     n->pprev = (struct hlist_node**)LIST_POISON2;
92*4882a593Smuzhiyun }
93*4882a593Smuzhiyun 
hlist_del_init(struct hlist_node * n)94*4882a593Smuzhiyun static inline void hlist_del_init(struct hlist_node *n)
95*4882a593Smuzhiyun {
96*4882a593Smuzhiyun     if (!hlist_unhashed(n)) {
97*4882a593Smuzhiyun         __hlist_del(n);
98*4882a593Smuzhiyun         INIT_HLIST_NODE(n);
99*4882a593Smuzhiyun     }
100*4882a593Smuzhiyun }
101*4882a593Smuzhiyun 
hlist_add_head(struct hlist_node * n,struct hlist_head * h)102*4882a593Smuzhiyun static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
103*4882a593Smuzhiyun {
104*4882a593Smuzhiyun     struct hlist_node *first = h->first;
105*4882a593Smuzhiyun     n->next = first;
106*4882a593Smuzhiyun     if (first)
107*4882a593Smuzhiyun         first->pprev = &n->next;
108*4882a593Smuzhiyun     WRITE_ONCE(h->first, n);
109*4882a593Smuzhiyun     n->pprev = &h->first;
110*4882a593Smuzhiyun }
111*4882a593Smuzhiyun 
hlist_add_before(struct hlist_node * n,struct hlist_node * next)112*4882a593Smuzhiyun static inline void hlist_add_before(struct hlist_node *n, struct hlist_node *next)
113*4882a593Smuzhiyun {
114*4882a593Smuzhiyun     n->pprev = next->pprev;
115*4882a593Smuzhiyun     n->next = next;
116*4882a593Smuzhiyun     next->pprev = &n->next;
117*4882a593Smuzhiyun     WRITE_ONCE(*(n->pprev), n);
118*4882a593Smuzhiyun }
119*4882a593Smuzhiyun 
hlist_add_behind(struct hlist_node * n,struct hlist_node * prev)120*4882a593Smuzhiyun static inline void hlist_add_behind(struct hlist_node *n, struct hlist_node *prev)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun     n->next = prev->next;
123*4882a593Smuzhiyun     WRITE_ONCE(prev->next, n);
124*4882a593Smuzhiyun     n->pprev = &prev->next;
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun     if (n->next)
127*4882a593Smuzhiyun         n->next->pprev  = &n->next;
128*4882a593Smuzhiyun }
129*4882a593Smuzhiyun 
hlist_add_fake(struct hlist_node * n)130*4882a593Smuzhiyun static inline void hlist_add_fake(struct hlist_node *n)
131*4882a593Smuzhiyun {
132*4882a593Smuzhiyun     n->pprev = &n->next;
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun 
hlist_fake(struct hlist_node * h)135*4882a593Smuzhiyun static inline int hlist_fake(struct hlist_node *h)
136*4882a593Smuzhiyun {
137*4882a593Smuzhiyun     return h->pprev == &h->next;
138*4882a593Smuzhiyun }
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun static inline int
hlist_is_singular_node(struct hlist_node * n,struct hlist_head * h)141*4882a593Smuzhiyun hlist_is_singular_node(struct hlist_node *n, struct hlist_head *h)
142*4882a593Smuzhiyun {
143*4882a593Smuzhiyun     return !n->next && n->pprev == &h->first;
144*4882a593Smuzhiyun }
145*4882a593Smuzhiyun 
hlist_move_list(struct hlist_head * old,struct hlist_head * _new)146*4882a593Smuzhiyun static inline void hlist_move_list(struct hlist_head *old,
147*4882a593Smuzhiyun                                    struct hlist_head *_new)
148*4882a593Smuzhiyun {
149*4882a593Smuzhiyun     _new->first = old->first;
150*4882a593Smuzhiyun     if (_new->first)
151*4882a593Smuzhiyun         _new->first->pprev = &_new->first;
152*4882a593Smuzhiyun     old->first = NULL;
153*4882a593Smuzhiyun }
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun #define hlist_for_each(pos, head) \
158*4882a593Smuzhiyun     for (pos = (head)->first; pos ; pos = pos->next)
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun #define hlist_for_each_safe(pos, n, head) \
161*4882a593Smuzhiyun     for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
162*4882a593Smuzhiyun          pos = n)
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun #define hlist_entry_safe(ptr, type, member) \
165*4882a593Smuzhiyun     ({ typeof(ptr) ____ptr = (ptr); \
166*4882a593Smuzhiyun        ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
167*4882a593Smuzhiyun     })
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun #define hlist_for_each_entry(pos, head, member)             \
170*4882a593Smuzhiyun     for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\
171*4882a593Smuzhiyun          pos;                           \
172*4882a593Smuzhiyun          pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun #define hlist_for_each_entry_continue(pos, member)          \
175*4882a593Smuzhiyun     for (pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member);\
176*4882a593Smuzhiyun          pos;                           \
177*4882a593Smuzhiyun          pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun #define hlist_for_each_entry_from(pos, member)              \
180*4882a593Smuzhiyun     for (; pos;                         \
181*4882a593Smuzhiyun          pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun #define hlist_for_each_entry_safe(pos, n, head, member)         \
184*4882a593Smuzhiyun     for (pos = hlist_entry_safe((head)->first, typeof(*pos), member);\
185*4882a593Smuzhiyun          pos && ({ n = pos->member.next; 1; });         \
186*4882a593Smuzhiyun          pos = hlist_entry_safe(n, typeof(*pos), member))
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun #define DEFINE_HASHTABLE(name, bits) \
189*4882a593Smuzhiyun     struct hlist_head name[1 << (bits)] = \
190*4882a593Smuzhiyun             { [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT }
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun #define DECLARE_HASHTABLE(name, bits) \
193*4882a593Smuzhiyun     struct hlist_head name[1 << (bits)]
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun #define ilog2(n) \
198*4882a593Smuzhiyun     ( \
199*4882a593Smuzhiyun         (n) & (1ULL << 63) ? 63 : \
200*4882a593Smuzhiyun         (n) & (1ULL << 62) ? 62 : \
201*4882a593Smuzhiyun         (n) & (1ULL << 61) ? 61 : \
202*4882a593Smuzhiyun         (n) & (1ULL << 60) ? 60 : \
203*4882a593Smuzhiyun         (n) & (1ULL << 59) ? 59 : \
204*4882a593Smuzhiyun         (n) & (1ULL << 58) ? 58 : \
205*4882a593Smuzhiyun         (n) & (1ULL << 57) ? 57 : \
206*4882a593Smuzhiyun         (n) & (1ULL << 56) ? 56 : \
207*4882a593Smuzhiyun         (n) & (1ULL << 55) ? 55 : \
208*4882a593Smuzhiyun         (n) & (1ULL << 54) ? 54 : \
209*4882a593Smuzhiyun         (n) & (1ULL << 53) ? 53 : \
210*4882a593Smuzhiyun         (n) & (1ULL << 52) ? 52 : \
211*4882a593Smuzhiyun         (n) & (1ULL << 51) ? 51 : \
212*4882a593Smuzhiyun         (n) & (1ULL << 50) ? 50 : \
213*4882a593Smuzhiyun         (n) & (1ULL << 49) ? 49 : \
214*4882a593Smuzhiyun         (n) & (1ULL << 48) ? 48 : \
215*4882a593Smuzhiyun         (n) & (1ULL << 47) ? 47 : \
216*4882a593Smuzhiyun         (n) & (1ULL << 46) ? 46 : \
217*4882a593Smuzhiyun         (n) & (1ULL << 45) ? 45 : \
218*4882a593Smuzhiyun         (n) & (1ULL << 44) ? 44 : \
219*4882a593Smuzhiyun         (n) & (1ULL << 43) ? 43 : \
220*4882a593Smuzhiyun         (n) & (1ULL << 42) ? 42 : \
221*4882a593Smuzhiyun         (n) & (1ULL << 41) ? 41 : \
222*4882a593Smuzhiyun         (n) & (1ULL << 40) ? 40 : \
223*4882a593Smuzhiyun         (n) & (1ULL << 39) ? 39 : \
224*4882a593Smuzhiyun         (n) & (1ULL << 38) ? 38 : \
225*4882a593Smuzhiyun         (n) & (1ULL << 37) ? 37 : \
226*4882a593Smuzhiyun         (n) & (1ULL << 36) ? 36 : \
227*4882a593Smuzhiyun         (n) & (1ULL << 35) ? 35 : \
228*4882a593Smuzhiyun         (n) & (1ULL << 34) ? 34 : \
229*4882a593Smuzhiyun         (n) & (1ULL << 33) ? 33 : \
230*4882a593Smuzhiyun         (n) & (1ULL << 32) ? 32 : \
231*4882a593Smuzhiyun         (n) & (1ULL << 31) ? 31 : \
232*4882a593Smuzhiyun         (n) & (1ULL << 30) ? 30 : \
233*4882a593Smuzhiyun         (n) & (1ULL << 29) ? 29 : \
234*4882a593Smuzhiyun         (n) & (1ULL << 28) ? 28 : \
235*4882a593Smuzhiyun         (n) & (1ULL << 27) ? 27 : \
236*4882a593Smuzhiyun         (n) & (1ULL << 26) ? 26 : \
237*4882a593Smuzhiyun         (n) & (1ULL << 25) ? 25 : \
238*4882a593Smuzhiyun         (n) & (1ULL << 24) ? 24 : \
239*4882a593Smuzhiyun         (n) & (1ULL << 23) ? 23 : \
240*4882a593Smuzhiyun         (n) & (1ULL << 22) ? 22 : \
241*4882a593Smuzhiyun         (n) & (1ULL << 21) ? 21 : \
242*4882a593Smuzhiyun         (n) & (1ULL << 20) ? 20 : \
243*4882a593Smuzhiyun         (n) & (1ULL << 19) ? 19 : \
244*4882a593Smuzhiyun         (n) & (1ULL << 18) ? 18 : \
245*4882a593Smuzhiyun         (n) & (1ULL << 17) ? 17 : \
246*4882a593Smuzhiyun         (n) & (1ULL << 16) ? 16 : \
247*4882a593Smuzhiyun         (n) & (1ULL << 15) ? 15 : \
248*4882a593Smuzhiyun         (n) & (1ULL << 14) ? 14 : \
249*4882a593Smuzhiyun         (n) & (1ULL << 13) ? 13 : \
250*4882a593Smuzhiyun         (n) & (1ULL << 12) ? 12 : \
251*4882a593Smuzhiyun         (n) & (1ULL << 11) ? 11 : \
252*4882a593Smuzhiyun         (n) & (1ULL << 10) ? 10 : \
253*4882a593Smuzhiyun         (n) & (1ULL << 9) ? 9 : \
254*4882a593Smuzhiyun         (n) & (1ULL << 8) ? 8 : \
255*4882a593Smuzhiyun         (n) & (1ULL << 7) ? 7 : \
256*4882a593Smuzhiyun         (n) & (1ULL << 6) ? 6 : \
257*4882a593Smuzhiyun         (n) & (1ULL << 5) ? 5 : \
258*4882a593Smuzhiyun         (n) & (1ULL << 4) ? 4 : \
259*4882a593Smuzhiyun         (n) & (1ULL << 3) ? 3 : \
260*4882a593Smuzhiyun         (n) & (1ULL << 2) ? 2 : \
261*4882a593Smuzhiyun         (n) & (1ULL << 1) ? 1 : 0 \
262*4882a593Smuzhiyun     )
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun #define HASH_SIZE(name) (ARRAY_SIZE(name))
265*4882a593Smuzhiyun #define HASH_BITS(name) ilog2(HASH_SIZE(name))
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun /* Use hash_32 when possible to allow for fast 32bit hashing in 64bit kernels. */
268*4882a593Smuzhiyun #define hash_min(val, bits) \
269*4882a593Smuzhiyun     (sizeof(val) <= 4 ? hash_32(val, bits) : hash_long(val, bits))
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun #define hash_add(hashtable, node, key) \
272*4882a593Smuzhiyun     hlist_add_head(node, &hashtable[hash_min(key, HASH_BITS(hashtable))])
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun /**
275*4882a593Smuzhiyun  * hash_empty - check whether a hashtable is empty
276*4882a593Smuzhiyun  * @hashtable: hashtable to check
277*4882a593Smuzhiyun  *
278*4882a593Smuzhiyun  * This has to be a macro since HASH_BITS() will not work on pointers since
279*4882a593Smuzhiyun  * it calculates the size during preprocessing.
280*4882a593Smuzhiyun  */
281*4882a593Smuzhiyun #define hash_empty(hashtable) __hash_empty(hashtable, HASH_SIZE(hashtable))
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun /**
284*4882a593Smuzhiyun  * hash_for_each - iterate over a hashtable
285*4882a593Smuzhiyun  * @name: hashtable to iterate
286*4882a593Smuzhiyun  * @bkt: integer to use as bucket loop cursor
287*4882a593Smuzhiyun  * @obj: the type * to use as a loop cursor for each entry
288*4882a593Smuzhiyun  * @member: the name of the hlist_node within the struct
289*4882a593Smuzhiyun  */
290*4882a593Smuzhiyun #define hash_for_each(name, bkt, obj, member)                           \
291*4882a593Smuzhiyun     for ((bkt) = 0, obj = NULL; obj == NULL && (bkt) < HASH_SIZE(name); \
292*4882a593Smuzhiyun          (bkt)++)                                                       \
293*4882a593Smuzhiyun     hlist_for_each_entry(obj, &name[bkt], member)
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun /**
296*4882a593Smuzhiyun  * hash_for_each_safe - iterate over a hashtable safe against removal of
297*4882a593Smuzhiyun  * hash entry
298*4882a593Smuzhiyun  * @name: hashtable to iterate
299*4882a593Smuzhiyun  * @bkt: integer to use as bucket loop cursor
300*4882a593Smuzhiyun  * @tmp: a &struct used for temporary storage
301*4882a593Smuzhiyun  * @obj: the type * to use as a loop cursor for each entry
302*4882a593Smuzhiyun  * @member: the name of the hlist_node within the struct
303*4882a593Smuzhiyun  */
304*4882a593Smuzhiyun #define hash_for_each_safe(name, bkt, tmp, obj, member)                 \
305*4882a593Smuzhiyun     for ((bkt) = 0, obj = NULL; obj == NULL && (bkt) < HASH_SIZE(name); \
306*4882a593Smuzhiyun          (bkt)++)                                                       \
307*4882a593Smuzhiyun     hlist_for_each_entry_safe(obj, tmp, &name[bkt], member)
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun #define hash_for_each_possible(name, obj, member, key) \
310*4882a593Smuzhiyun     hlist_for_each_entry(obj, &name[hash_min(key, HASH_BITS(name))], member)
311*4882a593Smuzhiyun 
hash_32(RK_U32 val,unsigned int bits)312*4882a593Smuzhiyun static inline RK_U32 hash_32(RK_U32 val, unsigned int bits)
313*4882a593Smuzhiyun {
314*4882a593Smuzhiyun     /* On some cpus multiply is faster, on others gcc will do shifts */
315*4882a593Smuzhiyun     RK_U32 hash = val * GOLDEN_RATIO_32;
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun     /* High bits are more random, so use them. */
318*4882a593Smuzhiyun     return hash >> (32 - bits);
319*4882a593Smuzhiyun }
320*4882a593Smuzhiyun 
__hash_32(RK_U32 val)321*4882a593Smuzhiyun static inline RK_U32 __hash_32(RK_U32 val)
322*4882a593Smuzhiyun {
323*4882a593Smuzhiyun     return val * GOLDEN_RATIO_32;
324*4882a593Smuzhiyun }
325*4882a593Smuzhiyun 
hash_64(RK_U64 val,unsigned int bits)326*4882a593Smuzhiyun static inline RK_U32 hash_64(RK_U64 val, unsigned int bits)
327*4882a593Smuzhiyun {
328*4882a593Smuzhiyun #if __SIZEOF_POINTER__ == 8
329*4882a593Smuzhiyun     /* 64x64-bit multiply is efficient on all 64-bit processors */
330*4882a593Smuzhiyun     return val * GOLDEN_RATIO_64 >> (64 - bits);
331*4882a593Smuzhiyun #else
332*4882a593Smuzhiyun     /* Hash 64 bits using only 32x32-bit multiply. */
333*4882a593Smuzhiyun     return hash_32((RK_U32)val ^ ((val >> 32) * GOLDEN_RATIO_32), bits);
334*4882a593Smuzhiyun #endif
335*4882a593Smuzhiyun }
336*4882a593Smuzhiyun 
hash_ptr(const void * ptr,unsigned int bits)337*4882a593Smuzhiyun static inline RK_U32 hash_ptr(const void *ptr, unsigned int bits)
338*4882a593Smuzhiyun {
339*4882a593Smuzhiyun     return hash_long((unsigned long)ptr, bits);
340*4882a593Smuzhiyun }
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun /* This really should be called fold32_ptr; it does no hashing to speak of. */
hash32_ptr(const void * ptr)343*4882a593Smuzhiyun static inline RK_U32 hash32_ptr(const void *ptr)
344*4882a593Smuzhiyun {
345*4882a593Smuzhiyun     unsigned long val = (unsigned long)ptr;
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun #if __SIZEOF_POINTER__ == 8
348*4882a593Smuzhiyun     val ^= (val >> 32);
349*4882a593Smuzhiyun #endif
350*4882a593Smuzhiyun     return (RK_U32)val;
351*4882a593Smuzhiyun }
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun /**
354*4882a593Smuzhiyun  * hash_hashed - check whether an object is in any hashtable
355*4882a593Smuzhiyun  * @node: the &struct hlist_node of the object to be checked
356*4882a593Smuzhiyun  */
hash_hashed(struct hlist_node * node)357*4882a593Smuzhiyun static inline bool hash_hashed(struct hlist_node *node)
358*4882a593Smuzhiyun {
359*4882a593Smuzhiyun     return !hlist_unhashed(node);
360*4882a593Smuzhiyun }
361*4882a593Smuzhiyun 
__hash_empty(struct hlist_head * ht,unsigned int sz)362*4882a593Smuzhiyun static inline bool __hash_empty(struct hlist_head *ht, unsigned int sz)
363*4882a593Smuzhiyun {
364*4882a593Smuzhiyun     unsigned int i;
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun     for (i = 0; i < sz; i++)
367*4882a593Smuzhiyun         if (!hlist_empty(&ht[i]))
368*4882a593Smuzhiyun             return false;
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun     return true;
371*4882a593Smuzhiyun }
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun /**
374*4882a593Smuzhiyun  * hash_del - remove an object from a hashtable
375*4882a593Smuzhiyun  * @node: &struct hlist_node of the object to remove
376*4882a593Smuzhiyun  */
hash_del(struct hlist_node * node)377*4882a593Smuzhiyun static inline void hash_del(struct hlist_node *node)
378*4882a593Smuzhiyun {
379*4882a593Smuzhiyun     hlist_del_init(node);
380*4882a593Smuzhiyun }
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun #ifdef __cplusplus
383*4882a593Smuzhiyun }
384*4882a593Smuzhiyun #endif
385*4882a593Smuzhiyun 
386*4882a593Smuzhiyun #endif /*__MPP_HASH_H__*/
387