src/bdd/cudd/cuddRef.c File Reference

#include "util_hack.h"
#include "cuddInt.h"
Include dependency graph for cuddRef.c:

Go to the source code of this file.

Functions

void Cudd_Ref (DdNode *n)
void Cudd_RecursiveDeref (DdManager *table, DdNode *n)
void Cudd_IterDerefBdd (DdManager *table, DdNode *n)
void Cudd_DelayedDerefBdd (DdManager *table, DdNode *n)
void Cudd_RecursiveDerefZdd (DdManager *table, DdNode *n)
void Cudd_Deref (DdNode *node)
int Cudd_CheckZeroRef (DdManager *manager)
void cuddReclaim (DdManager *table, DdNode *n)
void cuddReclaimZdd (DdManager *table, DdNode *n)
void cuddShrinkDeathRow (DdManager *table)
void cuddClearDeathRow (DdManager *table)
int cuddIsInDeathRow (DdManager *dd, DdNode *f)
int cuddTimesInDeathRow (DdManager *dd, DdNode *f)

Variables

static char rcsid[] DD_UNUSED = "$Id: cuddRef.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $"

Function Documentation

int Cudd_CheckZeroRef ( DdManager manager  ) 

Function********************************************************************

Synopsis [Checks the unique table for nodes with non-zero reference counts.]

Description [Checks the unique table for nodes with non-zero reference counts. It is normally called before Cudd_Quit to make sure that there are no memory leaks due to missing Cudd_RecursiveDeref's. Takes into account that reference counts may saturate and that the basic constants and the projection functions are referenced by the manager. Returns the number of nodes with non-zero reference count. (Except for the cases mentioned above.)]

SideEffects [None]

SeeAlso []

Definition at line 435 of file cuddRef.c.

00437 {
00438     int size;
00439     int i, j;
00440     int remain; /* the expected number of remaining references to one */
00441     DdNodePtr *nodelist;
00442     DdNode *node;
00443     DdNode *sentinel = &(manager->sentinel);
00444     DdSubtable *subtable;
00445     int count = 0;
00446     int index;
00447 
00448 #ifndef DD_NO_DEATH_ROW
00449     cuddClearDeathRow(manager);
00450 #endif
00451 
00452     /* First look at the BDD/ADD subtables. */
00453     remain = 1; /* reference from the manager */
00454     size = manager->size;
00455     remain += 2 * size; /* reference from the BDD projection functions */
00456 
00457     for (i = 0; i < size; i++) {
00458         subtable = &(manager->subtables[i]);
00459         nodelist = subtable->nodelist;
00460         for (j = 0; (unsigned) j < subtable->slots; j++) {
00461             node = nodelist[j];
00462             while (node != sentinel) {
00463                 if (node->ref != 0 && node->ref != DD_MAXREF) {
00464                     index = (int) node->index;
00465                     if (node != manager->vars[index]) {
00466                         count++;
00467                     } else {
00468                         if (node->ref != 1) {
00469                             count++;
00470                         }
00471                     }
00472                 }
00473                 node = node->next;
00474             }
00475         }
00476     }
00477 
00478     /* Then look at the ZDD subtables. */
00479     size = manager->sizeZ;
00480     if (size) /* references from ZDD universe */
00481         remain += 2;
00482 
00483     for (i = 0; i < size; i++) {
00484         subtable = &(manager->subtableZ[i]);
00485         nodelist = subtable->nodelist;
00486         for (j = 0; (unsigned) j < subtable->slots; j++) {
00487             node = nodelist[j];
00488             while (node != NULL) {
00489                 if (node->ref != 0 && node->ref != DD_MAXREF) {
00490                     index = (int) node->index;
00491                     if (node == manager->univ[manager->permZ[index]]) {
00492                         if (node->ref > 2) {
00493                             count++;
00494                         }
00495                     } else {
00496                         count++;
00497                     }
00498                 }
00499                 node = node->next;
00500             }
00501         }
00502     }
00503 
00504     /* Now examine the constant table. Plusinfinity, minusinfinity, and
00505     ** zero are referenced by the manager. One is referenced by the
00506     ** manager, by the ZDD universe, and by all projection functions.
00507     ** All other nodes should have no references.
00508     */
00509     nodelist = manager->constants.nodelist;
00510     for (j = 0; (unsigned) j < manager->constants.slots; j++) {
00511         node = nodelist[j];
00512         while (node != NULL) {
00513             if (node->ref != 0 && node->ref != DD_MAXREF) {
00514                 if (node == manager->one) {
00515                     if ((int) node->ref != remain) {
00516                         count++;
00517                     }
00518                 } else if (node == manager->zero ||
00519                 node == manager->plusinfinity ||
00520                 node == manager->minusinfinity) {
00521                     if (node->ref != 1) {
00522                         count++;
00523                     }
00524                 } else {
00525                     count++;
00526                 }
00527             }
00528             node = node->next;
00529         }
00530     }
00531     return(count);
00532 
00533 } /* end of Cudd_CheckZeroRef */

void Cudd_DelayedDerefBdd ( DdManager table,
DdNode n 
)

Function********************************************************************

Synopsis [Decreases the reference count of BDD node n.]

Description [Enqueues node n for later dereferencing. If the queue is full decreases the reference count of the oldest node N to make room for n. If N dies, recursively decreases the reference counts of its children. It is used to dispose of a BDD that is currently not needed, but may be useful again in the near future. The dereferencing proper is done as in Cudd_IterDerefBdd.]

SideEffects [None]

SeeAlso [Cudd_RecursiveDeref Cudd_IterDerefBdd]

Definition at line 243 of file cuddRef.c.

00246 {
00247     DdNode *N;
00248     int ord;
00249     DdNodePtr *stack;
00250     int SP;
00251 
00252     unsigned int live = table->keys - table->dead;
00253     if (live > table->peakLiveNodes) {
00254         table->peakLiveNodes = live;
00255     }
00256 
00257     n = Cudd_Regular(n);
00258 #ifdef DD_DEBUG
00259     assert(n->ref != 0);
00260 #endif
00261 
00262 #ifdef DD_NO_DEATH_ROW
00263     N = n;
00264 #else
00265     if (cuddIsConstant(n) || n->ref > 1) {
00266 #ifdef DD_DEBUG
00267         assert(n->ref != 1 && (!cuddIsConstant(n) || n == DD_ONE(table)));
00268 #endif
00269         cuddSatDec(n->ref);
00270         return;
00271     }
00272 
00273     N = table->deathRow[table->nextDead];
00274 
00275     if (N != NULL) {
00276 #endif
00277 #ifdef DD_DEBUG
00278         assert(!Cudd_IsComplement(N));
00279 #endif
00280         stack = table->stack;
00281         SP = 1;
00282         do {
00283 #ifdef DD_DEBUG
00284             assert(N->ref != 0);
00285 #endif
00286             if (N->ref == 1) {
00287                 N->ref = 0;
00288                 table->dead++;
00289 #ifdef DD_STATS
00290                 table->nodesDropped++;
00291 #endif
00292                 ord = table->perm[N->index];
00293                 stack[SP++] = Cudd_Regular(cuddE(N));
00294                 table->subtables[ord].dead++;
00295                 N = cuddT(N);
00296             } else {
00297                 cuddSatDec(N->ref);
00298                 N = stack[--SP];
00299             }
00300         } while (SP != 0);
00301 #ifndef DD_NO_DEATH_ROW
00302     }
00303     table->deathRow[table->nextDead] = n;
00304 
00305     /* Udate insertion point. */
00306     table->nextDead++;
00307     table->nextDead &= table->deadMask;
00308 #if 0
00309     if (table->nextDead == table->deathRowDepth) {
00310         if (table->deathRowDepth < table->looseUpTo / 2) {
00311             extern void (*MMoutOfMemory)(long);
00312             void (*saveHandler)(long) = MMoutOfMemory;
00313             DdNodePtr *newRow;
00314             MMoutOfMemory = Cudd_OutOfMem;
00315             newRow = REALLOC(DdNodePtr,table->deathRow,2*table->deathRowDepth);
00316             MMoutOfMemory = saveHandler;
00317             if (newRow == NULL) {
00318                 table->nextDead = 0;
00319             } else {
00320                 int i;
00321                 table->memused += table->deathRowDepth;
00322                 i = table->deathRowDepth;
00323                 table->deathRowDepth <<= 1;
00324                 for (; i < table->deathRowDepth; i++) {
00325                     newRow[i] = NULL;
00326                 }
00327                 table->deadMask = table->deathRowDepth - 1;
00328                 table->deathRow = newRow;
00329             }
00330         } else {
00331             table->nextDead = 0;
00332         }
00333     }
00334 #endif
00335 #endif
00336 
00337 } /* end of Cudd_DelayedDerefBdd */

void Cudd_Deref ( DdNode node  ) 

Function********************************************************************

Synopsis [Decreases the reference count of node.]

Description [Decreases the reference count of node. It is primarily used in recursive procedures to decrease the ref count of a result node before returning it. This accomplishes the goal of removing the protection applied by a previous Cudd_Ref.]

SideEffects [None]

SeeAlso [Cudd_RecursiveDeref Cudd_RecursiveDerefZdd Cudd_Ref]

Definition at line 407 of file cuddRef.c.

00409 {
00410     node = Cudd_Regular(node);
00411     cuddSatDec(node->ref);
00412 
00413 } /* end of Cudd_Deref */

void Cudd_IterDerefBdd ( DdManager table,
DdNode n 
)

Function********************************************************************

Synopsis [Decreases the reference count of BDD node n.]

Description [Decreases the reference count of node n. If n dies, recursively decreases the reference counts of its children. It is used to dispose of a BDD that is no longer needed. It is more efficient than Cudd_RecursiveDeref, but it cannot be used on ADDs. The greater efficiency comes from being able to assume that no constant node will ever die as a result of a call to this procedure.]

SideEffects [None]

SeeAlso [Cudd_RecursiveDeref Cudd_DelayedDerefBdd]

Definition at line 186 of file cuddRef.c.

00189 {
00190     DdNode *N;
00191     int ord;
00192     DdNodePtr *stack = table->stack;
00193     int SP = 1;
00194 
00195     unsigned int live = table->keys - table->dead;
00196     if (live > table->peakLiveNodes) {
00197         table->peakLiveNodes = live;
00198     }
00199 
00200     N = Cudd_Regular(n);
00201 
00202     do {
00203 #ifdef DD_DEBUG
00204         assert(N->ref != 0);
00205 #endif
00206 
00207         if (N->ref == 1) {
00208             N->ref = 0;
00209             table->dead++;
00210 #ifdef DD_STATS
00211             table->nodesDropped++;
00212 #endif
00213             ord = table->perm[N->index];
00214             stack[SP++] = Cudd_Regular(cuddE(N));
00215             table->subtables[ord].dead++;
00216             N = cuddT(N);
00217         } else {
00218             cuddSatDec(N->ref);
00219             N = stack[--SP];
00220         }
00221     } while (SP != 0);
00222 
00223 } /* end of Cudd_IterDerefBdd */

void Cudd_RecursiveDeref ( DdManager table,
DdNode n 
)

Function********************************************************************

Synopsis [Decreases the reference count of node n.]

Description [Decreases the reference count of node n. If n dies, recursively decreases the reference counts of its children. It is used to dispose of a DD that is no longer needed.]

SideEffects [None]

SeeAlso [Cudd_Deref Cudd_Ref Cudd_RecursiveDerefZdd]

Definition at line 123 of file cuddRef.c.

00126 {
00127     DdNode *N;
00128     int ord;
00129     DdNodePtr *stack = table->stack;
00130     int SP = 1;
00131 
00132     unsigned int live = table->keys - table->dead;
00133     if (live > table->peakLiveNodes) {
00134         table->peakLiveNodes = live;
00135     }
00136 
00137     N = Cudd_Regular(n);
00138 
00139     do {
00140 #ifdef DD_DEBUG
00141         assert(N->ref != 0);
00142 #endif
00143 
00144         if (N->ref == 1) {
00145             N->ref = 0;
00146             table->dead++;
00147 #ifdef DD_STATS
00148             table->nodesDropped++;
00149 #endif
00150             if (cuddIsConstant(N)) {
00151                 table->constants.dead++;
00152                 N = stack[--SP];
00153             } else {
00154                 ord = table->perm[N->index];
00155                 stack[SP++] = Cudd_Regular(cuddE(N));
00156                 table->subtables[ord].dead++;
00157                 N = cuddT(N);
00158             }
00159         } else {
00160             cuddSatDec(N->ref);
00161             N = stack[--SP];
00162         }
00163     } while (SP != 0);
00164 
00165 } /* end of Cudd_RecursiveDeref */

void Cudd_RecursiveDerefZdd ( DdManager table,
DdNode n 
)

Function********************************************************************

Synopsis [Decreases the reference count of ZDD node n.]

Description [Decreases the reference count of ZDD node n. If n dies, recursively decreases the reference counts of its children. It is used to dispose of a ZDD that is no longer needed.]

SideEffects [None]

SeeAlso [Cudd_Deref Cudd_Ref Cudd_RecursiveDeref]

Definition at line 354 of file cuddRef.c.

00357 {
00358     DdNode *N;
00359     int ord;
00360     DdNodePtr *stack = table->stack;
00361     int SP = 1;
00362 
00363     N = n;
00364 
00365     do {
00366 #ifdef DD_DEBUG
00367         assert(N->ref != 0);
00368 #endif
00369 
00370         cuddSatDec(N->ref);
00371     
00372         if (N->ref == 0) {
00373             table->deadZ++;
00374 #ifdef DD_STATS
00375             table->nodesDropped++;
00376 #endif
00377 #ifdef DD_DEBUG
00378             assert(!cuddIsConstant(N));
00379 #endif
00380             ord = table->permZ[N->index];
00381             stack[SP++] = cuddE(N);
00382             table->subtableZ[ord].dead++;
00383             N = cuddT(N);
00384         } else {
00385             N = stack[--SP];
00386         }
00387     } while (SP != 0);
00388 
00389 } /* end of Cudd_RecursiveDerefZdd */

void Cudd_Ref ( DdNode n  ) 

AutomaticStart AutomaticEnd Function********************************************************************

Synopsis [Increases the reference count of a node, if it is not saturated.]

Description []

SideEffects [None]

SeeAlso [Cudd_RecursiveDeref Cudd_Deref]

Definition at line 98 of file cuddRef.c.

00100 {
00101 
00102     n = Cudd_Regular(n);
00103 
00104     cuddSatInc(n->ref);
00105 
00106 } /* end of Cudd_Ref */

void cuddClearDeathRow ( DdManager table  ) 

Function********************************************************************

Synopsis [Clears the death row.]

Description []

SideEffects [None]

SeeAlso [Cudd_DelayedDerefBdd Cudd_IterDerefBdd Cudd_CheckZeroRef cuddGarbageCollect]

Definition at line 695 of file cuddRef.c.

00697 {
00698 #ifndef DD_NO_DEATH_ROW
00699     int i;
00700 
00701     for (i = 0; i < table->deathRowDepth; i++) {
00702         if (table->deathRow[i] == NULL) break;
00703         Cudd_IterDerefBdd(table,table->deathRow[i]);
00704         table->deathRow[i] = NULL;
00705     }
00706 #ifdef DD_DEBUG
00707     for (; i < table->deathRowDepth; i++) {
00708         assert(table->deathRow[i] == NULL);
00709     }
00710 #endif
00711     table->nextDead = 0;
00712 #endif
00713 
00714 } /* end of cuddClearDeathRow */

int cuddIsInDeathRow ( DdManager dd,
DdNode f 
)

Function********************************************************************

Synopsis [Checks whether a node is in the death row.]

Description [Checks whether a node is in the death row. Returns the position of the first occurrence if the node is present; -1 otherwise.]

SideEffects [None]

SeeAlso [Cudd_DelayedDerefBdd cuddClearDeathRow]

Definition at line 731 of file cuddRef.c.

00734 {
00735 #ifndef DD_NO_DEATH_ROW
00736     int i;
00737 
00738     for (i = 0; i < dd->deathRowDepth; i++) {
00739         if (f == dd->deathRow[i]) {
00740             return(i);
00741         }
00742     }
00743 #endif
00744 
00745     return(-1);
00746 
00747 } /* end of cuddIsInDeathRow */

void cuddReclaim ( DdManager table,
DdNode n 
)

Function********************************************************************

Synopsis [Brings children of a dead node back.]

Description []

SideEffects [None]

SeeAlso [cuddReclaimZdd]

Definition at line 553 of file cuddRef.c.

00556 {
00557     DdNode *N;
00558     int ord;
00559     DdNodePtr *stack = table->stack;
00560     int SP = 1;
00561     double initialDead = table->dead;
00562 
00563     N = Cudd_Regular(n);
00564 
00565 #ifdef DD_DEBUG
00566     assert(N->ref == 0);
00567 #endif
00568 
00569     do {
00570         if (N->ref == 0) {
00571             N->ref = 1;
00572             table->dead--;
00573             if (cuddIsConstant(N)) {
00574                 table->constants.dead--;
00575                 N = stack[--SP];
00576             } else {
00577                 ord = table->perm[N->index];
00578                 stack[SP++] = Cudd_Regular(cuddE(N));
00579                 table->subtables[ord].dead--;
00580                 N = cuddT(N);
00581             }
00582         } else {
00583             cuddSatInc(N->ref);
00584             N = stack[--SP];
00585         }
00586     } while (SP != 0);
00587 
00588     N = Cudd_Regular(n);
00589     cuddSatDec(N->ref);
00590     table->reclaimed += initialDead - table->dead;
00591 
00592 } /* end of cuddReclaim */

void cuddReclaimZdd ( DdManager table,
DdNode n 
)

Function********************************************************************

Synopsis [Brings children of a dead ZDD node back.]

Description []

SideEffects [None]

SeeAlso [cuddReclaim]

Definition at line 607 of file cuddRef.c.

00610 {
00611     DdNode *N;
00612     int ord;
00613     DdNodePtr *stack = table->stack;
00614     int SP = 1;
00615 
00616     N = n;
00617 
00618 #ifdef DD_DEBUG
00619     assert(N->ref == 0);
00620 #endif
00621 
00622     do {
00623         cuddSatInc(N->ref);
00624 
00625         if (N->ref == 1) {
00626             table->deadZ--;
00627             table->reclaimed++;
00628 #ifdef DD_DEBUG
00629             assert(!cuddIsConstant(N));
00630 #endif
00631             ord = table->permZ[N->index];
00632             stack[SP++] = cuddE(N);
00633             table->subtableZ[ord].dead--;
00634             N = cuddT(N);
00635         } else {
00636             N = stack[--SP];
00637         }
00638     } while (SP != 0);
00639 
00640     cuddSatDec(n->ref);
00641 
00642 } /* end of cuddReclaimZdd */

void cuddShrinkDeathRow ( DdManager table  ) 

Function********************************************************************

Synopsis [Shrinks the death row.]

Description [Shrinks the death row by a factor of four.]

SideEffects [None]

SeeAlso [cuddClearDeathRow]

Definition at line 657 of file cuddRef.c.

00659 {
00660 #ifndef DD_NO_DEATH_ROW
00661     int i;
00662 
00663     if (table->deathRowDepth > 3) {
00664         for (i = table->deathRowDepth/4; i < table->deathRowDepth; i++) {
00665             if (table->deathRow[i] == NULL) break;
00666             Cudd_IterDerefBdd(table,table->deathRow[i]);
00667             table->deathRow[i] = NULL;
00668         }
00669         table->deathRowDepth /= 4;
00670         table->deadMask = table->deathRowDepth - 2;
00671         if ((unsigned) table->nextDead > table->deadMask) {
00672             table->nextDead = 0;
00673         }
00674         table->deathRow = REALLOC(DdNodePtr, table->deathRow,
00675                                    table->deathRowDepth);
00676     }
00677 #endif
00678 
00679 } /* end of cuddShrinkDeathRow */

int cuddTimesInDeathRow ( DdManager dd,
DdNode f 
)

Function********************************************************************

Synopsis [Counts how many times a node is in the death row.]

Description []

SideEffects [None]

SeeAlso [Cudd_DelayedDerefBdd cuddClearDeathRow cuddIsInDeathRow]

Definition at line 762 of file cuddRef.c.

00765 {
00766     int count = 0;
00767 #ifndef DD_NO_DEATH_ROW
00768     int i;
00769 
00770     for (i = 0; i < dd->deathRowDepth; i++) {
00771         count += f == dd->deathRow[i];
00772     }
00773 #endif
00774 
00775     return(count);
00776 
00777 } /* end of cuddTimesInDeathRow */


Variable Documentation

char rcsid [] DD_UNUSED = "$Id: cuddRef.c,v 1.1.1.1 2003/02/24 22:23:53 wjiang Exp $" [static]

CFile***********************************************************************

FileName [cuddRef.c]

PackageName [cudd]

Synopsis [Functions that manipulate the reference counts.]

Description [External procedures included in this module:

Internal procedures included in this module:

]

SeeAlso []

Author [Fabio Somenzi]

Copyright [ This file was created at the University of Colorado at Boulder. The University of Colorado at Boulder makes no warranty about the suitability of this software for any purpose. It is presented on an AS IS basis.]

Definition at line 64 of file cuddRef.c.


Generated on Tue Jan 5 12:18:55 2010 for abc70930 by  doxygen 1.6.1