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 50 void 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 60 void 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 86 uint32 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 125 uint16* 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 168 void 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 226 uint16* 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 287 void 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