XenevaOS
Loading...
Searching...
No Matches
hashtable.h
Go to the documentation of this file.
1#ifndef __LINUX_HASHTABLE_H__
2#define __LINUX_HASHTABLE_H__
3
4/*
5 * DCL <linux/hashtable.h> -- the small open-chained table 8250_core.c keeps
6 * its per-irq port lists in:
7 *
8 * #define IRQ_HASH_BITS 5
9 * static DEFINE_HASHTABLE(irq_lists, IRQ_HASH_BITS);
10 * hash_add(irq_lists, &i->node, up->port.irq);
11 * hash_for_each_possible(irq_lists, obj, node, irq) ...
12 * hlist_del(&i->node);
13 *
14 * It needs three things to be right rather than to merely compile: both the
15 * add and the lookup must fold the key the same way (otherwise a port would
16 * be filed in one bucket and searched for in another and simply never be
17 * found), the bucket count must be a compile-time power of two, and the node
18 * unlink must tolerate a node that was never linked (8250_core.c:123 deletes
19 * a port it may not have inserted).
20 *
21 * hash_min() is therefore one macro used by both sides. Mainline folds with
22 * Fibonacci hashing; this is the plain mask. The two agree on which bucket a
23 * key belongs to -- only the spread differs, and 32 buckets over a handful of
24 * UARTs does not care about spread. HASH_BITS() gets its log2 from __builtin_ctz,
25 * which is exact for the power-of-two sizes DECLARE/DEFINE_HASHTABLE create.
26 */
27
28#include <linux/kernel.h> /* container_of */
29
30struct hlist_node {
32 struct hlist_node** pprev;
33};
34
35struct hlist_head {
37};
38
39#define INIT_HLIST_HEAD(head) do { (head)->first = 0; } while (0)
40#define INIT_HLIST_NODE(node) do { (node)->next = 0; (node)->pprev = 0; } while (0)
41
42static inline void hlist_add_head(struct hlist_node* n, struct hlist_head* h)
43{
44 struct hlist_node* first = h->first;
45 n->next = first;
46 n->pprev = &h->first;
47 h->first = n;
48 if (first)
49 first->pprev = &n->next;
50}
51
52static inline void hlist_del(struct hlist_node* n)
53{
54 struct hlist_node** p = n->pprev;
55 struct hlist_node* next = n->next;
56
57 /* Never linked (or already removed): the unlink is a no-op, not a bug. */
58 if (p) {
59 *p = next;
60 if (next)
61 next->pprev = p;
62 }
63 n->next = 0;
64 n->pprev = 0;
65}
66
67static inline int hlist_unhashed(const struct hlist_node* n)
68{
69 return !n->pprev;
70}
71
72#define hlist_entry(ptr, type, member) container_of(ptr, type, member)
73
74#define hlist_entry_safe(ptr, type, member) \
75 ((ptr) ? hlist_entry(ptr, type, member) : (type*)0)
76
77#define hlist_for_each_entry(pos, head, member) \
78 for (pos = hlist_entry_safe((head)->first, typeof(*pos), member); \
79 pos; \
80 pos = hlist_entry_safe((pos)->member.next, typeof(*pos), member))
81
82#define DECLARE_HASHTABLE(name, bits) struct hlist_head name[1 << (bits)]
83#define DEFINE_HASHTABLE(name, bits) DECLARE_HASHTABLE(name, bits)
84
85#define HASH_BITS(name) ((int)__builtin_ctz(sizeof(name) / sizeof(*(name))))
86
87/* One fold, used by hash_add and hash_for_each_possible alike. */
88#define hash_min(key, bits) ((unsigned int)(key) & ((1u << (bits)) - 1u))
89
90#define hash_add(hashtable, node, key) \
91 hlist_add_head(node, &hashtable[hash_min(key, HASH_BITS(hashtable))])
92
93#define hash_del(node) hlist_del(node)
94
95#define hash_empty(hashtable) __hash_empty(hashtable, HASH_BITS(hashtable))
96
97static inline int __hash_empty(struct hlist_head* ht, unsigned int bits)
98{
99 unsigned int i;
100 for (i = 0; i < (1u << bits); i++)
101 if (ht[i].first)
102 return 0;
103 return 1;
104}
105
106#define hash_for_each_possible(name, obj, member, key) \
107 hlist_for_each_entry(obj, \
108 &name[hash_min((unsigned int)(key), HASH_BITS(name))], member)
109
110#define hash_for_each_safe(name, bkt, tmp, obj, member) \
111 for ((bkt) = 0, (obj) = 0; (bkt) < (1u << HASH_BITS(name)) && \
112 (((obj) = hlist_entry_safe(name[bkt].first, typeof(*obj), member)), 1); \
113 (bkt)++, \
114 (obj) = 0)
115
116#define hash_for_each_possible_safe(name, obj, tmp, key, member) \
117 hlist_for_each_entry_safe(obj, tmp, \
118 &name[hash_min((unsigned int)(key), HASH_BITS(name))], member)
119
120#define hlist_for_each_entry_safe(pos, n, head, member) \
121 for (pos = hlist_entry_safe((head)->first, typeof(*pos), member); \
122 pos && ({ n = pos->member.next; 1; }); \
123 pos = hlist_entry_safe(n, typeof(*pos), member))
124
125#endif /* __LINUX_HASHTABLE_H__ */
int h
Definition layout.c:118
Definition hashtable.h:35
struct hlist_node * first
Definition hashtable.h:36
Definition hashtable.h:30
struct hlist_node ** pprev
Definition hashtable.h:32
struct hlist_node * next
Definition hashtable.h:31