--- saclib2.2.8-orig/src/FAIL.c +++ saclib2.2.8/src/FAIL.c @@ -1,7 +1,10 @@ /*====================================================================== FAIL(algName,msg,...) -Failure handler. +Failure handler. +** REDEFINED FOR QEPCAD! QepcadB needs to, potentially, kill some child +** processes. That's what this adds. A better long-term solution is to +** change Saclib's FAIL to add an analogue to "atexit". Inputs algName : the name of the algorithm which called this algorithm. @@ -20,12 +23,13 @@ #ifdef __STDC__ void FAIL(const char *algName, const char *msg,...) #else -void FAIL(algName,msg) __noreturn +void FAIL(algName,msg) const char *algName; const char *msg; #endif { va_list argPtr; + // extern int strcmp(); Step1: /* Basic message. */ SWRITE("\n\n"); @@ -187,10 +191,16 @@ goto Abort; } + /* TIMEOUT */ + if (!strcmp(algName,"TIMEOUT")) { + goto Exit; + } + Abort: /* Prepare for abort. */ SWRITE("\n\nNow the FAIL handler is aborting the program ...\n"); va_end(argPtr); - abort(); + //abort(); + exit(2); Exit: /* Prepare for exit. */ SWRITE("\n\nNow the FAIL handler is exiting the program ...\n"); --- saclib2.2.8-orig/src/GCSI.c +++ saclib2.2.8/src/GCSI.c @@ -16,17 +16,19 @@ occurs. ======================================================================*/ #include "saclib.h" +extern void gcw_MARK(); void GCSI(s,EACSTACK) Word s; char *EACSTACK; { - Word I,L,N,N1,Np,Np1,T,T1,c,inc; + Word I,L,N,N1,Np,Np1,T,T1,c,**i,j,inc; char *a; - /* hide I,L,N,N1,Np,Np1,T,T1,c,inc,a; */ + GCArray *v; + /* hide I,L,N,N1,Np,Np1,T,T1,c,i,j,inc,a,v; */ Step1: /* Setup. */ - if (GCM == 1) { + if (GCM == 1) { SWRITE("\nThe "); GWRITE(GCC+1); SWRITE("--th garbage collection....\n"); } @@ -48,17 +50,8 @@ L = I; } -/* Step3: /\* Mark the global variables. *\/ */ -/* L = GCGLOBALS; */ -/* while (L != NIL) { */ -/* c = *(PTRFIRST(L)); */ -/* if ((ISLIST(c) || ISGCA(c)) && !ISNIL(c)) MARK(c); */ -/* #if __WORDSIZE == 64 */ -/* L = -RED(L); L = -RED(L); L = -RED(L); L = -RED(L); */ -/* #else /\* Assumes 32-bit pointers. *\/ */ -/* L = -RED(L); L = -RED(L); */ -/* #endif */ -/* } */ +Step3b: /* Mark the GCWord variables. */ + gcw_MARK(); Step4: /* Mark the cells accessible from the system stack. */ if (((BACSTACK - EACSTACK) % s) != 0) @@ -113,7 +106,7 @@ Step8: /* Optional report. */ if (GCM == 1 || N <= NU / RHO) { - SWRITE("** "); + SWRITE("\n** "); GWRITE(N); SWRITE(" cells, "); GWRITE(Np); SWRITE(" arrays in "); GWRITE(T); SWRITE(" milliseconds.\n"); --- saclib2.2.8-orig/src/gcword.cc +++ saclib2.2.8/src/gcword.cc @@ -0,0 +1,70 @@ +/*************************************************************** +*** +*** gcword.cc +*** +*** This file implements the gcw_MARK() function, which is called +*** by the modified saclib garbage collector in order to account +*** for saclib Words pointed to by GCWord objects. +*** +*** This file implements the gcw_register(p) function, which is +*** called upon creation and upon destuction of a GCWord object. +*** Each call adds p, the address of the GCWord, to the vector G, +*** so that if a given address occurs an odd number of times, it +*** contains a live GCWord object ... which the garbage collector +*** needs to consider. +*** +*** The clean() function modifies vector G so that an address +*** appears in G after the call if and only if it appeared an odd +*** number of times before the call, and no address appears more +*** than once after the call. +*** +*** CWB 5/15/00 +***************************************************************/ +#include +#include +#include "gcword.h" +using namespace std; + +extern "C" { +void gcw_MARK(); +} + +static vector G; +static int lim = 10; + +void clean() +{ + //-- a hack to ensure that lim ends up being NU -------------// + if (lim < NU) lim = NU; + + sort(G.begin(),G.end()); + + //-- compacts sorted array by ignoring double values --------// + int i,j,N = G.size()-1; + for(i = 0; i < N; i++) + if (G[i] == G[i+1]) { + G[i] = G[i+1] = 0; + i++; } + for(i = 0, j = 0; j <= N; j++) + if (G[j] != 0) + swap(G[i++],G[j]); + G.resize(i); +} + +void gcw_register(Word *p) +{ + G.push_back(p); + if (G.size() == lim) + clean(); +} + +void gcw_MARK() +{ + // SWRITE("gcw size is: ");IWRITE(G.size()); SWRITE("\n"); + clean(); + for(int i = 0; i < G.size(); i++) + if (*G[i] > BETA && *G[i] < BETAp && (*G[i] & 1)) + MARK(*G[i]); + + return; +} --- saclib2.2.8-orig/src/gcword.h +++ saclib2.2.8/src/gcword.h @@ -0,0 +1,51 @@ +/*************************************************************** +*** +*** gcword.h +*** +*** This file defines the class GCWord, or "garbage collected +*** word". It is designed to be used in conjunction with +*** saclib to provide an easy way to incoporate garbage +*** collected saclib lists into class definitions and arrays. +*** It even makes global variables easier to define. +*** +*** An object of type GCWord behaves just like a "Word", except +*** that it is visible to the garbage collector even if it is +*** a member of some stucture or class or array or is, for any +*** other reason, not a local variable. Note: garbage +*** collection may be slowed by the presence of GCWord's! +*** +*** CWB 5/15/00 +***************************************************************/ + +#ifndef _GCW_ +#define _GCW_ + + +extern "C" { +#include "saclib.h" +} +extern void gcw_register(Word *); + + +class GCWord +{ +public: + Word W; + + //-- Constructors -------------------------------------------// + GCWord() { W = 0; gcw_register(&W); } + GCWord(const GCWord &X) { W = X.W; gcw_register(&W); } + GCWord(const Word &X) { W = X; gcw_register(&W); } + + //-- Destructor ---------------------------------------------// + ~GCWord() { gcw_register(&W); } + + //-- Assignment ---------------------------------------------// + GCWord& operator=(const GCWord& X) { W = X.W; return *this; } + GCWord& operator=(const Word& X) { W = X; return *this;} + + //-- Cast to Word -------------------------------------------// + operator Word() const { return W; } +}; + +#endif