diff options
author | Jacek Antonelli | 2008-08-15 23:45:04 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:45:04 -0500 |
commit | 117e22047c5752352342d64e3fb7ce00a4eb8113 (patch) | |
tree | e32de2cfba0dda8705ae528fcd1fbe23ba075685 /linden/indra/llcommon/llpagemem.h | |
parent | Second Life viewer sources 1.18.0.6 (diff) | |
download | meta-impy-117e22047c5752352342d64e3fb7ce00a4eb8113.zip meta-impy-117e22047c5752352342d64e3fb7ce00a4eb8113.tar.gz meta-impy-117e22047c5752352342d64e3fb7ce00a4eb8113.tar.bz2 meta-impy-117e22047c5752352342d64e3fb7ce00a4eb8113.tar.xz |
Second Life viewer sources 1.18.1.2
Diffstat (limited to 'linden/indra/llcommon/llpagemem.h')
-rw-r--r-- | linden/indra/llcommon/llpagemem.h | 393 |
1 files changed, 0 insertions, 393 deletions
diff --git a/linden/indra/llcommon/llpagemem.h b/linden/indra/llcommon/llpagemem.h deleted file mode 100644 index f3d6061..0000000 --- a/linden/indra/llcommon/llpagemem.h +++ /dev/null | |||
@@ -1,393 +0,0 @@ | |||
1 | /** | ||
2 | * @file llpagemem.h | ||
3 | * | ||
4 | * Copyright (c) 2002-2007, Linden Research, Inc. | ||
5 | * | ||
6 | * Second Life Viewer Source Code | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | #ifndef LL_LLPAGEMEM_H | ||
28 | #define LL_LLPAGEMEM_H | ||
29 | |||
30 | #if !LL_DARWIN | ||
31 | #include "malloc.h" | ||
32 | #endif | ||
33 | |||
34 | #include "llrand.h" | ||
35 | |||
36 | |||
37 | #ifndef __GNUC__ | ||
38 | template <class Object, U32 mPageSize=1024> | ||
39 | class LLPageMemory | ||
40 | { | ||
41 | private: | ||
42 | |||
43 | union XObject | ||
44 | { | ||
45 | XObject *mNextFreeObject; | ||
46 | U8 mObject[sizeof(Object)]; | ||
47 | }; | ||
48 | |||
49 | template <U32 mPageSize> struct Page | ||
50 | { | ||
51 | XObject *mFirstFreeObject; | ||
52 | U32 mObjectCount; | ||
53 | U8 mObjects[mPageSize-8]; | ||
54 | |||
55 | void init(U32 mObjPerPage) | ||
56 | { | ||
57 | XObject *o = (XObject*)&mObjects; | ||
58 | mObjectCount = 0; | ||
59 | mFirstFreeObject = o; | ||
60 | |||
61 | for (U32 i = 0; i < mObjPerPage-1; i++) | ||
62 | { | ||
63 | o->mNextFreeObject = o+1; | ||
64 | o++; | ||
65 | } | ||
66 | o->mNextFreeObject = NULL; | ||
67 | }; | ||
68 | |||
69 | Object* alloc() | ||
70 | { | ||
71 | if (mFirstFreeObject) | ||
72 | { | ||
73 | XObject *ret = mFirstFreeObject; | ||
74 | mFirstFreeObject = mFirstFreeObject->mNextFreeObject; | ||
75 | ret->mNextFreeObject = NULL; | ||
76 | mObjectCount++; | ||
77 | return (Object*)&ret->mObject; | ||
78 | }; | ||
79 | return NULL; | ||
80 | } | ||
81 | }; | ||
82 | |||
83 | U32 mObjPerPage; | ||
84 | U32 mMaxPages; | ||
85 | U32 mObjectCount; | ||
86 | |||
87 | Page<mPageSize>* mPageMemory; | ||
88 | Page<mPageSize>* mFirstPage; | ||
89 | |||
90 | public: | ||
91 | U32 precise, anywhere, fail; | ||
92 | |||
93 | void init() | ||
94 | { | ||
95 | Page<mPageSize> *p = mFirstPage; | ||
96 | for (U32 i = 0; i < mMaxPages; i++) | ||
97 | { | ||
98 | p[i].init(mObjPerPage); | ||
99 | } | ||
100 | |||
101 | precise = 0; | ||
102 | anywhere = 0; | ||
103 | fail = 0; | ||
104 | }; | ||
105 | |||
106 | public: | ||
107 | |||
108 | Page<mPageSize>* pageof(Object *object) | ||
109 | { | ||
110 | return (Page<mPageSize>*) ((((U32)object - 8) / mPageSize) * mPageSize ); | ||
111 | } | ||
112 | |||
113 | LLPageMemory(U32 maxObjects) | ||
114 | { | ||
115 | mObjPerPage = (mPageSize-8) / sizeof(Object); | ||
116 | mMaxPages = (maxObjects / mObjPerPage) + 1; | ||
117 | mObjectCount= 0; | ||
118 | |||
119 | //printf("%d objects per page, %d pages total, %d/%d objects\n", | ||
120 | // mObjPerPage, mMaxPages, mMaxPages * mObjPerPage,maxObjects); | ||
121 | |||
122 | mPageMemory = (Page<mPageSize>*)calloc(mPageSize,mMaxPages+1); | ||
123 | mFirstPage = mPageMemory; | ||
124 | U32 fix = ((U32)mPageMemory % mPageSize); | ||
125 | if (fix) mFirstPage = (Page<mPageSize>*)((U32)mPageMemory+mPageSize-fix); | ||
126 | |||
127 | //printf("fix = %d\n",fix); | ||
128 | |||
129 | init(); | ||
130 | }; | ||
131 | |||
132 | LLPageMemory(void *pageMem, U32 bytes) | ||
133 | { | ||
134 | } | ||
135 | |||
136 | ~LLPageMemory() | ||
137 | { | ||
138 | if (mPageMemory) | ||
139 | { | ||
140 | free(mPageMemory); | ||
141 | } | ||
142 | } | ||
143 | |||
144 | Object* alloc(Object *after=NULL) | ||
145 | { | ||
146 | Page<mPageSize> * p = mFirstPage; | ||
147 | Object * o = NULL; | ||
148 | U32 i = mMaxPages; | ||
149 | |||
150 | if (after) | ||
151 | { | ||
152 | o = pageof(after)->alloc(); | ||
153 | if (o) | ||
154 | { | ||
155 | precise++; | ||
156 | return o; | ||
157 | } | ||
158 | return NULL; | ||
159 | } | ||
160 | |||
161 | F32 frac = 1.0f / (F32)mMaxPages; | ||
162 | F32 thresh = 0.0f; | ||
163 | for (i = 0; i < mMaxPages; i++) | ||
164 | { | ||
165 | if (thresh > ((F32)p[i].mObjectCount / (F32)mObjPerPage)) | ||
166 | { | ||
167 | o = p[i].alloc(); | ||
168 | if (o) | ||
169 | { | ||
170 | //printf("allocating page %x obj %x\n",p, o); | ||
171 | anywhere++; | ||
172 | return o; | ||
173 | } | ||
174 | } | ||
175 | thresh += frac; | ||
176 | } | ||
177 | |||
178 | fail++; | ||
179 | return NULL; | ||
180 | }; | ||
181 | |||
182 | void free(Object *o) | ||
183 | { | ||
184 | if (!o) return; | ||
185 | |||
186 | Page<mPageSize> *page = pageof(o); | ||
187 | XObject *obj = (XObject*)o; | ||
188 | |||
189 | //printf("freeing %x\n",obj); | ||
190 | |||
191 | obj->mNextFreeObject = page->mFirstFreeObject; | ||
192 | page->mFirstFreeObject = obj; | ||
193 | page->mObjectCount--; | ||
194 | |||
195 | //printf("freeing page %x %d\n",page, page->mObjectCount); | ||
196 | }; | ||
197 | |||
198 | U32 indexof(Object *object) | ||
199 | { | ||
200 | if (!object) return -1; | ||
201 | |||
202 | return ((((U32)object-8) % mPageSize) / sizeof(Object)) + | ||
203 | ((pageof(object) - mFirstPage) * mObjPerPage); | ||
204 | } | ||
205 | |||
206 | |||
207 | void dump() | ||
208 | { | ||
209 | |||
210 | for (U32 i=0;i < mMaxPages;i++) | ||
211 | { | ||
212 | //printf("page %d %d/%d objects\n",i,mFirstPage[i].mObjectCount,mObjPerPage); | ||
213 | } | ||
214 | //printf("precise = %d anywhere %d ratio = %f\n",precise,anywhere,(F32)precise/(F32)(anywhere+precise)); | ||
215 | //printf("fail = %d\n",fail); | ||
216 | |||
217 | } | ||
218 | |||
219 | static void test() | ||
220 | { | ||
221 | struct Foo | ||
222 | { | ||
223 | U32 ord; | ||
224 | U32 foo[8]; | ||
225 | }; | ||
226 | |||
227 | const U32 count = 100; | ||
228 | U32 i,c; | ||
229 | U32 mix = 50; | ||
230 | |||
231 | LLPageMemory<Foo> mem(count); | ||
232 | LLRand rand(LLUUID::getRandomSeed()); | ||
233 | |||
234 | Foo *obj[count]; | ||
235 | |||
236 | for (i=0;i<count;i++) obj[i] = 0; | ||
237 | |||
238 | U32 x= 0; | ||
239 | for (U32 run=0; run < 10000 ;run++) | ||
240 | { | ||
241 | U32 m =rand.llrand(count); | ||
242 | for (c=0;c < m;c++) | ||
243 | { | ||
244 | U32 j = rand.llrand(count); | ||
245 | if (obj[j]) | ||
246 | { | ||
247 | mem.free(obj[j]); | ||
248 | obj[j] = 0; | ||
249 | } | ||
250 | } | ||
251 | |||
252 | m =rand.llrand(count); | ||
253 | for (c=0;c<m;c++) | ||
254 | { | ||
255 | U32 i = rand.llrand(count); | ||
256 | while (obj[i] && i < count) i++; | ||
257 | |||
258 | if (!obj[i]) | ||
259 | { | ||
260 | if (i > 0) obj[i] = mem.alloc(obj[i-1]); | ||
261 | else obj[i] = mem.alloc(); | ||
262 | if (obj[i]) obj[i]->ord = x++; | ||
263 | } | ||
264 | } | ||
265 | } | ||
266 | |||
267 | for (i = 0; i< count; i++) | ||
268 | { | ||
269 | //printf("obj[%2d] = %08x %02d %4d\n",i,obj[i],mem.indexof(obj[i]),(obj[i] ? obj[i]->ord : -1)); | ||
270 | } | ||
271 | |||
272 | mem.dump(); | ||
273 | } | ||
274 | }; | ||
275 | |||
276 | |||
277 | template <class Object> | ||
278 | class LLObjectPool | ||
279 | { | ||
280 | private: | ||
281 | |||
282 | class XObject | ||
283 | { | ||
284 | public: | ||
285 | Object mObject; | ||
286 | U32 mNextFreeObject; | ||
287 | |||
288 | XObject() { mObject = NULL; mNextFreeObject = 0; } | ||
289 | }; | ||
290 | |||
291 | U32 mNumObjects; | ||
292 | U32 mMaxObjects; | ||
293 | XObject* mObjects; | ||
294 | U32 mFirstFreeObject; | ||
295 | |||
296 | U32 indexof(XObject *xobj) { return (xobj - mObjects); } | ||
297 | |||
298 | public: | ||
299 | LLObjectPool(U32 maxObjects) | ||
300 | { | ||
301 | mMaxObjects = maxObjects; | ||
302 | mFirstFreeObject = 0; | ||
303 | |||
304 | mObjects = new XObject[mMaxObjects]; | ||
305 | |||
306 | //printf("objectpool allocated %d bytes\n",sizeof(XObject) * mMaxObjects); | ||
307 | |||
308 | for (U32 i=0;i<mMaxObjects;i++) mObjects[i].mNextFreeObject = i+1; | ||
309 | }; | ||
310 | |||
311 | ~LLObjectPool() | ||
312 | { | ||
313 | delete [] mObjects; | ||
314 | mObjects = NULL; | ||
315 | } | ||
316 | |||
317 | Object* alloc(Object *after=NULL) | ||
318 | { | ||
319 | XObject *obj = &mObjects[mFirstFreeObject]; | ||
320 | mFirstFreeObject = obj->mNextFreeObject; | ||
321 | if (mFirstFreeObject >= mMaxObjects) | ||
322 | { | ||
323 | llerrs << "Attempted to allocate too many objects out of pool\n" << llendl; | ||
324 | llassert(0); | ||
325 | } | ||
326 | return &obj->mObject; | ||
327 | }; | ||
328 | |||
329 | void free(Object *obj) | ||
330 | { | ||
331 | if (!obj) return; | ||
332 | XObject *xobj = (XObject*)obj; | ||
333 | xobj->mNextFreeObject = mFirstFreeObject; | ||
334 | mFirstFreeObject = indexof(xobj); | ||
335 | }; | ||
336 | |||
337 | static void test() | ||
338 | { | ||
339 | struct Foo | ||
340 | { | ||
341 | U32 ord; | ||
342 | U32 foo[8]; | ||
343 | }; | ||
344 | |||
345 | const U32 count = 100; | ||
346 | U32 i,c; | ||
347 | U32 mix = 50; | ||
348 | |||
349 | LLPageMemory<Foo> mem(count); | ||
350 | LLRand rand(LLUUID::getRandomSeed()); | ||
351 | |||
352 | Foo *obj[count]; | ||
353 | |||
354 | for (i=0;i<count;i++) obj[i] = 0; | ||
355 | |||
356 | U32 x= 0; | ||
357 | for (U32 run=0; run < 10000 ;run++) | ||
358 | { | ||
359 | U32 m =rand.llrand(count); | ||
360 | for (c=0;c < m;c++) | ||
361 | { | ||
362 | U32 j = rand.llrand(count); | ||
363 | if (obj[j]) | ||
364 | { | ||
365 | mem.free(obj[j]); | ||
366 | obj[j] = 0; | ||
367 | } | ||
368 | } | ||
369 | |||
370 | m =rand.llrand(count); | ||
371 | for (c=0;c<m;c++) | ||
372 | { | ||
373 | U32 i = rand.llrand(count); | ||
374 | while (obj[i] && i < count) i++; | ||
375 | |||
376 | if (!obj[i]) | ||
377 | { | ||
378 | if (i > 0) obj[i] = mem.alloc(obj[i-1]); | ||
379 | else obj[i] = mem.alloc(); | ||
380 | if (obj[i]) obj[i]->ord = x++; | ||
381 | } | ||
382 | } | ||
383 | } | ||
384 | |||
385 | for (i = 0; i< count; i++) | ||
386 | { | ||
387 | //printf("obj[%2d] = %08x %02d %4d\n",i,obj[i],mem.indexof(obj[i]),(obj[i] ? obj[i]->ord : -1)); | ||
388 | } | ||
389 | } | ||
390 | }; | ||
391 | #endif // !defined __GNUC__ | ||
392 | |||
393 | #endif | ||