00001
00019 #include "satMem.h"
00020 #include "extra.h"
00021
00025
00026 struct Sat_MmFixed_t_
00027 {
00028
00029 int nEntrySize;
00030 int nEntriesAlloc;
00031 int nEntriesUsed;
00032 int nEntriesMax;
00033 char * pEntriesFree;
00034
00035
00036 int nChunkSize;
00037 int nChunksAlloc;
00038 int nChunks;
00039 char ** pChunks;
00040
00041
00042 int nMemoryUsed;
00043 int nMemoryAlloc;
00044 };
00045
00046 struct Sat_MmFlex_t_
00047 {
00048
00049 int nEntriesUsed;
00050 char * pCurrent;
00051 char * pEnd;
00052
00053
00054 int nChunkSize;
00055 int nChunksAlloc;
00056 int nChunks;
00057 char ** pChunks;
00058
00059
00060 int nMemoryUsed;
00061 int nMemoryAlloc;
00062 };
00063
00064 struct Sat_MmStep_t_
00065 {
00066 int nMems;
00067 Sat_MmFixed_t ** pMems;
00068 int nMapSize;
00069 Sat_MmFixed_t ** pMap;
00070 };
00071
00075
00088 Sat_MmFixed_t * Sat_MmFixedStart( int nEntrySize )
00089 {
00090 Sat_MmFixed_t * p;
00091
00092 p = ALLOC( Sat_MmFixed_t, 1 );
00093 memset( p, 0, sizeof(Sat_MmFixed_t) );
00094
00095 p->nEntrySize = nEntrySize;
00096 p->nEntriesAlloc = 0;
00097 p->nEntriesUsed = 0;
00098 p->pEntriesFree = NULL;
00099
00100 if ( nEntrySize * (1 << 10) < (1<<16) )
00101 p->nChunkSize = (1 << 10);
00102 else
00103 p->nChunkSize = (1<<16) / nEntrySize;
00104 if ( p->nChunkSize < 8 )
00105 p->nChunkSize = 8;
00106
00107 p->nChunksAlloc = 64;
00108 p->nChunks = 0;
00109 p->pChunks = ALLOC( char *, p->nChunksAlloc );
00110
00111 p->nMemoryUsed = 0;
00112 p->nMemoryAlloc = 0;
00113 return p;
00114 }
00115
00127 void Sat_MmFixedStop( Sat_MmFixed_t * p, int fVerbose )
00128 {
00129 int i;
00130 if ( p == NULL )
00131 return;
00132 if ( fVerbose )
00133 {
00134 printf( "Fixed memory manager: Entry = %5d. Chunk = %5d. Chunks used = %5d.\n",
00135 p->nEntrySize, p->nChunkSize, p->nChunks );
00136 printf( " Entries used = %8d. Entries peak = %8d. Memory used = %8d. Memory alloc = %8d.\n",
00137 p->nEntriesUsed, p->nEntriesMax, p->nEntrySize * p->nEntriesUsed, p->nMemoryAlloc );
00138 }
00139 for ( i = 0; i < p->nChunks; i++ )
00140 free( p->pChunks[i] );
00141 free( p->pChunks );
00142 free( p );
00143 }
00144
00156 char * Sat_MmFixedEntryFetch( Sat_MmFixed_t * p )
00157 {
00158 char * pTemp;
00159 int i;
00160
00161
00162 if ( p->nEntriesUsed == p->nEntriesAlloc )
00163 {
00164 assert( p->pEntriesFree == NULL );
00165 if ( p->nChunks == p->nChunksAlloc )
00166 {
00167 p->nChunksAlloc *= 2;
00168 p->pChunks = REALLOC( char *, p->pChunks, p->nChunksAlloc );
00169 }
00170 p->pEntriesFree = ALLOC( char, p->nEntrySize * p->nChunkSize );
00171 p->nMemoryAlloc += p->nEntrySize * p->nChunkSize;
00172
00173 pTemp = p->pEntriesFree;
00174 for ( i = 1; i < p->nChunkSize; i++ )
00175 {
00176 *((char **)pTemp) = pTemp + p->nEntrySize;
00177 pTemp += p->nEntrySize;
00178 }
00179
00180 *((char **)pTemp) = NULL;
00181
00182 p->pChunks[ p->nChunks++ ] = p->pEntriesFree;
00183
00184 p->nEntriesAlloc += p->nChunkSize;
00185 }
00186
00187 p->nEntriesUsed++;
00188 if ( p->nEntriesMax < p->nEntriesUsed )
00189 p->nEntriesMax = p->nEntriesUsed;
00190
00191 pTemp = p->pEntriesFree;
00192 p->pEntriesFree = *((char **)pTemp);
00193 return pTemp;
00194 }
00195
00207 void Sat_MmFixedEntryRecycle( Sat_MmFixed_t * p, char * pEntry )
00208 {
00209
00210 p->nEntriesUsed--;
00211
00212 *((char **)pEntry) = p->pEntriesFree;
00213 p->pEntriesFree = pEntry;
00214 }
00215
00227 void Sat_MmFixedRestart( Sat_MmFixed_t * p )
00228 {
00229 int i;
00230 char * pTemp;
00231
00232
00233 for ( i = 1; i < p->nChunks; i++ )
00234 free( p->pChunks[i] );
00235 p->nChunks = 1;
00236
00237 pTemp = p->pChunks[0];
00238 for ( i = 1; i < p->nChunkSize; i++ )
00239 {
00240 *((char **)pTemp) = pTemp + p->nEntrySize;
00241 pTemp += p->nEntrySize;
00242 }
00243
00244 *((char **)pTemp) = NULL;
00245
00246 p->pEntriesFree = p->pChunks[0];
00247
00248 p->nMemoryAlloc = p->nEntrySize * p->nChunkSize;
00249 p->nMemoryUsed = 0;
00250 p->nEntriesAlloc = p->nChunkSize;
00251 p->nEntriesUsed = 0;
00252 }
00253
00265 int Sat_MmFixedReadMemUsage( Sat_MmFixed_t * p )
00266 {
00267 return p->nMemoryAlloc;
00268 }
00269
00270
00271
00283 Sat_MmFlex_t * Sat_MmFlexStart()
00284 {
00285 Sat_MmFlex_t * p;
00286
00287 p = ALLOC( Sat_MmFlex_t, 1 );
00288 memset( p, 0, sizeof(Sat_MmFlex_t) );
00289
00290 p->nEntriesUsed = 0;
00291 p->pCurrent = NULL;
00292 p->pEnd = NULL;
00293
00294 p->nChunkSize = (1 << 12);
00295 p->nChunksAlloc = 64;
00296 p->nChunks = 0;
00297 p->pChunks = ALLOC( char *, p->nChunksAlloc );
00298
00299 p->nMemoryUsed = 0;
00300 p->nMemoryAlloc = 0;
00301 return p;
00302 }
00303
00315 void Sat_MmFlexStop( Sat_MmFlex_t * p, int fVerbose )
00316 {
00317 int i;
00318 if ( p == NULL )
00319 return;
00320 if ( fVerbose )
00321 {
00322 printf( "Flexible memory manager: Chunk size = %d. Chunks used = %d.\n",
00323 p->nChunkSize, p->nChunks );
00324 printf( " Entries used = %d. Memory used = %d. Memory alloc = %d.\n",
00325 p->nEntriesUsed, p->nMemoryUsed, p->nMemoryAlloc );
00326 }
00327 for ( i = 0; i < p->nChunks; i++ )
00328 free( p->pChunks[i] );
00329 free( p->pChunks );
00330 free( p );
00331 }
00332
00344 char * Sat_MmFlexEntryFetch( Sat_MmFlex_t * p, int nBytes )
00345 {
00346 char * pTemp;
00347
00348 if ( p->pCurrent == NULL || p->pCurrent + nBytes > p->pEnd )
00349 {
00350 if ( p->nChunks == p->nChunksAlloc )
00351 {
00352 p->nChunksAlloc *= 2;
00353 p->pChunks = REALLOC( char *, p->pChunks, p->nChunksAlloc );
00354 }
00355 if ( nBytes > p->nChunkSize )
00356 {
00357
00358
00359 p->nChunkSize = 2 * nBytes;
00360 }
00361 p->pCurrent = ALLOC( char, p->nChunkSize );
00362 p->pEnd = p->pCurrent + p->nChunkSize;
00363 p->nMemoryAlloc += p->nChunkSize;
00364
00365 p->pChunks[ p->nChunks++ ] = p->pCurrent;
00366 }
00367 assert( p->pCurrent + nBytes <= p->pEnd );
00368
00369 p->nEntriesUsed++;
00370
00371 p->nMemoryUsed += nBytes;
00372
00373 pTemp = p->pCurrent;
00374 p->pCurrent += nBytes;
00375 return pTemp;
00376 }
00377
00389 int Sat_MmFlexReadMemUsage( Sat_MmFlex_t * p )
00390 {
00391 return p->nMemoryAlloc;
00392 }
00393
00394
00395
00396
00397
00418 Sat_MmStep_t * Sat_MmStepStart( int nSteps )
00419 {
00420 Sat_MmStep_t * p;
00421 int i, k;
00422 p = ALLOC( Sat_MmStep_t, 1 );
00423 p->nMems = nSteps;
00424
00425 p->pMems = ALLOC( Sat_MmFixed_t *, p->nMems );
00426 for ( i = 0; i < p->nMems; i++ )
00427 p->pMems[i] = Sat_MmFixedStart( (8<<i) );
00428
00429 p->nMapSize = (4<<p->nMems);
00430 p->pMap = ALLOC( Sat_MmFixed_t *, p->nMapSize+1 );
00431 p->pMap[0] = NULL;
00432 for ( k = 1; k <= 4; k++ )
00433 p->pMap[k] = p->pMems[0];
00434 for ( i = 0; i < p->nMems; i++ )
00435 for ( k = (4<<i)+1; k <= (8<<i); k++ )
00436 p->pMap[k] = p->pMems[i];
00437
00438
00439 return p;
00440 }
00441
00453 void Sat_MmStepStop( Sat_MmStep_t * p, int fVerbose )
00454 {
00455 int i;
00456 for ( i = 0; i < p->nMems; i++ )
00457 Sat_MmFixedStop( p->pMems[i], fVerbose );
00458 free( p->pMems );
00459 free( p->pMap );
00460 free( p );
00461 }
00462
00474 char * Sat_MmStepEntryFetch( Sat_MmStep_t * p, int nBytes )
00475 {
00476 if ( nBytes == 0 )
00477 return NULL;
00478 if ( nBytes > p->nMapSize )
00479 {
00480
00481 return ALLOC( char, nBytes );
00482 }
00483 return Sat_MmFixedEntryFetch( p->pMap[nBytes] );
00484 }
00485
00486
00498 void Sat_MmStepEntryRecycle( Sat_MmStep_t * p, char * pEntry, int nBytes )
00499 {
00500 if ( nBytes == 0 )
00501 return;
00502 if ( nBytes > p->nMapSize )
00503 {
00504 free( pEntry );
00505 return;
00506 }
00507 Sat_MmFixedEntryRecycle( p->pMap[nBytes], pEntry );
00508 }
00509
00521 int Sat_MmStepReadMemUsage( Sat_MmStep_t * p )
00522 {
00523 int i, nMemTotal = 0;
00524 for ( i = 0; i < p->nMems; i++ )
00525 nMemTotal += p->pMems[i]->nMemoryAlloc;
00526 return nMemTotal;
00527 }