abc/src/bdd/cudd/cuddTable.c
/**Function********************************************************************

  Synopsis    [Fast storage allocation for DdNodes in the table.]

  Description [Fast storage allocation for DdNodes in the table. The
  first 4 bytes of a chunk contain a pointer to the next block; the
  rest contains DD_MEM_CHUNK spaces for DdNodes.  Returns a pointer to
  a new node if successful; NULL is memory is full.]

  SideEffects [None]

  SeeAlso     [cuddDynamicAllocNode]

******************************************************************************/
Function
Synopsis    [Fast storage allocation for DdNodes in the table.]

Description [Fast storage allocation for DdNodes in the table. The
first 4 bytes of a chunk contain a pointer to the next block; the
rest contains DD_MEM_CHUNK spaces for DdNodes.  Returns a pointer to
a new node if successful; NULL is memory is full.]




Function Synopsis [ Fast storage allocation for DdNodes in the table . ] Description [ Fast storage allocation for DdNodes in the table . The first 4 bytes of a chunk contain a pointer to the next block ; the rest contains DD_MEM_CHUNK spaces for DdNodes . Returns a pointer to a new node if successful ; NULL is memory is full . ]
DdNode *
cuddAllocNode(
  DdManager * unique)
{
    int i;
    DdNodePtr *mem;
    DdNode *list, *node;
    extern DD_OOMFP MMoutOfMemory;
    DD_OOMFP saveHandler;
    if (unique->nextFree == NULL) {     
        if ((unique->keys - unique->dead) + (unique->keysZ - unique->deadZ) >
            unique->maxLive) {
            unique->errorCode = CUDD_TOO_MANY_NODES;
            return(NULL);
        }
        if (unique->stash == NULL || unique->memused > unique->maxmemhard) {
            (void) cuddGarbageCollect(unique,1);
            mem = NULL;
        }
        if (unique->nextFree == NULL) {
            if (unique->memused > unique->maxmemhard) {
                unique->errorCode = CUDD_MAX_MEM_EXCEEDED;
                return(NULL);
            }
            saveHandler = MMoutOfMemory;
            MMoutOfMemory = Cudd_OutOfMem;
            mem = (DdNodePtr *) ABC_ALLOC(DdNode,DD_MEM_CHUNK + 2);
            MMoutOfMemory = saveHandler;
            if (mem == NULL) {
                if (cuddGarbageCollect(unique,1) == 0) {
                    if (unique->stash != NULL) {
                        ABC_FREE(unique->stash);
                        unique->stash = NULL;
                        cuddSlowTableGrowth(unique);
                        mem = (DdNodePtr *) ABC_ALLOC(DdNode,DD_MEM_CHUNK + 2);
                    }
                    if (mem == NULL) {
                        (*MMoutOfMemory)(sizeof(DdNode)*(DD_MEM_CHUNK + 1));
                        unique->errorCode = CUDD_MEMORY_OUT;
#ifdef DD_VERBOSE
                        (void) fprintf(unique->err,
                                       "cuddAllocNode: out of memory");
                        (void) fprintf(unique->err, "Memory in use = %lu\n",
                                       unique->memused);
#endif
                        return(NULL);
                    }
                }
            }
            if (mem != NULL) {  
                ptruint offset;
                unique->memused += (DD_MEM_CHUNK + 1) * sizeof(DdNode);
                mem[0] = (DdNodePtr) unique->memoryList;
                unique->memoryList = mem;
                offset = (ptruint) mem & (32 - 1);
                mem += (32 - offset) / sizeof(DdNodePtr);
                assert(((ptruint) mem & (32 - 1)) == 0);
                list = (DdNode *) mem;
                i = 1;
                do {
                    list[i - 1].ref = 0;
                    list[i - 1].next = &list[i];
                } while (++i < DD_MEM_CHUNK);
                list[DD_MEM_CHUNK-1].ref = 0;
                list[DD_MEM_CHUNK-1].next = NULL;
                unique->nextFree = &list[0];
            }
        }
    }
    unique->allocated++;
    node = unique->nextFree;
    unique->nextFree = node->next;
    node->Id = (unique->allocated<<4);
    return(node);
}
DdNode * cuddAllocNode ( DdManager * unique ) { int i ; DdNodePtr * mem ; DdNode * list , * node ; extern DD_OOMFP MMoutOfMemory ; DD_OOMFP saveHandler ; if ( unique -> nextFree == NULL ) { if ( ( unique -> keys - unique -> dead ) + ( unique -> keysZ - unique -> deadZ ) > unique -> maxLive ) { unique -> errorCode = CUDD_TOO_MANY_NODES ; return ( NULL ) ; } if ( unique -> stash == NULL || unique -> memused > unique -> maxmemhard ) { ( void ) cuddGarbageCollect ( unique , 1 ) ; mem = NULL ; } if ( unique -> nextFree == NULL ) { if ( unique -> memused > unique -> maxmemhard ) { unique -> errorCode = CUDD_MAX_MEM_EXCEEDED ; return ( NULL ) ; } saveHandler = MMoutOfMemory ; MMoutOfMemory = Cudd_OutOfMem ; mem = ( DdNodePtr * ) ABC_ALLOC ( DdNode , DD_MEM_CHUNK + 2 ) ; MMoutOfMemory = saveHandler ; if ( mem == NULL ) { if ( cuddGarbageCollect ( unique , 1 ) == 0 ) { if ( unique -> stash != NULL ) { ABC_FREE ( unique -> stash ) ; unique -> stash = NULL ; cuddSlowTableGrowth ( unique ) ; mem = ( DdNodePtr * ) ABC_ALLOC ( DdNode , DD_MEM_CHUNK + 2 ) ; } if ( mem == NULL ) { ( * MMoutOfMemory ) ( sizeof ( DdNode ) * ( DD_MEM_CHUNK + 1 ) ) ; unique -> errorCode = CUDD_MEMORY_OUT ; #ifdef DD_VERBOSE ( void ) fprintf ( unique -> err , " " ) ; ( void ) fprintf ( unique -> err , " \n " , unique -> memused ) ; #endif return ( NULL ) ; } } } if ( mem != NULL ) { ptruint offset ; unique -> memused += ( DD_MEM_CHUNK + 1 ) * sizeof ( DdNode ) ; mem [ 0 ] = ( DdNodePtr ) unique -> memoryList ; unique -> memoryList = mem ; offset = ( ptruint ) mem & ( 32 - 1 ) ; mem += ( 32 - offset ) / sizeof ( DdNodePtr ) ; assert ( ( ( ptruint ) mem & ( 32 - 1 ) ) == 0 ) ; list = ( DdNode * ) mem ; i = 1 ; do { list [ i - 1 ] . ref = 0 ; list [ i - 1 ] . next = & list [ i ] ; } while ( ++ i < DD_MEM_CHUNK ) ; list [ DD_MEM_CHUNK - 1 ] . ref = 0 ; list [ DD_MEM_CHUNK - 1 ] . next = NULL ; unique -> nextFree = & list [ 0 ] ; } } } unique -> allocated ++ ; node = unique -> nextFree ; unique -> nextFree = node -> next ; node -> Id = ( unique -> allocated << 4 ) ; return ( node ) ; }
Function
Synopsis    [Fast storage allocation for DdNodes in the table.]
Function Synopsis [ Fast storage allocation for DdNodes in the table . ]
/* free list is empty */ /* Check for exceeded limits. */ /* Try to allocate a new block. */ //            mem = (DdNodePtr *) ABC_ALLOC(DdNode,DD_MEM_CHUNK + 1); /* No more memory: Try collecting garbage. If this succeeds,
                ** we end up with mem still NULL, but unique->nextFree !=
                ** NULL. */ /* Last resort: Free the memory stashed away, if there
                    ** any. If this succeeeds, mem != NULL and
                    ** unique->nextFree still NULL. */ /* Inhibit resizing of tables. */ /* Now try again. */ //                        mem = (DdNodePtr *) ABC_ALLOC(DdNode,DD_MEM_CHUNK + 1); /* Out of luck. Call the default handler to do
                        ** whatever it specifies for a failed malloc.
                        ** If this handler returns, then set error code,
                        ** print warning, and return. */ /* successful allocation; slice memory */ /* Here we rely on the fact that a DdNode is as large as 4 pointers.  */ //                offset = (ptruint) mem & (sizeof(DdNode) - 1); //                mem += (sizeof(DdNode) - offset) / sizeof(DdNodePtr); //                assert(((ptruint) mem & (sizeof(DdNode) - 1)) == 0); //                list = (DdNode *) mem;