VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/util/idpool.c@ 71997

最後變更 在這個檔案從71997是 53726,由 vboxsync 提交於 10 年 前

properties.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 5.0 KB
 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include "chromium.h"
8#include "cr_error.h"
9#include "cr_mem.h"
10#include "cr_idpool.h"
11
12
13#define CR_MAXUINT ((GLuint) 0xFFFFFFFF)
14
15typedef struct FreeElemRec {
16 GLuint min;
17 GLuint max;
18 struct FreeElemRec *next;
19 struct FreeElemRec *prev;
20} FreeElem;
21
22struct CRIdPoolRec {
23 FreeElem *freeList;
24};
25
26
27
28CRIdPool *crAllocIdPool( void )
29{
30 CRIdPool *pool = (CRIdPool *) crCalloc(sizeof(CRIdPool));
31 pool->freeList = (FreeElem *) crCalloc(sizeof(FreeElem));
32 pool->freeList->min = 1;
33 pool->freeList->max = CR_MAXUINT;
34 pool->freeList->next = NULL;
35 pool->freeList->prev = NULL;
36 return pool;
37}
38
39void crFreeIdPool( CRIdPool *pool )
40{
41 FreeElem *i, *next;
42 for (i = pool->freeList; i; i = next)
43 {
44 next = i->next;
45 crFree(i);
46 }
47 crFree(pool);
48}
49
50/*
51 * Allocate a block of <count> IDs. Return index of first one.
52 * Return 0 if we fail.
53 */
54GLuint crIdPoolAllocBlock( CRIdPool *pool, GLuint count )
55{
56 FreeElem *f;
57 GLuint ret;
58
59 CRASSERT(count > 0);
60
61 f = pool->freeList;
62 while (f)
63 {
64 if (f->max - f->min + 1 >= (GLuint) count)
65 {
66 /* found a sufficiently large enough block */
67 ret = f->min;
68 f->min += count;
69
70 if (f->min == f->max)
71 {
72 /* remove this block from linked list */
73 if (f == pool->freeList)
74 {
75 /* remove from head */
76 pool->freeList = pool->freeList->next;
77 pool->freeList->prev = NULL;
78 }
79 else
80 {
81 /* remove from elsewhere */
82 f->prev->next = f->next;
83 f->next->prev = f->prev;
84 }
85 crFree(f);
86 }
87
88#ifdef DEBUG
89 /* make sure the IDs really are allocated */
90 {
91 GLuint i;
92 for (i = 0; i < count; i++)
93 {
94 CRASSERT(crIdPoolIsIdUsed(pool, ret + i));
95 }
96 }
97#endif
98
99 return ret;
100 }
101 else {
102 f = f->next;
103 }
104 }
105
106 /* failed to find free block */
107 return 0;
108}
109
110
111/*
112 * Free a block of <count> IDs starting at <first>.
113 */
114void crIdPoolFreeBlock( CRIdPool *pool, GLuint first, GLuint count )
115{
116 FreeElem *i;
117 FreeElem *newelem;
118
119 /*********************************/
120 /* Add the name to the freeList */
121 /* Find the bracketing sequences */
122
123 for (i = pool->freeList; i && i->next && i->next->min < first; i = i->next)
124 {
125 /* EMPTY BODY */
126 }
127
128 /* j will always be valid */
129 if (!i)
130 return;
131 if (!i->next && i->max == first)
132 return;
133
134 /* Case: j:(~,first-1) */
135 if (i->max + 1 == first)
136 {
137 i->max += count;
138 if (i->next && i->max+1 >= i->next->min)
139 {
140 /* Collapse */
141 i->next->min = i->min;
142 i->next->prev = i->prev;
143 if (i->prev)
144 {
145 i->prev->next = i->next;
146 }
147 if (i == pool->freeList)
148 {
149 pool->freeList = i->next;
150 }
151 crFree(i);
152 }
153 return;
154 }
155
156 /* Case: j->next: (first+1, ~) */
157 if (i->next && i->next->min - count == first)
158 {
159 i->next->min -= count;
160 if (i->max + 1 >= i->next->min)
161 {
162 /* Collapse */
163 i->next->min = i->min;
164 i->next->prev = i->prev;
165 if (i->prev)
166 {
167 i->prev->next = i->next;
168 }
169 if (i == pool->freeList)
170 {
171 pool->freeList = i->next;
172 }
173 crFree(i);
174 }
175 return;
176 }
177
178 /* Case: j: (first+1, ~) j->next: null */
179 if (!i->next && i->min - count == first)
180 {
181 i->min -= count;
182 return;
183 }
184
185 /* allocate a new FreeElem node */
186 newelem = (FreeElem *) crCalloc(sizeof(FreeElem));
187 newelem->min = first;
188 newelem->max = first + count - 1;
189
190 /* Case: j: (~,first-(2+)) j->next: (first+(2+), ~) or null */
191 if (first > i->max)
192 {
193 newelem->prev = i;
194 newelem->next = i->next;
195 if (i->next)
196 {
197 i->next->prev = newelem;
198 }
199 i->next = newelem;
200 return;
201 }
202
203 /* Case: j: (first+(2+), ~) */
204 /* Can only happen if j = t->freeList! */
205 if (i == pool->freeList && i->min > first)
206 {
207 newelem->next = i;
208 newelem->prev = i->prev;
209 i->prev = newelem;
210 pool->freeList = newelem;
211 return;
212 }
213}
214
215
216
217/*
218 * Mark the given Id as being allocated.
219 */
220void crIdPoolAllocId( CRIdPool *pool, GLuint id )
221{
222 FreeElem *f;
223
224 CRASSERT(id > 0);
225
226 f = pool->freeList;
227 while (f)
228 {
229 if (id >= f->min && id <= f->max)
230 {
231 /* found the block */
232 if (id == f->min)
233 {
234 f->min++;
235 }
236 else if (id == f->max)
237 {
238 f->max--;
239 }
240 else
241 {
242 /* somewhere in the middle - split the block */
243 FreeElem *newelem = (FreeElem *) crCalloc(sizeof(FreeElem));
244 newelem->min = id + 1;
245 newelem->max = f->max;
246 f->max = id - 1;
247 newelem->next = f->next;
248 if (f->next)
249 f->next->prev = newelem;
250 newelem->prev = f;
251 f->next = newelem;
252 }
253 return;
254 }
255 f = f->next;
256 }
257
258 /* if we get here, the ID was already allocated - that's OK */
259}
260
261
262/*
263 * Determine if the given id is free. Return GL_TRUE if so.
264 */
265GLboolean crIdPoolIsIdFree( const CRIdPool *pool, GLuint id )
266{
267 FreeElem *i;
268
269 /* First find which region it fits in */
270 for (i = pool->freeList; i && !(i->min <= id && id <= i->max); i=i->next)
271 {
272 /* EMPTY BODY */
273 }
274
275 if (i)
276 return GL_TRUE;
277 else
278 return GL_FALSE;
279}
280
281
282/*
283 * Determine if the given id is used. Return GL_TRUE if so.
284 */
285GLboolean crIdPoolIsIdUsed( const CRIdPool *pool, GLuint id )
286{
287 return (GLboolean) !crIdPoolIsIdFree( pool, id);
288}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette