| /**CFile**************************************************************** |
| |
| FileName [fraigMem.c] |
| |
| PackageName [FRAIG: Functionally reduced AND-INV graphs.] |
| |
| Synopsis [Fixed-size-entry memory manager for the FRAIG package.] |
| |
| Author [Alan Mishchenko <alanmi@eecs.berkeley.edu>] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 2.0. Started - October 1, 2004] |
| |
| Revision [$Id: fraigMem.c,v 1.4 2005/07/08 01:01:31 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "fraigInt.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| struct Fraig_MemFixed_t_ |
| { |
| // information about individual entries |
| int nEntrySize; // the size of one entry |
| int nEntriesAlloc; // the total number of entries allocated |
| int nEntriesUsed; // the number of entries in use |
| int nEntriesMax; // the max number of entries in use |
| char * pEntriesFree; // the linked list of free entries |
| |
| // this is where the memory is stored |
| int nChunkSize; // the size of one chunk |
| int nChunksAlloc; // the maximum number of memory chunks |
| int nChunks; // the current number of memory chunks |
| char ** pChunks; // the allocated memory |
| |
| // statistics |
| int nMemoryUsed; // memory used in the allocated entries |
| int nMemoryAlloc; // memory allocated |
| }; |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [Starts the internal memory manager.] |
| |
| Description [Can only work with entry size at least 4 byte long.] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Fraig_MemFixed_t * Fraig_MemFixedStart( int nEntrySize ) |
| { |
| Fraig_MemFixed_t * p; |
| |
| p = ABC_ALLOC( Fraig_MemFixed_t, 1 ); |
| memset( p, 0, sizeof(Fraig_MemFixed_t) ); |
| |
| p->nEntrySize = nEntrySize; |
| p->nEntriesAlloc = 0; |
| p->nEntriesUsed = 0; |
| p->pEntriesFree = NULL; |
| |
| if ( nEntrySize * (1 << 10) < (1<<16) ) |
| p->nChunkSize = (1 << 10); |
| else |
| p->nChunkSize = (1<<16) / nEntrySize; |
| if ( p->nChunkSize < 8 ) |
| p->nChunkSize = 8; |
| |
| p->nChunksAlloc = 64; |
| p->nChunks = 0; |
| p->pChunks = ABC_ALLOC( char *, p->nChunksAlloc ); |
| |
| p->nMemoryUsed = 0; |
| p->nMemoryAlloc = 0; |
| return p; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Stops the internal memory manager.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Fraig_MemFixedStop( Fraig_MemFixed_t * p, int fVerbose ) |
| { |
| int i; |
| if ( p == NULL ) |
| return; |
| if ( fVerbose ) |
| { |
| printf( "Fixed memory manager: Entry = %5d. Chunk = %5d. Chunks used = %5d.\n", |
| p->nEntrySize, p->nChunkSize, p->nChunks ); |
| printf( " Entries used = %8d. Entries peak = %8d. Memory used = %8d. Memory alloc = %8d.\n", |
| p->nEntriesUsed, p->nEntriesMax, p->nEntrySize * p->nEntriesUsed, p->nMemoryAlloc ); |
| } |
| for ( i = 0; i < p->nChunks; i++ ) |
| ABC_FREE( p->pChunks[i] ); |
| ABC_FREE( p->pChunks ); |
| ABC_FREE( p ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Extracts one entry from the memory manager.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| char * Fraig_MemFixedEntryFetch( Fraig_MemFixed_t * p ) |
| { |
| char * pTemp; |
| int i; |
| |
| // check if there are still free entries |
| if ( p->nEntriesUsed == p->nEntriesAlloc ) |
| { // need to allocate more entries |
| assert( p->pEntriesFree == NULL ); |
| if ( p->nChunks == p->nChunksAlloc ) |
| { |
| p->nChunksAlloc *= 2; |
| p->pChunks = ABC_REALLOC( char *, p->pChunks, p->nChunksAlloc ); |
| } |
| p->pEntriesFree = ABC_ALLOC( char, p->nEntrySize * p->nChunkSize ); |
| p->nMemoryAlloc += p->nEntrySize * p->nChunkSize; |
| // transform these entries into a linked list |
| pTemp = p->pEntriesFree; |
| for ( i = 1; i < p->nChunkSize; i++ ) |
| { |
| *((char **)pTemp) = pTemp + p->nEntrySize; |
| pTemp += p->nEntrySize; |
| } |
| // set the last link |
| *((char **)pTemp) = NULL; |
| // add the chunk to the chunk storage |
| p->pChunks[ p->nChunks++ ] = p->pEntriesFree; |
| // add to the number of entries allocated |
| p->nEntriesAlloc += p->nChunkSize; |
| } |
| // incrememt the counter of used entries |
| p->nEntriesUsed++; |
| if ( p->nEntriesMax < p->nEntriesUsed ) |
| p->nEntriesMax = p->nEntriesUsed; |
| // return the first entry in the free entry list |
| pTemp = p->pEntriesFree; |
| p->pEntriesFree = *((char **)pTemp); |
| return pTemp; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Returns one entry into the memory manager.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Fraig_MemFixedEntryRecycle( Fraig_MemFixed_t * p, char * pEntry ) |
| { |
| // decrement the counter of used entries |
| p->nEntriesUsed--; |
| // add the entry to the linked list of free entries |
| *((char **)pEntry) = p->pEntriesFree; |
| p->pEntriesFree = pEntry; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Frees all associated memory and resets the manager.] |
| |
| Description [Relocates all the memory except the first chunk.] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Fraig_MemFixedRestart( Fraig_MemFixed_t * p ) |
| { |
| int i; |
| char * pTemp; |
| |
| // deallocate all chunks except the first one |
| for ( i = 1; i < p->nChunks; i++ ) |
| ABC_FREE( p->pChunks[i] ); |
| p->nChunks = 1; |
| // transform these entries into a linked list |
| pTemp = p->pChunks[0]; |
| for ( i = 1; i < p->nChunkSize; i++ ) |
| { |
| *((char **)pTemp) = pTemp + p->nEntrySize; |
| pTemp += p->nEntrySize; |
| } |
| // set the last link |
| *((char **)pTemp) = NULL; |
| // set the free entry list |
| p->pEntriesFree = p->pChunks[0]; |
| // set the correct statistics |
| p->nMemoryAlloc = p->nEntrySize * p->nChunkSize; |
| p->nMemoryUsed = 0; |
| p->nEntriesAlloc = p->nChunkSize; |
| p->nEntriesUsed = 0; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Reports the memory usage.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Fraig_MemFixedReadMemUsage( Fraig_MemFixed_t * p ) |
| { |
| return p->nMemoryAlloc; |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |