00001
00021 #include "msatInt.h"
00022
00026
00027 struct Msat_MmFixed_t_
00028 {
00029
00030 int nEntrySize;
00031 int nEntriesAlloc;
00032 int nEntriesUsed;
00033 int nEntriesMax;
00034 char * pEntriesFree;
00035
00036
00037 int nChunkSize;
00038 int nChunksAlloc;
00039 int nChunks;
00040 char ** pChunks;
00041
00042
00043 int nMemoryUsed;
00044 int nMemoryAlloc;
00045 };
00046
00047 struct Msat_MmFlex_t_
00048 {
00049
00050 int nEntriesUsed;
00051 char * pCurrent;
00052 char * pEnd;
00053
00054
00055 int nChunkSize;
00056 int nChunksAlloc;
00057 int nChunks;
00058 char ** pChunks;
00059
00060
00061 int nMemoryUsed;
00062 int nMemoryAlloc;
00063 };
00064
00065
00066 struct Msat_MmStep_t_
00067 {
00068 int nMems;
00069 Msat_MmFixed_t ** pMems;
00070 int nMapSize;
00071 Msat_MmFixed_t ** pMap;
00072 };
00073
00077
00090 Msat_MmFixed_t * Msat_MmFixedStart( int nEntrySize )
00091 {
00092 Msat_MmFixed_t * p;
00093
00094 p = ALLOC( Msat_MmFixed_t, 1 );
00095 memset( p, 0, sizeof(Msat_MmFixed_t) );
00096
00097 p->nEntrySize = nEntrySize;
00098 p->nEntriesAlloc = 0;
00099 p->nEntriesUsed = 0;
00100 p->pEntriesFree = NULL;
00101
00102 if ( nEntrySize * (1 << 10) < (1<<16) )
00103 p->nChunkSize = (1 << 10);
00104 else
00105 p->nChunkSize = (1<<16) / nEntrySize;
00106 if ( p->nChunkSize < 8 )
00107 p->nChunkSize = 8;
00108
00109 p->nChunksAlloc = 64;
00110 p->nChunks = 0;
00111 p->pChunks = ALLOC( char *, p->nChunksAlloc );
00112
00113 p->nMemoryUsed = 0;
00114 p->nMemoryAlloc = 0;
00115 return p;
00116 }
00117
00129 void Msat_MmFixedStop( Msat_MmFixed_t * p, int fVerbose )
00130 {
00131 int i;
00132 if ( p == NULL )
00133 return;
00134 if ( fVerbose )
00135 {
00136 printf( "Fixed memory manager: Entry = %5d. Chunk = %5d. Chunks used = %5d.\n",
00137 p->nEntrySize, p->nChunkSize, p->nChunks );
00138 printf( " Entries used = %8d. Entries peak = %8d. Memory used = %8d. Memory alloc = %8d.\n",
00139 p->nEntriesUsed, p->nEntriesMax, p->nEntrySize * p->nEntriesUsed, p->nMemoryAlloc );
00140 }
00141 for ( i = 0; i < p->nChunks; i++ )
00142 free( p->pChunks[i] );
00143 free( p->pChunks );
00144 free( p );
00145 }
00146
00158 char * Msat_MmFixedEntryFetch( Msat_MmFixed_t * p )
00159 {
00160 char * pTemp;
00161 int i;
00162
00163
00164 if ( p->nEntriesUsed == p->nEntriesAlloc )
00165 {
00166 assert( p->pEntriesFree == NULL );
00167 if ( p->nChunks == p->nChunksAlloc )
00168 {
00169 p->nChunksAlloc *= 2;
00170 p->pChunks = REALLOC( char *, p->pChunks, p->nChunksAlloc );
00171 }
00172 p->pEntriesFree = ALLOC( char, p->nEntrySize * p->nChunkSize );
00173 p->nMemoryAlloc += p->nEntrySize * p->nChunkSize;
00174
00175 pTemp = p->pEntriesFree;
00176 for ( i = 1; i < p->nChunkSize; i++ )
00177 {
00178 *((char **)pTemp) = pTemp + p->nEntrySize;
00179 pTemp += p->nEntrySize;
00180 }
00181
00182 *((char **)pTemp) = NULL;
00183
00184 p->pChunks[ p->nChunks++ ] = p->pEntriesFree;
00185
00186 p->nEntriesAlloc += p->nChunkSize;
00187 }
00188
00189 p->nEntriesUsed++;
00190 if ( p->nEntriesMax < p->nEntriesUsed )
00191 p->nEntriesMax = p->nEntriesUsed;
00192
00193 pTemp = p->pEntriesFree;
00194 p->pEntriesFree = *((char **)pTemp);
00195 return pTemp;
00196 }
00197
00209 void Msat_MmFixedEntryRecycle( Msat_MmFixed_t * p, char * pEntry )
00210 {
00211
00212 p->nEntriesUsed--;
00213
00214 *((char **)pEntry) = p->pEntriesFree;
00215 p->pEntriesFree = pEntry;
00216 }
00217
00229 void Msat_MmFixedRestart( Msat_MmFixed_t * p )
00230 {
00231 int i;
00232 char * pTemp;
00233
00234
00235 for ( i = 1; i < p->nChunks; i++ )
00236 free( p->pChunks[i] );
00237 p->nChunks = 1;
00238
00239 pTemp = p->pChunks[0];
00240 for ( i = 1; i < p->nChunkSize; i++ )
00241 {
00242 *((char **)pTemp) = pTemp + p->nEntrySize;
00243 pTemp += p->nEntrySize;
00244 }
00245
00246 *((char **)pTemp) = NULL;
00247
00248 p->pEntriesFree = p->pChunks[0];
00249
00250 p->nMemoryAlloc = p->nEntrySize * p->nChunkSize;
00251 p->nMemoryUsed = 0;
00252 p->nEntriesAlloc = p->nChunkSize;
00253 p->nEntriesUsed = 0;
00254 }
00255
00267 int Msat_MmFixedReadMemUsage( Msat_MmFixed_t * p )
00268 {
00269 return p->nMemoryAlloc;
00270 }
00271
00272
00273
00285 Msat_MmFlex_t * Msat_MmFlexStart()
00286 {
00287 Msat_MmFlex_t * p;
00288
00289 p = ALLOC( Msat_MmFlex_t, 1 );
00290 memset( p, 0, sizeof(Msat_MmFlex_t) );
00291
00292 p->nEntriesUsed = 0;
00293 p->pCurrent = NULL;
00294 p->pEnd = NULL;
00295
00296 p->nChunkSize = (1 << 12);
00297 p->nChunksAlloc = 64;
00298 p->nChunks = 0;
00299 p->pChunks = ALLOC( char *, p->nChunksAlloc );
00300
00301 p->nMemoryUsed = 0;
00302 p->nMemoryAlloc = 0;
00303 return p;
00304 }
00305
00317 void Msat_MmFlexStop( Msat_MmFlex_t * p, int fVerbose )
00318 {
00319 int i;
00320 if ( p == NULL )
00321 return;
00322 if ( fVerbose )
00323 {
00324 printf( "Flexible memory manager: Chunk size = %d. Chunks used = %d.\n",
00325 p->nChunkSize, p->nChunks );
00326 printf( " Entries used = %d. Memory used = %d. Memory alloc = %d.\n",
00327 p->nEntriesUsed, p->nMemoryUsed, p->nMemoryAlloc );
00328 }
00329 for ( i = 0; i < p->nChunks; i++ )
00330 free( p->pChunks[i] );
00331 free( p->pChunks );
00332 free( p );
00333 }
00334
00346 char * Msat_MmFlexEntryFetch( Msat_MmFlex_t * p, int nBytes )
00347 {
00348 char * pTemp;
00349
00350 if ( p->pCurrent == NULL || p->pCurrent + nBytes > p->pEnd )
00351 {
00352 if ( p->nChunks == p->nChunksAlloc )
00353 {
00354 p->nChunksAlloc *= 2;
00355 p->pChunks = REALLOC( char *, p->pChunks, p->nChunksAlloc );
00356 }
00357 if ( nBytes > p->nChunkSize )
00358 {
00359
00360
00361 p->nChunkSize = 2 * nBytes;
00362 }
00363 p->pCurrent = ALLOC( char, p->nChunkSize );
00364 p->pEnd = p->pCurrent + p->nChunkSize;
00365 p->nMemoryAlloc += p->nChunkSize;
00366
00367 p->pChunks[ p->nChunks++ ] = p->pCurrent;
00368 }
00369 assert( p->pCurrent + nBytes <= p->pEnd );
00370
00371 p->nEntriesUsed++;
00372
00373 p->nMemoryUsed += nBytes;
00374
00375 pTemp = p->pCurrent;
00376 p->pCurrent += nBytes;
00377 return pTemp;
00378 }
00379
00391 int Msat_MmFlexReadMemUsage( Msat_MmFlex_t * p )
00392 {
00393 return p->nMemoryAlloc;
00394 }
00395
00396
00397
00398
00399
00420 Msat_MmStep_t * Msat_MmStepStart( int nSteps )
00421 {
00422 Msat_MmStep_t * p;
00423 int i, k;
00424 p = ALLOC( Msat_MmStep_t, 1 );
00425 p->nMems = nSteps;
00426
00427 p->pMems = ALLOC( Msat_MmFixed_t *, p->nMems );
00428 for ( i = 0; i < p->nMems; i++ )
00429 p->pMems[i] = Msat_MmFixedStart( (8<<i) );
00430
00431 p->nMapSize = (4<<p->nMems);
00432 p->pMap = ALLOC( Msat_MmFixed_t *, p->nMapSize+1 );
00433 p->pMap[0] = NULL;
00434 for ( k = 1; k <= 4; k++ )
00435 p->pMap[k] = p->pMems[0];
00436 for ( i = 0; i < p->nMems; i++ )
00437 for ( k = (4<<i)+1; k <= (8<<i); k++ )
00438 p->pMap[k] = p->pMems[i];
00439
00440
00441 return p;
00442 }
00443
00455 void Msat_MmStepStop( Msat_MmStep_t * p, int fVerbose )
00456 {
00457 int i;
00458 for ( i = 0; i < p->nMems; i++ )
00459 Msat_MmFixedStop( p->pMems[i], fVerbose );
00460 free( p->pMems );
00461 free( p->pMap );
00462 free( p );
00463 }
00464
00476 char * Msat_MmStepEntryFetch( Msat_MmStep_t * p, int nBytes )
00477 {
00478 if ( nBytes == 0 )
00479 return NULL;
00480 if ( nBytes > p->nMapSize )
00481 {
00482
00483 return ALLOC( char, nBytes );
00484 }
00485 return Msat_MmFixedEntryFetch( p->pMap[nBytes] );
00486 }
00487
00488
00500 void Msat_MmStepEntryRecycle( Msat_MmStep_t * p, char * pEntry, int nBytes )
00501 {
00502 if ( nBytes == 0 )
00503 return;
00504 if ( nBytes > p->nMapSize )
00505 {
00506 free( pEntry );
00507 return;
00508 }
00509 Msat_MmFixedEntryRecycle( p->pMap[nBytes], pEntry );
00510 }
00511
00523 int Msat_MmStepReadMemUsage( Msat_MmStep_t * p )
00524 {
00525 int i, nMemTotal = 0;
00526 for ( i = 0; i < p->nMems; i++ )
00527 nMemTotal += p->pMems[i]->nMemoryAlloc;
00528 return nMemTotal;
00529 }