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;