|
1 From b6ab114212c0e4c3346ceb5b207f14c526ab81e7 Mon Sep 17 00:00:00 2001 |
|
2 From: Eamon Walsh <[email protected]> |
|
3 Date: Fri, 12 Sep 2008 19:11:53 -0400 |
|
4 Subject: [PATCH] Array-index based devPrivates implementation. |
|
5 |
|
6 Note: DevPrivateKey is now pointer-to-int, which means |
|
7 each key now needs to point to some global storage of |
|
8 size at least sizeof(int). |
|
9 --- |
|
10 dix/privates.c | 209 +++++++++++++++++++++++++++------------------------- |
|
11 include/privates.h | 2 |
|
12 2 files changed, 109 insertions(+), 102 deletions(-) |
|
13 |
|
14 diff --git a/dix/privates.c b/dix/privates.c |
|
15 index efb3204..ca03317 100644 |
|
16 --- a/dix/privates.c |
|
17 +++ b/dix/privates.c |
|
18 @@ -40,9 +40,8 @@ #include "colormapst.h" |
|
19 #include "inputstr.h" |
|
20 |
|
21 struct _Private { |
|
22 - DevPrivateKey key; |
|
23 - pointer value; |
|
24 - struct _Private *next; |
|
25 + int state; |
|
26 + pointer value; |
|
27 }; |
|
28 |
|
29 typedef struct _PrivateDesc { |
|
30 @@ -50,22 +49,36 @@ typedef struct _PrivateDesc { |
|
31 unsigned size; |
|
32 CallbackListPtr initfuncs; |
|
33 CallbackListPtr deletefuncs; |
|
34 - struct _PrivateDesc *next; |
|
35 } PrivateDescRec; |
|
36 |
|
37 +#define PRIV_MAX 256 |
|
38 +#define PRIV_STEP 16 |
|
39 + |
|
40 /* list of all allocated privates */ |
|
41 -static PrivateDescRec *items = NULL; |
|
42 +static PrivateDescRec items[PRIV_MAX]; |
|
43 +static int nextPriv; |
|
44 |
|
45 -static _X_INLINE PrivateDescRec * |
|
46 +static PrivateDescRec * |
|
47 findItem(const DevPrivateKey key) |
|
48 { |
|
49 - PrivateDescRec *item = items; |
|
50 - while (item) { |
|
51 - if (item->key == key) |
|
52 - return item; |
|
53 - item = item->next; |
|
54 + if (!*key) { |
|
55 + if (nextPriv >= PRIV_MAX) |
|
56 + return NULL; |
|
57 + |
|
58 + items[nextPriv].key = key; |
|
59 + *key = nextPriv; |
|
60 + nextPriv++; |
|
61 } |
|
62 - return NULL; |
|
63 + |
|
64 + return items + *key; |
|
65 +} |
|
66 + |
|
67 +static _X_INLINE int |
|
68 +privateExists(PrivateRec **privates, const DevPrivateKey key) |
|
69 +{ |
|
70 + return *key && *privates && |
|
71 + (*privates)[0].state > *key && |
|
72 + (*privates)[*key].state; |
|
73 } |
|
74 |
|
75 /* |
|
76 @@ -75,21 +88,10 @@ _X_EXPORT int |
|
77 dixRequestPrivate(const DevPrivateKey key, unsigned size) |
|
78 { |
|
79 PrivateDescRec *item = findItem(key); |
|
80 - if (item) { |
|
81 - if (size > item->size) |
|
82 - item->size = size; |
|
83 - } else { |
|
84 - item = (PrivateDescRec *)xalloc(sizeof(PrivateDescRec)); |
|
85 - if (!item) |
|
86 - return FALSE; |
|
87 - memset(item, 0, sizeof(PrivateDescRec)); |
|
88 - |
|
89 - /* add privates descriptor */ |
|
90 - item->key = key; |
|
91 + if (!item) |
|
92 + return FALSE; |
|
93 + if (size > item->size) |
|
94 item->size = size; |
|
95 - item->next = items; |
|
96 - items = item; |
|
97 - } |
|
98 return TRUE; |
|
99 } |
|
100 |
|
101 @@ -100,25 +102,52 @@ _X_EXPORT pointer * |
|
102 dixAllocatePrivate(PrivateRec **privates, const DevPrivateKey key) |
|
103 { |
|
104 PrivateDescRec *item = findItem(key); |
|
105 + PrivateCallbackRec calldata; |
|
106 PrivateRec *ptr; |
|
107 - unsigned size = sizeof(PrivateRec); |
|
108 - |
|
109 - if (item) |
|
110 - size += item->size; |
|
111 + pointer value; |
|
112 + int oldsize, newsize; |
|
113 + |
|
114 + newsize = (*key / PRIV_STEP + 1) * PRIV_STEP; |
|
115 |
|
116 - ptr = (PrivateRec *)xcalloc(size, 1); |
|
117 - if (!ptr) |
|
118 + /* resize or init privates array */ |
|
119 + if (!item) |
|
120 return NULL; |
|
121 - ptr->key = key; |
|
122 - ptr->value = (size > sizeof(PrivateRec)) ? (ptr + 1) : NULL; |
|
123 - ptr->next = *privates; |
|
124 - *privates = ptr; |
|
125 - |
|
126 - /* call any init funcs and return */ |
|
127 - if (item) { |
|
128 - PrivateCallbackRec calldata = { key, &ptr->value }; |
|
129 - CallCallbacks(&item->initfuncs, &calldata); |
|
130 + |
|
131 + /* initialize privates array if necessary */ |
|
132 + if (!*privates) { |
|
133 + ptr = xcalloc(newsize, sizeof(*ptr)); |
|
134 + if (!ptr) |
|
135 + return NULL; |
|
136 + *privates = ptr; |
|
137 + (*privates)[0].state = newsize; |
|
138 + } |
|
139 + |
|
140 + oldsize = (*privates)[0].state; |
|
141 + |
|
142 + /* resize privates array if necessary */ |
|
143 + if (*key >= oldsize) { |
|
144 + ptr = xrealloc(*privates, newsize * sizeof(*ptr)); |
|
145 + if (!ptr) |
|
146 + return NULL; |
|
147 + memset(ptr + oldsize, 0, (newsize - oldsize) * sizeof(*ptr)); |
|
148 + *privates = ptr; |
|
149 + (*privates)[0].state = newsize; |
|
150 + } |
|
151 + |
|
152 + /* initialize slot */ |
|
153 + ptr = *privates + *key; |
|
154 + ptr->state = 1; |
|
155 + if (item->size) { |
|
156 + value = xcalloc(item->size, 1); |
|
157 + if (!value) |
|
158 + return NULL; |
|
159 + ptr->value = value; |
|
160 } |
|
161 + |
|
162 + calldata.key = key; |
|
163 + calldata.value = &ptr->value; |
|
164 + CallCallbacks(&item->initfuncs, &calldata); |
|
165 + |
|
166 return &ptr->value; |
|
167 } |
|
168 |
|
169 @@ -128,14 +157,10 @@ dixAllocatePrivate(PrivateRec **privates |
|
170 _X_EXPORT pointer |
|
171 dixLookupPrivate(PrivateRec **privates, const DevPrivateKey key) |
|
172 { |
|
173 - PrivateRec *rec = *privates; |
|
174 pointer *ptr; |
|
175 |
|
176 - while (rec) { |
|
177 - if (rec->key == key) |
|
178 - return rec->value; |
|
179 - rec = rec->next; |
|
180 - } |
|
181 + if (privateExists(privates, key)) |
|
182 + return (*privates)[*key].value; |
|
183 |
|
184 ptr = dixAllocatePrivate(privates, key); |
|
185 return ptr ? *ptr : NULL; |
|
186 @@ -147,13 +172,8 @@ dixLookupPrivate(PrivateRec **privates, |
|
187 _X_EXPORT pointer * |
|
188 dixLookupPrivateAddr(PrivateRec **privates, const DevPrivateKey key) |
|
189 { |
|
190 - PrivateRec *rec = *privates; |
|
191 - |
|
192 - while (rec) { |
|
193 - if (rec->key == key) |
|
194 - return &rec->value; |
|
195 - rec = rec->next; |
|
196 - } |
|
197 + if (privateExists(privates, key)) |
|
198 + return &(*privates)[*key].value; |
|
199 |
|
200 return dixAllocatePrivate(privates, key); |
|
201 } |
|
202 @@ -164,16 +184,10 @@ dixLookupPrivateAddr(PrivateRec **privat |
|
203 _X_EXPORT int |
|
204 dixSetPrivate(PrivateRec **privates, const DevPrivateKey key, pointer val) |
|
205 { |
|
206 - PrivateRec *rec; |
|
207 - |
|
208 top: |
|
209 - rec = *privates; |
|
210 - while (rec) { |
|
211 - if (rec->key == key) { |
|
212 - rec->value = val; |
|
213 - return TRUE; |
|
214 - } |
|
215 - rec = rec->next; |
|
216 + if (privateExists(privates, key)) { |
|
217 + (*privates)[*key].value = val; |
|
218 + return TRUE; |
|
219 } |
|
220 |
|
221 if (!dixAllocatePrivate(privates, key)) |
|
222 @@ -187,27 +201,23 @@ dixSetPrivate(PrivateRec **privates, con |
|
223 _X_EXPORT void |
|
224 dixFreePrivates(PrivateRec *privates) |
|
225 { |
|
226 - PrivateRec *ptr, *next; |
|
227 - PrivateDescRec *item; |
|
228 + int i; |
|
229 PrivateCallbackRec calldata; |
|
230 |
|
231 - /* first pass calls the delete callbacks */ |
|
232 - for (ptr = privates; ptr; ptr = ptr->next) { |
|
233 - item = findItem(ptr->key); |
|
234 - if (item) { |
|
235 - calldata.key = ptr->key; |
|
236 - calldata.value = &ptr->value; |
|
237 - CallCallbacks(&item->deletefuncs, &calldata); |
|
238 - } |
|
239 - } |
|
240 - |
|
241 - /* second pass frees the memory */ |
|
242 - ptr = privates; |
|
243 - while (ptr) { |
|
244 - next = ptr->next; |
|
245 - xfree(ptr); |
|
246 - ptr = next; |
|
247 - } |
|
248 + if (privates) |
|
249 + for (i = 1; i < privates->state; i++) |
|
250 + if (privates[i].state) { |
|
251 + /* call the delete callbacks */ |
|
252 + calldata.key = items[i].key; |
|
253 + calldata.value = &privates[i].value; |
|
254 + CallCallbacks(&items[i].deletefuncs, &calldata); |
|
255 + |
|
256 + /* free pre-allocated memory */ |
|
257 + if (items[i].size) |
|
258 + xfree(privates[i].value); |
|
259 + } |
|
260 + |
|
261 + xfree(privates); |
|
262 } |
|
263 |
|
264 /* |
|
265 @@ -218,11 +228,9 @@ dixRegisterPrivateInitFunc(const DevPriv |
|
266 CallbackProcPtr callback, pointer data) |
|
267 { |
|
268 PrivateDescRec *item = findItem(key); |
|
269 - if (!item) { |
|
270 - if (!dixRequestPrivate(key, 0)) |
|
271 - return FALSE; |
|
272 - item = findItem(key); |
|
273 - } |
|
274 + if (!item) |
|
275 + return FALSE; |
|
276 + |
|
277 return AddCallback(&item->initfuncs, callback, data); |
|
278 } |
|
279 |
|
280 @@ -231,11 +239,9 @@ dixRegisterPrivateDeleteFunc(const DevPr |
|
281 CallbackProcPtr callback, pointer data) |
|
282 { |
|
283 PrivateDescRec *item = findItem(key); |
|
284 - if (!item) { |
|
285 - if (!dixRequestPrivate(key, 0)) |
|
286 - return FALSE; |
|
287 - item = findItem(key); |
|
288 - } |
|
289 + if (!item) |
|
290 + return FALSE; |
|
291 + |
|
292 return AddCallback(&item->deletefuncs, callback, data); |
|
293 } |
|
294 |
|
295 @@ -292,16 +298,17 @@ dixLookupPrivateOffset(RESTYPE type) |
|
296 int |
|
297 dixResetPrivates(void) |
|
298 { |
|
299 - PrivateDescRec *next; |
|
300 - |
|
301 - /* reset internal structures */ |
|
302 - while (items) { |
|
303 - next = items->next; |
|
304 - DeleteCallbackList(&items->initfuncs); |
|
305 - DeleteCallbackList(&items->deletefuncs); |
|
306 - xfree(items); |
|
307 - items = next; |
|
308 + int i; |
|
309 + |
|
310 + /* reset private descriptors */ |
|
311 + for (i = 1; i < nextPriv; i++) { |
|
312 + *items[i].key = 0; |
|
313 + DeleteCallbackList(&items[i].initfuncs); |
|
314 + DeleteCallbackList(&items[i].deletefuncs); |
|
315 } |
|
316 + nextPriv = 1; |
|
317 + |
|
318 + /* reset offsets */ |
|
319 if (offsets) |
|
320 xfree(offsets); |
|
321 offsetsSize = sizeof(offsetDefaults); |
|
322 diff --git a/include/privates.h b/include/privates.h |
|
323 index 98d893c..e3fa83c 100644 |
|
324 --- a/include/privates.h |
|
325 +++ b/include/privates.h |
|
326 @@ -19,7 +19,7 @@ #include "resource.h" |
|
327 * STUFF FOR PRIVATES |
|
328 *****************************************************************/ |
|
329 |
|
330 -typedef void *DevPrivateKey; |
|
331 +typedef int *DevPrivateKey; |
|
332 struct _Private; |
|
333 typedef struct _Private PrivateRec; |
|
334 |
|
335 -- |
|
336 1.4.1 |
|
337 |