aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/llpagemem.h
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:45:04 -0500
committerJacek Antonelli2008-08-15 23:45:04 -0500
commit117e22047c5752352342d64e3fb7ce00a4eb8113 (patch)
treee32de2cfba0dda8705ae528fcd1fbe23ba075685 /linden/indra/llcommon/llpagemem.h
parentSecond Life viewer sources 1.18.0.6 (diff)
downloadmeta-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.h393
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__
38template <class Object, U32 mPageSize=1024>
39class LLPageMemory
40{
41private:
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
90public:
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
106public:
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
277template <class Object>
278class LLObjectPool
279{
280private:
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
298public:
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