00001
00021 #include "extra.h"
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 struct Extra_MmFixed_t_
00032 {
00033
00034 int nEntrySize;
00035 int nEntriesAlloc;
00036 int nEntriesUsed;
00037 int nEntriesMax;
00038 char * pEntriesFree;
00039
00040
00041 int nChunkSize;
00042 int nChunksAlloc;
00043 int nChunks;
00044 char ** pChunks;
00045
00046
00047 int nMemoryUsed;
00048 int nMemoryAlloc;
00049 };
00050
00051 struct Extra_MmFlex_t_
00052 {
00053
00054 int nEntriesUsed;
00055 char * pCurrent;
00056 char * pEnd;
00057
00058
00059 int nChunkSize;
00060 int nChunksAlloc;
00061 int nChunks;
00062 char ** pChunks;
00063
00064
00065 int nMemoryUsed;
00066 int nMemoryAlloc;
00067 };
00068
00069
00070 struct Extra_MmStep_t_
00071 {
00072 int nMems;
00073 Extra_MmFixed_t ** pMems;
00074 int nMapSize;
00075 Extra_MmFixed_t ** pMap;
00076 int nLargeChunksAlloc;
00077 int nLargeChunks;
00078 void ** pLargeChunks;
00079 };
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00096
00097
00098
00099
00103
00104
00105
00106
00119 Extra_MmFixed_t * Extra_MmFixedStart( int nEntrySize )
00120 {
00121 Extra_MmFixed_t * p;
00122
00123 p = ALLOC( Extra_MmFixed_t, 1 );
00124 memset( p, 0, sizeof(Extra_MmFixed_t) );
00125
00126 p->nEntrySize = nEntrySize;
00127 p->nEntriesAlloc = 0;
00128 p->nEntriesUsed = 0;
00129 p->pEntriesFree = NULL;
00130
00131 if ( nEntrySize * (1 << 10) < (1<<16) )
00132 p->nChunkSize = (1 << 10);
00133 else
00134 p->nChunkSize = (1<<16) / nEntrySize;
00135 if ( p->nChunkSize < 8 )
00136 p->nChunkSize = 8;
00137
00138 p->nChunksAlloc = 64;
00139 p->nChunks = 0;
00140 p->pChunks = ALLOC( char *, p->nChunksAlloc );
00141
00142 p->nMemoryUsed = 0;
00143 p->nMemoryAlloc = 0;
00144 return p;
00145 }
00146
00158 void Extra_MmFixedPrint( Extra_MmFixed_t * p )
00159 {
00160 printf( "Fixed memory manager: Entry = %5d. Chunk = %5d. Chunks used = %5d.\n",
00161 p->nEntrySize, p->nChunkSize, p->nChunks );
00162 printf( " Entries used = %8d. Entries peak = %8d. Memory used = %8d. Memory alloc = %8d.\n",
00163 p->nEntriesUsed, p->nEntriesMax, p->nEntrySize * p->nEntriesUsed, p->nMemoryAlloc );
00164 }
00165
00177 void Extra_MmFixedStop( Extra_MmFixed_t * p )
00178 {
00179 int i;
00180 if ( p == NULL )
00181 return;
00182 for ( i = 0; i < p->nChunks; i++ )
00183 free( p->pChunks[i] );
00184 free( p->pChunks );
00185 free( p );
00186 }
00187
00199 char * Extra_MmFixedEntryFetch( Extra_MmFixed_t * p )
00200 {
00201 char * pTemp;
00202 int i;
00203
00204
00205 if ( p->nEntriesUsed == p->nEntriesAlloc )
00206 {
00207 assert( p->pEntriesFree == NULL );
00208 if ( p->nChunks == p->nChunksAlloc )
00209 {
00210 p->nChunksAlloc *= 2;
00211 p->pChunks = REALLOC( char *, p->pChunks, p->nChunksAlloc );
00212 }
00213 p->pEntriesFree = ALLOC( char, p->nEntrySize * p->nChunkSize );
00214 p->nMemoryAlloc += p->nEntrySize * p->nChunkSize;
00215
00216 pTemp = p->pEntriesFree;
00217 for ( i = 1; i < p->nChunkSize; i++ )
00218 {
00219 *((char **)pTemp) = pTemp + p->nEntrySize;
00220 pTemp += p->nEntrySize;
00221 }
00222
00223 *((char **)pTemp) = NULL;
00224
00225 p->pChunks[ p->nChunks++ ] = p->pEntriesFree;
00226
00227 p->nEntriesAlloc += p->nChunkSize;
00228 }
00229
00230 p->nEntriesUsed++;
00231 if ( p->nEntriesMax < p->nEntriesUsed )
00232 p->nEntriesMax = p->nEntriesUsed;
00233
00234 pTemp = p->pEntriesFree;
00235 p->pEntriesFree = *((char **)pTemp);
00236 return pTemp;
00237 }
00238
00250 void Extra_MmFixedEntryRecycle( Extra_MmFixed_t * p, char * pEntry )
00251 {
00252
00253 p->nEntriesUsed--;
00254
00255 *((char **)pEntry) = p->pEntriesFree;
00256 p->pEntriesFree = pEntry;
00257 }
00258
00270 void Extra_MmFixedRestart( Extra_MmFixed_t * p )
00271 {
00272 int i;
00273 char * pTemp;
00274
00275
00276 for ( i = 1; i < p->nChunks; i++ )
00277 free( p->pChunks[i] );
00278 p->nChunks = 1;
00279
00280 pTemp = p->pChunks[0];
00281 for ( i = 1; i < p->nChunkSize; i++ )
00282 {
00283 *((char **)pTemp) = pTemp + p->nEntrySize;
00284 pTemp += p->nEntrySize;
00285 }
00286
00287 *((char **)pTemp) = NULL;
00288
00289 p->pEntriesFree = p->pChunks[0];
00290
00291 p->nMemoryAlloc = p->nEntrySize * p->nChunkSize;
00292 p->nMemoryUsed = 0;
00293 p->nEntriesAlloc = p->nChunkSize;
00294 p->nEntriesUsed = 0;
00295 }
00296
00308 int Extra_MmFixedReadMemUsage( Extra_MmFixed_t * p )
00309 {
00310 return p->nMemoryAlloc;
00311 }
00312
00324 int Extra_MmFixedReadMaxEntriesUsed( Extra_MmFixed_t * p )
00325 {
00326 return p->nEntriesMax;
00327 }
00328
00329
00341 Extra_MmFlex_t * Extra_MmFlexStart()
00342 {
00343 Extra_MmFlex_t * p;
00344
00345 p = ALLOC( Extra_MmFlex_t, 1 );
00346 memset( p, 0, sizeof(Extra_MmFlex_t) );
00347
00348 p->nEntriesUsed = 0;
00349 p->pCurrent = NULL;
00350 p->pEnd = NULL;
00351
00352 p->nChunkSize = (1 << 10);
00353 p->nChunksAlloc = 64;
00354 p->nChunks = 0;
00355 p->pChunks = ALLOC( char *, p->nChunksAlloc );
00356
00357 p->nMemoryUsed = 0;
00358 p->nMemoryAlloc = 0;
00359 return p;
00360 }
00361
00373 void Extra_MmFlexPrint( Extra_MmFlex_t * p )
00374 {
00375 printf( "Flexible memory manager: Chunk size = %d. Chunks used = %d.\n",
00376 p->nChunkSize, p->nChunks );
00377 printf( " Entries used = %d. Memory used = %d. Memory alloc = %d.\n",
00378 p->nEntriesUsed, p->nMemoryUsed, p->nMemoryAlloc );
00379 }
00380
00392 void Extra_MmFlexStop( Extra_MmFlex_t * p )
00393 {
00394 int i;
00395 if ( p == NULL )
00396 return;
00397
00398 for ( i = 0; i < p->nChunks; i++ )
00399 free( p->pChunks[i] );
00400 free( p->pChunks );
00401 free( p );
00402 }
00403
00415 char * Extra_MmFlexEntryFetch( Extra_MmFlex_t * p, int nBytes )
00416 {
00417 char * pTemp;
00418
00419 if ( p->pCurrent == NULL || p->pCurrent + nBytes > p->pEnd )
00420 {
00421 if ( p->nChunks == p->nChunksAlloc )
00422 {
00423 p->nChunksAlloc *= 2;
00424 p->pChunks = REALLOC( char *, p->pChunks, p->nChunksAlloc );
00425 }
00426 if ( nBytes > p->nChunkSize )
00427 {
00428
00429
00430 p->nChunkSize = 2 * nBytes;
00431 }
00432 p->pCurrent = ALLOC( char, p->nChunkSize );
00433 p->pEnd = p->pCurrent + p->nChunkSize;
00434 p->nMemoryAlloc += p->nChunkSize;
00435
00436 p->pChunks[ p->nChunks++ ] = p->pCurrent;
00437 }
00438 assert( p->pCurrent + nBytes <= p->pEnd );
00439
00440 p->nEntriesUsed++;
00441
00442 p->nMemoryUsed += nBytes;
00443
00444 pTemp = p->pCurrent;
00445 p->pCurrent += nBytes;
00446 return pTemp;
00447 }
00448
00460 int Extra_MmFlexReadMemUsage( Extra_MmFlex_t * p )
00461 {
00462 return p->nMemoryAlloc;
00463 }
00464
00465
00466
00467
00468
00489 Extra_MmStep_t * Extra_MmStepStart( int nSteps )
00490 {
00491 Extra_MmStep_t * p;
00492 int i, k;
00493 p = ALLOC( Extra_MmStep_t, 1 );
00494 memset( p, 0, sizeof(Extra_MmStep_t) );
00495 p->nMems = nSteps;
00496
00497 p->pMems = ALLOC( Extra_MmFixed_t *, p->nMems );
00498 for ( i = 0; i < p->nMems; i++ )
00499 p->pMems[i] = Extra_MmFixedStart( (8<<i) );
00500
00501 p->nMapSize = (4<<p->nMems);
00502 p->pMap = ALLOC( Extra_MmFixed_t *, p->nMapSize+1 );
00503 p->pMap[0] = NULL;
00504 for ( k = 1; k <= 4; k++ )
00505 p->pMap[k] = p->pMems[0];
00506 for ( i = 0; i < p->nMems; i++ )
00507 for ( k = (4<<i)+1; k <= (8<<i); k++ )
00508 p->pMap[k] = p->pMems[i];
00509
00510
00511 return p;
00512 }
00513
00525 void Extra_MmStepStop( Extra_MmStep_t * p )
00526 {
00527 int i;
00528 for ( i = 0; i < p->nMems; i++ )
00529 Extra_MmFixedStop( p->pMems[i] );
00530
00531
00532
00533
00534
00535
00536 free( p->pMems );
00537 free( p->pMap );
00538 free( p );
00539 }
00540
00552 char * Extra_MmStepEntryFetch( Extra_MmStep_t * p, int nBytes )
00553 {
00554 if ( nBytes == 0 )
00555 return NULL;
00556 if ( nBytes > p->nMapSize )
00557 {
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570 return ALLOC( char, nBytes );
00571 }
00572 return Extra_MmFixedEntryFetch( p->pMap[nBytes] );
00573 }
00574
00575
00587 void Extra_MmStepEntryRecycle( Extra_MmStep_t * p, char * pEntry, int nBytes )
00588 {
00589 if ( nBytes == 0 )
00590 return;
00591 if ( nBytes > p->nMapSize )
00592 {
00593 free( pEntry );
00594 return;
00595 }
00596 Extra_MmFixedEntryRecycle( p->pMap[nBytes], pEntry );
00597 }
00598
00610 int Extra_MmStepReadMemUsage( Extra_MmStep_t * p )
00611 {
00612 int i, nMemTotal = 0;
00613 for ( i = 0; i < p->nMems; i++ )
00614 nMemTotal += p->pMems[i]->nMemoryAlloc;
00615 return nMemTotal;
00616 }
00617
00618
00619
00620
00621
00622
00623
00624
00625