/* NAME {* bdd\_delref *} SECTION {* kernel *} SHORT {* decreases the reference count on a node *} PROTO {* BDD bdd_delref(BDD r) *} DESCR {* Reference counting is done on externaly referenced nodes only and the count for a specific node {\tt r} can and must be decreased using this function to make it possible to reclaim the node in the next garbage collection. *} ALSO {* bdd\_addref *} RETURN {* The BDD node {\tt r}. *} */ BDD bdd_delref(BDD root) { BUDDY_PROLOGUE; ADD_ARG1(T_BDD,root); if (root < 2 || !bddrunning) RETURN_BDD(root); if (root >= bddnodesize) RETURN_BDD(bdd_error(BDD_ILLBDD)); if (LOW(root) == INVALID_BDD) RETURN_BDD(bdd_error(BDD_ILLBDD)); /* if the following line is present, fails there much earlier */ if (!HASREF(root)) bdd_error(BDD_BREAK); /* distinctive */ DECREF(root); if(!HASREF(root)) trace_del_bdd(T_BDD,(void *)root); RETURN_BDD(root); }
/* NAME {* bdd\_delref *} SECTION {* kernel *} SHORT {* decreases the reference count on a node *} PROTO {* BDD bdd_delref(BDD r) *} DESCR {* Reference counting is done on externaly referenced nodes only and the count for a specific node {\tt r} can and must be decreased using this function to make it possible to reclaim the node in the next garbage collection. *} ALSO {* bdd\_addref *} RETURN {* The BDD node {\tt r}. *} */ BDD bdd_delref(BDD root) { if (root < 2 || !bddrunning) return root; if (root >= bddnodesize) return bdd_error(BDD_ILLBDD); if (LOW(root) == -1) return bdd_error(BDD_ILLBDD); /* if the following line is present, fails there much earlier */ if (!HASREF(root)) bdd_error(BDD_BREAK); /* distinctive */ DECREF(root); return root; }
void bdd_gbc(void) { int *r; int n; long int c2, c1 = clock(); if (gbc_handler != NULL) { bddGbcStat s; s.nodes = bddnodesize; s.freenodes = bddfreenum; s.time = 0; s.sumtime = gbcclock; s.num = gbcollectnum; gbc_handler(1, &s); } for (r=bddrefstack ; r<bddrefstacktop ; r++) bdd_mark(*r); for (n=0 ; n<bddnodesize ; n++) { if (HASREF(n)) bdd_mark(n); SETHASH(n, 0); } bddfreepos = 0; bddfreenum = 0; for (n=bddnodesize-1 ; n>=2 ; n--) { register BddNode *node = &bddnodes[n]; if (MARKEDp(node) && LOWp(node) != INVALID_BDD) { register unsigned int hash; UNMARKp(node); hash = NODEHASH(LEVELp(node), LOWp(node), HIGHp(node)); SETNEXTp(node, HASH(hash)); SETHASH(hash, n); } else { SETLOWpz(node, INVALID_BDD); // obliterates refcount SETNEXTpz(node, bddfreepos); // obliterates lev, mark bddfreepos = n; bddfreenum++; } } bdd_operator_reset(); c2 = clock(); gbcclock += c2-c1; gbcollectnum++; if (gbc_handler != NULL) { bddGbcStat s; s.nodes = bddnodesize; s.freenodes = bddfreenum; s.time = c2-c1; s.sumtime = gbcclock; s.num = gbcollectnum; gbc_handler(0, &s); } }