/**CFile**************************************************************** FileName [fraigMem.c] PackageName [FRAIG: Functionally reduced AND-INV graphs.] Synopsis [Fixed-size-entry memory manager for the FRAIG package.] Author [Alan Mishchenko ] 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