diff options
author | Alex Deucher | 2015-04-20 11:04:22 -0500 |
---|---|---|
committer | Alex Deucher | 2015-08-05 12:47:48 -0500 |
commit | 09361395363805b5892d48d7bc10cf717e4d2927 (patch) | |
tree | c81192a93843d2f9af16df2b9ec71a66579314d5 /amdgpu/util_hash_table.c | |
parent | a3c89dda5b519f6b217bebe97f6795b820931b78 (diff) | |
download | external-libdrm-09361395363805b5892d48d7bc10cf717e4d2927.tar.gz external-libdrm-09361395363805b5892d48d7bc10cf717e4d2927.tar.xz external-libdrm-09361395363805b5892d48d7bc10cf717e4d2927.zip |
drm: add libdrm_amdgpu (v7)
This is the new ioctl wrapper used by the new admgpu driver.
It's primarily used by xf86-video-amdgpu and mesa.
v2: fix amdgpu_drm.h install
v3: Integrate some of the sugestions from Emil:
clean up Makefile.am, configure.ac
capitalize header guards
fix _FILE_OFFSET_BITS with config.h
use drm_mmap/drm_munmap
Remove unused ARRAY_SIZE macro
use shared list implementation
use shared math implementation
use drmGetNodeTypeFromFd helper
v4: remove unused tiling defines
v5: include amdgpu.h in Makefile.am
v6: update amdgpu_drm.h
v7: libdrm.h -> libdrm_macros.h
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'amdgpu/util_hash_table.c')
-rw-r--r-- | amdgpu/util_hash_table.c | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/amdgpu/util_hash_table.c b/amdgpu/util_hash_table.c new file mode 100644 index 00000000..cb7213c3 --- /dev/null +++ b/amdgpu/util_hash_table.c | |||
@@ -0,0 +1,257 @@ | |||
1 | /************************************************************************** | ||
2 | * | ||
3 | * Copyright 2008 VMware, Inc. | ||
4 | * All Rights Reserved. | ||
5 | * | ||
6 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
7 | * copy of this software and associated documentation files (the | ||
8 | * "Software"), to deal in the Software without restriction, including | ||
9 | * without limitation the rights to use, copy, modify, merge, publish, | ||
10 | * distribute, sub license, and/or sell copies of the Software, and to | ||
11 | * permit persons to whom the Software is furnished to do so, subject to | ||
12 | * the following conditions: | ||
13 | * | ||
14 | * The above copyright notice and this permission notice (including the | ||
15 | * next paragraph) shall be included in all copies or substantial portions | ||
16 | * of the Software. | ||
17 | * | ||
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. | ||
21 | * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR | ||
22 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
23 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
24 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
25 | * | ||
26 | **************************************************************************/ | ||
27 | |||
28 | /** | ||
29 | * @file | ||
30 | * General purpose hash table implementation. | ||
31 | * | ||
32 | * Just uses the util_hash for now, but it might be better switch to a linear | ||
33 | * probing hash table implementation at some point -- as it is said they have | ||
34 | * better lookup and cache performance and it appears to be possible to write | ||
35 | * a lock-free implementation of such hash tables . | ||
36 | * | ||
37 | * @author José Fonseca <jfonseca@vmware.com> | ||
38 | */ | ||
39 | |||
40 | |||
41 | |||
42 | #include "util_hash_table.h" | ||
43 | #include "util_hash.h" | ||
44 | |||
45 | #include <stdlib.h> | ||
46 | #include <assert.h> | ||
47 | |||
48 | struct util_hash_table | ||
49 | { | ||
50 | struct util_hash *head; | ||
51 | |||
52 | /** Hash function */ | ||
53 | unsigned (*make_hash)(void *key); | ||
54 | |||
55 | /** Compare two keys */ | ||
56 | int (*compare)(void *key1, void *key2); | ||
57 | }; | ||
58 | |||
59 | struct util_hash_table_item | ||
60 | { | ||
61 | void *key; | ||
62 | void *value; | ||
63 | }; | ||
64 | |||
65 | |||
66 | static struct util_hash_table_item * | ||
67 | util_hash_table_item(struct util_hash_iter iter) | ||
68 | { | ||
69 | return (struct util_hash_table_item *)util_hash_iter_data(iter); | ||
70 | } | ||
71 | |||
72 | struct util_hash_table *util_hash_table_create(unsigned (*hash)(void *key), | ||
73 | int (*compare)(void *key1, void *key2)) | ||
74 | { | ||
75 | struct util_hash_table *ht; | ||
76 | |||
77 | ht = malloc(sizeof(struct util_hash_table)); | ||
78 | if(!ht) | ||
79 | return NULL; | ||
80 | |||
81 | ht->head = util_hash_create(); | ||
82 | if(!ht->head) { | ||
83 | free(ht); | ||
84 | return NULL; | ||
85 | } | ||
86 | |||
87 | ht->make_hash = hash; | ||
88 | ht->compare = compare; | ||
89 | |||
90 | return ht; | ||
91 | } | ||
92 | |||
93 | static struct util_hash_iter | ||
94 | util_hash_table_find_iter(struct util_hash_table *ht, | ||
95 | void *key, unsigned key_hash) | ||
96 | { | ||
97 | struct util_hash_iter iter; | ||
98 | struct util_hash_table_item *item; | ||
99 | |||
100 | iter = util_hash_find(ht->head, key_hash); | ||
101 | while (!util_hash_iter_is_null(iter)) { | ||
102 | item = (struct util_hash_table_item *)util_hash_iter_data(iter); | ||
103 | if (!ht->compare(item->key, key)) | ||
104 | break; | ||
105 | iter = util_hash_iter_next(iter); | ||
106 | } | ||
107 | |||
108 | return iter; | ||
109 | } | ||
110 | |||
111 | static struct util_hash_table_item * | ||
112 | util_hash_table_find_item(struct util_hash_table *ht, | ||
113 | void *key, unsigned key_hash) | ||
114 | { | ||
115 | struct util_hash_iter iter; | ||
116 | struct util_hash_table_item *item; | ||
117 | |||
118 | iter = util_hash_find(ht->head, key_hash); | ||
119 | while (!util_hash_iter_is_null(iter)) { | ||
120 | item = (struct util_hash_table_item *)util_hash_iter_data(iter); | ||
121 | if (!ht->compare(item->key, key)) | ||
122 | return item; | ||
123 | iter = util_hash_iter_next(iter); | ||
124 | } | ||
125 | |||
126 | return NULL; | ||
127 | } | ||
128 | |||
129 | void util_hash_table_set(struct util_hash_table *ht, void *key, void *value) | ||
130 | { | ||
131 | unsigned key_hash; | ||
132 | struct util_hash_table_item *item; | ||
133 | struct util_hash_iter iter; | ||
134 | |||
135 | assert(ht); | ||
136 | if (!ht) | ||
137 | return; | ||
138 | |||
139 | key_hash = ht->make_hash(key); | ||
140 | |||
141 | item = util_hash_table_find_item(ht, key, key_hash); | ||
142 | if(item) { | ||
143 | /* TODO: key/value destruction? */ | ||
144 | item->value = value; | ||
145 | return; | ||
146 | } | ||
147 | |||
148 | item = malloc(sizeof(struct util_hash_table_item)); | ||
149 | if(!item) | ||
150 | return; | ||
151 | |||
152 | item->key = key; | ||
153 | item->value = value; | ||
154 | |||
155 | iter = util_hash_insert(ht->head, key_hash, item); | ||
156 | if(util_hash_iter_is_null(iter)) { | ||
157 | free(item); | ||
158 | return; | ||
159 | } | ||
160 | } | ||
161 | |||
162 | void *util_hash_table_get(struct util_hash_table *ht, void *key) | ||
163 | { | ||
164 | unsigned key_hash; | ||
165 | struct util_hash_table_item *item; | ||
166 | |||
167 | assert(ht); | ||
168 | if (!ht) | ||
169 | return NULL; | ||
170 | |||
171 | key_hash = ht->make_hash(key); | ||
172 | |||
173 | item = util_hash_table_find_item(ht, key, key_hash); | ||
174 | if(!item) | ||
175 | return NULL; | ||
176 | |||
177 | return item->value; | ||
178 | } | ||
179 | |||
180 | void util_hash_table_remove(struct util_hash_table *ht, void *key) | ||
181 | { | ||
182 | unsigned key_hash; | ||
183 | struct util_hash_iter iter; | ||
184 | struct util_hash_table_item *item; | ||
185 | |||
186 | assert(ht); | ||
187 | if (!ht) | ||
188 | return; | ||
189 | |||
190 | key_hash = ht->make_hash(key); | ||
191 | |||
192 | iter = util_hash_table_find_iter(ht, key, key_hash); | ||
193 | if(util_hash_iter_is_null(iter)) | ||
194 | return; | ||
195 | |||
196 | item = util_hash_table_item(iter); | ||
197 | assert(item); | ||
198 | free(item); | ||
199 | |||
200 | util_hash_erase(ht->head, iter); | ||
201 | } | ||
202 | |||
203 | void util_hash_table_clear(struct util_hash_table *ht) | ||
204 | { | ||
205 | struct util_hash_iter iter; | ||
206 | struct util_hash_table_item *item; | ||
207 | |||
208 | assert(ht); | ||
209 | if (!ht) | ||
210 | return; | ||
211 | |||
212 | iter = util_hash_first_node(ht->head); | ||
213 | while (!util_hash_iter_is_null(iter)) { | ||
214 | item = (struct util_hash_table_item *)util_hash_take(ht->head, util_hash_iter_key(iter)); | ||
215 | free(item); | ||
216 | iter = util_hash_first_node(ht->head); | ||
217 | } | ||
218 | } | ||
219 | |||
220 | void util_hash_table_foreach(struct util_hash_table *ht, | ||
221 | void (*callback)(void *key, void *value, void *data), | ||
222 | void *data) | ||
223 | { | ||
224 | struct util_hash_iter iter; | ||
225 | struct util_hash_table_item *item; | ||
226 | |||
227 | assert(ht); | ||
228 | if (!ht) | ||
229 | return; | ||
230 | |||
231 | iter = util_hash_first_node(ht->head); | ||
232 | while (!util_hash_iter_is_null(iter)) { | ||
233 | item = (struct util_hash_table_item *)util_hash_iter_data(iter); | ||
234 | callback(item->key, item->value, data); | ||
235 | iter = util_hash_iter_next(iter); | ||
236 | } | ||
237 | } | ||
238 | |||
239 | void util_hash_table_destroy(struct util_hash_table *ht) | ||
240 | { | ||
241 | struct util_hash_iter iter; | ||
242 | struct util_hash_table_item *item; | ||
243 | |||
244 | assert(ht); | ||
245 | if (!ht) | ||
246 | return; | ||
247 | |||
248 | iter = util_hash_first_node(ht->head); | ||
249 | while (!util_hash_iter_is_null(iter)) { | ||
250 | item = (struct util_hash_table_item *)util_hash_iter_data(iter); | ||
251 | free(item); | ||
252 | iter = util_hash_iter_next(iter); | ||
253 | } | ||
254 | |||
255 | util_hash_delete(ht->head); | ||
256 | free(ht); | ||
257 | } | ||