00001
00021 #include "aig.h"
00022
00026
00027 struct Aig_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 Aig_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 struct Aig_MmStep_t_
00066 {
00067 int nMems;
00068 Aig_MmFixed_t ** pMems;
00069 int nMapSize;
00070 Aig_MmFixed_t ** pMap;
00071 };
00072
00073 #define ALLOC(type, num) ((type *) malloc(sizeof(type) * (num)))
00074 #define FREE(obj) ((obj) ? (free((char *) (obj)), (obj) = 0) : 0)
00075 #define REALLOC(type, obj, num) \
00076 ((obj) ? ((type *) realloc((char *)(obj), sizeof(type) * (num))) : \
00077 ((type *) malloc(sizeof(type) * (num))))
00078
00082
00095 Aig_MmFixed_t * Aig_MmFixedStart( int nEntrySize, int nEntriesMax )
00096 {
00097 Aig_MmFixed_t * p;
00098
00099 p = ALLOC( Aig_MmFixed_t, 1 );
00100 memset( p, 0, sizeof(Aig_MmFixed_t) );
00101
00102 p->nEntrySize = nEntrySize;
00103 p->nEntriesAlloc = 0;
00104 p->nEntriesUsed = 0;
00105 p->pEntriesFree = NULL;
00106
00107 p->nChunkSize = nEntriesMax / 8;
00108 if ( p->nChunkSize < 8 )
00109 p->nChunkSize = 8;
00110
00111 p->nChunksAlloc = 64;
00112 p->nChunks = 0;
00113 p->pChunks = ALLOC( char *, p->nChunksAlloc );
00114
00115 p->nMemoryUsed = 0;
00116 p->nMemoryAlloc = 0;
00117 return p;
00118 }
00119
00131 void Aig_MmFixedStop( Aig_MmFixed_t * p, int fVerbose )
00132 {
00133 int i;
00134 if ( p == NULL )
00135 return;
00136 if ( fVerbose )
00137 {
00138 printf( "Fixed memory manager: Entry = %5d. Chunk = %5d. Chunks used = %5d.\n",
00139 p->nEntrySize, p->nChunkSize, p->nChunks );
00140 printf( " Entries used = %8d. Entries peak = %8d. Memory used = %8d. Memory alloc = %8d.\n",
00141 p->nEntriesUsed, p->nEntriesMax, p->nEntrySize * p->nEntriesUsed, p->nMemoryAlloc );
00142 }
00143 for ( i = 0; i < p->nChunks; i++ )
00144 free( p->pChunks[i] );
00145 free( p->pChunks );
00146 free( p );
00147 }
00148
00160 char * Aig_MmFixedEntryFetch( Aig_MmFixed_t * p )
00161 {
00162 char * pTemp;
00163 int i;
00164
00165
00166 if ( p->nEntriesUsed == p->nEntriesAlloc )
00167 {
00168 assert( p->pEntriesFree == NULL );
00169 if ( p->nChunks == p->nChunksAlloc )
00170 {
00171 p->nChunksAlloc *= 2;
00172 p->pChunks = REALLOC( char *, p->pChunks, p->nChunksAlloc );
00173 }
00174 p->pEntriesFree = ALLOC( char, p->nEntrySize * p->nChunkSize );
00175 p->nMemoryAlloc += p->nEntrySize * p->nChunkSize;
00176
00177 pTemp = p->pEntriesFree;
00178 for ( i = 1; i < p->nChunkSize; i++ )
00179 {
00180 *((char **)pTemp) = pTemp + p->nEntrySize;
00181 pTemp += p->nEntrySize;
00182 }
00183
00184 *((char **)pTemp) = NULL;
00185
00186 p->pChunks[ p->nChunks++ ] = p->pEntriesFree;
00187
00188 p->nEntriesAlloc += p->nChunkSize;
00189 }
00190
00191 p->nEntriesUsed++;
00192 if ( p->nEntriesMax < p->nEntriesUsed )
00193 p->nEntriesMax = p->nEntriesUsed;
00194
00195 pTemp = p->pEntriesFree;
00196 p->pEntriesFree = *((char **)pTemp);
00197 return pTemp;
00198 }
00199
00211 void Aig_MmFixedEntryRecycle( Aig_MmFixed_t * p, char * pEntry )
00212 {
00213
00214 p->nEntriesUsed--;
00215
00216 *((char **)pEntry) = p->pEntriesFree;
00217 p->pEntriesFree = pEntry;
00218 }
00219
00231 void Aig_MmFixedRestart( Aig_MmFixed_t * p )
00232 {
00233 int i;
00234 char * pTemp;
00235 if ( p->nChunks == 0 )
00236 return;
00237
00238 for ( i = 1; i < p->nChunks; i++ )
00239 free( p->pChunks[i] );
00240 p->nChunks = 1;
00241
00242 pTemp = p->pChunks[0];
00243 for ( i = 1; i < p->nChunkSize; i++ )
00244 {
00245 *((char **)pTemp) = pTemp + p->nEntrySize;
00246 pTemp += p->nEntrySize;
00247 }
00248
00249 *((char **)pTemp) = NULL;
00250
00251 p->pEntriesFree = p->pChunks[0];
00252
00253 p->nMemoryAlloc = p->nEntrySize * p->nChunkSize;
00254 p->nMemoryUsed = 0;
00255 p->nEntriesAlloc = p->nChunkSize;
00256 p->nEntriesUsed = 0;
00257 }
00258
00270 int Aig_MmFixedReadMemUsage( Aig_MmFixed_t * p )
00271 {
00272 return p->nMemoryAlloc;
00273 }
00274
00286 int Aig_MmFixedReadMaxEntriesUsed( Aig_MmFixed_t * p )
00287 {
00288 return p->nEntriesMax;
00289 }
00290
00291
00292
00304 Aig_MmFlex_t * Aig_MmFlexStart()
00305 {
00306 Aig_MmFlex_t * p;
00307
00308 p = ALLOC( Aig_MmFlex_t, 1 );
00309 memset( p, 0, sizeof(Aig_MmFlex_t) );
00310
00311 p->nEntriesUsed = 0;
00312 p->pCurrent = NULL;
00313 p->pEnd = NULL;
00314
00315 p->nChunkSize = (1 << 18);
00316 p->nChunksAlloc = 64;
00317 p->nChunks = 0;
00318 p->pChunks = ALLOC( char *, p->nChunksAlloc );
00319
00320 p->nMemoryUsed = 0;
00321 p->nMemoryAlloc = 0;
00322 return p;
00323 }
00324
00336 void Aig_MmFlexStop( Aig_MmFlex_t * p, int fVerbose )
00337 {
00338 int i;
00339 if ( p == NULL )
00340 return;
00341 if ( fVerbose )
00342 {
00343 printf( "Flexible memory manager: Chunk size = %d. Chunks used = %d.\n",
00344 p->nChunkSize, p->nChunks );
00345 printf( " Entries used = %d. Memory used = %d. Memory alloc = %d.\n",
00346 p->nEntriesUsed, p->nMemoryUsed, p->nMemoryAlloc );
00347 }
00348 for ( i = 0; i < p->nChunks; i++ )
00349 free( p->pChunks[i] );
00350 free( p->pChunks );
00351 free( p );
00352 }
00353
00365 char * Aig_MmFlexEntryFetch( Aig_MmFlex_t * p, int nBytes )
00366 {
00367 char * pTemp;
00368
00369 if ( p->pCurrent == NULL || p->pCurrent + nBytes > p->pEnd )
00370 {
00371 if ( p->nChunks == p->nChunksAlloc )
00372 {
00373 p->nChunksAlloc *= 2;
00374 p->pChunks = REALLOC( char *, p->pChunks, p->nChunksAlloc );
00375 }
00376 if ( nBytes > p->nChunkSize )
00377 {
00378
00379
00380 p->nChunkSize = 2 * nBytes;
00381 }
00382 p->pCurrent = ALLOC( char, p->nChunkSize );
00383 p->pEnd = p->pCurrent + p->nChunkSize;
00384 p->nMemoryAlloc += p->nChunkSize;
00385
00386 p->pChunks[ p->nChunks++ ] = p->pCurrent;
00387 }
00388 assert( p->pCurrent + nBytes <= p->pEnd );
00389
00390 p->nEntriesUsed++;
00391
00392 p->nMemoryUsed += nBytes;
00393
00394 pTemp = p->pCurrent;
00395 p->pCurrent += nBytes;
00396 return pTemp;
00397 }
00398
00410 void Aig_MmFlexRestart( Aig_MmFlex_t * p )
00411 {
00412 int i;
00413 if ( p->nChunks == 0 )
00414 return;
00415
00416 for ( i = 1; i < p->nChunks; i++ )
00417 free( p->pChunks[i] );
00418 p->nChunks = 1;
00419 p->nMemoryAlloc = p->nChunkSize;
00420
00421 p->pCurrent = p->pChunks[0];
00422 p->pEnd = p->pCurrent + p->nChunkSize;
00423 p->nEntriesUsed = 0;
00424 p->nMemoryUsed = 0;
00425 }
00426
00438 int Aig_MmFlexReadMemUsage( Aig_MmFlex_t * p )
00439 {
00440 return p->nMemoryUsed;
00441 }
00442
00443
00444
00445
00446
00467 Aig_MmStep_t * Aig_MmStepStart( int nSteps )
00468 {
00469 Aig_MmStep_t * p;
00470 int i, k;
00471 p = ALLOC( Aig_MmStep_t, 1 );
00472 memset( p, 0, sizeof(Aig_MmStep_t) );
00473 p->nMems = nSteps;
00474
00475 p->pMems = ALLOC( Aig_MmFixed_t *, p->nMems );
00476 for ( i = 0; i < p->nMems; i++ )
00477 p->pMems[i] = Aig_MmFixedStart( (8<<i), (1<<13) );
00478
00479 p->nMapSize = (4<<p->nMems);
00480 p->pMap = ALLOC( Aig_MmFixed_t *, p->nMapSize+1 );
00481 p->pMap[0] = NULL;
00482 for ( k = 1; k <= 4; k++ )
00483 p->pMap[k] = p->pMems[0];
00484 for ( i = 0; i < p->nMems; i++ )
00485 for ( k = (4<<i)+1; k <= (8<<i); k++ )
00486 p->pMap[k] = p->pMems[i];
00487
00488
00489 return p;
00490 }
00491
00503 void Aig_MmStepStop( Aig_MmStep_t * p, int fVerbose )
00504 {
00505 int i;
00506 for ( i = 0; i < p->nMems; i++ )
00507 Aig_MmFixedStop( p->pMems[i], fVerbose );
00508
00509
00510
00511
00512
00513
00514 free( p->pMems );
00515 free( p->pMap );
00516 free( p );
00517 }
00518
00530 char * Aig_MmStepEntryFetch( Aig_MmStep_t * p, int nBytes )
00531 {
00532 if ( nBytes == 0 )
00533 return NULL;
00534 if ( nBytes > p->nMapSize )
00535 {
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548 return ALLOC( char, nBytes );
00549 }
00550 return Aig_MmFixedEntryFetch( p->pMap[nBytes] );
00551 }
00552
00553
00565 void Aig_MmStepEntryRecycle( Aig_MmStep_t * p, char * pEntry, int nBytes )
00566 {
00567 if ( nBytes == 0 )
00568 return;
00569 if ( nBytes > p->nMapSize )
00570 {
00571 free( pEntry );
00572 return;
00573 }
00574 Aig_MmFixedEntryRecycle( p->pMap[nBytes], pEntry );
00575 }
00576
00588 int Aig_MmStepReadMemUsage( Aig_MmStep_t * p )
00589 {
00590 int i, nMemTotal = 0;
00591 for ( i = 0; i < p->nMems; i++ )
00592 nMemTotal += p->pMems[i]->nMemoryAlloc;
00593 return nMemTotal;
00594 }
00595