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 }