sl@0
|
1 |
/* Copyright (c) 2009 The Khronos Group Inc.
|
sl@0
|
2 |
* Portions copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies)
|
sl@0
|
3 |
*
|
sl@0
|
4 |
* Permission is hereby granted, free of charge, to any person obtaining a
|
sl@0
|
5 |
* copy of this software and/or associated documentation files (the
|
sl@0
|
6 |
* "Materials"), to deal in the Materials without restriction, including
|
sl@0
|
7 |
* without limitation the rights to use, copy, modify, merge, publish,
|
sl@0
|
8 |
* distribute, sublicense, and/or sell copies of the Materials, and to
|
sl@0
|
9 |
* permit persons to whom the Materials are furnished to do so, subject to
|
sl@0
|
10 |
* the following conditions:
|
sl@0
|
11 |
*
|
sl@0
|
12 |
* The above copyright notice and this permission notice shall be included
|
sl@0
|
13 |
* in all copies or substantial portions of the Materials.
|
sl@0
|
14 |
*
|
sl@0
|
15 |
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
sl@0
|
16 |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
sl@0
|
17 |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
sl@0
|
18 |
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
sl@0
|
19 |
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
sl@0
|
20 |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
sl@0
|
21 |
* MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
sl@0
|
22 |
*/
|
sl@0
|
23 |
|
sl@0
|
24 |
/*
|
sl@0
|
25 |
* owfpool.c
|
sl@0
|
26 |
*/
|
sl@0
|
27 |
|
sl@0
|
28 |
|
sl@0
|
29 |
#ifdef __cplusplus
|
sl@0
|
30 |
extern "C"
|
sl@0
|
31 |
{
|
sl@0
|
32 |
#endif
|
sl@0
|
33 |
|
sl@0
|
34 |
|
sl@0
|
35 |
#include <string.h>
|
sl@0
|
36 |
#include <stdio.h>
|
sl@0
|
37 |
#include <stdlib.h>
|
sl@0
|
38 |
|
sl@0
|
39 |
#include "owfdebug.h"
|
sl@0
|
40 |
#include "owftypes.h"
|
sl@0
|
41 |
#include "owfpool.h"
|
sl@0
|
42 |
#include "owfmemory.h"
|
sl@0
|
43 |
|
sl@0
|
44 |
|
sl@0
|
45 |
|
sl@0
|
46 |
|
sl@0
|
47 |
OWF_API_CALL OWF_POOL*
|
sl@0
|
48 |
OWF_Pool_Create(size_t objectSize, size_t objectCount)
|
sl@0
|
49 |
{
|
sl@0
|
50 |
OWF_POOL* pool;
|
sl@0
|
51 |
char* chunk;
|
sl@0
|
52 |
OWFuint32* entries;
|
sl@0
|
53 |
|
sl@0
|
54 |
/* we be needing some memories, aye */
|
sl@0
|
55 |
pool = (OWF_POOL*)xalloc(sizeof(OWF_POOL), 1);
|
sl@0
|
56 |
entries = (OWFuint32*)xalloc(sizeof(OWFuint32), objectCount);
|
sl@0
|
57 |
chunk = (char*)xalloc((objectSize + sizeof(OWFuint32*)), objectCount);
|
sl@0
|
58 |
|
sl@0
|
59 |
if (pool && entries && chunk)
|
sl@0
|
60 |
{
|
sl@0
|
61 |
size_t i;
|
sl@0
|
62 |
|
sl@0
|
63 |
/* setup pool */
|
sl@0
|
64 |
pool->entries = entries;
|
sl@0
|
65 |
pool->chunk = chunk;
|
sl@0
|
66 |
pool->capacity =
|
sl@0
|
67 |
pool->free = objectCount;
|
sl@0
|
68 |
pool->firstFree = 0;
|
sl@0
|
69 |
pool->entrySize = objectSize;
|
sl@0
|
70 |
|
sl@0
|
71 |
/* initially all objects are marked as free */
|
sl@0
|
72 |
for (i = 0; i < objectCount-1; i++) {
|
sl@0
|
73 |
entries[i] = i+1;
|
sl@0
|
74 |
}
|
sl@0
|
75 |
/* terminate chain */
|
sl@0
|
76 |
entries[objectCount-1] = EOC;
|
sl@0
|
77 |
}
|
sl@0
|
78 |
else
|
sl@0
|
79 |
{
|
sl@0
|
80 |
/* failed miserably. bail out. */
|
sl@0
|
81 |
xfree(pool);
|
sl@0
|
82 |
pool = NULL;
|
sl@0
|
83 |
xfree(entries);
|
sl@0
|
84 |
xfree(chunk);
|
sl@0
|
85 |
}
|
sl@0
|
86 |
|
sl@0
|
87 |
return pool;
|
sl@0
|
88 |
}
|
sl@0
|
89 |
|
sl@0
|
90 |
OWF_API_CALL void*
|
sl@0
|
91 |
OWF_Pool_GetObject(OWF_POOL* pool)
|
sl@0
|
92 |
{
|
sl@0
|
93 |
void* object = NULL;
|
sl@0
|
94 |
|
sl@0
|
95 |
if (pool)
|
sl@0
|
96 |
{
|
sl@0
|
97 |
/* we have objects left in the pool? */
|
sl@0
|
98 |
if (pool->firstFree != EOC)
|
sl@0
|
99 |
{
|
sl@0
|
100 |
OWFuint32* temp;
|
sl@0
|
101 |
OWFuint32 chunk;
|
sl@0
|
102 |
|
sl@0
|
103 |
chunk = (OWFuint32) pool->chunk;
|
sl@0
|
104 |
|
sl@0
|
105 |
/* calculate offset inside the chunk */
|
sl@0
|
106 |
temp = (OWFuint32*) (chunk + (pool->entrySize +
|
sl@0
|
107 |
sizeof(OWFuint32*)) * pool->firstFree);
|
sl@0
|
108 |
/* remember way back to home */
|
sl@0
|
109 |
temp[0] = (OWFuint32) pool;
|
sl@0
|
110 |
object = (void*) &temp[1];
|
sl@0
|
111 |
pool->firstFree = pool->entries[pool->firstFree];
|
sl@0
|
112 |
--pool->free;
|
sl@0
|
113 |
|
sl@0
|
114 |
OWF_ASSERT((OWFuint32) object > (OWFuint32) pool->chunk);
|
sl@0
|
115 |
OWF_ASSERT((int)object != 0x5eaf00d);
|
sl@0
|
116 |
}
|
sl@0
|
117 |
}
|
sl@0
|
118 |
return object;
|
sl@0
|
119 |
}
|
sl@0
|
120 |
|
sl@0
|
121 |
OWF_API_CALL void
|
sl@0
|
122 |
OWF_Pool_PutObject(void* object)
|
sl@0
|
123 |
{
|
sl@0
|
124 |
OWFuint32* temp = (OWFuint32*) object;
|
sl@0
|
125 |
|
sl@0
|
126 |
if (temp && temp[-1])
|
sl@0
|
127 |
{
|
sl@0
|
128 |
OWF_POOL* pool;
|
sl@0
|
129 |
OWFuint32 addr;
|
sl@0
|
130 |
OWFuint32 chunk;
|
sl@0
|
131 |
OWFuint32 entrySize;
|
sl@0
|
132 |
|
sl@0
|
133 |
addr = (OWFuint32) object - 4;
|
sl@0
|
134 |
pool = (OWF_POOL*) temp[-1];
|
sl@0
|
135 |
chunk = (OWFuint32) pool->chunk;
|
sl@0
|
136 |
entrySize = pool->entrySize + sizeof(OWFuint32*);
|
sl@0
|
137 |
|
sl@0
|
138 |
if (addr >= chunk &&
|
sl@0
|
139 |
addr < (chunk + pool->capacity * entrySize))
|
sl@0
|
140 |
{
|
sl@0
|
141 |
OWFuint32 index = (addr - chunk) / entrySize;
|
sl@0
|
142 |
|
sl@0
|
143 |
pool->entries[index] = pool->firstFree;
|
sl@0
|
144 |
pool->firstFree = index;
|
sl@0
|
145 |
memset(object, 0x0, pool->entrySize);
|
sl@0
|
146 |
++pool->free;
|
sl@0
|
147 |
}
|
sl@0
|
148 |
else
|
sl@0
|
149 |
{
|
sl@0
|
150 |
/* invalid object */
|
sl@0
|
151 |
OWF_ASSERT(0);
|
sl@0
|
152 |
}
|
sl@0
|
153 |
}
|
sl@0
|
154 |
}
|
sl@0
|
155 |
|
sl@0
|
156 |
OWF_API_CALL void
|
sl@0
|
157 |
OWF_Pool_Destroy(OWF_POOL* pool)
|
sl@0
|
158 |
{
|
sl@0
|
159 |
if (pool)
|
sl@0
|
160 |
{
|
sl@0
|
161 |
xfree(pool->entries);
|
sl@0
|
162 |
xfree(pool->chunk);
|
sl@0
|
163 |
memset(pool, 0, sizeof(OWF_POOL));
|
sl@0
|
164 |
xfree(pool);
|
sl@0
|
165 |
}
|
sl@0
|
166 |
}
|
sl@0
|
167 |
|
sl@0
|
168 |
|
sl@0
|
169 |
#ifdef __cplusplus
|
sl@0
|
170 |
}
|
sl@0
|
171 |
#endif
|