1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include <linux/types.h>
18
19#include <dspbridge/host_os.h>
20#include <dspbridge/gh.h>
21
22struct element {
23 struct element *next;
24 u8 data[1];
25};
26
27struct gh_t_hash_tab {
28 u16 max_bucket;
29 u16 val_size;
30 struct element **buckets;
31 u16(*hash) (void *, u16);
32 bool(*match) (void *, void *);
33 void (*delete) (void *);
34};
35
36static void noop(void *p);
37
38
39
40
41
42struct gh_t_hash_tab *gh_create(u16 max_bucket, u16 val_size,
43 u16(*hash) (void *, u16), bool(*match) (void *,
44 void *),
45 void (*delete) (void *))
46{
47 struct gh_t_hash_tab *hash_tab;
48 u16 i;
49 hash_tab = kzalloc(sizeof(struct gh_t_hash_tab), GFP_KERNEL);
50 if (hash_tab == NULL)
51 return NULL;
52 hash_tab->max_bucket = max_bucket;
53 hash_tab->val_size = val_size;
54 hash_tab->hash = hash;
55 hash_tab->match = match;
56 hash_tab->delete = delete == NULL ? noop : delete;
57
58 hash_tab->buckets =
59 kzalloc(sizeof(struct element *) * max_bucket, GFP_KERNEL);
60 if (hash_tab->buckets == NULL) {
61 gh_delete(hash_tab);
62 return NULL;
63 }
64
65 for (i = 0; i < max_bucket; i++)
66 hash_tab->buckets[i] = NULL;
67
68 return hash_tab;
69}
70
71
72
73
74void gh_delete(struct gh_t_hash_tab *hash_tab)
75{
76 struct element *elem, *next;
77 u16 i;
78
79 if (hash_tab != NULL) {
80 if (hash_tab->buckets != NULL) {
81 for (i = 0; i < hash_tab->max_bucket; i++) {
82 for (elem = hash_tab->buckets[i]; elem != NULL;
83 elem = next) {
84 next = elem->next;
85 (*hash_tab->delete) (elem->data);
86 kfree(elem);
87 }
88 }
89
90 kfree(hash_tab->buckets);
91 }
92
93 kfree(hash_tab);
94 }
95}
96
97
98
99
100
101void *gh_find(struct gh_t_hash_tab *hash_tab, void *key)
102{
103 struct element *elem;
104
105 elem = hash_tab->buckets[(*hash_tab->hash) (key, hash_tab->max_bucket)];
106
107 for (; elem; elem = elem->next) {
108 if ((*hash_tab->match) (key, elem->data))
109 return elem->data;
110 }
111
112 return NULL;
113}
114
115
116
117
118
119void *gh_insert(struct gh_t_hash_tab *hash_tab, void *key, void *value)
120{
121 struct element *elem;
122 u16 i;
123 char *src, *dst;
124
125 elem = kzalloc(sizeof(struct element) - 1 + hash_tab->val_size,
126 GFP_KERNEL);
127 if (elem != NULL) {
128
129 dst = (char *)elem->data;
130 src = (char *)value;
131 for (i = 0; i < hash_tab->val_size; i++)
132 *dst++ = *src++;
133
134 i = (*hash_tab->hash) (key, hash_tab->max_bucket);
135 elem->next = hash_tab->buckets[i];
136 hash_tab->buckets[i] = elem;
137
138 return elem->data;
139 }
140
141 return NULL;
142}
143
144
145
146
147
148static void noop(void *p)
149{
150 p = p;
151}
152
153#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
154
155
156
157
158
159
160
161
162void gh_iterate(struct gh_t_hash_tab *hash_tab,
163 void (*callback)(void *, void *), void *user_data)
164{
165 struct element *elem;
166 u32 i;
167
168 if (hash_tab && hash_tab->buckets)
169 for (i = 0; i < hash_tab->max_bucket; i++) {
170 elem = hash_tab->buckets[i];
171 while (elem) {
172 callback(&elem->data, user_data);
173 elem = elem->next;
174 }
175 }
176}
177#endif
178