blob: 523b939cbf0f363cf261f5849e131da00e8ddffb [file] [log] [blame]
The Android Open Source Project30957f52008-10-21 07:00:00 -07001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/* ---- includes ----------------------------------------------------------- */
18
19#include "b_BasicEm/Functions.h"
20#include "b_BasicEm/DynMemManager.h"
21#include "b_BasicEm/Context.h"
22
23/* ------------------------------------------------------------------------- */
24
25/* minimum block size dynamically allocated in function nextBlock (affects only shared memory) */
26#define bbs_DYN_MEM_MIN_NEW_BLOCK_SIZE 0
27
28/** Offset to actual memory area on allocated memory blocks (in 16-bit words).
29 * Value needs to be large enough to hold the pointer to the next memory block
30 * and the size value (32-bit) of the memory area.
31 */
32#define bbs_MEM_OFFSET 6
33
34/* ========================================================================= */
35/* */
36/* ---- \ghd{ auxiliary functions } ---------------------------------------- */
37/* */
38/* ========================================================================= */
39
40/* ------------------------------------------------------------------------- */
41
42/* ========================================================================= */
43/* */
44/* ---- \ghd{ constructor / destructor } ----------------------------------- */
45/* */
46/* ========================================================================= */
47
48/* ------------------------------------------------------------------------- */
49
50void bbs_DynMemManager_init( struct bbs_Context* cpA,
51 struct bbs_DynMemManager* ptrA )
52{
53 ptrA->memPtrE = NULL;
54 ptrA->mallocFPtrE = NULL;
55 ptrA->freeFPtrE = NULL;
56}
57
58/* ------------------------------------------------------------------------- */
59
60void bbs_DynMemManager_exit( struct bbs_Context* cpA,
61 struct bbs_DynMemManager* ptrA )
62{
63 ptrA->memPtrE = NULL;
64 ptrA->mallocFPtrE = NULL;
65 ptrA->freeFPtrE = NULL;
66}
67
68/* ------------------------------------------------------------------------- */
69
70/* ========================================================================= */
71/* */
72/* ---- \ghd{ operators } -------------------------------------------------- */
73/* */
74/* ========================================================================= */
75
76/* ------------------------------------------------------------------------- */
77
78/* ========================================================================= */
79/* */
80/* ---- \ghd{ query functions } -------------------------------------------- */
81/* */
82/* ========================================================================= */
83
84/* ------------------------------------------------------------------------- */
85
86uint32 bbs_DynMemManager_allocatedSize( struct bbs_Context* cpA,
87 const struct bbs_DynMemManager* ptrA )
88{
89 uint32 sizeL = 0;
90 uint16* pL = ( uint16* )ptrA->memPtrE;
91 while( pL != NULL )
92 {
93 sizeL += ( ( uint32* )pL )[ 2 ];
94 pL = *( uint16** )pL;
95 }
96 return sizeL;
97}
98
99/* ------------------------------------------------------------------------- */
100
101/* ========================================================================= */
102/* */
103/* ---- \ghd{ modify functions } ------------------------------------------- */
104/* */
105/* ========================================================================= */
106
107/* ------------------------------------------------------------------------- */
108
109/* ========================================================================= */
110/* */
111/* ---- \ghd{ I/O } -------------------------------------------------------- */
112/* */
113/* ========================================================================= */
114
115/* ------------------------------------------------------------------------- */
116
117/* ========================================================================= */
118/* */
119/* ---- \ghd{ exec functions } --------------------------------------------- */
120/* */
121/* ========================================================================= */
122
123/* ------------------------------------------------------------------------- */
124
125uint16* bbs_DynMemManager_alloc( struct bbs_Context* cpA,
126 struct bbs_DynMemManager* ptrA,
127 const struct bbs_MemSeg* memSegPtrA,
128 uint32 sizeA )
129{
130 uint16* pL = NULL;
131 bbs_DEF_fNameL( "uint16* bbs_DynMemManager_alloc( struct bbs_DynMemManager* ptrA, uint32 sizeA )" )
132
133
134 if( ptrA->mallocFPtrE == NULL )
135 {
136 bbs_ERROR1( "%s:\n Malloc handler not defined.\n", fNameL );
137 return NULL;
138 }
139
140 if( ptrA->memPtrE == NULL )
141 {
142 ptrA->memPtrE = ptrA->mallocFPtrE( cpA, memSegPtrA, ( sizeA + bbs_MEM_OFFSET ) << 1 );
143 pL = ptrA->memPtrE;
144 }
145 else
146 {
147 uint16** ppL = ( uint16** )ptrA->memPtrE;
148 while( *ppL != NULL ) ppL = ( uint16** )*ppL;
149 *ppL = ptrA->mallocFPtrE( cpA, memSegPtrA, ( sizeA + bbs_MEM_OFFSET ) << 1 );
150 pL = *ppL;
151 }
152
153 if( pL == NULL )
154 {
155 bbs_ERR1( bbs_ERR_OUT_OF_MEMORY, "%s:\n Allocation failed.\n", fNameL );
156 return NULL;
157 }
158
159 ( ( uint32* )pL )[ 0 ] = 0;
160 ( ( uint32* )pL )[ 1 ] = 0;
161 ( ( uint32* )pL )[ 2 ] = sizeA + bbs_MEM_OFFSET;
162
163 return pL + bbs_MEM_OFFSET;
164}
165
166/* ------------------------------------------------------------------------- */
167
168void bbs_DynMemManager_free( struct bbs_Context* cpA,
169 struct bbs_DynMemManager* ptrA,
170 uint16* memPtrA )
171{
172 bbs_DEF_fNameL( "void bbs_DynMemManager_free( .... )" )
173
174 if( ptrA->memPtrE == NULL )
175 {
176 bbs_ERROR1( "%s:\n Memory was not allocated.\n", fNameL );
177 return;
178 }
179 else if( ptrA->memPtrE + bbs_MEM_OFFSET == memPtrA )
180 {
181 uint16* memPtrL = ptrA->memPtrE;
182 ptrA->memPtrE = *( uint16** )ptrA->memPtrE;
183 ptrA->freeFPtrE( memPtrL );
184 }
185 else
186 {
187 uint16* p0L = NULL;
188 uint16* pL = ( uint16* )ptrA->memPtrE;
189
190 while( pL != NULL )
191 {
192 if( pL + bbs_MEM_OFFSET == memPtrA ) break;
193 p0L = pL;
194 pL = *( uint16** )pL;
195 }
196
197 if( pL != NULL )
198 {
199 if( ptrA->freeFPtrE == NULL )
200 {
201 bbs_ERROR1( "%s:\n Free handler not defined.\n", fNameL );
202 return;
203 }
204
205 if( p0L != NULL )
206 {
207 *( uint16** )p0L = *( uint16** )pL;
208 }
209 else
210 {
211 ptrA->memPtrE = *( uint16** )pL;
212 }
213
214 ptrA->freeFPtrE( pL );
215 }
216 else
217 {
218 bbs_ERROR1( "%s:\n Attempt to free memory that was not allocated.\n", fNameL );
219 return;
220 }
221 }
222}
223
224/* ------------------------------------------------------------------------- */
225
226uint16* bbs_DynMemManager_nextBlock( struct bbs_Context* cpA,
227 struct bbs_DynMemManager* ptrA,
228 const struct bbs_MemSeg* memSegPtrA,
229 uint16* curBlockPtrA,
230 uint32 minSizeA,
231 uint32* actualSizePtrA )
232{
233 uint16* pL = ( uint16* )ptrA->memPtrE;
234 bbs_DEF_fNameL( "uint16* bbs_DynMemManager_nextBlock( .... )" )
235
236 if( curBlockPtrA != NULL )
237 {
238 /* find current block */
239 while( pL != NULL )
240 {
241 if( pL + bbs_MEM_OFFSET == curBlockPtrA ) break;
242 pL = *( uint16** )pL;
243 }
244
245 if( pL == NULL )
246 {
247 bbs_ERROR1( "%s:\nCould not find current memory block.\n", fNameL );
248 *actualSizePtrA = 0;
249 return NULL;
250 }
251
252 /* go to next block */
253 pL = *( uint16** )pL;
254 }
255
256 /* find next fitting block */
257 while( pL != NULL )
258 {
259 if( ( ( uint32* )pL )[ 2 ] >= minSizeA + bbs_MEM_OFFSET ) break;
260 pL = *( uint16** )pL;
261 }
262
263 if( pL == NULL )
264 {
265 /* no proper block -> allocate new one */
266 uint32 blockSizeL = minSizeA > bbs_DYN_MEM_MIN_NEW_BLOCK_SIZE ? minSizeA : bbs_DYN_MEM_MIN_NEW_BLOCK_SIZE;
267 uint16* memPtrL = bbs_DynMemManager_alloc( cpA, ptrA, memSegPtrA, blockSizeL );
268 if( memPtrL != NULL )
269 {
270 *actualSizePtrA = blockSizeL;
271 }
272 else
273 {
274 *actualSizePtrA = 0;
275 }
276 return memPtrL;
277 }
278 else
279 {
280 *actualSizePtrA = ( ( uint32* )pL )[ 2 ] - bbs_MEM_OFFSET;
281 return pL + bbs_MEM_OFFSET;
282 }
283}
284
285/* ------------------------------------------------------------------------- */
286
287void bbs_DynMemManager_freeAll( struct bbs_Context* cpA, struct bbs_DynMemManager* ptrA )
288{
289 uint16** ppL = ( uint16** )ptrA->memPtrE;
290 while( ppL != NULL )
291 {
292 uint16* memPtrL = ( uint16* )ppL;
293 ppL = ( uint16** )*ppL;
294 ptrA->freeFPtrE( memPtrL );
295 }
296 ptrA->memPtrE = NULL;
297}
298
299/* ------------------------------------------------------------------------- */
300
301/* ========================================================================= */