13d0407baSopenharmony_ci/* 23d0407baSopenharmony_ci * Copyright (c) 2021 Rockchip Electronics Co., Ltd. 33d0407baSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 43d0407baSopenharmony_ci * you may not use this file except in compliance with the License. 53d0407baSopenharmony_ci * You may obtain a copy of the License at 63d0407baSopenharmony_ci * 73d0407baSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 83d0407baSopenharmony_ci * 93d0407baSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 103d0407baSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 113d0407baSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 123d0407baSopenharmony_ci * See the License for the specific language governing permissions and 133d0407baSopenharmony_ci * limitations under the License. 143d0407baSopenharmony_ci */ 153d0407baSopenharmony_ci 163d0407baSopenharmony_ci#ifndef __MPP_HASH_H__ 173d0407baSopenharmony_ci#define __MPP_HASH_H__ 183d0407baSopenharmony_ci 193d0407baSopenharmony_ci#include <stdbool.h> 203d0407baSopenharmony_ci 213d0407baSopenharmony_ci#include "rk_type.h" 223d0407baSopenharmony_ci 233d0407baSopenharmony_ci#ifdef __cplusplus 243d0407baSopenharmony_ciextern "C" { 253d0407baSopenharmony_ci#endif 263d0407baSopenharmony_ci 273d0407baSopenharmony_ci#define GOLDEN_RATIO_32 0x61C88647 283d0407baSopenharmony_ci#define GOLDEN_RATIO_64 0x61C8864680B583EBull 293d0407baSopenharmony_ci 303d0407baSopenharmony_ci#if __SIZEOF_POINTER__ == 4 313d0407baSopenharmony_ci#define GOLDEN_RATIO_PRIME GOLDEN_RATIO_32 323d0407baSopenharmony_ci#define hash_long(val, bits) hash_32(val, bits) 333d0407baSopenharmony_ci#elif __SIZEOF_POINTER__ == 8 343d0407baSopenharmony_ci#define GOLDEN_RATIO_PRIME GOLDEN_RATIO_64 353d0407baSopenharmony_ci#define hash_long(val, bits) hash_64(val, bits) 363d0407baSopenharmony_ci#else 373d0407baSopenharmony_ci#error __SIZEOF_POINTER__ not 4 or 8 383d0407baSopenharmony_ci#endif 393d0407baSopenharmony_ci 403d0407baSopenharmony_ci#define typeof __typeof__ 413d0407baSopenharmony_ci 423d0407baSopenharmony_cistruct hlist_node { 433d0407baSopenharmony_ci struct hlist_node *next, **pprev; 443d0407baSopenharmony_ci}; 453d0407baSopenharmony_ci 463d0407baSopenharmony_cistruct hlist_head { 473d0407baSopenharmony_ci struct hlist_node *first; 483d0407baSopenharmony_ci}; 493d0407baSopenharmony_ci 503d0407baSopenharmony_ci#define HLIST_HEAD_INIT \ 513d0407baSopenharmony_ci { \ 523d0407baSopenharmony_ci .first = NULL \ 533d0407baSopenharmony_ci } 543d0407baSopenharmony_ci#define HLIST_HEAD(name) struct hlist_head name = {.first = NULL} 553d0407baSopenharmony_ci#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) 563d0407baSopenharmony_ci 573d0407baSopenharmony_ci#define LIST_POISON1 ((void *)0x100) 583d0407baSopenharmony_ci#define LIST_POISON2 ((void *)0x200) 593d0407baSopenharmony_ci 603d0407baSopenharmony_ci#define WRITE_ONCE(var, val) (*((volatile typeof(val) *)(&(var))) = (val)) 613d0407baSopenharmony_ci 623d0407baSopenharmony_ci#define READ_ONCE(var) (*((volatile typeof(var) *)(&(var)))) 633d0407baSopenharmony_ci 643d0407baSopenharmony_cistatic inline void INIT_HLIST_NODE(struct hlist_node *h) 653d0407baSopenharmony_ci{ 663d0407baSopenharmony_ci h->next = NULL; 673d0407baSopenharmony_ci h->pprev = NULL; 683d0407baSopenharmony_ci} 693d0407baSopenharmony_ci 703d0407baSopenharmony_cistatic inline int hlist_unhashed(const struct hlist_node *h) 713d0407baSopenharmony_ci{ 723d0407baSopenharmony_ci return !h->pprev; 733d0407baSopenharmony_ci} 743d0407baSopenharmony_ci 753d0407baSopenharmony_cistatic inline int hlist_empty(const struct hlist_head *h) 763d0407baSopenharmony_ci{ 773d0407baSopenharmony_ci return !h->first; 783d0407baSopenharmony_ci} 793d0407baSopenharmony_ci 803d0407baSopenharmony_cistatic inline void _hlist_del(struct hlist_node *n) 813d0407baSopenharmony_ci{ 823d0407baSopenharmony_ci struct hlist_node *next = n->next; 833d0407baSopenharmony_ci struct hlist_node **pprev = n->pprev; 843d0407baSopenharmony_ci 853d0407baSopenharmony_ci WRITE_ONCE(*pprev, next); 863d0407baSopenharmony_ci if (next) { 873d0407baSopenharmony_ci next->pprev = pprev; 883d0407baSopenharmony_ci } 893d0407baSopenharmony_ci} 903d0407baSopenharmony_ci 913d0407baSopenharmony_cistatic inline void hlist_del(struct hlist_node *n) 923d0407baSopenharmony_ci{ 933d0407baSopenharmony_ci _hlist_del(n); 943d0407baSopenharmony_ci n->next = (struct hlist_node *)LIST_POISON1; 953d0407baSopenharmony_ci n->pprev = (struct hlist_node **)LIST_POISON2; 963d0407baSopenharmony_ci} 973d0407baSopenharmony_ci 983d0407baSopenharmony_cistatic inline void hlist_del_init(struct hlist_node *n) 993d0407baSopenharmony_ci{ 1003d0407baSopenharmony_ci if (!hlist_unhashed(n)) { 1013d0407baSopenharmony_ci _hlist_del(n); 1023d0407baSopenharmony_ci INIT_HLIST_NODE(n); 1033d0407baSopenharmony_ci } 1043d0407baSopenharmony_ci} 1053d0407baSopenharmony_ci 1063d0407baSopenharmony_cistatic inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) 1073d0407baSopenharmony_ci{ 1083d0407baSopenharmony_ci struct hlist_node *first = h->first; 1093d0407baSopenharmony_ci n->next = first; 1103d0407baSopenharmony_ci if (first) { 1113d0407baSopenharmony_ci first->pprev = &n->next; 1123d0407baSopenharmony_ci } 1133d0407baSopenharmony_ci WRITE_ONCE(h->first, n); 1143d0407baSopenharmony_ci n->pprev = &h->first; 1153d0407baSopenharmony_ci} 1163d0407baSopenharmony_ci 1173d0407baSopenharmony_cistatic inline void hlist_add_before(struct hlist_node *n, struct hlist_node *next) 1183d0407baSopenharmony_ci{ 1193d0407baSopenharmony_ci n->pprev = next->pprev; 1203d0407baSopenharmony_ci n->next = next; 1213d0407baSopenharmony_ci next->pprev = &n->next; 1223d0407baSopenharmony_ci WRITE_ONCE(*(n->pprev), n); 1233d0407baSopenharmony_ci} 1243d0407baSopenharmony_ci 1253d0407baSopenharmony_cistatic inline void hlist_add_behind(struct hlist_node *n, struct hlist_node *prev) 1263d0407baSopenharmony_ci{ 1273d0407baSopenharmony_ci n->next = prev->next; 1283d0407baSopenharmony_ci WRITE_ONCE(prev->next, n); 1293d0407baSopenharmony_ci n->pprev = &prev->next; 1303d0407baSopenharmony_ci if (n->next) { 1313d0407baSopenharmony_ci n->next->pprev = &n->next; 1323d0407baSopenharmony_ci } 1333d0407baSopenharmony_ci} 1343d0407baSopenharmony_ci 1353d0407baSopenharmony_cistatic inline void hlist_add_fake(struct hlist_node *n) 1363d0407baSopenharmony_ci{ 1373d0407baSopenharmony_ci n->pprev = &n->next; 1383d0407baSopenharmony_ci} 1393d0407baSopenharmony_ci 1403d0407baSopenharmony_cistatic inline int hlist_fake(struct hlist_node *h) 1413d0407baSopenharmony_ci{ 1423d0407baSopenharmony_ci return h->pprev == &h->next; 1433d0407baSopenharmony_ci} 1443d0407baSopenharmony_ci 1453d0407baSopenharmony_cistatic inline int hlist_is_singular_node(struct hlist_node *n, struct hlist_head *h) 1463d0407baSopenharmony_ci{ 1473d0407baSopenharmony_ci return !n->next && n->pprev == &h->first; 1483d0407baSopenharmony_ci} 1493d0407baSopenharmony_ci 1503d0407baSopenharmony_cistatic inline void hlist_move_list(struct hlist_head *old, struct hlist_head *_new) 1513d0407baSopenharmony_ci{ 1523d0407baSopenharmony_ci _new->first = old->first; 1533d0407baSopenharmony_ci if (_new->first) { 1543d0407baSopenharmony_ci _new->first->pprev = &_new->first; 1553d0407baSopenharmony_ci } 1563d0407baSopenharmony_ci old->first = NULL; 1573d0407baSopenharmony_ci} 1583d0407baSopenharmony_ci 1593d0407baSopenharmony_ci#define hlist_entry(ptr, type, member) container_of(ptr, type, member) 1603d0407baSopenharmony_ci 1613d0407baSopenharmony_ci#define hlist_for_each(pos, head) for ((pos) = (head)->first; (pos); pos = (pos)->next) 1623d0407baSopenharmony_ci 1633d0407baSopenharmony_ci#define hlist_for_each_safe(pos, n, head) \ 1643d0407baSopenharmony_ci for ((pos) = (head)->first; (pos) && ( { \ 1653d0407baSopenharmony_ci n = (pos)->next; \ 1663d0407baSopenharmony_ci 1; \ 1673d0407baSopenharmony_ci }); \ 1683d0407baSopenharmony_ci pos = n) 1693d0407baSopenharmony_ci 1703d0407baSopenharmony_ci#define hlist_entry_safe(ptr, type, member) \ 1713d0407baSopenharmony_ci ( { \ 1723d0407baSopenharmony_ci typeof(ptr) ____ptr = (ptr); \ 1733d0407baSopenharmony_ci ____ptr ? hlist_entry(____ptr, type, member) : NULL; \ 1743d0407baSopenharmony_ci }) 1753d0407baSopenharmony_ci 1763d0407baSopenharmony_ci#define hlist_for_each_entry(pos, head, member) \ 1773d0407baSopenharmony_ci do { \ 1783d0407baSopenharmony_ci for ((pos) = hlist_entry_safe((head)->first, typeof(*(pos)), member); pos; \ 1793d0407baSopenharmony_ci pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) \ 1803d0407baSopenharmony_ci } while (0) 1813d0407baSopenharmony_ci 1823d0407baSopenharmony_ci#define hlist_for_each_entry_continue(pos, member) \ 1833d0407baSopenharmony_ci do { \ 1843d0407baSopenharmony_ci for ((pos) = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member); pos; \ 1853d0407baSopenharmony_ci pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) \ 1863d0407baSopenharmony_ci } while (0) 1873d0407baSopenharmony_ci 1883d0407baSopenharmony_ci#define hlist_for_each_entry_from(pos, member) \ 1893d0407baSopenharmony_ci do { \ 1903d0407baSopenharmony_ci for (; pos; pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) \ 1913d0407baSopenharmony_ci } while (0) 1923d0407baSopenharmony_ci 1933d0407baSopenharmony_ci#define hlist_for_each_entry_safe(pos, n, head, member) \ 1943d0407baSopenharmony_ci do { \ 1953d0407baSopenharmony_ci for ((pos) = hlist_entry_safe((head)->first, typeof(*(pos)), member); (pos) && ( { \ 1963d0407baSopenharmony_ci n = (pos)->member.next; \ 1973d0407baSopenharmony_ci 1; \ 1983d0407baSopenharmony_ci }); \ 1993d0407baSopenharmony_ci (pos) = hlist_entry_safe(n, typeof(*(pos)), member)) \ 2003d0407baSopenharmony_ci } while (0) 2013d0407baSopenharmony_ci 2023d0407baSopenharmony_ci#define DEFINE_HASHTABLE(name, bits) \ 2033d0407baSopenharmony_ci struct hlist_head name[1 << (bits)] = {[0 ...((1 << (bits)) - 1)] = HLIST_HEAD_INIT} 2043d0407baSopenharmony_ci 2053d0407baSopenharmony_ci#define DECLARE_HASHTABLE(name, bits) struct hlist_head name[1 << (bits)] 2063d0407baSopenharmony_ci 2073d0407baSopenharmony_ci#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 2083d0407baSopenharmony_ci 2093d0407baSopenharmony_ci#define ilog2(n) \ 2103d0407baSopenharmony_ci ((n) & (1ULL << 63) ? 63 \ 2113d0407baSopenharmony_ci : (n) & (1ULL << 62) ? 62 \ 2123d0407baSopenharmony_ci : (n) & (1ULL << 61) ? 61 \ 2133d0407baSopenharmony_ci : (n) & (1ULL << 60) ? 60 \ 2143d0407baSopenharmony_ci : (n) & (1ULL << 59) ? 59 \ 2153d0407baSopenharmony_ci : (n) & (1ULL << 58) ? 58 \ 2163d0407baSopenharmony_ci : (n) & (1ULL << 57) ? 57 \ 2173d0407baSopenharmony_ci : (n) & (1ULL << 56) ? 56 \ 2183d0407baSopenharmony_ci : (n) & (1ULL << 55) ? 55 \ 2193d0407baSopenharmony_ci : (n) & (1ULL << 54) ? 54 \ 2203d0407baSopenharmony_ci : (n) & (1ULL << 53) ? 53 \ 2213d0407baSopenharmony_ci : (n) & (1ULL << 52) ? 52 \ 2223d0407baSopenharmony_ci : (n) & (1ULL << 51) ? 51 \ 2233d0407baSopenharmony_ci : (n) & (1ULL << 50) ? 50 \ 2243d0407baSopenharmony_ci : (n) & (1ULL << 49) ? 49 \ 2253d0407baSopenharmony_ci : (n) & (1ULL << 48) ? 48 \ 2263d0407baSopenharmony_ci : (n) & (1ULL << 47) ? 47 \ 2273d0407baSopenharmony_ci : (n) & (1ULL << 46) ? 46 \ 2283d0407baSopenharmony_ci : (n) & (1ULL << 45) ? 45 \ 2293d0407baSopenharmony_ci : (n) & (1ULL << 44) ? 44 \ 2303d0407baSopenharmony_ci : (n) & (1ULL << 43) ? 43 \ 2313d0407baSopenharmony_ci : (n) & (1ULL << 42) ? 42 \ 2323d0407baSopenharmony_ci : (n) & (1ULL << 41) ? 41 \ 2333d0407baSopenharmony_ci : (n) & (1ULL << 40) ? 40 \ 2343d0407baSopenharmony_ci : (n) & (1ULL << 39) ? 39 \ 2353d0407baSopenharmony_ci : (n) & (1ULL << 38) ? 38 \ 2363d0407baSopenharmony_ci : (n) & (1ULL << 37) ? 37 \ 2373d0407baSopenharmony_ci : (n) & (1ULL << 36) ? 36 \ 2383d0407baSopenharmony_ci : (n) & (1ULL << 35) ? 35 \ 2393d0407baSopenharmony_ci : (n) & (1ULL << 34) ? 34 \ 2403d0407baSopenharmony_ci : (n) & (1ULL << 33) ? 33 \ 2413d0407baSopenharmony_ci : (n) & (1ULL << 32) ? 32 \ 2423d0407baSopenharmony_ci : (n) & (1ULL << 31) ? 31 \ 2433d0407baSopenharmony_ci : (n) & (1ULL << 30) ? 30 \ 2443d0407baSopenharmony_ci : (n) & (1ULL << 29) ? 29 \ 2453d0407baSopenharmony_ci : (n) & (1ULL << 28) ? 28 \ 2463d0407baSopenharmony_ci : (n) & (1ULL << 27) ? 27 \ 2473d0407baSopenharmony_ci : (n) & (1ULL << 26) ? 26 \ 2483d0407baSopenharmony_ci : (n) & (1ULL << 25) ? 25 \ 2493d0407baSopenharmony_ci : (n) & (1ULL << 24) ? 24 \ 2503d0407baSopenharmony_ci : (n) & (1ULL << 23) ? 23 \ 2513d0407baSopenharmony_ci : (n) & (1ULL << 22) ? 22 \ 2523d0407baSopenharmony_ci : (n) & (1ULL << 21) ? 21 \ 2533d0407baSopenharmony_ci : (n) & (1ULL << 20) ? 20 \ 2543d0407baSopenharmony_ci : (n) & (1ULL << 19) ? 19 \ 2553d0407baSopenharmony_ci : (n) & (1ULL << 18) ? 18 \ 2563d0407baSopenharmony_ci : (n) & (1ULL << 17) ? 17 \ 2573d0407baSopenharmony_ci : (n) & (1ULL << 16) ? 16 \ 2583d0407baSopenharmony_ci : (n) & (1ULL << 15) ? 15 \ 2593d0407baSopenharmony_ci : (n) & (1ULL << 14) ? 14 \ 2603d0407baSopenharmony_ci : (n) & (1ULL << 13) ? 13 \ 2613d0407baSopenharmony_ci : (n) & (1ULL << 12) ? 12 \ 2623d0407baSopenharmony_ci : (n) & (1ULL << 11) ? 11 \ 2633d0407baSopenharmony_ci : (n) & (1ULL << 10) ? 10 \ 2643d0407baSopenharmony_ci : (n) & (1ULL << 9) ? 9 \ 2653d0407baSopenharmony_ci : (n) & (1ULL << 8) ? 8 \ 2663d0407baSopenharmony_ci : (n) & (1ULL << 7) ? 7 \ 2673d0407baSopenharmony_ci : (n) & (1ULL << 6) ? 6 \ 2683d0407baSopenharmony_ci : (n) & (1ULL << 5) ? 5 \ 2693d0407baSopenharmony_ci : (n) & (1ULL << 4) ? 4 \ 2703d0407baSopenharmony_ci : (n) & (1ULL << 3) ? 3 \ 2713d0407baSopenharmony_ci : (n) & (1ULL << 2) ? 2 \ 2723d0407baSopenharmony_ci : (n) & (1ULL << 1) ? 1 \ 2733d0407baSopenharmony_ci : 0) 2743d0407baSopenharmony_ci 2753d0407baSopenharmony_ci#define HASH_SIZE(name) (ARRAY_SIZE(name)) 2763d0407baSopenharmony_ci#define HASH_BITS(name) ilog2(HASH_SIZE(name)) 2773d0407baSopenharmony_ci 2783d0407baSopenharmony_ci/* Use hash_32 when possible to allow for fast 32bit hashing in 64bit kernels. */ 2793d0407baSopenharmony_ci#define hash_min(val, bits) (sizeof(val) <= 4 ? hash_32(val, bits) : hash_long(val, bits)) 2803d0407baSopenharmony_ci 2813d0407baSopenharmony_ci#define hash_add(hashtable, node, key) hlist_add_head(node, &(hashtable)[hash_min(key, HASH_BITS(hashtable))]) 2823d0407baSopenharmony_ci 2833d0407baSopenharmony_ci/** 2843d0407baSopenharmony_ci * hash_empty - check whether a hashtable is empty 2853d0407baSopenharmony_ci * @hashtable: hashtable to check 2863d0407baSopenharmony_ci * 2873d0407baSopenharmony_ci * This has to be a macro since HASH_BITS() will not work on pointers since 2883d0407baSopenharmony_ci * it calculates the size during preprocessing. 2893d0407baSopenharmony_ci */ 2903d0407baSopenharmony_ci#define hash_empty(hashtable) _hash_empty(hashtable, HASH_SIZE(hashtable)) 2913d0407baSopenharmony_ci 2923d0407baSopenharmony_ci/** 2933d0407baSopenharmony_ci * hash_for_each - iterate over a hashtable 2943d0407baSopenharmony_ci * @name: hashtable to iterate 2953d0407baSopenharmony_ci * @bkt: integer to use as bucket loop cursor 2963d0407baSopenharmony_ci * @obj: the type * to use as a loop cursor for each entry 2973d0407baSopenharmony_ci * @member: the name of the hlist_node within the struct 2983d0407baSopenharmony_ci */ 2993d0407baSopenharmony_ci#define hash_for_each(name, bkt, obj, member) \ 3003d0407baSopenharmony_ci for ((bkt) = 0, (obj) = NULL; (obj) == NULL && (bkt) < HASH_SIZE(name); (bkt)++) \ 3013d0407baSopenharmony_ci hlist_for_each_entry((obj), &(name)[bkt], member) 3023d0407baSopenharmony_ci 3033d0407baSopenharmony_ci/** 3043d0407baSopenharmony_ci * hash_for_each_safe - iterate over a hashtable safe against removal of 3053d0407baSopenharmony_ci * hash entry 3063d0407baSopenharmony_ci * @name: hashtable to iterate 3073d0407baSopenharmony_ci * @bkt: integer to use as bucket loop cursor 3083d0407baSopenharmony_ci * @tmp: a &struct used for temporary storage 3093d0407baSopenharmony_ci * @obj: the type * to use as a loop cursor for each entry 3103d0407baSopenharmony_ci * @member: the name of the hlist_node within the struct 3113d0407baSopenharmony_ci */ 3123d0407baSopenharmony_ci#define hash_for_each_safe(name, bkt, tmp, obj, member) \ 3133d0407baSopenharmony_ci for ((bkt) = 0, (obj) = NULL; (obj) == NULL && (bkt) < HASH_SIZE(name); (bkt)++) \ 3143d0407baSopenharmony_ci hlist_for_each_entry_safe((obj), (tmp), &(name)[bkt], (member)) 3153d0407baSopenharmony_ci 3163d0407baSopenharmony_ci#define hash_for_each_possible(name, obj, member, key) \ 3173d0407baSopenharmony_ci hlist_for_each_entry((obj), &(name)[hash_min((key), HASH_BITS(name))], (member)) 3183d0407baSopenharmony_ci 3193d0407baSopenharmony_cistatic inline unsigned int hash_32(unsigned int val, unsigned int bits) 3203d0407baSopenharmony_ci{ 3213d0407baSopenharmony_ci /* On some cpus multiply is faster, on others gcc will do shifts */ 3223d0407baSopenharmony_ci unsigned int hash = val * GOLDEN_RATIO_32; 3233d0407baSopenharmony_ci 3243d0407baSopenharmony_ci /* High bits are more random, so use them. */ 3253d0407baSopenharmony_ci return hash >> (32 - bits); // (32 - bits) 3263d0407baSopenharmony_ci} 3273d0407baSopenharmony_ci 3283d0407baSopenharmony_cistatic inline unsigned int _hash_32(unsigned int val) 3293d0407baSopenharmony_ci{ 3303d0407baSopenharmony_ci return val * GOLDEN_RATIO_32; 3313d0407baSopenharmony_ci} 3323d0407baSopenharmony_ci 3333d0407baSopenharmony_cistatic inline unsigned int hash_64(RK_U64 val, unsigned int bits) 3343d0407baSopenharmony_ci{ 3353d0407baSopenharmony_ci#if __SIZEOF_POINTER__ == 8 3363d0407baSopenharmony_ci /* 64x64-bit multiply is efficient on all 64-bit processors */ 3373d0407baSopenharmony_ci return (val * GOLDEN_RATIO_64) >> (64 - bits); 3383d0407baSopenharmony_ci#else 3393d0407baSopenharmony_ci /* Hash 64 bits using only 32x32-bit multiply. */ 3403d0407baSopenharmony_ci return hash_32((unsigned int)val ^ ((val >> 32) * GOLDEN_RATIO_32), bits); 3413d0407baSopenharmony_ci#endif 3423d0407baSopenharmony_ci} 3433d0407baSopenharmony_ci 3443d0407baSopenharmony_cistatic inline unsigned int hash_ptr(const void *ptr, unsigned int bits) 3453d0407baSopenharmony_ci{ 3463d0407baSopenharmony_ci return hash_long((unsigned long)ptr, bits); 3473d0407baSopenharmony_ci} 3483d0407baSopenharmony_ci 3493d0407baSopenharmony_ci/* This really should be called fold32_ptr; it does no hashing to speak of. */ 3503d0407baSopenharmony_cistatic inline unsigned int hash32_ptr(const void *ptr) 3513d0407baSopenharmony_ci{ 3523d0407baSopenharmony_ci unsigned long val = (unsigned long)ptr; 3533d0407baSopenharmony_ci 3543d0407baSopenharmony_ci#if __SIZEOF_POINTER__ == 8 3553d0407baSopenharmony_ci val ^= (val >> 32); // (val >> 32) 3563d0407baSopenharmony_ci#endif 3573d0407baSopenharmony_ci return (unsigned int)val; 3583d0407baSopenharmony_ci} 3593d0407baSopenharmony_ci 3603d0407baSopenharmony_ci/** 3613d0407baSopenharmony_ci * hash_hashed - check whether an object is in any hashtable 3623d0407baSopenharmony_ci * @node: the &struct hlist_node of the object to be checked 3633d0407baSopenharmony_ci */ 3643d0407baSopenharmony_cistatic inline bool hash_hashed(struct hlist_node *node) 3653d0407baSopenharmony_ci{ 3663d0407baSopenharmony_ci return !hlist_unhashed(node); 3673d0407baSopenharmony_ci} 3683d0407baSopenharmony_ci 3693d0407baSopenharmony_cistatic inline bool _hash_empty(struct hlist_head *ht, unsigned int sz) 3703d0407baSopenharmony_ci{ 3713d0407baSopenharmony_ci unsigned int i; 3723d0407baSopenharmony_ci 3733d0407baSopenharmony_ci for (i = 0; i < sz; i++) { 3743d0407baSopenharmony_ci if (!hlist_empty(&ht[i])) { 3753d0407baSopenharmony_ci return false; 3763d0407baSopenharmony_ci } 3773d0407baSopenharmony_ci } 3783d0407baSopenharmony_ci return true; 3793d0407baSopenharmony_ci} 3803d0407baSopenharmony_ci 3813d0407baSopenharmony_ci/** 3823d0407baSopenharmony_ci * hash_del - remove an object from a hashtable 3833d0407baSopenharmony_ci * @node: &struct hlist_node of the object to remove 3843d0407baSopenharmony_ci */ 3853d0407baSopenharmony_cistatic inline void hash_del(struct hlist_node *node) 3863d0407baSopenharmony_ci{ 3873d0407baSopenharmony_ci hlist_del_init(node); 3883d0407baSopenharmony_ci} 3893d0407baSopenharmony_ci 3903d0407baSopenharmony_ci#ifdef __cplusplus 3913d0407baSopenharmony_ci} 3923d0407baSopenharmony_ci#endif 3933d0407baSopenharmony_ci 3943d0407baSopenharmony_ci#endif 395