DynMemManager.c revision 7f81d9b6fa7f2ec161b682622db577a28c90b49f
1/* 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/* ========================================================================= */ 302