diff --git a/check/user.frm b/check/user.frm index 1ddcb801..a08ee8d9 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 bbe93e31..235b9343 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 4c30cbd7..3be41960 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 35d5bc6a..2d755dab 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 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 5799be89..d77e744c 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 247741b6..736cff42 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 c491542c..ee54e35e 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 a435944b..58ef4670 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 5df5bb04..06df6280 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 4c2fe359..1c016a54 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 d27888fe..58a8aab4 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 4d03ad1d..6422b749 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;