/**CFile**************************************************************** FileName [utilMem.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Memory recycling utilities.] Synopsis [Memory recycling utilities.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 20, 2005.] Revision [$Id: utilMem.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ #include #include #include #include #include "abc_global.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// typedef struct Vec_Mem_t_ Vec_Mem_t; struct Vec_Mem_t_ { int nCap; int nSize; void ** pArray; }; void * s_vAllocs = NULL; void * s_vFrees = NULL; int s_fInterrupt = 0; #define ABC_MEM_ALLOC(type, num) ((type *) malloc(sizeof(type) * (num))) #define ABC_MEM_CALLOC(type, num) ((type *) calloc((num), sizeof(type))) #define ABC_MEM_FALLOC(type, num) ((type *) memset(malloc(sizeof(type) * (num)), 0xff, sizeof(type) * (num))) #define ABC_MEM_FREE(obj) ((obj) ? (free((char *) (obj)), (obj) = 0) : 0) #define ABC_MEM_REALLOC(type, obj, num) \ ((obj) ? ((type *) realloc((char *)(obj), sizeof(type) * (num))) : \ ((type *) malloc(sizeof(type) * (num)))) //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Allocates a vector with the given capacity.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline Vec_Mem_t * Vec_MemAlloc( int nCap ) { Vec_Mem_t * p; p = ABC_MEM_ALLOC( Vec_Mem_t, 1 ); if ( nCap > 0 && nCap < 8 ) nCap = 8; p->nSize = 0; p->nCap = nCap; p->pArray = p->nCap? ABC_MEM_ALLOC( void *, p->nCap ) : NULL; return p; } /**Function************************************************************* Synopsis [Frees the vector.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline void Vec_MemFree( Vec_Mem_t * p ) { ABC_MEM_FREE( p->pArray ); ABC_MEM_FREE( p ); } /**Function************************************************************* Synopsis [Resizes the vector to the given capacity.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline void Vec_MemGrow( Vec_Mem_t * p, int nCapMin ) { if ( p->nCap >= nCapMin ) return; p->pArray = ABC_MEM_REALLOC( void *, p->pArray, nCapMin ); p->nCap = nCapMin; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline void Vec_MemPush( Vec_Mem_t * p, void * Entry ) { if ( p->nSize == p->nCap ) { if ( p->nCap < 16 ) Vec_MemGrow( p, 16 ); else Vec_MemGrow( p, 2 * p->nCap ); } p->pArray[p->nSize++] = Entry; } /**Function************************************************************* Synopsis [Sorting the entries by their integer value.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static void Vec_MemSort( Vec_Mem_t * p, int (*Vec_MemSortCompare)() ) { if ( p->nSize < 2 ) return; qsort( (void *)p->pArray, p->nSize, sizeof(void *), (int (*)(const void *, const void *)) Vec_MemSortCompare ); } /**Function************************************************************* Synopsis [Remembers an allocated pointer.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void * Util_MemRecAlloc( void * pMem ) { if ( s_vAllocs ) Vec_MemPush( (Vec_Mem_t *)s_vAllocs, pMem ); return pMem; } /**Function************************************************************* Synopsis [Remembers a deallocated pointer.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void * Util_MemRecFree( void * pMem ) { if ( s_vFrees ) Vec_MemPush( (Vec_Mem_t *)s_vFrees, pMem ); return pMem; } /**Function************************************************************* Synopsis [Procedure used for sorting the nodes in decreasing order of levels.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Util_ComparePointers( void ** pp1, void ** pp2 ) { if ( *pp1 < *pp2 ) return -1; if ( *pp1 > *pp2 ) return 1; return 0; } /**Function************************************************************* Synopsis [Finds entries that do not appear in both lists.] Description [Assumes that the vectors are sorted in the increasing order.] SideEffects [] SeeAlso [] ***********************************************************************/ static inline Vec_Mem_t * Vec_MemTwoMerge( Vec_Mem_t * vArr1, Vec_Mem_t * vArr2 ) { Vec_Mem_t * vArr = Vec_MemAlloc( vArr1->nSize + vArr2->nSize ); void ** pBeg = vArr->pArray; void ** pBeg1 = vArr1->pArray; void ** pBeg2 = vArr2->pArray; void ** pEnd1 = vArr1->pArray + vArr1->nSize; void ** pEnd2 = vArr2->pArray + vArr2->nSize; while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 ) { if ( *pBeg1 == *pBeg2 ) pBeg1++, pBeg2++; else if ( *pBeg1 < *pBeg2 ) { free( *pBeg1 ); *pBeg++ = *pBeg1++; } else assert( 0 ); // *pBeg++ = *pBeg2++; } while ( pBeg1 < pEnd1 ) *pBeg++ = *pBeg1++; // while ( pBeg2 < pEnd2 ) // *pBeg++ = *pBeg2++; assert( pBeg2 >= pEnd2 ); vArr->nSize = pBeg - vArr->pArray; assert( vArr->nSize <= vArr->nCap ); assert( vArr->nSize >= vArr1->nSize ); assert( vArr->nSize >= vArr2->nSize ); return vArr; } /**Function************************************************************* Synopsis [Recycles the accumulated memory.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Util_MemRecRecycle() { Vec_Mem_t * vMerge; assert( s_vAllocs == NULL ); assert( s_vFrees == NULL ); Vec_MemSort( (Vec_Mem_t *)s_vAllocs, (int (*)())Util_ComparePointers ); Vec_MemSort( (Vec_Mem_t *)s_vFrees, (int (*)())Util_ComparePointers ); vMerge = (Vec_Mem_t *)Vec_MemTwoMerge( (Vec_Mem_t *)s_vAllocs, (Vec_Mem_t *)s_vFrees ); Vec_MemFree( vMerge ); } /**Function************************************************************* Synopsis [Starts memory structures.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Util_MemRecStart() { assert( s_vAllocs == NULL && s_vFrees == NULL ); s_vAllocs = Vec_MemAlloc( 1000 ); s_vFrees = Vec_MemAlloc( 1000 ); } /**Function************************************************************* Synopsis [Quits memory structures.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Util_MemRecQuit() { assert( s_vAllocs != NULL && s_vFrees != NULL ); Vec_MemFree( (Vec_Mem_t *)s_vAllocs ); Vec_MemFree( (Vec_Mem_t *)s_vFrees ); } /**Function************************************************************* Synopsis [Starts memory structures.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Util_MemRecIsSet() { return s_vAllocs != NULL && s_vFrees != NULL; } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END