From 33335ca6d533cd1076de6390021f61090be364e0 Mon Sep 17 00:00:00 2001 From: Josh Davies Date: Thu, 5 Mar 2026 13:47:43 +0000 Subject: [PATCH] perf: make max and min dollar variables thread-local Use thread-local dollar variables for ModuleOption minimum and maximum dollars. With this change they work exactly like ModuleOption local, except at the end of the module the final value is computed and put into the global dollar value. --- sources/declare.h | 1 + sources/dollar.c | 100 +++++++++++++++++++++++--------------------- sources/execute.c | 76 +++++++++++++++++++++++++++++++-- sources/factor.c | 2 +- sources/if.c | 32 ++++++++++---- sources/message.c | 8 ++-- sources/module.c | 2 +- sources/normal.c | 28 ++++++------- sources/proces.c | 50 +++++++++++----------- sources/structs.h | 2 +- sources/transform.c | 6 +-- sources/wildcard.c | 6 +-- 12 files changed, 203 insertions(+), 110 deletions(-) diff --git a/sources/declare.h b/sources/declare.h index cbe9283d..976e90de 100644 --- a/sources/declare.h +++ b/sources/declare.h @@ -1277,6 +1277,7 @@ extern WORD *MakeDollarInteger(PHEAD WORD *,WORD **); extern WORD *MakeDollarMod(PHEAD WORD *,WORD **); extern int GetDolNum(PHEAD WORD *, WORD *); extern void AddPotModdollar(WORD); +extern int DollarLocalCopy(WORD); extern int Optimize(WORD, int); extern int ClearOptimize(void); diff --git a/sources/dollar.c b/sources/dollar.c index 3a3cccf7..19a5be92 100644 --- a/sources/dollar.c +++ b/sources/dollar.c @@ -236,7 +236,7 @@ int AssignDollar(PHEAD WORD *term, WORD level) Terminate(-1); } dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } } @@ -252,8 +252,7 @@ int AssignDollar(PHEAD WORD *term, WORD level) */ #ifdef WITHPTHREADS if ( dtype > 0 ) { -/* LOCK(d->pthreadslockwrite); */ - LOCK(d->pthreadslockread); + if ( ! DollarLocalCopy(dtype) ) { LOCK(d->pthreadslockread); } NewValIsZero:; switch ( d->type ) { case DOLZERO: goto NoChangeZero; @@ -278,8 +277,7 @@ NewValIsZero:; cbuf[AM.dbufnum].NumTerms[numdollar] = 0; NoChangeZero:; CleanDollarFactors(d); -/* UNLOCK(d->pthreadslockwrite); */ - UNLOCK(d->pthreadslockread); + if ( ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } AN.ncmod = oldncmod; return(0); } @@ -301,8 +299,7 @@ NoChangeZero:; */ #ifdef WITHPTHREADS if ( dtype > 0 ) { -/* LOCK(d->pthreadslockwrite); */ - LOCK(d->pthreadslockread); + if ( ! DollarLocalCopy(dtype) ) { LOCK(d->pthreadslockread); } if ( d->size < MINALLOC ) { WORD oldsize, *oldwhere, i; oldsize = d->size; oldwhere = d->where; @@ -365,8 +362,7 @@ HandleDolZero:; cbuf[AM.dbufnum].NumTerms[numdollar] = 1; NoChangeOne:; CleanDollarFactors(d); -/* UNLOCK(d->pthreadslockwrite); */ - UNLOCK(d->pthreadslockread); + if ( ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } AN.ncmod = oldncmod; return(0); } @@ -398,7 +394,7 @@ NoChangeOne:; depends on the dollar variable. */ #ifdef WITHPTHREADS - LOCK(d->pthreadslockread); + if ( ! DollarLocalCopy(dtype) ) { LOCK(d->pthreadslockread); } #endif CleanDollarFactors(d); /* @@ -566,8 +562,7 @@ HandleDolZero1:; } #ifdef WITHPTHREADS NoChange:; -/* UNLOCK(d->pthreadslockwrite); */ - UNLOCK(d->pthreadslockread); + if ( ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } #endif AN.ncmod = oldncmod; return(0); @@ -924,7 +919,7 @@ void WildDollars(PHEAD WORD *term) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } else { @@ -1084,7 +1079,7 @@ WORD DolToTensor(PHEAD WORD numdollar) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } else { @@ -1122,7 +1117,7 @@ WORD DolToTensor(PHEAD WORD numdollar) retval = 0; } #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } #endif return(retval); } @@ -1145,7 +1140,7 @@ WORD DolToFunction(PHEAD WORD numdollar) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } else { @@ -1179,7 +1174,7 @@ WORD DolToFunction(PHEAD WORD numdollar) retval = 0; } #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } #endif return(retval); } @@ -1202,7 +1197,7 @@ WORD DolToVector(PHEAD WORD numdollar) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } else { @@ -1243,7 +1238,7 @@ WORD DolToVector(PHEAD WORD numdollar) retval = 0; } #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } #endif return(retval); } @@ -1265,7 +1260,7 @@ WORD DolToNumber(PHEAD WORD numdollar) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } } @@ -1325,7 +1320,7 @@ WORD DolToSymbol(PHEAD WORD numdollar) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } else { @@ -1356,7 +1351,7 @@ WORD DolToSymbol(PHEAD WORD numdollar) retval = -1; } #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } #endif return(retval); } @@ -1379,7 +1374,7 @@ WORD DolToIndex(PHEAD WORD numdollar) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } else { @@ -1432,7 +1427,7 @@ WORD DolToIndex(PHEAD WORD numdollar) retval = 0; } #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } #endif return(retval); } @@ -1461,7 +1456,7 @@ DOLLARS DolToTerms(PHEAD WORD numdollar) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } } @@ -1608,7 +1603,7 @@ LONG DolToLong(PHEAD WORD numdollar) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } } @@ -1759,11 +1754,10 @@ int InsideDollar(PHEAD WORD *ll, WORD level) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } else { -/* LOCK(d->pthreadslockwrite); */ LOCK(d->pthreadslockread); } } @@ -1816,10 +1810,7 @@ int InsideDollar(PHEAD WORD *ll, WORD level) Now we have a little cleaning up to do */ #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { -/* UNLOCK(d->pthreadslockwrite); */ - UNLOCK(d->pthreadslockread); - } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } #endif if ( newd->factors ) M_free(newd->factors,"Dollar factors"); M_free(newd,"Copy of dollar variable"); @@ -1870,7 +1861,7 @@ LONG TermsInDollar(WORD num) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } else { @@ -1895,7 +1886,7 @@ LONG TermsInDollar(WORD num) else if ( d->type == DOLZERO ) n = 0; else n = 1; #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } #endif return(n); } @@ -1919,7 +1910,7 @@ LONG SizeOfDollar(WORD num) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } else { @@ -1947,7 +1938,7 @@ LONG SizeOfDollar(WORD num) else if ( d->type == DOLZERO ) n = 0; else n = 1; #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } #endif return(n); } @@ -2656,7 +2647,7 @@ WORD EvalDoLoopArg(PHEAD WORD *arg, WORD par) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } } @@ -2784,7 +2775,7 @@ WORD TestDoLoop(PHEAD WORD *lhsbuf, WORD level) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } } @@ -2862,7 +2853,7 @@ WORD TestEndDoLoop(PHEAD WORD *lhsbuf, WORD level) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } } @@ -2970,7 +2961,7 @@ int DollarFactorize(PHEAD WORD numdollar) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } else { @@ -2981,7 +2972,7 @@ int DollarFactorize(PHEAD WORD numdollar) #endif CleanDollarFactors(d); #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } #endif if ( d->type != DOLTERMS ) { /* only one term */ if ( d->type != DOLZERO ) d->nfactors = 1; @@ -3231,13 +3222,13 @@ int DollarFactorize(PHEAD WORD numdollar) Be careful: there should be more than one factor now. */ #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { LOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { LOCK(d->pthreadslockread); } #endif if ( nfactors == 1 && extrafactor == 0 ) { /* we can use the buf1 contents */ if ( factorsincontent == 0 ) { d->nfactors = 1; #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } #endif /* We used here (before 3-sep-2015) the original and did not make @@ -3289,7 +3280,7 @@ getout2: AR.SortType = oldsorttype; M_free(d->factors,"factors in dollar"); d->factors = 0; #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } #endif M_free(buf3,"DollarFactorize-4"); if ( buf2 != buf1 && buf2 ) M_free(buf2,"DollarFactorize-4"); @@ -3533,7 +3524,7 @@ nextj:; #] Step 8: */ #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } #endif return(0); } @@ -3852,7 +3843,7 @@ int GetDolNum(PHEAD WORD *t, WORD *tstop) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } else { @@ -3906,7 +3897,7 @@ int GetDolNum(PHEAD WORD *t, WORD *tstop) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } else { @@ -3962,4 +3953,19 @@ void AddPotModdollar(WORD numdollar) /* #] AddPotModdollar : + #[ DollarLocalCopy : +*/ + +/** + * Returns 1 if the ModOptdollar type implies a thread-local copy when running + * in TFORM (WITHPTHREADS), and 0 otherwise. + */ +inline int DollarLocalCopy(WORD type) { + if ( type == MODLOCAL ) { return 1; }; + if ( type == MODMIN ) { return 1; }; + if ( type == MODMAX ) { return 1; }; + return 0; +} +/* + #] DollarLocalCopy : */ diff --git a/sources/execute.c b/sources/execute.c index 2514370c..654385c7 100644 --- a/sources/execute.c +++ b/sources/execute.c @@ -904,9 +904,79 @@ int DoExecute(WORD par, WORD skip) #ifdef WITHPTHREADS for ( j = 0; j < NumModOptdollars; j++ ) { if ( ModOptdollars[j].dstruct ) { -/* - First clean up dollar values. -*/ + + //Here we must collect global maximum or minimum dollar values, for + //MODMAX and MODMIN cases, and put them in the global dollar variable. + //Then we clean up. + + if ( ModOptdollars[j].type == MODMAX || ModOptdollars[j].type == MODMIN ) { + const WORD globalnumber = ModOptdollars[j].number; + const DOLLARS gd = Dollars + globalnumber; + + // If the global dollar is DOLZERO, convert it into DOLNUMBER. + // Note that parts of the code rely on the trailing zero. + if ( gd->type == DOLZERO ) { + gd->type = DOLNUMBER; + gd->where[0] = 4; + gd->where[1] = 0; + gd->where[2] = 1; + gd->where[3] = 3; + gd->where[4] = 0; + } + + for ( i = 0; i < AM.totalnumberofthreads; i++ ) { + const DOLLARS ld = &(ModOptdollars[j].dstruct[i]); + const WORD type = ld->type; + + // This can happen when a thread doesn't obtain a dollar value, + // for instance if it did not process any terms. + if ( type == DOLUNDEFINED ) continue; + + if ( type != DOLZERO && type != DOLNUMBER ) { + MLOCK(ErrorMessageLock); + MesPrint("Illegal dollar variable type in MODMIN/MODMAX case: %d", type); + MUNLOCK(ErrorMessageLock); + Terminate(-1); + } + + // If the thread value is DOLZERO, convert it to DOLNUMBER: + if ( type == DOLZERO ) { + ld->where[0] = 4; + ld->where[1] = 0; + ld->where[2] = 1; + ld->where[3] = 3; + ld->where[4] = 0; + } + + // MODMIN and MODMAX are supposed to work only for "short integers". Thus + // the term data should be "4 N 1 +-3". Use CompCoef to make the comparison: + const WORD cmp = CompCoef(gd->where, ld->where); + if ( ( ModOptdollars[j].type == MODMAX && cmp < 0 ) || + ( ModOptdollars[j].type == MODMIN && cmp > 0 ) ) { + // Update the global value: + for ( int v = 0; v < 5; v++ ) { + gd->where[v] = ld->where[v]; + } + if ( gd->where[4] != 0 ) { + // The loop above should have put a trailing zero after the coeff + // size. If not, there is probably a bug somewhere else... + MLOCK(ErrorMessageLock); + MesPrint("Missing trailing zero in MODMIN/MODMAX global dollar %d", + globalnumber); + MUNLOCK(ErrorMessageLock); + Terminate(-1); + } + } + } + + // If the global dollar is 0, convert it into DOLZERO: + if ( gd->where[1] == 0 ) { + gd->type = DOLZERO; + gd->where[0] = 0; + } + } + + // Now clean up the thread-local variables for ( i = 0; i < AM.totalnumberofthreads; i++ ) { if ( ModOptdollars[j].dstruct[i].size > 0 ) { CleanDollarFactors(&(ModOptdollars[j].dstruct[i])); diff --git a/sources/factor.c b/sources/factor.c index cc4b8224..8212c475 100644 --- a/sources/factor.c +++ b/sources/factor.c @@ -71,7 +71,7 @@ int FactorIn(PHEAD WORD *term, WORD level) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } } diff --git a/sources/if.c b/sources/if.c index 0e0f2485..edfa656b 100644 --- a/sources/if.c +++ b/sources/if.c @@ -316,7 +316,7 @@ int DoIfStatement(PHEAD WORD *ifcode, WORD *term) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } } @@ -471,7 +471,7 @@ int DoIfStatement(PHEAD WORD *ifcode, WORD *term) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } else { @@ -532,7 +532,9 @@ int DoIfStatement(PHEAD WORD *ifcode, WORD *term) case DOLUNDEFINED: if ( AC.UnsureDollarMode == 0 ) { #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { + UNLOCK(d->pthreadslockread); + } #endif MLOCK(ErrorMessageLock); MesPrint("$%s is undefined",AC.dollarnames->namebuffer+d->name); @@ -549,7 +551,9 @@ int DoIfStatement(PHEAD WORD *ifcode, WORD *term) || d->where[2] < 0 || d->where[2] >= AM.OffsetIndex ) { if ( AC.UnsureDollarMode == 0 ) { #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { + UNLOCK(d->pthreadslockread); + } #endif MLOCK(ErrorMessageLock); MesPrint("$%s is of wrong type",AC.dollarnames->namebuffer+d->name); @@ -570,7 +574,9 @@ int DoIfStatement(PHEAD WORD *ifcode, WORD *term) } else if ( AC.UnsureDollarMode == 0 ) { #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { + UNLOCK(d->pthreadslockread); + } #endif MLOCK(ErrorMessageLock); MesPrint("$%s is of wrong type",AC.dollarnames->namebuffer+d->name); @@ -586,7 +592,9 @@ int DoIfStatement(PHEAD WORD *ifcode, WORD *term) ) { if ( AC.UnsureDollarMode == 0 ) { #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { + UNLOCK(d->pthreadslockread); + } #endif MLOCK(ErrorMessageLock); MesPrint("$%s is of wrong type",AC.dollarnames->namebuffer+d->name); @@ -635,7 +643,9 @@ int DoIfStatement(PHEAD WORD *ifcode, WORD *term) else { if ( AC.UnsureDollarMode == 0 ) { #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { + UNLOCK(d->pthreadslockread); + } #endif MLOCK(ErrorMessageLock); MesPrint("$%s is of wrong type",AC.dollarnames->namebuffer+d->name); @@ -661,7 +671,9 @@ int DoIfStatement(PHEAD WORD *ifcode, WORD *term) generic:; if ( AC.UnsureDollarMode == 0 ) { #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { + UNLOCK(d->pthreadslockread); + } #endif MLOCK(ErrorMessageLock); MesPrint("$%s is of wrong type",AC.dollarnames->namebuffer+d->name); @@ -673,7 +685,9 @@ generic:; } } #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { + UNLOCK(d->pthreadslockread); + } #endif } break; diff --git a/sources/message.c b/sources/message.c index ab5f94c1..fd7240e0 100644 --- a/sources/message.c +++ b/sources/message.c @@ -421,7 +421,7 @@ int MesPrint(const char *fmt, ... ) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } else { @@ -480,7 +480,7 @@ printterms: first = 1; AddToLine((UBYTE *)Out); if ( WriteInnerTerm(term,first) ) { #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } #endif Terminate(-1); } @@ -511,7 +511,7 @@ dosubterm: if ( AC.LineLength > MAXLINELENGTH ) AC.LineLength = MAXLINELENGTH AddToLine((UBYTE *)Out); if ( WriteSubTerm(tt,1) ) { #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } #endif Terminate(-1); } @@ -615,7 +615,7 @@ dollarzero: *t++ = '0'; *t = 0; } } #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } #endif AN.listinprint += 2; while ( AN.listinprint[0] == DOLLAREXPR2 ) AN.listinprint += 2; diff --git a/sources/module.c b/sources/module.c index 86ec356d..a6a70627 100644 --- a/sources/module.c +++ b/sources/module.c @@ -693,7 +693,7 @@ UBYTE * DoModDollar(UBYTE *s, int type) md->number = number; md->type = type; #ifdef WITHPTHREADS - if ( type == MODLOCAL ) { + if ( DollarLocalCopy(type) ) { int j, i; DOLLARS dglobal, dlocal; md->dstruct = (DOLLARS)Malloc1( diff --git a/sources/normal.c b/sources/normal.c index 93d6e4c0..196e01fd 100644 --- a/sources/normal.c +++ b/sources/normal.c @@ -557,7 +557,7 @@ NextSymbol:; } if ( nummodopt < NumModOptdollars ) { ptype = ModOptdollars[nummodopt].type; - if ( ptype == MODLOCAL ) { + if ( DollarLocalCopy(ptype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } else { @@ -568,7 +568,7 @@ NextSymbol:; #endif if ( d->type == DOLZERO ) { #ifdef WITHPTHREADS - if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslockread); } #endif if ( t[3] == 0 ) goto NormZZ; if ( t[3] < 0 ) goto NormInf; @@ -584,7 +584,7 @@ NextSymbol:; } if ( nnum == 0 || ( nnum == 1 && lnum[0] == 0 ) ) { #ifdef WITHPTHREADS - if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslockread); } #endif if ( t[3] < 0 ) goto NormInf; else if ( t[3] == 0 ) goto NormZZ; @@ -595,7 +595,7 @@ NextSymbol:; if ( t[3] < 0 ) { if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) ) { #ifdef WITHPTHREADS - if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslockread); } #endif goto FromNorm; } @@ -603,7 +603,7 @@ NextSymbol:; else if ( t[3] > 0 ) { if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) ) { #ifdef WITHPTHREADS - if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslockread); } #endif goto FromNorm; } @@ -613,7 +613,7 @@ NextSymbol:; else if ( d->type == DOLINDEX ) { if ( d->index == 0 ) { #ifdef WITHPTHREADS - if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslockread); } #endif goto NormZero; } @@ -684,7 +684,7 @@ NextSymbol:; t[4] = AM.dbufnum; if ( t[3] == 0 ) { #ifdef WITHPTHREADS - if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslockread); } #endif break; } @@ -693,7 +693,7 @@ NextSymbol:; while ( t < m ) { if ( *t == DOLLAREXPRESSION ) { #ifdef WITHPTHREADS - if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslockread); } #endif d = Dollars + t[2]; #ifdef WITHPTHREADS @@ -703,7 +703,7 @@ NextSymbol:; } if ( nummodopt < NumModOptdollars ) { ptype = ModOptdollars[nummodopt].type; - if ( ptype == MODLOCAL ) { + if ( DollarLocalCopy(ptype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } else { @@ -720,13 +720,13 @@ NextSymbol:; t += t[1]; } #ifdef WITHPTHREADS - if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslockread); } #endif goto RegEnd; } else { #ifdef WITHPTHREADS - if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslockread); } #endif MLOCK(ErrorMessageLock); MesPrint("!!!This $ variation has not been implemented yet!!!"); @@ -734,7 +734,7 @@ NextSymbol:; goto NormMin; } #ifdef WITHPTHREADS - if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslockread); } #endif } else { @@ -1123,7 +1123,7 @@ PasteIn:; } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } } @@ -4592,7 +4592,7 @@ WORD DetCommu(WORD *terms) else if ( *t == DOLLAREXPRESSION ) { /* Technically this is not correct. We have to test first - whether this is MODLOCAL (in TFORM) and if so, use the + whether this is DollarLocalCopy (in TFORM) and if so, use the local version. Anyway, this should be rare to never occurring because dollars should be replaced. */ diff --git a/sources/proces.c b/sources/proces.c index 812449b1..d43e7bb2 100644 --- a/sources/proces.c +++ b/sources/proces.c @@ -2298,7 +2298,7 @@ int InFunction(PHEAD WORD *term, WORD *termout) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } else { @@ -2447,12 +2447,12 @@ int InFunction(PHEAD WORD *term, WORD *termout) AC.dollarnames->namebuffer+d->name); MUNLOCK(ErrorMessageLock); #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } #endif Terminate(-1); } #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } #endif r = term + *term; t = v; @@ -2532,7 +2532,7 @@ int InFunction(PHEAD WORD *term, WORD *termout) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } else { @@ -2566,7 +2566,7 @@ int InFunction(PHEAD WORD *term, WORD *termout) else { wrongtype:; #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } #endif MLOCK(ErrorMessageLock); MesPrint("$%s has wrong type for tensor substitution", @@ -2632,7 +2632,7 @@ wrongtype:; break; case DOLUNDEFINED: #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } #endif MLOCK(ErrorMessageLock); MesPrint("$%s is undefined in tensor substitution", @@ -2642,7 +2642,7 @@ wrongtype:; return(-1); } #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } #endif w[1] = w[1] - 2 + (m-to); from += 2; @@ -3452,7 +3452,7 @@ SkipCount: level++; } if ( nummodopt < NumModOptdollars ) { ddtype = ModOptdollars[nummodopt].type; - if ( ddtype == MODLOCAL ) { + if ( DollarLocalCopy(ddtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } else { @@ -3480,13 +3480,13 @@ SkipCount: level++; ,AC.dollarnames->namebuffer+d->name); MUNLOCK(ErrorMessageLock); #ifdef WITHPTHREADS - if ( ddtype > 0 && ddtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( ddtype > 0 && ! DollarLocalCopy(ddtype) ) { UNLOCK(d->pthreadslockread); } #endif goto GenCall; } theindex = d->index; #ifdef WITHPTHREADS - if ( ddtype > 0 && ddtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( ddtype > 0 && ! DollarLocalCopy(ddtype) ) { UNLOCK(d->pthreadslockread); } #endif } cp[1] = SUBEXPSIZE+4; @@ -3547,7 +3547,7 @@ SkipCount: level++; } if ( nummodopt < NumModOptdollars ) { ddtype = ModOptdollars[nummodopt].type; - if ( ddtype == MODLOCAL ) { + if ( DollarLocalCopy(ddtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } else { @@ -3574,13 +3574,13 @@ SkipCount: level++; ,AC.dollarnames->namebuffer+d->name); MUNLOCK(ErrorMessageLock); #ifdef WITHPTHREADS - if ( ddtype > 0 && ddtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( ddtype > 0 && ! DollarLocalCopy(ddtype) ) { UNLOCK(d->pthreadslockread); } #endif goto GenCall; } theindex = d->index; #ifdef WITHPTHREADS - if ( ddtype > 0 && ddtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( ddtype > 0 && ! DollarLocalCopy(ddtype) ) { UNLOCK(d->pthreadslockread); } #endif } *cp++ = INDTOIND; @@ -4126,7 +4126,7 @@ AutoGen: i = *AT.TMout; } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { dd = ModOptdollars[nummodopt].dstruct+AT.identity; } } @@ -4190,13 +4190,15 @@ AutoGen: i = *AT.TMout; } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype != MODLOCAL && dtype != MODSUM ) { + if ( dtype == MODMAX || dtype == MODMIN ) { if ( StartBuf[0] && StartBuf[StartBuf[0]] ) { MLOCK(ErrorMessageLock); MesPrint("A dollar variable with modoption max or min can have only one term"); MUNLOCK(ErrorMessageLock); goto GenCall; } + } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { LOCK(d->pthreadslockread); } } @@ -4232,7 +4234,7 @@ AutoGen: i = *AT.TMout; } */ #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL && dtype != MODSUM ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } if ( ( AS.Balancing && CC->numrhs == 0 ) && StartBuf[posisub] ) { if ( ( id = ConditionalGetAvailableThread() ) >= 0 ) { if ( BalanceRunThread(BHEAD id,termout,level) < 0 ) goto GenCall; @@ -4242,7 +4244,7 @@ AutoGen: i = *AT.TMout; #endif if ( Generator(BHEAD termout,level) < 0 ) goto GenCall; #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { dtype = 0; break; } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { dtype = 0; break; } #endif if ( iscopy == 0 && ( extractbuff != AM.dbufnum ) ) { /* @@ -4259,7 +4261,7 @@ AutoGen: i = *AT.TMout; Ce->Pointer = Ce->rhs[Ce->numrhs--]; } #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL && dtype != MODSUM ) { UNLOCK(d->pthreadslockread); dtype = 0; } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); dtype = 0; } #endif if ( iscopy ) { if ( d->nfactors > 1 ) { @@ -4317,7 +4319,7 @@ AutoGen: i = *AT.TMout; *AN.RepPoint = 1; AR.expchanged = 1; #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL && dtype != MODSUM ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } if ( ( AS.Balancing && CC->numrhs == 0 ) && ( i > 0 ) && ( id = ConditionalGetAvailableThread() ) >= 0 ) { if ( BalanceRunThread(BHEAD id,termout,level) < 0 ) goto GenCall; @@ -4326,7 +4328,7 @@ AutoGen: i = *AT.TMout; #endif if ( Generator(BHEAD termout,level) ) goto GenCall; #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { dtype = 0; break; } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { dtype = 0; break; } #endif if ( iscopy == 0 && ( extractbuff != AM.dbufnum ) ) StartBuf = cbuf[extractbuff].Buffer; @@ -4334,7 +4336,7 @@ AutoGen: i = *AT.TMout; } } while ( i > 0 ); #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL && dtype != MODSUM ) { UNLOCK(d->pthreadslockread); dtype = 0; } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); dtype = 0; } #endif if ( iscopy ) { if ( d->nfactors > 1 ) { @@ -4381,7 +4383,7 @@ AutoGen: i = *AT.TMout; *AN.RepPoint = 1; AR.expchanged = 1; #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL && dtype != MODSUM ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } if ( ( AS.Balancing && CC->numrhs == 0 ) && ( i > 0 ) && ( id = ConditionalGetAvailableThread() ) >= 0 ) { if ( BalanceRunThread(BHEAD id,termout,level) < 0 ) goto GenCall; } @@ -4389,7 +4391,7 @@ AutoGen: i = *AT.TMout; #endif if ( Generator(BHEAD termout,level) ) goto GenCall; #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL && dtype != MODSUM ) { dtype = 0; break; } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { dtype = 0; break; } #endif if ( iscopy == 0 && ( extractbuff != AM.dbufnum ) ) StartBuf = cbuf[extractbuff].Buffer; @@ -4397,7 +4399,7 @@ AutoGen: i = *AT.TMout; } } #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL && dtype != MODSUM ) { UNLOCK(d->pthreadslockread); dtype = 0; } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); dtype = 0; } #endif if ( iscopy ) { if ( d->nfactors > 1 ) { diff --git a/sources/structs.h b/sources/structs.h index c4c64897..89858f3e 100644 --- a/sources/structs.h +++ b/sources/structs.h @@ -561,7 +561,7 @@ typedef struct DoLlArS { typedef struct MoDoPtDoLlArS { #ifdef WITHPTHREADS - DOLLARS dstruct; /* If local dollar: list of DOLLARS for each thread */ + DOLLARS dstruct; /* If local,min,max dollar: list of DOLLARS for each thread */ #endif WORD number; WORD type; diff --git a/sources/transform.c b/sources/transform.c index d2b11fb8..98d2bd2f 100644 --- a/sources/transform.c +++ b/sources/transform.c @@ -2206,7 +2206,7 @@ int RunPermute(PHEAD WORD *fun, WORD *args, WORD *info) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } else { @@ -2232,7 +2232,7 @@ int RunPermute(PHEAD WORD *fun, WORD *args, WORD *info) } else { IllType: - MLOCK(ErrorMessageLock); + MLOCK(ErrorMessageLock); MesPrint("Illegal type of $-variable in RunPermute"); MUNLOCK(ErrorMessageLock); Terminate(-1); @@ -2258,7 +2258,7 @@ int RunPermute(PHEAD WORD *fun, WORD *args, WORD *info) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } else { diff --git a/sources/wildcard.c b/sources/wildcard.c index 9eebe1c7..0a98a440 100644 --- a/sources/wildcard.c +++ b/sources/wildcard.c @@ -1401,7 +1401,7 @@ int ResolveSet(PHEAD WORD *from, WORD *to, WORD *subs) } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; - if ( dtype == MODLOCAL ) { + if ( DollarLocalCopy(dtype) ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } else { @@ -1440,7 +1440,7 @@ int ResolveSet(PHEAD WORD *from, WORD *to, WORD *subs) } } #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } #endif MLOCK(ErrorMessageLock); MesPrint("Unusable type of variable $%s in set substitution", @@ -1450,7 +1450,7 @@ int ResolveSet(PHEAD WORD *from, WORD *to, WORD *subs) } GotOne:; #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslockread); } #endif ii = m[*w]; if ( ii >= 2*MAXPOWER ) i3 = ii - 2*MAXPOWER;