blob: 0bce119b79bb363e2fbfeaa160880f6b9fa513e0 [file] [log] [blame]
/**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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#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