fraigMem.c 7.43 KB
Newer Older
Alan Mishchenko committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/**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"

21 22 23
ABC_NAMESPACE_IMPL_START


Alan Mishchenko committed
24 25 26 27 28 29 30 31 32 33 34
////////////////////////////////////////////////////////////////////////
///                        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
35
    char *        pEntriesFree;  // the linked list of free entries
Alan Mishchenko committed
36 37 38 39 40 41 42 43 44 45 46 47 48

    // 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
};

////////////////////////////////////////////////////////////////////////
Alan Mishchenko committed
49
///                     FUNCTION DEFINITIONS                         ///
Alan Mishchenko committed
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
////////////////////////////////////////////////////////////////////////

/**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;

Alan Mishchenko committed
67
    p = ABC_ALLOC( Fraig_MemFixed_t, 1 );
Alan Mishchenko committed
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
    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;
Alan Mishchenko committed
84
    p->pChunks       = ABC_ALLOC( char *, p->nChunksAlloc );
Alan Mishchenko committed
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114

    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++ )
Alan Mishchenko committed
115 116 117
        ABC_FREE( p->pChunks[i] );
    ABC_FREE( p->pChunks );
    ABC_FREE( p );
Alan Mishchenko committed
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
}

/**Function*************************************************************

  Synopsis    [Extracts one entry from the memory manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
char * Fraig_MemFixedEntryFetch( Fraig_MemFixed_t * p )
{
    char * pTemp;
    int i;

136
    // check if there are still free entries
Alan Mishchenko committed
137 138 139 140 141 142
    if ( p->nEntriesUsed == p->nEntriesAlloc )
    { // need to allocate more entries
        assert( p->pEntriesFree == NULL );
        if ( p->nChunks == p->nChunksAlloc )
        {
            p->nChunksAlloc *= 2;
Alan Mishchenko committed
143
            p->pChunks = ABC_REALLOC( char *, p->pChunks, p->nChunksAlloc ); 
Alan Mishchenko committed
144
        }
Alan Mishchenko committed
145
        p->pEntriesFree = ABC_ALLOC( char, p->nEntrySize * p->nChunkSize );
Alan Mishchenko committed
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
        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;
165
    // return the first entry in the free entry list
Alan Mishchenko committed
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
    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--;
186
    // add the entry to the linked list of free entries
Alan Mishchenko committed
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
    *((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;

Alan Mishchenko committed
207
    // deallocate all chunks except the first one
Alan Mishchenko committed
208
    for ( i = 1; i < p->nChunks; i++ )
Alan Mishchenko committed
209
        ABC_FREE( p->pChunks[i] );
Alan Mishchenko committed
210 211 212 213 214 215 216 217 218 219
    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;
220
    // set the free entry list
Alan Mishchenko committed
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
    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                                ///
////////////////////////////////////////////////////////////////////////


250 251
ABC_NAMESPACE_IMPL_END