diff --git a/check/fixes.frm b/check/fixes.frm index 3ad37168..d16b8523 100644 --- a/check/fixes.frm +++ b/check/fixes.frm @@ -1409,6 +1409,63 @@ assert stdout =~ exact_pattern(<<'EOF') F EOF *--#] Issue129_2 : +*--#[ Issue138_1 : +CFunction f,a,b,c,d; +Symbol x,y; +Local F = (1+f((a+b)^2,(a+b)*(c*d)))^20; +.sort +Identify f(x?,y?) = f(gcd_(x,y)); +ToPolynomial; +.sort +FromPolynomial; +Identify f(a+b) = -1; +Print; +.end +assert succeeded? +assert result("F") =~ expr("0") +*--#] Issue138_1 : +*--#[ Issue138_2 : +CFunction f,g; +Symbol x,y; +Local F = (1+f((g(x)+g(y))^2))^20; +FactArg f; +ToPolynomial; +.sort +FromPolynomial; +Identify f(g(x)+g(y),g(x)+g(y)) = -1; +Print; +.end +assert succeeded? +assert result("F") =~ expr("0") +*--#] Issue138_2 : +*--#[ Issue138_3 : +CFunction f,g; +Symbol x,y; +Local F = (1+f((g(x)+g(y))^2))^20; +FactArg f; +ArgToExtraSymbol g; +.sort +FromPolynomial; +Identify f(g(x)+g(y),g(x)+g(y)) = -1; +Print; +.end +assert succeeded? +assert result("F") =~ expr("0") +*--#] Issue138_3 : +*--#[ Issue138_4 : +CFunction f,g,h; +Symbol x,y; +Local F = (1+f((g(x)+g(y)+h(x)+h(y))^2))^20; +ArgToExtraSymbol g; +FactArg f; +.sort +FromPolynomial; +Identify f(g(x)+g(y)+h(x)+h(y),g(x)+g(y)+h(x)+h(y)) = -1; +Print; +.end +assert succeeded? +assert result("F") =~ expr("0") +*--#] Issue138_4 : *--#[ Issue139 : * Corrupted characters in printing f(-2147483648) CF f; diff --git a/sources/argument.c b/sources/argument.c index 12a2308f..069d37f5 100644 --- a/sources/argument.c +++ b/sources/argument.c @@ -2076,7 +2076,7 @@ int ArgFactorize(PHEAD WORD *argin, WORD *argout) #ifdef NEWORDER WORD *tt; #endif - WORD startebuf = cbuf[AT.ebufnum].numrhs,oldword; + WORD startebuf = cbuf[AT.ebufnum].numrhs, extrasymbolbase = -1, oldword; WORD oldsorttype = AR.SortType, numargs; int error = 0, action = 0, i, ii, number, sign = 1; @@ -2254,7 +2254,7 @@ int ArgFactorize(PHEAD WORD *argin, WORD *argout) argextra = AT.WorkPointer; NewSort(BHEAD0); while ( t < tstop ) { - if ( LocalConvertToPoly(BHEAD t,argextra,startebuf,0) < 0 ) { + if ( LocalConvertToPoly(BHEAD t,argextra,startebuf,0,&extrasymbolbase) < 0 ) { error = -1; getout: AR.SortType = oldsorttype; @@ -2309,8 +2309,8 @@ int ArgFactorize(PHEAD WORD *argin, WORD *argout) argextra = AT.WorkPointer; NewSort(BHEAD0); while ( t < tstop ) { - if ( ConvertFromPoly(BHEAD t,argextra,numxsymbol,CC->numrhs-startebuf+numxsymbol - ,startebuf-numxsymbol,1) <= 0 ) { + if ( ConvertFromPoly(BHEAD t,argextra,extrasymbolbase,CC->numrhs-startebuf+extrasymbolbase + ,startebuf-extrasymbolbase,1) <= 0 ) { TermFree(argcopy2,"argcopy2"); LowerSortLevel(); error = -3; diff --git a/sources/compcomm.c b/sources/compcomm.c index 4c281613..55a11766 100644 --- a/sources/compcomm.c +++ b/sources/compcomm.c @@ -2223,11 +2223,6 @@ int CoSplitLastArg(UBYTE *s) { return(DoArgument(s,TYPESPLITLASTARG)); } */ int CoFactArg(UBYTE *s) { - if ( ( AC.topolynomialflag & TOPOLYNOMIALFLAG ) != 0 ) { - MesPrint("&ToPolynomial statement and FactArg statement are not allowed in the same module"); - return(1); - } - AC.topolynomialflag |= FACTARGFLAG; return(DoArgument(s,TYPEFACTARG)); } @@ -5953,9 +5948,8 @@ int CoDropSymbols(UBYTE *s) Converts the current term as much as possible to symbols. Keeps a list of all objects converted to symbols in AM.sbufnum. - Note that this cannot be executed in parallel because we have only - a single compiler buffer for this. Hence we switch on the noparallel - module option. + There is only a single compiler buffer for this. In TFORM we protect access + to it with AM.sbuflock; in ParFORM the statement is executed on the master. Option(s): OnlyFunctions [,name1][,name2][,...,namem]; @@ -5965,10 +5959,6 @@ int CoToPolynomial(UBYTE *inp) { int error = 0; while ( *inp == ' ' || *inp == ',' || *inp == '\t' ) inp++; - if ( ( AC.topolynomialflag & ~TOPOLYNOMIALFLAG ) != 0 ) { - MesPrint("&ToPolynomial statement and FactArg statement are not allowed in the same module"); - return(1); - } if ( AO.OptimizeResult.code != NULL ) { MesPrint("&Using ToPolynomial statement when there are still optimization results active."); MesPrint("&Please use #ClearOptimize instruction first."); @@ -6067,11 +6057,6 @@ int CoArgToExtraSymbol(UBYTE *s) CBUF *C = cbuf + AC.cbufnum; WORD *lhs; - /* TODO: resolve interference with rational arithmetic. (#138) */ - if ( ( AC.topolynomialflag & ~TOPOLYNOMIALFLAG ) != 0 ) { - MesPrint("&ArgToExtraSymbol statement and FactArg statement are not allowed in the same module"); - return(1); - } if ( AO.OptimizeResult.code != NULL ) { MesPrint("&Using ArgToExtraSymbol statement when there are still optimization results active."); MesPrint("&Please use #ClearOptimize instruction first."); diff --git a/sources/comtool.c b/sources/comtool.c index 06ee9263..a54f4133 100644 --- a/sources/comtool.c +++ b/sources/comtool.c @@ -526,6 +526,8 @@ balance:; Returns -1 if the element is not in the tree. The advantage of this routine over InsTree is that this routine can be run in parallel. + Note that this function is not actually thread-safe, due to the update + of "usage". */ int FindTree(int bufnum, WORD *subexpr) diff --git a/sources/declare.h b/sources/declare.h index cd4fb2e4..a8d62dfb 100644 --- a/sources/declare.h +++ b/sources/declare.h @@ -1576,10 +1576,10 @@ extern int RunHtoZArg(PHEAD WORD *fun, WORD *args); extern int NormPolyTerm(PHEAD WORD *); extern WORD ComparePoly(WORD *, WORD *, WORD); extern int ConvertToPoly(PHEAD WORD *, WORD *,WORD *,WORD); -extern int LocalConvertToPoly(PHEAD WORD *, WORD *, WORD,WORD); +extern int LocalConvertToPoly(PHEAD WORD *, WORD *, WORD,WORD,WORD *); extern int ConvertFromPoly(PHEAD WORD *, WORD *, WORD, WORD, WORD, WORD); extern int FindSubterm(WORD *); -extern int FindLocalSubterm(PHEAD WORD *, WORD); +extern int FindLocalSubterm(PHEAD WORD *, WORD, WORD); extern void PrintSubtermList(int,int); extern void PrintExtraSymbol(int,WORD *,int); extern int FindSubexpression(WORD *); @@ -1606,8 +1606,8 @@ extern WORD *PolyDiv(PHEAD WORD *,WORD *,char *); extern void GCDclean(PHEAD WORD *, WORD *); extern WORD *TakeSymbolContent(PHEAD WORD *,WORD *); extern int GCDterms(PHEAD WORD *,WORD *,WORD *); -extern WORD *PutExtraSymbols(PHEAD WORD *,WORD,int *); -extern WORD *TakeExtraSymbols(PHEAD WORD *,WORD); +extern WORD *PutExtraSymbols(PHEAD WORD *,WORD,int *,WORD *); +extern WORD *TakeExtraSymbols(PHEAD WORD *,WORD,WORD); extern WORD *MultiplyWithTerm(PHEAD WORD *, WORD *,WORD); extern WORD *TakeContent(PHEAD WORD *, WORD *); extern int MergeSymbolLists(PHEAD WORD *, WORD *, int); diff --git a/sources/dollar.c b/sources/dollar.c index 0b50ff52..0d323808 100644 --- a/sources/dollar.c +++ b/sources/dollar.c @@ -2949,7 +2949,7 @@ int DollarFactorize(PHEAD WORD numdollar) #endif int i, j, jj, action = 0, sign = 1; LONG insize, ii; - WORD startebuf = cbuf[AT.ebufnum].numrhs; + WORD startebuf = cbuf[AT.ebufnum].numrhs, extrasymbolbase = -1; WORD nfactors, factorsincontent, extrafactor = 0; WORD oldsorttype = AR.SortType; @@ -3144,7 +3144,7 @@ int DollarFactorize(PHEAD WORD numdollar) NewSort(BHEAD0); NewSort(BHEAD0); while ( *t ) { - if ( LocalConvertToPoly(BHEAD t,termextra,startebuf,0) < 0 ) { + if ( LocalConvertToPoly(BHEAD t,termextra,startebuf,0,&extrasymbolbase) < 0 ) { getout: AR.SortType = oldsorttype; M_free(buf1,"DollarFactorize-2"); @@ -3274,8 +3274,8 @@ int DollarFactorize(PHEAD WORD numdollar) NewSort(BHEAD0); NewSort(BHEAD0); while ( *term ) { - if ( ConvertFromPoly(BHEAD term,argextra,numxsymbol,CC->numrhs-startebuf+numxsymbol - ,startebuf-numxsymbol,1) <= 0 ) { + if ( ConvertFromPoly(BHEAD term,argextra,extrasymbolbase,CC->numrhs-startebuf+extrasymbolbase + ,startebuf-extrasymbolbase,1) <= 0 ) { LowerSortLevel(); getout2: AR.SortType = oldsorttype; M_free(d->factors,"factors in dollar"); diff --git a/sources/ftypes.h b/sources/ftypes.h index 999a9014..091accb7 100644 --- a/sources/ftypes.h +++ b/sources/ftypes.h @@ -1043,7 +1043,6 @@ typedef int (*TFUN1)(UBYTE *,int); #define NOLYNDON 2 #define TOPOLYNOMIALFLAG 1 -#define FACTARGFLAG 2 #define OLDFACTARG 1 #define NEWFACTARG 0 diff --git a/sources/notation.c b/sources/notation.c index 64107ad8..6f7c2d19 100644 --- a/sources/notation.c +++ b/sources/notation.c @@ -505,13 +505,25 @@ int ConvertToPoly(PHEAD WORD *term, WORD *outterm, WORD *comlist, WORD par) * buffer and represented by a symbol. The numbering of the extra * symbols is down from the maximum. In principle there can be a * problem when running into the already assigned ones. - * This uses the FindTree for searching in the global tree and - * then looks further in the AT.ebufnum. This allows fully parallel - * processing. Hence we need no locks. Cannot be used in the same - * module as ConvertToPoly. + * The temporary extrasymbol definitions live in the private AT.ebufnum. + * We don't touch the global definitions, beyond determining the current + * number of global extrasymbols, under a lock. */ -int LocalConvertToPoly(PHEAD WORD *term, WORD *outterm, WORD startebuf, WORD par) +/** Helper function: copy the current numxsymbol, under a lock. Local temporary + * extrasymbol numbers will follow this. If the argument is positive, we have + * already stored the global numxsymbol and don't store it again. */ +static WORD LocalExtraSymbolBase(WORD *base) +{ + if ( *base < 0 ) { + LOCK(AM.sbuflock); + *base = numxsymbol; + UNLOCK(AM.sbuflock); + } + return(*base); +} + +int LocalConvertToPoly(PHEAD WORD *term, WORD *outterm, WORD startebuf, WORD par, WORD *base) { WORD *tout, *tstop, ncoef, *t, *r, *tt, *ttwo = 0; int i, action = 0; @@ -536,7 +548,7 @@ int LocalConvertToPoly(PHEAD WORD *term, WORD *outterm, WORD startebuf, WORD par tout[2] = 4; tout[3] = r[0]; tout[4] = -1; - i = FindLocalSubterm(BHEAD tout+1,startebuf); + i = FindLocalSubterm(BHEAD tout+1,startebuf,LocalExtraSymbolBase(base)); *tout++ = SYMBOL; *tout++ = 4; *tout++ = MAXVARIABLES-i; @@ -560,7 +572,7 @@ int LocalConvertToPoly(PHEAD WORD *term, WORD *outterm, WORD startebuf, WORD par else { tout[5] = 1; } - i = FindLocalSubterm(BHEAD tout+1,startebuf); + i = FindLocalSubterm(BHEAD tout+1,startebuf,LocalExtraSymbolBase(base)); *tout++ = SYMBOL; *tout++ = 4; *tout++ = MAXVARIABLES-i; @@ -577,7 +589,7 @@ int LocalConvertToPoly(PHEAD WORD *term, WORD *outterm, WORD startebuf, WORD par tout[2] = 4; tout[3] = r[0]; tout[4] = r[1]; - i = FindLocalSubterm(BHEAD tout+1,startebuf); + i = FindLocalSubterm(BHEAD tout+1,startebuf,LocalExtraSymbolBase(base)); *tout++ = SYMBOL; *tout++ = 4; *tout++ = MAXVARIABLES-i; @@ -593,7 +605,7 @@ int LocalConvertToPoly(PHEAD WORD *term, WORD *outterm, WORD startebuf, WORD par tout[1] = INDEX; tout[2] = 3; tout[3] = r[0]; - i = FindLocalSubterm(BHEAD tout+1,startebuf); + i = FindLocalSubterm(BHEAD tout+1,startebuf,LocalExtraSymbolBase(base)); *tout++ = SYMBOL; *tout++ = 4; *tout++ = MAXVARIABLES-i; @@ -615,7 +627,7 @@ int LocalConvertToPoly(PHEAD WORD *term, WORD *outterm, WORD startebuf, WORD par else { t += t[1]; } } else if ( *t >= FUNCTION ) { - i = FindLocalSubterm(BHEAD t,startebuf); + i = FindLocalSubterm(BHEAD t,startebuf,LocalExtraSymbolBase(base)); t += t[1]; *tout++ = SYMBOL; *tout++ = 4; @@ -661,65 +673,61 @@ int LocalConvertToPoly(PHEAD WORD *term, WORD *outterm, WORD startebuf, WORD par subexpressions when extra symbols have been replaced. */ +#ifdef WITHPTHREADS +/** Helper function: we only lock sbuflock if the term actually has an + * extrasymbol to replace. Search for one. */ +static int PolyHasExtraSymbols(WORD *term, WORD from, WORD to) +{ + WORD *t, *tt, *tstop, *tstop1; + + tstop = term + *term - ABS(term[*term-1]); + for ( t = term + 1; t < tstop; t += t[1] ) { + if ( *t != SYMBOL ) { + continue; + } + tstop1 = t + t[1]; + for ( tt = t + 2; tt < tstop1; tt += 2 ) { + if ( *tt >= MAXVARIABLES - to && *tt < MAXVARIABLES - from ) { + return(1); + } + } + } + return(0); +} +#endif + +static int ConvertFromPolyImpl(PHEAD WORD *term, WORD *outterm, WORD from, WORD to, WORD offset, WORD par); + int ConvertFromPoly(PHEAD WORD *term, WORD *outterm, WORD from, WORD to, WORD offset, WORD par) +{ + int locked = 0, result; + /* LocalConvertToPoly uses only AT.ebufnum. Expression-level FromPolynomial + * needs the global lock if the term contains a global extrasymbol. */ +#ifdef WITHPTHREADS + if ( ! par && PolyHasExtraSymbols(term,from,to) ) { + LOCK(AM.sbuflock); + locked = 1; + } +#endif + result = ConvertFromPolyImpl(BHEAD term,outterm,from,to,offset,par); +#ifdef WITHPTHREADS + if ( locked ) { + UNLOCK(AM.sbuflock); + } +#else + DUMMYUSE(locked); +#endif + return(result); +} + +static int ConvertFromPolyImpl(PHEAD WORD *term, WORD *outterm, WORD from, WORD to, WORD offset, WORD par) { WORD *tout, *tstop, *tstop1, ncoef, *t, *r, *tt; int i; -/* first = 1; */ tt = term + *term; tout = outterm+1; ncoef = ABS(tt[-1]); tstop = tt - ncoef; -/* - r = t = term + 1; - while ( t < tstop ) { - if ( *t == SYMBOL ) { - tstop1 = t + t[1]; - tt = t + 2; - while ( tt < tstop1 ) { - if ( ( *tt < MAXVARIABLES - to ) - || ( *tt >= MAXVARIABLES - from ) ) { - tt += 2; - } - else break; - } - if ( tt >= tstop1 ) { t = tstop1; continue; } - while ( r < t ) *tout++ = *r++; - t += 2; - first = 0; - while ( t < tstop1 ) { - if ( ( *t < MAXVARIABLES - to ) - || ( *t >= MAXVARIABLES - from ) ) { - *tout++ = SYMBOL; - *tout++ = 4; - *tout++ = *t++; - *tout++ = *t++; - } - else { - *tout++ = SUBEXPRESSION; - *tout++ = SUBEXPSIZE; - *tout++ = MAXVARIABLES - *t++ + offset; - *tout++ = *t++; - if ( par ) *tout++ = AT.ebufnum; - else *tout++ = AM.sbufnum; - FILLSUB(tout) - } - } - r = t; - } - else { - t += t[1]; - } - } - if ( first ) { - i = *term; t = term; - NCOPY(outterm,t,i); - return(*term); - } - while ( r < t ) *tout++ = *r++; - NCOPY(tout,tstop,ncoef) - *outterm = tout-outterm; -*/ t = term + 1; while ( t < tstop ) { if ( *t == SYMBOL ) { @@ -771,7 +779,8 @@ int ConvertFromPoly(PHEAD WORD *term, WORD *outterm, WORD from, WORD to, WORD of Searching is by tree structure. Adding changes the tree. - Notice that in TFORM we should be in sequential mode. + Writing to the global extra-symbol buffer and its search tree is protected + in TFORM by AM.sbuflock. */ int FindSubterm(WORD *subterm) @@ -837,14 +846,15 @@ int FindSubterm(WORD *subterm) #[ FindLocalSubterm : In this routine we look up a variable. - If we don't find it we will enter it in the subterm compiler buffer - Searching is by tree structure. - Adding changes the tree. + If we don't find it we enter it in the thread-private compiler buffer. - Notice that in TFORM we should be in sequential mode. + The definitions and lookup are private to this thread. The numbering + starts after the stored global base, but may overlap global symbols + created by other threads after that store. The definitions are temporary, + so this doesn't matter. */ -int FindLocalSubterm(PHEAD WORD *subterm, WORD startebuf) +int FindLocalSubterm(PHEAD WORD *subterm, WORD startebuf, WORD base) { WORD old[5], *ss, *term, i, j, *t1, *t2; int number; @@ -857,13 +867,7 @@ int FindLocalSubterm(PHEAD WORD *subterm, WORD startebuf) old[0] = *term; old[1] = ss[0]; old[2] = ss[1]; old[3] = ss[2]; old[4] = ss[3]; ss[0] = 1; ss[1] = 1; ss[2] = 3; ss[3] = 0; *term = subterm[1]+4; /* - First see whether we have this one already in the global buffer. -*/ - number = FindTree(AM.sbufnum,term); - if ( number > 0 ) goto wearehappy; -/* - Now look whether it is in the ebufnum between startebuf and numrhs - Note however that we need an offset of (numxsymbol-startebuf) + Look whether it is in the private ebufnum between startebuf and numrhs. */ for ( i = startebuf+1; i <= C->numrhs; i++ ) { t1 = C->rhs[i]; t2 = term; @@ -871,7 +875,7 @@ int FindLocalSubterm(PHEAD WORD *subterm, WORD startebuf) j = *t1; while ( *t1 == *t2 && j > 0 ) { t1++; t2++; j--; } if ( j <= 0 ) { - number = i-startebuf+numxsymbol; + number = i-startebuf+base; goto wearehappy; } } @@ -882,7 +886,7 @@ int FindLocalSubterm(PHEAD WORD *subterm, WORD startebuf) AddRHS(AT.ebufnum,1); AddNtoC(AT.ebufnum,*term,term,9); AddToCB(C,0) - number = C->numrhs-startebuf+numxsymbol; + number = C->numrhs-startebuf+base; wearehappy: *term = old[0]; ss[0] = old[1]; ss[1] = old[2]; ss[2] = old[3]; ss[3] = old[4]; return(number); @@ -1094,7 +1098,8 @@ void PrintExtraSymbol(int num, WORD *terms,int par) Searching is by tree structure. Adding changes the tree. - Notice that in TFORM we should be in sequential mode. + Writing to the global extra-symbol buffer and its search tree is protected + in TFORM by AM.sbuflock. */ int FindSubexpression(WORD *subexpr) diff --git a/sources/polywrap.cc b/sources/polywrap.cc index db085107..072daa2c 100644 --- a/sources/polywrap.cc +++ b/sources/polywrap.cc @@ -1194,6 +1194,7 @@ int poly_factorize_expression(EXPRESSIONS expr) { WORD *term = AT.WorkPointer; WORD startebuf = cbuf[AT.ebufnum].numrhs; + WORD extrasymbolbase = -1; FILEHANDLE *file; POSITION pos; @@ -1275,7 +1276,7 @@ int poly_factorize_expression(EXPRESSIONS expr) { Terminate(-1); } buffer.check_memory(bufpos); - if (LocalConvertToPoly(BHEAD term, buffer.terms + bufpos, startebuf,0) < 0) { + if (LocalConvertToPoly(BHEAD term, buffer.terms + bufpos,startebuf,0,&extrasymbolbase) < 0) { /* INTERNAL_ERROR_EXCL_START */ MesPrint("!>ERROR: in LocalConvertToPoly [factorize_expression]"); Terminate(-1); @@ -1413,8 +1414,8 @@ int poly_factorize_expression(EXPRESSIONS expr) { for (WORD *t=buffer.terms; *t!=0; t+=*t) { // substitute extra symbols - if (ConvertFromPoly(BHEAD t, term, numxsymbol, CC->numrhs-startebuf+numxsymbol, - startebuf-numxsymbol, 1) <= 0 ) { + if (ConvertFromPoly(BHEAD t, term, extrasymbolbase, CC->numrhs-startebuf+extrasymbolbase, + startebuf-extrasymbolbase, 1) <= 0 ) { /* INTERNAL_ERROR_EXCL_START */ MesPrint("!>ERROR: in ConvertFromPoly [factorize_expression]"); Terminate(-1); @@ -1430,7 +1431,9 @@ int poly_factorize_expression(EXPRESSIONS expr) { // sort and store in buffer WORD *buffer; - if (EndSort(BHEAD (WORD *)((void *)(&buffer)),2) < 0) return -1; + if (EndSort(BHEAD (WORD *)((void *)(&buffer)),2) < 0) { + return -1; + } LONG bufsize=0; for (WORD *t=buffer; *t!=0; t+=*t) diff --git a/sources/ratio.c b/sources/ratio.c index e1f29daa..6849d3f8 100644 --- a/sources/ratio.c +++ b/sources/ratio.c @@ -1150,7 +1150,7 @@ WORD *GCDfunction3(PHEAD WORD *in1, WORD *in2) WORD oldsorttype = AR.SortType, *ow = AT.WorkPointer;; WORD *t, *tt, *gcdout, *term1, *term2, *confree1, *confree2, *gcdout1, *proper1, *proper2; int i, actionflag1, actionflag2; - WORD startebuf = cbuf[AT.ebufnum].numrhs; + WORD startebuf = cbuf[AT.ebufnum].numrhs, extrasymbolbase = -1; WORD tryterm1, tryterm2; if ( in2[*in2] == 0 ) { t = in1; in1 = in2; in2 = t; } if ( in1[*in1] == 0 ) { /* First input with only one term */ @@ -1187,7 +1187,7 @@ WORD *GCDfunction3(PHEAD WORD *in1, WORD *in2) Now we have to replace all non-symbols and symbols to a negative power by extra symbols. */ - if ( ( proper1 = PutExtraSymbols(BHEAD confree1,startebuf,&actionflag1) ) == 0 ) goto CalledFrom; + if ( ( proper1 = PutExtraSymbols(BHEAD confree1,startebuf,&actionflag1,&extrasymbolbase) ) == 0 ) goto CalledFrom; if ( confree1 != in1 ) { if ( tryterm1 ) { TermFree(confree1,"TakeContent"); } else { M_free(confree1,"TakeContent"); } @@ -1195,7 +1195,7 @@ WORD *GCDfunction3(PHEAD WORD *in1, WORD *in2) /* TermFree(confree1,"TakeSymbolContent"); */ - if ( ( proper2 = PutExtraSymbols(BHEAD confree2,startebuf,&actionflag2) ) == 0 ) goto CalledFrom; + if ( ( proper2 = PutExtraSymbols(BHEAD confree2,startebuf,&actionflag2,&extrasymbolbase) ) == 0 ) goto CalledFrom; if ( confree2 != in2 ) { if ( tryterm2 ) { TermFree(confree2,"TakeContent"); } else { M_free(confree2,"TakeContent"); } @@ -1212,7 +1212,7 @@ WORD *GCDfunction3(PHEAD WORD *in1, WORD *in2) AR.SortType = oldsorttype; if ( actionflag1 || actionflag2 ) { - if ( ( gcdout = TakeExtraSymbols(BHEAD gcdout1,startebuf) ) == 0 ) goto CalledFrom; + if ( ( gcdout = TakeExtraSymbols(BHEAD gcdout1,startebuf,extrasymbolbase) ) == 0 ) goto CalledFrom; M_free(gcdout1,"gcdout"); } else { @@ -1246,14 +1246,14 @@ WORD *GCDfunction3(PHEAD WORD *in1, WORD *in2) #[ PutExtraSymbols : */ -WORD *PutExtraSymbols(PHEAD WORD *in,WORD startebuf,int *actionflag) +WORD *PutExtraSymbols(PHEAD WORD *in,WORD startebuf,int *actionflag,WORD *extrasymbolbase) { WORD *termout = AT.WorkPointer; int action; *actionflag = 0; NewSort(BHEAD0); while ( *in ) { - if ( ( action = LocalConvertToPoly(BHEAD in,termout,startebuf,0) ) < 0 ) { + if ( ( action = LocalConvertToPoly(BHEAD in,termout,startebuf,0,extrasymbolbase) ) < 0 ) { LowerSortLevel(); goto CalledFrom; } @@ -1275,7 +1275,7 @@ WORD *PutExtraSymbols(PHEAD WORD *in,WORD startebuf,int *actionflag) #[ TakeExtraSymbols : */ -WORD *TakeExtraSymbols(PHEAD WORD *in,WORD startebuf) +WORD *TakeExtraSymbols(PHEAD WORD *in,WORD startebuf,WORD extrasymbolbase) { CBUF *C = cbuf+AC.cbufnum; CBUF *CC = cbuf+AT.ebufnum; @@ -1284,7 +1284,7 @@ WORD *TakeExtraSymbols(PHEAD WORD *in,WORD startebuf) termout = AT.WorkPointer; NewSort(BHEAD0); while ( *in ) { - if ( ConvertFromPoly(BHEAD in,termout,numxsymbol,CC->numrhs-startebuf+numxsymbol,startebuf-numxsymbol,1) <= 0 ) { + if ( ConvertFromPoly(BHEAD in,termout,extrasymbolbase,CC->numrhs-startebuf+extrasymbolbase,startebuf-extrasymbolbase,1) <= 0 ) { LowerSortLevel(); goto CalledFrom; } @@ -2851,7 +2851,7 @@ int DIVfunction(PHEAD WORD *term,WORD level,int par) WORD *tstop, *tend, *r3, *rr, *rstop, tlength, rlength, newlength; WORD *proper1, *proper2, *proper3 = 0, numdol = -1; int numargs = 0, type1, type2, actionflag1, actionflag2; - WORD startebuf = cbuf[AT.ebufnum].numrhs; + WORD startebuf = cbuf[AT.ebufnum].numrhs, extrasymbolbase = -1; int division = ( par <= 2 ); /* false for mul_ */ if ( par < 0 || par > 3 ) { /* INTERNAL_ERROR_EXCL_START */ @@ -2939,8 +2939,8 @@ divzero:; M_free(arg1,"DIVfunction"); return(0); } - if ( ( proper1 = PutExtraSymbols(BHEAD arg1,startebuf,&actionflag1) ) == 0 ) goto CalledFrom; - if ( ( proper2 = PutExtraSymbols(BHEAD arg2,startebuf,&actionflag2) ) == 0 ) goto CalledFrom; + if ( ( proper1 = PutExtraSymbols(BHEAD arg1,startebuf,&actionflag1,&extrasymbolbase) ) == 0 ) goto CalledFrom; + if ( ( proper2 = PutExtraSymbols(BHEAD arg2,startebuf,&actionflag2,&extrasymbolbase) ) == 0 ) goto CalledFrom; /* if ( type2 == 0 ) M_free(arg2,"DIVfunction"); else { @@ -2965,7 +2965,7 @@ divzero:; else if ( par == 3 ) proper3 = poly_mul(BHEAD proper1, proper2); if ( proper3 == 0 ) goto CalledFrom; if ( actionflag1 || actionflag2 ) { - if ( ( arg3 = TakeExtraSymbols(BHEAD proper3,startebuf) ) == 0 ) goto CalledFrom; + if ( ( arg3 = TakeExtraSymbols(BHEAD proper3,startebuf,extrasymbolbase) ) == 0 ) goto CalledFrom; M_free(proper3,"DIVfunction"); } else { diff --git a/sources/structs.h b/sources/structs.h index 707e3e0f..6789af4d 100644 --- a/sources/structs.h +++ b/sources/structs.h @@ -1438,7 +1438,7 @@ struct M_const { #ifdef WITHPTHREADS pthread_rwlock_t handlelock; /* (M) */ pthread_mutex_t storefilelock; /* (M) */ - pthread_mutex_t sbuflock; /* (M) Lock for writing in the AM.sbuffer */ + pthread_mutex_t sbuflock; /* (M) Lock for the global AM.sbuffer */ LONG ThreadScratSize; /* (M) Size of Fscr[0/2] buffers of the workers */ LONG ThreadScratOutSize; /* (M) Size of Fscr[1] buffers of the workers */ #endif @@ -1843,7 +1843,7 @@ struct C_const { int NoCompress; /* (R) Controls native compression */ int IsFortran90; /* Tells whether the Fortran is Fortran90 */ int MultiBracketLevels; /* Number of elements in MultiBracketBuf */ - int topolynomialflag; /* To avoid ToPolynomial and FactArg together */ + int topolynomialflag; /* Module can add entries to the global extra-symbol buffer */ int ffbufnum; /* Buffer number for user defined factorizations */ int OldFactArgFlag; int MemDebugFlag; /* Only used when MALLOCDEBUG in tools.c */