From 2633bed7165608fe05b092f67130bb77e4fa8298 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. --- check/user.frm | 46 +++++++++++++++++++ doc/manual/statements.tex | 38 +++++++++------- sources/declare.h | 1 + sources/dollar.c | 93 ++++++++++++++++++++++----------------- 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 +-- 14 files changed, 271 insertions(+), 119 deletions(-) diff --git a/check/user.frm b/check/user.frm index 1ddcb8017..a08ee8d98 100644 --- a/check/user.frm +++ b/check/user.frm @@ -736,6 +736,52 @@ Print check; .end assert result("check") =~ expr("0") *--#] jodavies_prf_1 : +*--#[ jodavies_dollar_locks : +#- + +#: TermsInSmall 2M + +* A larger version of this test can be used to easily demonstrate the +* performance improvement due to max/min dollar locking changes in TFORM, +* see PR 807. + +Symbol x,i; +CFunction sum; + +#define N "{32*8}" +*#define BLOCK "200000" +#define BLOCK "20" + +Local test = + #do i = 0,{`N'-1} + + sum(i,`i'*`BLOCK',{`i'+1}*`BLOCK'-1,x^i) + #enddo + ; +.sort +Identify sum(?a) = sum_(?a); +.sort + +#$min = `N'*`BLOCK'; +#$max = -1; + +If (Count(x,1) > $max) $max = count_(x,1); +If (Count(x,1) < $min) $min = count_(x,1); + +ModuleOption maximum $max; +ModuleOption minimum $min; +.sort + +#message max: `$max' +#message min: `$min' +.end +assert succeeded? +assert stdout =~ exact_pattern(<<'EOF') +~~~max: 5119 +EOF +assert stdout =~ exact_pattern(<<'EOF') +~~~min: 0 +EOF +*--#] jodavies_dollar_locks : *--#[ tueda_prf_1 : #- Off Statistics; diff --git a/doc/manual/statements.tex b/doc/manual/statements.tex index bbe93e316..235b93436 100644 --- a/doc/manual/statements.tex +++ b/doc/manual/statements.tex @@ -3164,30 +3164,36 @@ \section{moduleoption} \leftvitem{3.5cm}{local\index{moduleoption!local}} \rightvitem{13cm}{Should be followed by a list of \$-variables. Indicates that the contents of the indicated \$-variables\index{\$-variable} are not -relevant once the module has been finished and neither is the term by term -order in which the \$-variables obtain their value. In practise each +relevant once the module has been finished, and neither is the term by term +order in which the \$-variables obtain their value. In practice each processor\index{processor}/thread\index{thread} will work with its own copy of this variable.} \leftvitem{3.5cm}{maximum\index{moduleoption!maximum}} -\rightvitem{13cm}{Should be followed by a list of -\$-variables\index{\$-variable}. Indicates that of the contents of the -indicated \$-variables the maximum is the only thing that is relevant once -the module has been finished. The term by term order in which the -\$-variables obtain their value is not relevant.} +\rightvitem{13cm}{Should be followed by a list of \$-variables\index{\$-variable}. +Indicates that only the maximum value of the \$-variables is relevant once the +module has finished. The term-by-term order in which the \$-variables obtain +their value is not relevant. In practice each processor\index{processor}/thread +\index{thread} will work with its own copy of the variable, and the +maximal value is kept at the end of term processing. The variables should +contain numbers only.} \leftvitem{3.5cm}{minimum\index{moduleoption!minimum}} -\rightvitem{13cm}{Should be followed by a list of -\$-variables\index{\$-variable}. Indicates that of the contents of the -indicated \$-variables the minimum is the only thing that is relevant once -the module has been finished. The term by term order in which the -\$-variables obtain their value is not relevant.} +\rightvitem{13cm}{Should be followed by a list of \$-variables\index{\$-variable}. +Indicates that only the minimum value of the \$-variables is relevant once the +module has finished. The term-by-term order in which the \$-variables obtain +their value is not relevant. In practice each processor\index{processor}/thread +\index{thread} will work with its own copy of the variable, and the +minimal value is kept at the end of term processing. The variables should contain +numbers only.} \leftvitem{3.5cm}{sum\index{moduleoption!sum}} -\rightvitem{13cm}{Should be followed by a list of -\$-variables\index{\$-variable}. Indicates that the indicated \$-variables -are representing a sum. The term by term order in which the \$-variables -obtain their value is not relevant.} +\rightvitem{13cm}{Should be followed by a list of \$-variables\index{\$-variable}. +Indicates that the specified \$-variables represent a sum. The term-by-term +order in which the \$-variables obtain their value is not relevant. +In practice, this is a global dollar variable for which all parallel read and +write accesses are protected by locks. The variables should contain numbers +only.} \noindent The options `local', `maximum', `minimum' and `sum' are for parallel versions of \FORM\@. The presence of \$-variables can be a problem diff --git a/sources/declare.h b/sources/declare.h index 4c30cbd78..3be419608 100644 --- a/sources/declare.h +++ b/sources/declare.h @@ -1283,6 +1283,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 35d5bc6a0..2d755dabc 100644 --- a/sources/dollar.c +++ b/sources/dollar.c @@ -234,7 +234,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; } } @@ -250,7 +250,7 @@ int AssignDollar(PHEAD WORD *term, WORD level) */ #ifdef WITHPTHREADS if ( dtype > 0 ) { - LOCK(d->pthreadslock); + if ( ! DollarLocalCopy(dtype) ) { LOCK(d->pthreadslock); } NewValIsZero:; switch ( d->type ) { case DOLZERO: goto NoChangeZero; @@ -275,7 +275,7 @@ NewValIsZero:; cbuf[AM.dbufnum].NumTerms[numdollar] = 0; NoChangeZero:; CleanDollarFactors(d); - UNLOCK(d->pthreadslock); + if ( ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } AN.ncmod = oldncmod; return(0); } @@ -297,7 +297,7 @@ NoChangeZero:; */ #ifdef WITHPTHREADS if ( dtype > 0 ) { - LOCK(d->pthreadslock); + if ( ! DollarLocalCopy(dtype) ) { LOCK(d->pthreadslock); } if ( d->size < MINALLOC ) { WORD oldsize, *oldwhere, i; oldsize = d->size; oldwhere = d->where; @@ -360,7 +360,7 @@ HandleDolZero:; cbuf[AM.dbufnum].NumTerms[numdollar] = 1; NoChangeOne:; CleanDollarFactors(d); - UNLOCK(d->pthreadslock); + if ( ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } AN.ncmod = oldncmod; return(0); } @@ -392,7 +392,7 @@ NoChangeOne:; depends on the dollar variable. */ #ifdef WITHPTHREADS - LOCK(d->pthreadslock); + if ( ! DollarLocalCopy(dtype) ) { LOCK(d->pthreadslock); } #endif CleanDollarFactors(d); /* @@ -560,7 +560,7 @@ HandleDolZero1:; } #ifdef WITHPTHREADS NoChange:; - UNLOCK(d->pthreadslock); + if ( ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } #endif AN.ncmod = oldncmod; return(0); @@ -917,7 +917,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 { @@ -1077,7 +1077,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 { @@ -1115,7 +1115,7 @@ WORD DolToTensor(PHEAD WORD numdollar) retval = 0; } #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } #endif return(retval); } @@ -1138,7 +1138,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 { @@ -1172,7 +1172,7 @@ WORD DolToFunction(PHEAD WORD numdollar) retval = 0; } #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } #endif return(retval); } @@ -1195,7 +1195,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 { @@ -1236,7 +1236,7 @@ WORD DolToVector(PHEAD WORD numdollar) retval = 0; } #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } #endif return(retval); } @@ -1258,7 +1258,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; } } @@ -1318,7 +1318,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 { @@ -1349,7 +1349,7 @@ WORD DolToSymbol(PHEAD WORD numdollar) retval = -1; } #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } #endif return(retval); } @@ -1372,7 +1372,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 { @@ -1425,7 +1425,7 @@ WORD DolToIndex(PHEAD WORD numdollar) retval = 0; } #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } #endif return(retval); } @@ -1454,7 +1454,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; } } @@ -1600,7 +1600,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; } } @@ -1751,7 +1751,7 @@ 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 { @@ -1807,9 +1807,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->pthreadslock); - } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } #endif if ( newd->factors ) M_free(newd->factors,"Dollar factors"); M_free(newd,"Copy of dollar variable"); @@ -1860,7 +1858,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 { @@ -1885,7 +1883,7 @@ LONG TermsInDollar(WORD num) else if ( d->type == DOLZERO ) n = 0; else n = 1; #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } #endif return(n); } @@ -1909,7 +1907,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 { @@ -1937,7 +1935,7 @@ LONG SizeOfDollar(WORD num) else if ( d->type == DOLZERO ) n = 0; else n = 1; #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } #endif return(n); } @@ -2646,7 +2644,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; } } @@ -2774,7 +2772,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; } } @@ -2852,7 +2850,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; } } @@ -2960,7 +2958,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 { @@ -2971,7 +2969,7 @@ int DollarFactorize(PHEAD WORD numdollar) #endif CleanDollarFactors(d); #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } #endif if ( d->type != DOLTERMS ) { /* only one term */ if ( d->type != DOLZERO ) d->nfactors = 1; @@ -3221,13 +3219,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->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { LOCK(d->pthreadslock); } #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->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } #endif /* We used here (before 3-sep-2015) the original and did not make @@ -3279,7 +3277,7 @@ getout2: AR.SortType = oldsorttype; M_free(d->factors,"factors in dollar"); d->factors = 0; #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } #endif M_free(buf3,"DollarFactorize-4"); if ( buf2 != buf1 && buf2 ) M_free(buf2,"DollarFactorize-4"); @@ -3523,7 +3521,7 @@ nextj:; #] Step 8: */ #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } #endif return(0); } @@ -3842,7 +3840,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 { @@ -3896,7 +3894,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 { @@ -3952,4 +3950,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 2514370ca..654385c70 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 cc4b82246..8212c4759 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 5799be891..d77e744c9 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->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { + UNLOCK(d->pthreadslock); + } #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->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { + UNLOCK(d->pthreadslock); + } #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->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { + UNLOCK(d->pthreadslock); + } #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->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { + UNLOCK(d->pthreadslock); + } #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->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { + UNLOCK(d->pthreadslock); + } #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->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { + UNLOCK(d->pthreadslock); + } #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->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { + UNLOCK(d->pthreadslock); + } #endif } break; diff --git a/sources/message.c b/sources/message.c index 247741b6c..736cff428 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->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } #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->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } #endif Terminate(-1); } @@ -615,7 +615,7 @@ dollarzero: *t++ = '0'; *t = 0; } } #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } #endif AN.listinprint += 2; while ( AN.listinprint[0] == DOLLAREXPR2 ) AN.listinprint += 2; diff --git a/sources/module.c b/sources/module.c index c491542cf..ee54e35eb 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 a435944bd..58ef46707 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->pthreadslock); } + if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslock); } #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->pthreadslock); } + if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslock); } #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->pthreadslock); } + if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslock); } #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->pthreadslock); } + if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslock); } #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->pthreadslock); } + if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslock); } #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->pthreadslock); } + if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslock); } #endif break; } @@ -693,7 +693,7 @@ NextSymbol:; while ( t < m ) { if ( *t == DOLLAREXPRESSION ) { #ifdef WITHPTHREADS - if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslock); } + if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslock); } #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->pthreadslock); } + if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslock); } #endif goto RegEnd; } else { #ifdef WITHPTHREADS - if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslock); } + if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslock); } #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->pthreadslock); } + if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslock); } #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 5df5bb048..06df62804 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->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } #endif Terminate(-1); } #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } #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->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } #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->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } #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->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } #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->pthreadslock); } + if ( ddtype > 0 && ! DollarLocalCopy(ddtype) ) { UNLOCK(d->pthreadslock); } #endif goto GenCall; } theindex = d->index; #ifdef WITHPTHREADS - if ( ddtype > 0 && ddtype != MODLOCAL ) { UNLOCK(d->pthreadslock); } + if ( ddtype > 0 && ! DollarLocalCopy(ddtype) ) { UNLOCK(d->pthreadslock); } #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->pthreadslock); } + if ( ddtype > 0 && ! DollarLocalCopy(ddtype) ) { UNLOCK(d->pthreadslock); } #endif goto GenCall; } theindex = d->index; #ifdef WITHPTHREADS - if ( ddtype > 0 && ddtype != MODLOCAL ) { UNLOCK(d->pthreadslock); } + if ( ddtype > 0 && ! DollarLocalCopy(ddtype) ) { UNLOCK(d->pthreadslock); } #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->pthreadslock); } } @@ -4232,7 +4234,7 @@ AutoGen: i = *AT.TMout; } */ #ifdef WITHPTHREADS - if ( dtype > 0 && dtype != MODLOCAL && dtype != MODSUM ) { UNLOCK(d->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } 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->pthreadslock); dtype = 0; } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); 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->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } 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->pthreadslock); dtype = 0; } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); 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->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } 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->pthreadslock); dtype = 0; } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); dtype = 0; } #endif if ( iscopy ) { if ( d->nfactors > 1 ) { diff --git a/sources/structs.h b/sources/structs.h index 4c2fe3593..1c016a549 100644 --- a/sources/structs.h +++ b/sources/structs.h @@ -560,7 +560,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 d27888fe9..58a8aab44 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 4d03ad1de..6422b749f 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->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } #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->pthreadslock); } + if ( dtype > 0 && ! DollarLocalCopy(dtype) ) { UNLOCK(d->pthreadslock); } #endif ii = m[*w]; if ( ii >= 2*MAXPOWER ) i3 = ii - 2*MAXPOWER;