75int PackFloat(WORD *,mpf_t);
76int UnpackFloat(mpf_t, WORD *);
77void RatToFloat(mpf_t result, UWORD *formrat,
int ratsize);
80static int numberofthreads;
81static int numberofworkers;
82static int identityofthreads = 0;
83static int *listofavailables;
84static int topofavailables = 0;
85static pthread_key_t identitykey;
86static INILOCK(numberofthreadslock)
87static INILOCK(availabilitylock)
88static pthread_t *threadpointers = 0;
89static pthread_mutex_t *wakeuplocks;
90static pthread_mutex_t *wakeupmasterthreadlocks;
91static pthread_cond_t *wakeupconditions;
92static pthread_condattr_t *wakeupconditionattributes;
94static int *wakeupmasterthread;
95static INILOCK(wakeupmasterlock)
96static pthread_cond_t wakeupmasterconditions = PTHREAD_COND_INITIALIZER;
97static pthread_cond_t *wakeupmasterthreadconditions;
98static int wakeupmaster = 0;
99static int identityretval;
101static LONG *timerinfo;
102static LONG *sumtimerinfo;
103static int numberclaimed;
105static THREADBUCKET **threadbuckets, **freebuckets;
106static int numthreadbuckets;
107static int numberoffullbuckets;
112INIRWLOCK(dummyrwlock)
113static pthread_cond_t dummywakeupcondition = PTHREAD_COND_INITIALIZER;
117static int numberofsortbots;
118static INILOCK(wakeupsortbotlock)
119static pthread_cond_t wakeupsortbotconditions = PTHREAD_COND_INITIALIZER;
120static int topsortbotavailables = 0;
121static LONG numberofterms;
134void StartIdentity(
void)
136 pthread_key_create(&identitykey,FinishIdentity);
147void FinishIdentity(
void *keyp)
161int SetIdentity(
int *identityretval)
169 LOCK(numberofthreadslock);
170 *identityretval = identityofthreads++;
171 UNLOCK(numberofthreadslock);
172 pthread_setspecific(identitykey,(
void *)identityretval);
173 return(*identityretval);
197 if ( identityofthreads <= 1 )
return(0);
206 identity = (
int *)pthread_getspecific(identitykey);
219void BeginIdentities(
void)
222 SetIdentity(&identityretval);
236void StartHandleLock(
void)
238 AM.handlelock = dummyrwlock;
262int StartAllThreads(
int number)
264 int identity, j, dummy, mul;
270 timerinfo = (LONG *)Malloc1(
sizeof(LONG)*number*2,
"timerinfo");
271 sumtimerinfo = (LONG *)Malloc1(
sizeof(LONG)*number*2,
"sumtimerinfo");
272 for ( j = 0; j < number*2; j++ ) { timerinfo[j] = 0; sumtimerinfo[j] = 0; }
275 timerinfo = (LONG *)Malloc1(
sizeof(LONG)*number,
"timerinfo");
276 sumtimerinfo = (LONG *)Malloc1(
sizeof(LONG)*number,
"sumtimerinfo");
277 for ( j = 0; j < number; j++ ) { timerinfo[j] = 0; sumtimerinfo[j] = 0; }
281 listofavailables = (
int *)Malloc1(
sizeof(
int)*(number+1),
"listofavailables");
282 threadpointers = (pthread_t *)Malloc1(
sizeof(pthread_t)*number*mul,
"threadpointers");
283 AB = (ALLPRIVATES **)Malloc1(
sizeof(ALLPRIVATES *)*number*mul,
"Private structs");
285 wakeup = (
int *)Malloc1(
sizeof(
int)*number*mul,
"wakeup");
286 wakeuplocks = (pthread_mutex_t *)Malloc1(
sizeof(pthread_mutex_t)*number*mul,
"wakeuplocks");
287 wakeupconditions = (pthread_cond_t *)Malloc1(
sizeof(pthread_cond_t)*number*mul,
"wakeupconditions");
288 wakeupconditionattributes = (pthread_condattr_t *)
289 Malloc1(
sizeof(pthread_condattr_t)*number*mul,
"wakeupconditionattributes");
291 wakeupmasterthread = (
int *)Malloc1(
sizeof(
int)*number*mul,
"wakeupmasterthread");
292 wakeupmasterthreadlocks = (pthread_mutex_t *)Malloc1(
sizeof(pthread_mutex_t)*number*mul,
"wakeupmasterthreadlocks");
293 wakeupmasterthreadconditions = (pthread_cond_t *)Malloc1(
sizeof(pthread_cond_t)*number*mul,
"wakeupmasterthread");
295 numberofthreads = number;
296 numberofworkers = number - 1;
297 threadpointers[identity] = pthread_self();
305 sigemptyset(&sig_set);
306 sigaddset(&sig_set, SIGALRM);
307 pthread_sigmask(SIG_BLOCK, &sig_set, NULL);
310 for ( j = 1; j < number; j++ ) {
311 if ( pthread_create(&thethread,NULL,RunThread,(
void *)(&dummy)) )
317 B = InitializeOneThread(identity);
318 AR.infile = &(AR.Fscr[0]);
319 AR.outfile = &(AR.Fscr[1]);
320 AR.hidefile = &(AR.Fscr[2]);
321 AM.sbuflock = dummylock;
322 AS.inputslock = dummylock;
323 AS.outputslock = dummylock;
324 AS.MaxExprSizeLock = dummylock;
325 AP.PreVarLock = dummylock;
326 AC.halfmodlock = dummylock;
327 MakeThreadBuckets(number,0);
335 if ( numberofworkers > 2 ) {
336 numberofsortbots = numberofworkers-2;
337 for ( j = numberofworkers+1; j < 2*numberofworkers-1; j++ ) {
338 if ( pthread_create(&thethread,NULL,RunSortBot,(
void *)(&dummy)) )
343 numberofsortbots = 0;
345 MasterWaitAllSortBots();
348 IniSortBlocks(number-1);
350 AM.storefilelock = dummylock;
354 pthread_sigmask(SIG_UNBLOCK, &sig_set, NULL);
363 MesPrint(
"!>Cannot start %d threads",number);
376UBYTE *scratchname[] = { (UBYTE *)
"scratchsize",
377 (UBYTE *)
"scratchsize",
378 (UBYTE *)
"hidesize" };
405ALLPRIVATES *InitializeOneThread(
int identity)
407 WORD *t, *ScratchBuf;
408 int i, j, bsize, *bp;
409 LONG ScratchSize[3], IOsize;
413 wakeup[identity] = 0;
414 wakeuplocks[identity] = dummylock;
415 pthread_condattr_init(&(wakeupconditionattributes[identity]));
416 pthread_condattr_setpshared(&(wakeupconditionattributes[identity]),PTHREAD_PROCESS_PRIVATE);
417 wakeupconditions[identity] = dummywakeupcondition;
418 pthread_cond_init(&(wakeupconditions[identity]),&(wakeupconditionattributes[identity]));
419 wakeupmasterthread[identity] = 0;
420 wakeupmasterthreadlocks[identity] = dummylock;
421 wakeupmasterthreadconditions[identity] = dummywakeupcondition;
423 bsize =
sizeof(ALLPRIVATES);
424 bsize = (bsize+
sizeof(int)-1)/
sizeof(int);
425 B = (ALLPRIVATES *)Malloc1(
sizeof(
int)*bsize,
"B struct");
426 for ( bp = (
int *)B, j = 0; j < bsize; j++ ) *bp++ = 0;
445 if ( identity > 0 )
TimeCPU(0);
449 if ( identity > numberofworkers ) {
454 LONG length = AM.WorkSize*
sizeof(WORD)/8+AM.MaxTer*2;
455 AT.WorkSpace = (WORD *)Malloc1(length,
"WorkSpace");
456 AT.WorkTop = AT.WorkSpace + length/
sizeof(WORD);
457 AT.WorkPointer = AT.WorkSpace;
458 AT.identity = identity;
463 if ( AN.SoScratC == 0 ) {
464 AN.SoScratC = (UWORD *)Malloc1(2*(AM.MaxTal+2)*
sizeof(UWORD),
"Scratch in SortBot");
470 AT.comsym[1] = SYMBOL;
481 AT.comfun[0] = FUNHEAD+4;
482 AT.comfun[1] = FUNCTION;
483 AT.comfun[2] = FUNHEAD;
486 for ( i = 4; i <= FUNHEAD; i++ )
489 AT.comfun[FUNHEAD+1] = 1;
490 AT.comfun[FUNHEAD+2] = 1;
491 AT.comfun[FUNHEAD+3] = 3;
493 AT.comind[1] = INDEX;
501 AT.sizeprimelist = 0;
505 AR.CompareRoutine = (COMPAREDUMMY)(&
Compare1);
510 AR.wranfnpair1 = NPAIR1;
511 AR.wranfnpair2 = NPAIR2;
515 AN.SplitScratchSize = AN.InScratch = 0;
516 AN.SplitScratch1 = 0;
517 AN.SplitScratchSize1 = AN.InScratch1 = 0;
519 AN.FunSorts = (
SORTING **)Malloc1((AN.NumFunSorts+1)*
sizeof(
SORTING *),
"FunSort pointers");
520 for ( i = 0; i <= AN.NumFunSorts; i++ ) AN.FunSorts[i] = 0;
521 AN.FunSorts[0] = AT.S0 = AT.SS;
522 AN.idfunctionflag = 0;
527 if ( identity == 0 && AN.SoScratC == 0 ) {
528 AN.SoScratC = (UWORD *)Malloc1(2*(AM.MaxTal+2)*
sizeof(UWORD),
"Scratch in SortBot");
531 AR.CurDum = AM.IndDum;
532 for ( j = 0; j < 3; j++ ) {
533 if ( identity == 0 ) {
535 ScratchSize[j] = AM.HideSize;
538 ScratchSize[j] = AM.ScratSize;
540 if ( ScratchSize[j] < 10*AM.MaxTer ) ScratchSize[j] = 10 * AM.MaxTer;
548 if ( j == 1 ) ScratchSize[j] = AM.ThreadScratOutSize;
549 else ScratchSize[j] = AM.ThreadScratSize;
550 if ( ScratchSize[j] < 4*AM.MaxTer ) ScratchSize[j] = 4 * AM.MaxTer;
553 ScratchSize[j] = ( ScratchSize[j] + 255 ) / 256;
554 ScratchSize[j] = ScratchSize[j] * 256;
555 ScratchBuf = (WORD *)Malloc1(ScratchSize[j]*
sizeof(WORD),(
char *)(scratchname[j]));
556 AR.Fscr[j].POsize = ScratchSize[j] *
sizeof(WORD);
557 AR.Fscr[j].POfull = AR.Fscr[j].POfill = AR.Fscr[j].PObuffer = ScratchBuf;
558 AR.Fscr[j].POstop = AR.Fscr[j].PObuffer + ScratchSize[j];
559 PUTZERO(AR.Fscr[j].POposition);
560 AR.Fscr[j].pthreadslock = dummylock;
561 AR.Fscr[j].wPOsize = AR.Fscr[j].POsize;
562 AR.Fscr[j].wPObuffer = AR.Fscr[j].PObuffer;
563 AR.Fscr[j].wPOfill = AR.Fscr[j].POfill;
564 AR.Fscr[j].wPOfull = AR.Fscr[j].POfull;
565 AR.Fscr[j].wPOstop = AR.Fscr[j].POstop;
569 AR.Fscr[0].handle = -1;
570 AR.Fscr[1].handle = -1;
571 AR.Fscr[2].handle = -1;
572 AR.FoStage4[0].handle = -1;
573 AR.FoStage4[1].handle = -1;
574 IOsize = AM.S0->file.POsize;
576 AR.FoStage4[0].ziosize = IOsize;
577 AR.FoStage4[1].ziosize = IOsize;
578 AR.FoStage4[0].ziobuffer = 0;
579 AR.FoStage4[1].ziobuffer = 0;
581 AR.FoStage4[0].POsize = ((IOsize+
sizeof(WORD)-1)/
sizeof(WORD))*
sizeof(WORD);
582 AR.FoStage4[1].POsize = ((IOsize+
sizeof(WORD)-1)/
sizeof(WORD))*
sizeof(WORD);
584 AR.hidefile = &(AR.Fscr[2]);
585 AR.StoreData.Handle = -1;
586 AR.SortType = AC.SortType;
588 AN.IndDum = AM.IndDum;
590 if ( identity > 0 ) {
591 s = (UBYTE *)(FG.fname); i = 0;
592 while ( *s ) { s++; i++; }
593 s = (UBYTE *)Malloc1(
sizeof(
char)*(i+12),
"name for Fscr[0] file");
594 snprintf((
char *)s,i+12,
"%s.%d",FG.fname,identity);
595 s[i-3] =
's'; s[i-2] =
'c'; s[i-1] =
'0';
596 AR.Fscr[0].name = (
char *)s;
597 s = (UBYTE *)(FG.fname); i = 0;
598 while ( *s ) { s++; i++; }
599 s = (UBYTE *)Malloc1(
sizeof(
char)*(i+12),
"name for Fscr[1] file");
600 snprintf((
char *)s,i+12,
"%s.%d",FG.fname,identity);
601 s[i-3] =
's'; s[i-2] =
'c'; s[i-1] =
'1';
602 AR.Fscr[1].name = (
char *)s;
605 AR.CompressBuffer = (WORD *)Malloc1((AM.CompressSize+10)*
sizeof(WORD),
"compresssize");
606 AR.ComprTop = AR.CompressBuffer + AM.CompressSize;
607 AR.CompareRoutine = (COMPAREDUMMY)(&
Compare1);
612 AT.WorkSpace = (WORD *)Malloc1(AM.WorkSize*
sizeof(WORD),
"WorkSpace");
613 AT.WorkTop = AT.WorkSpace + AM.WorkSize;
614 AT.WorkPointer = AT.WorkSpace;
616 AT.Nest = (
NESTING)Malloc1((LONG)
sizeof(
struct NeStInG)*AM.maxFlevels,
"functionlevels");
617 AT.NestStop = AT.Nest + AM.maxFlevels;
618 AT.NestPoin = AT.Nest;
620 AT.WildMask = (WORD *)Malloc1((LONG)AM.MaxWildcards*
sizeof(WORD),
"maxwildcards");
622 LOCK(availabilitylock);
627 UNLOCK(availabilitylock);
629 AT.RepCount = (
int *)Malloc1((LONG)((AM.RepMax+3)*
sizeof(
int)),
"repeat buffers");
630 AN.RepPoint = AT.RepCount;
634 AT.RepTop = AT.RepCount + AM.RepMax;
636 AT.WildArgTaken = (WORD *)Malloc1((LONG)AC.WildcardBufferSize*
sizeof(WORD)/2
637 ,
"argument list names");
638 AT.WildcardBufferSize = AC.WildcardBufferSize;
639 AT.previousEfactor = 0;
641 AT.identity = identity;
642 AT.LoadBalancing = 0;
648 if ( AT.WorkSpace == 0 ||
652 AT.WildArgTaken == 0 )
goto OnError;
657 AT.comsym[1] = SYMBOL;
668 AT.comfun[0] = FUNHEAD+4;
669 AT.comfun[1] = FUNCTION;
670 AT.comfun[2] = FUNHEAD;
673 for ( i = 4; i <= FUNHEAD; i++ )
676 AT.comfun[FUNHEAD+1] = 1;
677 AT.comfun[FUNHEAD+2] = 1;
678 AT.comfun[FUNHEAD+3] = 3;
680 AT.comind[1] = INDEX;
686 AT.locwildvalue[0] = SUBEXPRESSION;
687 AT.locwildvalue[1] = SUBEXPSIZE;
688 for ( i = 2; i < SUBEXPSIZE; i++ ) AT.locwildvalue[i] = 0;
689 AT.mulpat[0] = TYPEMULT;
690 AT.mulpat[1] = SUBEXPSIZE+3;
692 AT.mulpat[3] = SUBEXPRESSION;
693 AT.mulpat[4] = SUBEXPSIZE;
696 for ( i = 7; i < SUBEXPSIZE+5; i++ ) AT.mulpat[i] = 0;
697 AT.proexp[0] = SUBEXPSIZE+4;
698 AT.proexp[1] = EXPRESSION;
699 AT.proexp[2] = SUBEXPSIZE;
702 for ( i = 5; i < SUBEXPSIZE+1; i++ ) AT.proexp[i] = 0;
703 AT.proexp[SUBEXPSIZE+1] = 1;
704 AT.proexp[SUBEXPSIZE+2] = 1;
705 AT.proexp[SUBEXPSIZE+3] = 3;
706 AT.proexp[SUBEXPSIZE+4] = 0;
707 AT.dummysubexp[0] = SUBEXPRESSION;
708 AT.dummysubexp[1] = SUBEXPSIZE+4;
709 for ( i = 2; i < SUBEXPSIZE; i++ ) AT.dummysubexp[i] = 0;
710 AT.dummysubexp[SUBEXPSIZE] = WILDDUMMY;
711 AT.dummysubexp[SUBEXPSIZE+1] = 4;
712 AT.dummysubexp[SUBEXPSIZE+2] = 0;
713 AT.dummysubexp[SUBEXPSIZE+3] = 0;
715 AT.MinVecArg[0] = 7+ARGHEAD;
716 AT.MinVecArg[ARGHEAD] = 7;
717 AT.MinVecArg[1+ARGHEAD] = INDEX;
718 AT.MinVecArg[2+ARGHEAD] = 3;
719 AT.MinVecArg[3+ARGHEAD] = 0;
720 AT.MinVecArg[4+ARGHEAD] = 1;
721 AT.MinVecArg[5+ARGHEAD] = 1;
722 AT.MinVecArg[6+ARGHEAD] = -3;
724 *t++ = 4+ARGHEAD+FUNHEAD;
725 for ( i = 1; i < ARGHEAD; i++ ) *t++ = 0;
729 for ( i = 2; i < FUNHEAD; i++ ) *t++ = 0;
730 *t++ = 1; *t++ = 1; *t++ = 3;
733 AT.sizeprimelist = 0;
735 AT.nfac = AT.nBer = 0;
740 AR.wranfnpair1 = NPAIR1;
741 AR.wranfnpair2 = NPAIR2;
744 AT.NormData = Malloc1(
sizeof(*(AT.NormData)),
"NormData thread pointers");
746 AT.NormData[0] = AllocNormData();
750 AN.SplitScratchSize = AN.InScratch = 0;
751 AN.SplitScratch1 = 0;
752 AN.SplitScratchSize1 = AN.InScratch1 = 0;
757 if ( identity == 0 ) {
765 AT.S0 = AllocSort(AM.S0->LargeSize*
sizeof(WORD)/numberofworkers
766 ,AM.S0->SmallSize*
sizeof(WORD)/numberofworkers
767 ,AM.S0->SmallEsize*
sizeof(WORD)/numberofworkers
771 ,AM.S0->MaxFpatches/numberofworkers
775 AR.CompressPointer = AR.CompressBuffer;
779 AT.StoreCache = AT.StoreCacheAlloc = 0;
780 if ( AM.NumStoreCaches > 0 ) {
783 size =
sizeof(
struct StOrEcAcHe)+AM.SizeStoreCache;
784 size = ((size-1)/
sizeof(
size_t)+1)*
sizeof(
size_t);
785 AT.StoreCacheAlloc = (
STORECACHE)Malloc1(size*AM.NumStoreCaches,
"StoreCaches");
786 sa = AT.StoreCache = AT.StoreCacheAlloc;
787 for ( i = 0; i < AM.NumStoreCaches; i++ ) {
789 if ( i == AM.NumStoreCaches-1 ) {
795 SETBASEPOSITION(sa->position,-1);
796 SETBASEPOSITION(sa->toppos,-1);
805 MLOCK(ErrorMessageLock);
806 MesPrint(
"!>Error initializing thread %d",identity);
807 MUNLOCK(ErrorMessageLock);
827void FinalizeOneThread(
int identity)
829 timerinfo[identity] =
TimeCPU(1);
842void ClearAllThreads(
void)
846 for ( i = 1; i <= numberofworkers; i++ ) {
847 WakeupThread(i,CLEARCLOCK);
850 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
851 WakeupThread(i,CLEARCLOCK);
866void TerminateAllThreads(
void)
869 for ( i = 1; i <= numberofworkers; i++ ) {
871 WakeupThread(i,TERMINATETHREAD);
874 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
875 WakeupThread(i,TERMINATETHREAD);
878 for ( i = 1; i <= numberofworkers; i++ ) {
879 pthread_join(threadpointers[i],NULL);
882 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
883 pthread_join(threadpointers[i],NULL);
917int MakeThreadBuckets(
int number,
int par)
920 LONG sizethreadbuckets;
926 sizethreadbuckets = (AC.ThreadBucketSize*MAXTER)/4;
931 if ( AM.MaxTer/
sizeof(WORD) > MAXTER ) {
932 scale += log(((
float)AM.MaxTer/
sizeof(WORD))/MAXTER);
934 sizethreadbuckets = (LONG)((
float)sizethreadbuckets*scale);
938 sizethreadbuckets = MaX((ULONG)sizethreadbuckets, BUCKETMINTERMS*AM.MaxTer/
sizeof(WORD));
941 numthreadbuckets = 2*(number-1);
942 threadbuckets = (THREADBUCKET **)Malloc1(numthreadbuckets*
sizeof(THREADBUCKET *),
"threadbuckets");
943 freebuckets = (THREADBUCKET **)Malloc1(numthreadbuckets*
sizeof(THREADBUCKET *),
"freebuckets");
946 if ( sizethreadbuckets <= threadbuckets[0]->threadbuffersize )
return(0);
947 for ( i = 0; i < numthreadbuckets; i++ ) {
948 thr = threadbuckets[i];
949 M_free(thr->deferbuffer,
"deferbuffer");
950 M_free(thr->threadbuffer,
"threadbuffer");
951 M_free(thr->compressbuffer,
"compressbuffer");
955 for ( i = 0; i < numthreadbuckets; i++ ) {
956 threadbuckets[i] = (THREADBUCKET *)Malloc1(
sizeof(THREADBUCKET),
"threadbuckets");
957 threadbuckets[i]->lock = dummylock;
960 for ( i = 0; i < numthreadbuckets; i++ ) {
961 thr = threadbuckets[i];
962 thr->threadbuffersize = sizethreadbuckets;
965 thr->compressbuffersize = AM.MaxTer/
sizeof(WORD);
966 thr->free = BUCKETFREE;
967 thr->deferbuffer = (
POSITION *)Malloc1((AC.ThreadBucketSize+1)*
sizeof(
POSITION),
"deferbuffer");
968 thr->threadbuffer = (WORD *)Malloc1(sizethreadbuckets*
sizeof(WORD),
"threadbuffer");
969 thr->compressbuffer = (WORD *)Malloc1(thr->compressbuffersize*
sizeof(WORD),
"compressbuffer");
970 thr->busy = BUCKETPREPARINGTERM;
971 thr->usenum = thr->totnum = 0;
972 thr->type = BUCKETDOINGTERMS;
988int GetTimerInfo(LONG** ti,LONG** sti)
993 return AM.totalnumberofthreads*2;
995 return AM.totalnumberofthreads;
1009void WriteTimerInfo(LONG* ti,LONG* sti)
1013 int max = AM.totalnumberofthreads*2;
1015 int max = AM.totalnumberofthreads;
1017 for ( i=0; i<max; ++i ) {
1018 timerinfo[i] = ti[i];
1019 sumtimerinfo[i] = sti[i];
1032LONG GetWorkerTimes(
void)
1036 for ( i = 1; i <= numberofworkers; i++ ) retval += timerinfo[i] + sumtimerinfo[i];
1038 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ )
1039 retval += timerinfo[i] + sumtimerinfo[i];
1054int UpdateOneThread(
int identity)
1056 ALLPRIVATES *B = AB[identity], *B0 = AB[0];
1057 AR.GetFile = AR0.GetFile;
1058 AR.KeptInHold = AR0.KeptInHold;
1059 AR.CurExpr = AR0.CurExpr;
1060 AR.SortType = AC.SortType;
1061 if ( AT.WildcardBufferSize < AC.WildcardBufferSize ) {
1062 M_free(AT.WildArgTaken,
"argument list names");
1063 AT.WildcardBufferSize = AC.WildcardBufferSize;
1064 AT.WildArgTaken = (WORD *)Malloc1((LONG)AC.WildcardBufferSize*
sizeof(WORD)/2
1065 ,
"argument list names");
1066 if ( AT.WildArgTaken == 0 )
return(-1);
1088int LoadOneThread(
int from,
int identity, THREADBUCKET *thr,
int par)
1091 ALLPRIVATES *B = AB[identity], *B0 = AB[from];
1093 AR.DefPosition = AR0.DefPosition;
1094 AR.NoCompress = AR0.NoCompress;
1095 AR.gzipCompress = AR0.gzipCompress;
1096 AR.BracketOn = AR0.BracketOn;
1097 AR.CurDum = AR0.CurDum;
1098 AR.DeferFlag = AR0.DeferFlag;
1100 AR.sLevel = AR0.sLevel;
1101 AR.Stage4Name = AR0.Stage4Name;
1102 AR.GetOneFile = AR0.GetOneFile;
1103 AR.PolyFun = AR0.PolyFun;
1104 AR.PolyFunInv = AR0.PolyFunInv;
1105 AR.PolyFunType = AR0.PolyFunType;
1106 AR.PolyFunExp = AR0.PolyFunExp;
1107 AR.PolyFunVar = AR0.PolyFunVar;
1108 AR.PolyFunPow = AR0.PolyFunPow;
1109 AR.Eside = AR0.Eside;
1110 AR.Cnumlhs = AR0.Cnumlhs;
1122 t1 = AR.CompressBuffer; t2 = AR0.CompressBuffer;
1123 while ( t2 < AR0.CompressPointer ) *t1++ = *t2++;
1124 AR.CompressPointer = t1;
1128 AR.CompressPointer = AR.CompressBuffer;
1130 if ( AR.DeferFlag ) {
1131 if ( AR.infile->handle < 0 ) {
1132 AR.infile->POfill = AR0.infile->POfill;
1139 AR.infile->POfull = AR.infile->POfill = AR.infile->PObuffer;
1143 AN.threadbuck = thr;
1144 AN.ninterms = thr->firstterm;
1146 else if ( par == 1 ) {
1148 t1 = thr->threadbuffer; tstop = t1 + *t1;
1149 t2 = AT.WorkPointer;
1150 while ( t1 < tstop ) *t2++ = *t1++;
1151 AN.ninterms = thr->firstterm;
1154 AN.ncmod = AC.ncmod;
1155 AT.BrackBuf = AT0.BrackBuf;
1156 AT.bracketindexflag = AT0.bracketindexflag;
1184int BalanceRunThread(PHEAD
int identity, WORD *term, WORD level)
1191 LoadOneThread(AT.identity,identity,0,2);
1197 BB->R.level = level;
1198 BB->T.TMbuff = AT.TMbuff;
1199 ti = AT.RepCount; tti = BB->T.RepCount;
1200 i = AN.RepPoint - AT.RepCount;
1201 BB->N.RepPoint = BB->T.RepCount + i;
1202 for ( ; i >= 0; i-- ) tti[i] = ti[i];
1204 t = term; i = *term;
1205 tt = BB->T.WorkSpace;
1207 BB->T.WorkPointer = tt;
1209 WakeupThread(identity,HIGHERLEVELGENERATION);
1222void SetWorkerFiles(
void)
1225 ALLPRIVATES *B, *B0 = AB[0];
1226 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
1228 AR.infile = &(AR.Fscr[0]);
1229 AR.outfile = &(AR.Fscr[1]);
1230 AR.hidefile = &(AR.Fscr[2]);
1231 AR.infile->handle = AR0.infile->handle;
1232 AR.hidefile->handle = AR0.hidefile->handle;
1233 if ( AR.infile->handle < 0 ) {
1234 AR.infile->PObuffer = AR0.infile->PObuffer;
1235 AR.infile->POstop = AR0.infile->POstop;
1236 AR.infile->POfill = AR0.infile->POfill;
1237 AR.infile->POfull = AR0.infile->POfull;
1238 AR.infile->POsize = AR0.infile->POsize;
1239 AR.InInBuf = AR0.InInBuf;
1240 AR.infile->POposition = AR0.infile->POposition;
1241 AR.infile->filesize = AR0.infile->filesize;
1244 AR.infile->PObuffer = AR.infile->wPObuffer;
1245 AR.infile->POstop = AR.infile->wPOstop;
1246 AR.infile->POfill = AR.infile->wPOfill;
1247 AR.infile->POfull = AR.infile->wPOfull;
1248 AR.infile->POsize = AR.infile->wPOsize;
1250 PUTZERO(AR.infile->POposition);
1258 AR.outfile->PObuffer = AR.outfile->wPObuffer;
1259 AR.outfile->POstop = AR.outfile->wPOstop;
1260 AR.outfile->POfill = AR.outfile->wPOfill;
1261 AR.outfile->POfull = AR.outfile->wPOfull;
1262 AR.outfile->POsize = AR.outfile->wPOsize;
1263 PUTZERO(AR.outfile->POposition);
1265 if ( AR.hidefile->handle < 0 ) {
1266 AR.hidefile->PObuffer = AR0.hidefile->PObuffer;
1267 AR.hidefile->POstop = AR0.hidefile->POstop;
1268 AR.hidefile->POfill = AR0.hidefile->POfill;
1269 AR.hidefile->POfull = AR0.hidefile->POfull;
1270 AR.hidefile->POsize = AR0.hidefile->POsize;
1271 AR.InHiBuf = AR0.InHiBuf;
1272 AR.hidefile->POposition = AR0.hidefile->POposition;
1273 AR.hidefile->filesize = AR0.hidefile->filesize;
1276 AR.hidefile->PObuffer = AR.hidefile->wPObuffer;
1277 AR.hidefile->POstop = AR.hidefile->wPOstop;
1278 AR.hidefile->POfill = AR.hidefile->wPOfill;
1279 AR.hidefile->POfull = AR.hidefile->wPOfull;
1280 AR.hidefile->POsize = AR.hidefile->wPOsize;
1282 PUTZERO(AR.hidefile->POposition);
1285 if ( AR0.StoreData.dirtyflag ) {
1286 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
1288 AR.StoreData = AR0.StoreData;
1304void *RunThread(
void *dummy)
1306 WORD *term, *ttin, *tt, *ttco, *oldwork;
1307 int identity, wakeupsignal, identityretv, i, tobereleased, errorcode;
1313 identity = SetIdentity(&identityretv);
1314 threadpointers[identity] = pthread_self();
1315 B = InitializeOneThread(identity);
1316 while ( ( wakeupsignal = ThreadWait(identity) ) > 0 ) {
1317 switch ( wakeupsignal ) {
1321 case STARTNEWEXPRESSION:
1326 if ( UpdateOneThread(identity) ) {
1328 MLOCK(ErrorMessageLock);
1329 MesPrint(
"!>Update error in starting expression in thread %d in module %d",identity,AC.CModule);
1330 MUNLOCK(ErrorMessageLock);
1334 AR.DeferFlag = AC.ComDefer;
1335 AR.sLevel = AS.sLevel;
1336 AR.MaxDum = AM.IndDum;
1337 AR.expchanged = AB[0]->R.expchanged;
1338 AR.expflags = AB[0]->R.expflags;
1339 AR.PolyFun = AB[0]->R.PolyFun;
1340 AR.PolyFunInv = AB[0]->R.PolyFunInv;
1341 AR.PolyFunType = AB[0]->R.PolyFunType;
1342 AR.PolyFunExp = AB[0]->R.PolyFunExp;
1343 AR.PolyFunVar = AB[0]->R.PolyFunVar;
1344 AR.PolyFunPow = AB[0]->R.PolyFunPow;
1354 case LOWESTLEVELGENERATION:
1356 if ( AC.InnerTest ) {
1357 if ( StrCmp(AC.TestValue,(UBYTE *)INNERTEST) == 0 ) {
1358 MesPrint(
"Testing(Worker%d): value = %s",AT.identity,AC.TestValue);
1362 e = Expressions + AR.CurExpr;
1363 thr = AN.threadbuck;
1364 ppdef = thr->deferbuffer;
1365 ttin = thr->threadbuffer;
1366 ttco = thr->compressbuffer;
1367 term = AT.WorkPointer;
1370 AN.inputnumber = thr->firstterm;
1371 AN.ninterms = thr->firstterm;
1374 tt = term; i = *ttin;
1376 AT.WorkPointer = tt;
1377 if ( AR.DeferFlag ) {
1378 tt = AR.CompressBuffer; i = *ttco;
1380 AR.CompressPointer = tt;
1381 AR.DefPosition = ppdef[0]; ppdef++;
1383 if ( thr->free == BUCKETTERMINATED ) {
1391 if ( thr->usenum == thr->totnum ) {
1392 thr->free = BUCKETCOMINGFREE;
1395 thr->free = BUCKETRELEASED;
1405 thr->busy = BUCKETDOINGTERM;
1413 AN.RepPoint = AT.RepCount + 1;
1415 if ( ( e->vflags & ISFACTORIZED ) != 0 && term[1] == HAAKJE ) {
1419 if ( AR.DeferFlag ) {
1420 AR.CurDum = AN.IndDum = Expressions[AR.CurExpr].numdummies + AM.IndDum;
1423 AN.IndDum = AM.IndDum;
1424 AR.CurDum = ReNumber(BHEAD term);
1426 if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
1428 if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1429 else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1431 else if ( AC.PolyRatFunChanged ) PolyFunDirty(BHEAD term);
1432 if ( ( AP.PreDebug & THREADSDEBUG ) != 0 ) {
1433 MLOCK(ErrorMessageLock);
1434 MesPrint(
"Thread %w executing term:");
1435 PrintTerm(term,
"LLG");
1436 MUNLOCK(ErrorMessageLock);
1438 if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
1439 && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1440 PolyFunClean(BHEAD term);
1445 MLOCK(ErrorMessageLock);
1446 MesPrint(
"!>Error in processing one term in thread %d in module %d",identity,AC.CModule);
1447 MUNLOCK(ErrorMessageLock);
1455 thr->busy = BUCKETPREPARINGTERM;
1463 if ( thr->free == BUCKETTERMINATED ) {
1464 if ( thr->usenum == thr->totnum ) {
1465 thr->free = BUCKETCOMINGFREE;
1468 thr->free = BUCKETRELEASED;
1472 if ( tobereleased )
goto bucketstolen;
1474 thr->free = BUCKETCOMINGFREE;
1478 thr->busy = BUCKETTOBERELEASED;
1485 AT.WorkPointer = term;
1493 LOCK(AT.SB.MasterBlockLock[1]);
1496 case FINISHEXPRESSION:
1504 LOCK(AT.SB.MasterBlockLock[1]);
1505 ThreadClaimedBlock(identity);
1511 case FINISHEXPRESSION2:
1516 if ( AC.ThreadSortFileSynch ) {
1517 if ( AT.S0->file.handle >= 0 ) {
1518 SynchFile(AT.S0->file.handle);
1521 AT.SB.FillBlock = 1;
1522 AT.SB.MasterFill[1] = AT.SB.MasterStart[1];
1523 errorcode =
EndSort(BHEAD AT.S0->sBuffer,0);
1524 UNLOCK(AT.SB.MasterBlockLock[AT.SB.FillBlock]);
1527 MLOCK(ErrorMessageLock);
1528 MesPrint(
"Error terminating sort in thread %d in module %d",identity,AC.CModule);
1529 MUNLOCK(ErrorMessageLock);
1537 case CLEANUPEXPRESSION:
1541 if ( AR.outfile->handle >= 0 ) {
1542 CloseFile(AR.outfile->handle);
1543 AR.outfile->handle = -1;
1544 remove(AR.outfile->name);
1545 AR.outfile->POfill = AR.outfile->POfull = AR.outfile->PObuffer;
1546 PUTZERO(AR.outfile->POposition);
1547 PUTZERO(AR.outfile->filesize);
1550 AR.outfile->POfill = AR.outfile->POfull = AR.outfile->PObuffer;
1551 PUTZERO(AR.outfile->POposition);
1552 PUTZERO(AR.outfile->filesize);
1555 CBUF *C = cbuf+AT.ebufnum;
1557 if ( C->numrhs > 0 || C->numlhs > 0 ) {
1559 w = C->
rhs; ii = C->numrhs;
1560 do { *w++ = 0; }
while ( --ii > 0 );
1563 w = C->
lhs; ii = C->numlhs;
1564 do { *w++ = 0; }
while ( --ii > 0 );
1566 C->numlhs = C->numrhs = 0;
1567 ClearTree(AT.ebufnum);
1576 case HIGHERLEVELGENERATION:
1581 term = AT.WorkSpace; AT.WorkPointer = term + *term;
1584 MLOCK(ErrorMessageLock);
1585 MesPrint(
"Error in load balancing one term at level %d in thread %d in module %d",AR.level,AT.identity,AC.CModule);
1586 MUNLOCK(ErrorMessageLock);
1589 AT.WorkPointer = term;
1595 case STARTNEWMODULE:
1605 case TERMINATETHREAD:
1623 case DOONEEXPRESSION: {
1628 WORD oldBracketOn = AR.BracketOn;
1629 WORD *oldBrackBuf = AT.BrackBuf;
1630 WORD oldbracketindexflag = AT.bracketindexflag;
1631 WORD fromspectator = 0;
1632 e = Expressions + AR.exprtodo;
1635 AR.SortType = AC.SortType;
1637 if ( ( e->vflags & ISFACTORIZED ) != 0 ) {
1639 AT.BrackBuf = AM.BracketFactors;
1640 AT.bracketindexflag = 1;
1643 position = AS.OldOnFile[i];
1644 if ( e->status == HIDDENLEXPRESSION || e->status == HIDDENGEXPRESSION
1645 || e->status == UNHIDELEXPRESSION || e->status == UNHIDEGEXPRESSION ) {
1646 AR.GetFile = 2; fi = AR.hidefile;
1649 AR.GetFile = 0; fi = AR.infile;
1657 SetScratch(fi,&position);
1658 term = oldwork = AT.WorkPointer;
1659 AR.CompressPointer = AR.CompressBuffer;
1660 AR.CompressPointer[0] = 0;
1662 if ( GetTerm(BHEAD term) <= 0 ) {
1663 MLOCK(ErrorMessageLock);
1664 MesPrint(
"Expression %d has problems in scratchfile (t)",i);
1665 MUNLOCK(ErrorMessageLock);
1668 if ( AT.bracketindexflag > 0 ) OpenBracketIndex(i);
1670 if ( term[5] < 0 ) {
1671 fromspectator = -term[5];
1672 PUTZERO(AM.SpectatorFiles[fromspectator-1].readpos);
1673 term[5] = AC.cbufnum;
1675 PUTZERO(outposition);
1677 fout->POfill = fout->POfull = fout->PObuffer;
1678 fout->POposition = outposition;
1679 if ( fout->
handle >= 0 ) {
1680 fout->POposition = outposition;
1692 if (
PutOut(BHEAD term,&outposition,fout,0) < 0 )
goto ProcErr;
1694 AR.DeferFlag = AC.ComDefer;
1696 AR.sLevel = AB[0]->R.sLevel;
1697 term = AT.WorkPointer;
1699 AR.MaxDum = AM.IndDum;
1701 if ( fromspectator ) {
1702 while ( GetFromSpectator(term,fromspectator-1) ) {
1703 AT.WorkPointer = term + *term;
1704 AN.RepPoint = AT.RepCount + 1;
1705 AN.IndDum = AM.IndDum;
1706 AR.CurDum = ReNumber(BHEAD term);
1707 if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
1709 if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1710 else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1712 else if ( AC.PolyRatFunChanged ) PolyFunDirty(BHEAD term);
1713 if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
1714 && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1715 PolyFunClean(BHEAD term);
1723 while ( GetTerm(BHEAD term) ) {
1724 SeekScratch(fi,&position);
1725 AN.ninterms++; dd = AN.deferskipped;
1726 if ( ( e->vflags & ISFACTORIZED ) != 0 && term[1] == HAAKJE ) {
1730 if ( AC.CollectFun && *term <= (AM.MaxTer/(2*(LONG)
sizeof(WORD))) ) {
1731 if ( GetMoreTerms(term) < 0 ) {
1734 SeekScratch(fi,&position);
1736 AT.WorkPointer = term + *term;
1737 AN.RepPoint = AT.RepCount + 1;
1738 if ( AR.DeferFlag ) {
1739 AR.CurDum = AN.IndDum = Expressions[AR.exprtodo].numdummies;
1742 AN.IndDum = AM.IndDum;
1743 AR.CurDum = ReNumber(BHEAD term);
1745 if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
1747 if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1748 else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1750 else if ( AC.PolyRatFunChanged ) PolyFunDirty(BHEAD term);
1751 if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
1752 && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1753 PolyFunClean(BHEAD term);
1760 SetScratch(fi,&position);
1761 if ( fi == AR.hidefile ) {
1762 AR.InHiBuf = (fi->POfull-fi->PObuffer)
1763 -DIFBASE(position,fi->POposition)/
sizeof(WORD);
1766 AR.InInBuf = (fi->POfull-fi->PObuffer)
1767 -DIFBASE(position,fi->POposition)/
sizeof(WORD);
1772 if (
EndSort(BHEAD AT.S0->sBuffer,0) < 0 )
goto ProcErr;
1773 e->numdummies = AR.MaxDum - AM.IndDum;
1774 AR.BracketOn = oldBracketOn;
1775 AT.BrackBuf = oldBrackBuf;
1776 if ( ( e->vflags & TOBEFACTORED ) != 0 )
1778 else if ( ( ( e->vflags & TOBEUNFACTORED ) != 0 )
1779 && ( ( e->vflags & ISFACTORIZED ) != 0 ) )
1781 if ( AT.S0->TermsLeft ) e->vflags &= ~ISZERO;
1782 else e->vflags |= ISZERO;
1783 if ( AR.expchanged == 0 ) e->vflags |= ISUNMODIFIED;
1784 if ( AT.S0->TermsLeft ) AR.expflags |= ISZERO;
1785 if ( AR.expchanged ) AR.expflags |= ISUNMODIFIED;
1787 AT.bracketindexflag = oldbracketindexflag;
1792 SeekScratch(fout,&outposition);
1793 LOCK(AS.outputslock);
1794 oldoutfile = AB[0]->R.outfile;
1795 if ( e->status == INTOHIDELEXPRESSION || e->status == INTOHIDEGEXPRESSION ) {
1796 AB[0]->R.outfile = AB[0]->R.hidefile;
1798 SeekScratch(AB[0]->R.outfile,&position);
1799 e->onfile = position;
1800 if ( CopyExpression(fout,AB[0]->R.outfile) < 0 ) {
1801 AB[0]->R.outfile = oldoutfile;
1802 UNLOCK(AS.outputslock);
1803 MLOCK(ErrorMessageLock);
1804 MesPrint(
"Error copying output of 'InParallel' expression to master. Thread: %d",identity);
1805 MUNLOCK(ErrorMessageLock);
1808 AB[0]->R.outfile = oldoutfile;
1809 AB[0]->R.expflags = AR.expflags;
1810 UNLOCK(AS.outputslock);
1812 if ( fout->
handle >= 0 ) {
1816 PUTZERO(fout->POposition);
1817 PUTZERO(fout->filesize);
1818 fout->POfill = fout->POfull = fout->PObuffer;
1822 AT.WorkPointer = oldwork;
1846 e = Expressions + AR.CurExpr;
1847 binfo = e->bracketinfo;
1848 thr = AN.threadbuck;
1850 if ( AR.GetFile == 2 ) fi = AR.hidefile;
1851 else fi = AR.infile;
1853 ADD2POS(where,AS.OldOnFile[AR.CurExpr]);
1854 SetScratch(fi,&(where));
1855 stoppos = binfo->
indexbuffer[thr->lastbracket].next;
1856 ADD2POS(stoppos,AS.OldOnFile[AR.CurExpr]);
1857 AN.ninterms = thr->firstterm;
1862 ttco = AR.CompressBuffer;
1866 AR.CompressPointer = ttco;
1867 term = AT.WorkPointer;
1868 while ( GetTerm(BHEAD term) ) {
1869 SeekScratch(fi,&where);
1870 AT.WorkPointer = term + *term;
1871 AN.IndDum = AM.IndDum;
1872 AR.CurDum = ReNumber(BHEAD term);
1873 if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
1875 if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1876 else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1878 else if ( AC.PolyRatFunChanged ) PolyFunDirty(BHEAD term);
1879 if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
1880 && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1881 PolyFunClean(BHEAD term);
1883 if ( ( AP.PreDebug & THREADSDEBUG ) != 0 ) {
1884 MLOCK(ErrorMessageLock);
1885 MesPrint(
"Thread %w executing term:");
1886 PrintTerm(term,
"DoBrackets");
1887 MUNLOCK(ErrorMessageLock);
1889 AT.WorkPointer = term + *term;
1892 MLOCK(ErrorMessageLock);
1893 MesPrint(
"Error in processing one term in thread %d in module %d",identity,AC.CModule);
1894 MUNLOCK(ErrorMessageLock);
1898 SetScratch(fi,&(where));
1899 if ( ISGEPOS(where,stoppos) )
break;
1901 AT.WorkPointer = term;
1902 thr->free = BUCKETCOMINGFREE;
1913 sumtimerinfo[identity] +=
TimeCPU(1);
1914 timerinfo[identity] =
TimeCPU(0);
1921 case MCTSEXPANDTREE:
1922 AT.optimtimes = AB[0]->T.optimtimes;
1923 find_Horner_MCTS_expand_tree();
1929 case OPTIMIZEEXPRESSION:
1937 MLOCK(ErrorMessageLock);
1938 MesPrint(
"!>Illegal wakeup signal %d for thread %d",wakeupsignal,identity);
1939 MUNLOCK(ErrorMessageLock);
1946 timerinfo[identity] =
TimeCPU(1);
1954 flint_final_cleanup_thread();
1956 FinalizeOneThread(identity);
1976void *RunSortBot(
void *dummy)
1978 int identity, wakeupsignal, identityretv;
1979 ALLPRIVATES *B, *BB;
1981 identity = SetIdentity(&identityretv);
1982 threadpointers[identity] = pthread_self();
1983 B = InitializeOneThread(identity);
1984 while ( ( wakeupsignal = SortBotWait(identity) ) > 0 ) {
1985 switch ( wakeupsignal ) {
1990 AR.CompressBuffer = AB[0]->R.CompressBuffer;
1991 AR.ComprTop = AB[0]->R.ComprTop;
1992 AR.CompressPointer = AB[0]->R.CompressPointer;
1993 AR.CurExpr = AB[0]->R.CurExpr;
1994 AR.PolyFun = AB[0]->R.PolyFun;
1995 AR.PolyFunInv = AB[0]->R.PolyFunInv;
1996 AR.PolyFunType = AB[0]->R.PolyFunType;
1997 AR.PolyFunExp = AB[0]->R.PolyFunExp;
1998 AR.PolyFunVar = AB[0]->R.PolyFunVar;
1999 AR.PolyFunPow = AB[0]->R.PolyFunPow;
2000 AR.SortType = AC.SortType;
2001 if ( AR.PolyFun == 0 ) { AT.SS->PolyFlag = 0; }
2002 else if ( AR.PolyFunType == 1 ) { AT.SS->PolyFlag = 1; }
2003 else if ( AR.PolyFunType == 2 ) {
2004 if ( AR.PolyFunExp == 2
2005 || AR.PolyFunExp == 3 ) AT.SS->PolyFlag = 1;
2006 else AT.SS->PolyFlag = 2;
2008 AT.SS->PolyWise = 0;
2009 AN.ncmod = AC.ncmod;
2010 LOCK(AT.SB.MasterBlockLock[1]);
2011 BB = AB[AT.SortBotIn1];
2012 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
2013 BB = AB[AT.SortBotIn2];
2014 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
2015 AT.SB.FillBlock = 1;
2016 AT.SB.MasterFill[1] = AT.SB.MasterStart[1];
2017 SETBASEPOSITION(AN.theposition,0);
2019 AT.SS->verbComparisons = 0;
2021 AT.SS->verbMaxTermSize = 0;
2034 case TERMINATETHREAD:
2044 sumtimerinfo[identity] +=
TimeCPU(1);
2045 timerinfo[identity] =
TimeCPU(0);
2053 MLOCK(ErrorMessageLock);
2054 MesPrint(
"!>Illegal wakeup signal %d for thread %d",wakeupsignal,identity);
2055 MUNLOCK(ErrorMessageLock);
2067 flint_final_cleanup_thread();
2069 FinalizeOneThread(identity);
2090void IAmAvailable(
int identity)
2093 LOCK(availabilitylock);
2094 top = topofavailables;
2095 listofavailables[topofavailables++] = identity;
2097 UNLOCK(availabilitylock);
2098 LOCK(wakeupmasterlock);
2099 wakeupmaster = identity;
2100 pthread_cond_signal(&wakeupmasterconditions);
2101 UNLOCK(wakeupmasterlock);
2104 UNLOCK(availabilitylock);
2120int GetAvailableThread(
void)
2123 LOCK(availabilitylock);
2124 if ( topofavailables > 0 ) retval = listofavailables[--topofavailables];
2125 UNLOCK(availabilitylock);
2126 if ( retval >= 0 ) {
2131 LOCK(wakeuplocks[retval]);
2132 UNLOCK(wakeuplocks[retval]);
2148int ConditionalGetAvailableThread(
void)
2151 if ( topofavailables > 0 ) {
2152 LOCK(availabilitylock);
2153 if ( topofavailables > 0 ) {
2154 retval = listofavailables[--topofavailables];
2156 UNLOCK(availabilitylock);
2157 if ( retval >= 0 ) {
2162 LOCK(wakeuplocks[retval]);
2163 UNLOCK(wakeuplocks[retval]);
2182int GetThread(
int identity)
2185 LOCK(availabilitylock);
2186 for ( j = 0; j < topofavailables; j++ ) {
2187 if ( identity == listofavailables[j] )
break;
2189 if ( j < topofavailables ) {
2191 for ( ; j < topofavailables; j++ ) {
2192 listofavailables[j] = listofavailables[j+1];
2196 UNLOCK(availabilitylock);
2213int ThreadWait(
int identity)
2216 LOCK(wakeuplocks[identity]);
2217 LOCK(availabilitylock);
2218 top = topofavailables;
2219 for ( j = topofavailables; j > 0; j-- )
2220 listofavailables[j] = listofavailables[j-1];
2221 listofavailables[0] = identity;
2223 if ( top == 0 || topofavailables == numberofworkers ) {
2224 UNLOCK(availabilitylock);
2225 LOCK(wakeupmasterlock);
2226 wakeupmaster = identity;
2227 pthread_cond_signal(&wakeupmasterconditions);
2228 UNLOCK(wakeupmasterlock);
2231 UNLOCK(availabilitylock);
2233 while ( wakeup[identity] == 0 ) {
2234 pthread_cond_wait(&(wakeupconditions[identity]),&(wakeuplocks[identity]));
2236 retval = wakeup[identity];
2237 wakeup[identity] = 0;
2238 UNLOCK(wakeuplocks[identity]);
2257int SortBotWait(
int identity)
2260 LOCK(wakeuplocks[identity]);
2261 LOCK(availabilitylock);
2262 topsortbotavailables++;
2263 if ( topsortbotavailables >= numberofsortbots ) {
2264 UNLOCK(availabilitylock);
2265 LOCK(wakeupsortbotlock);
2266 wakeupmaster = identity;
2267 pthread_cond_signal(&wakeupsortbotconditions);
2268 UNLOCK(wakeupsortbotlock);
2271 UNLOCK(availabilitylock);
2273 while ( wakeup[identity] == 0 ) {
2274 pthread_cond_wait(&(wakeupconditions[identity]),&(wakeuplocks[identity]));
2276 retval = wakeup[identity];
2277 wakeup[identity] = 0;
2278 UNLOCK(wakeuplocks[identity]);
2298int ThreadClaimedBlock(
int identity)
2300 LOCK(availabilitylock);
2302 if ( numberclaimed >= numberofworkers ) {
2303 UNLOCK(availabilitylock);
2304 LOCK(wakeupmasterlock);
2305 wakeupmaster = identity;
2306 pthread_cond_signal(&wakeupmasterconditions);
2307 UNLOCK(wakeupmasterlock);
2310 UNLOCK(availabilitylock);
2329 LOCK(wakeupmasterlock);
2330 while ( wakeupmaster == 0 ) {
2331 pthread_cond_wait(&wakeupmasterconditions,&wakeupmasterlock);
2333 retval = wakeupmaster;
2335 UNLOCK(wakeupmasterlock);
2349int MasterWaitThread(
int identity)
2352 LOCK(wakeupmasterthreadlocks[identity]);
2353 while ( wakeupmasterthread[identity] == 0 ) {
2354 pthread_cond_wait(&(wakeupmasterthreadconditions[identity])
2355 ,&(wakeupmasterthreadlocks[identity]));
2357 retval = wakeupmasterthread[identity];
2358 wakeupmasterthread[identity] = 0;
2359 UNLOCK(wakeupmasterthreadlocks[identity]);
2373void MasterWaitAll(
void)
2375 LOCK(wakeupmasterlock);
2376 while ( topofavailables < numberofworkers ) {
2377 pthread_cond_wait(&wakeupmasterconditions,&wakeupmasterlock);
2379 UNLOCK(wakeupmasterlock);
2395void MasterWaitAllSortBots(
void)
2397 LOCK(wakeupsortbotlock);
2398 while ( topsortbotavailables < numberofsortbots ) {
2399 pthread_cond_wait(&wakeupsortbotconditions,&wakeupsortbotlock);
2401 UNLOCK(wakeupsortbotlock);
2417void MasterWaitAllBlocks(
void)
2419 LOCK(wakeupmasterlock);
2420 while ( numberclaimed < numberofworkers ) {
2421 pthread_cond_wait(&wakeupmasterconditions,&wakeupmasterlock);
2423 UNLOCK(wakeupmasterlock);
2439void WakeupThread(
int identity,
int signalnumber)
2441 if ( signalnumber == 0 ) {
2443 MLOCK(ErrorMessageLock);
2444 MesPrint(
"!>Illegal wakeup signal for thread %d",identity);
2445 MUNLOCK(ErrorMessageLock);
2449 LOCK(wakeuplocks[identity]);
2450 wakeup[identity] = signalnumber;
2451 pthread_cond_signal(&(wakeupconditions[identity]));
2452 UNLOCK(wakeuplocks[identity]);
2467void WakeupMasterFromThread(
int identity,
int signalnumber)
2469 if ( signalnumber == 0 ) {
2471 MLOCK(ErrorMessageLock);
2472 MesPrint(
"!>Illegal wakeup signal for master %d",identity);
2473 MUNLOCK(ErrorMessageLock);
2477 LOCK(wakeupmasterthreadlocks[identity]);
2478 wakeupmasterthread[identity] = signalnumber;
2479 pthread_cond_signal(&(wakeupmasterthreadconditions[identity]));
2480 UNLOCK(wakeupmasterthreadlocks[identity]);
2492int SendOneBucket(
int type)
2494 ALLPRIVATES *B0 = AB[0];
2495 THREADBUCKET *thr = 0;
2497 for ( j = 0; j < numthreadbuckets; j++ ) {
2498 if ( threadbuckets[j]->free == BUCKETFILLED ) {
2499 thr = threadbuckets[j];
2500 for ( k = j+1; k < numthreadbuckets; k++ )
2501 threadbuckets[k-1] = threadbuckets[k];
2502 threadbuckets[numthreadbuckets-1] = thr;
2507 while ( (
id = GetAvailableThread() ) < 0 ) { MasterWait(); }
2511 LoadOneThread(0,
id,thr,0);
2512 thr->busy = BUCKETASSIGNED;
2513 thr->free = BUCKETINUSE;
2514 numberoffullbuckets--;
2522 WakeupThread(
id,type);
2550int InParallelProcessor(
void)
2553 int i, id, retval = 0, num = 0;
2555 if ( numberofworkers >= 2 ) {
2557 for ( i = 0; i < NumExpressions; i++ ) {
2559 if ( e->partodo <= 0 )
continue;
2560 if ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION
2561 || e->status == UNHIDELEXPRESSION || e->status == UNHIDEGEXPRESSION
2562 || e->status == INTOHIDELEXPRESSION || e->status == INTOHIDEGEXPRESSION ) {
2568 if ( e->counter == 0 ) {
2575 while ( (
id = GetAvailableThread() ) < 0 ) { MasterWait(); }
2576 LoadOneThread(0,
id,0,-1);
2577 AB[id]->R.exprtodo = i;
2578 WakeupThread(
id,DOONEEXPRESSION);
2584 if ( num > 0 ) MasterWaitAll();
2586 if ( AC.CollectFun ) AR.DeferFlag = 0;
2589 for ( i = 0; i < NumExpressions; i++ ) {
2590 Expressions[i].partodo = 0;
2624int ThreadsProcessor(
EXPRESSIONS e, WORD LastExpression, WORD fromspectator)
2626 ALLPRIVATES *B0 = AB[0], *B = B0;
2627 int id, oldgzipCompress, endofinput = 0, j, still, k, defcount = 0, bra = 0, first = 1;
2628 LONG dd = 0, ddd, thrbufsiz, thrbufsiz0, thrbufsiz2, numbucket = 0, numpasses;
2630 WORD *oldworkpointer = AT0.WorkPointer, *tt, *ttco = 0, *t1 = 0, ter, *tstop = 0, *t2;
2631 THREADBUCKET *thr = 0;
2633 GETTERM GetTermP = &GetTerm;
2634 POSITION eonfile = AS.OldOnFile[e-Expressions];
2635 numberoffullbuckets = 0;
2641 AM.tracebackflag = 1;
2643 AS.sLevel = AR0.sLevel;
2644 LOCK(availabilitylock);
2645 topofavailables = 0;
2646 for (
id = 1;
id <= numberofworkers;
id++ ) {
2647 WakeupThread(
id,STARTNEWEXPRESSION);
2649 UNLOCK(availabilitylock);
2655 if ( AC.numpfirstnum > 0 ) {
2656 for ( j = 0; j < AC.numpfirstnum; j++ ) {
2657 AC.inputnumbers[j] = -1;
2669 thrbufsiz2 = thrbufsiz = AC.ThreadBucketSize-1;
2670 if ( ( e->counter / ( numberofworkers * 5 ) ) < thrbufsiz ) {
2671 thrbufsiz = e->counter / ( numberofworkers * 5 ) - 1;
2672 if ( thrbufsiz < 0 ) thrbufsiz = 0;
2674 thrbufsiz0 = thrbufsiz;
2676 thrbufsiz = thrbufsiz0 / (2 << numpasses);
2680 for ( j = 0; j < numthreadbuckets; j++ )
2681 threadbuckets[j]->free = BUCKETFREE;
2682 thr = threadbuckets[0];
2691 if ( e->bracketinfo && AC.CollectFun == 0 && AR0.DeferFlag == 0 ) {
2696 for ( n = 0; n < e->bracketinfo->indexfill; n++ ) {
2697 num = TreatIndexEntry(B0,n);
2705 for ( j = 0; j < numthreadbuckets; j++ ) {
2706 switch ( threadbuckets[j]->free ) {
2708 thr = threadbuckets[j];
2710 case BUCKETCOMINGFREE:
2711 thr = threadbuckets[j];
2712 thr->free = BUCKETFREE;
2713 for ( k = j+1; k < numthreadbuckets; k++ )
2714 threadbuckets[k-1] = threadbuckets[k];
2715 threadbuckets[numthreadbuckets-1] = thr;
2723 if ( j < numthreadbuckets ) {
2727 thr->firstbracket = n;
2728 thr->lastbracket = n + num - 1;
2729 thr->type = BUCKETDOINGBRACKET;
2730 thr->free = BUCKETFILLED;
2731 thr->firstterm = AN0.ninterms;
2732 for ( j = n; j < n+num; j++ ) {
2733 AN0.ninterms += e->bracketinfo->
indexbuffer[j].termsinbracket;
2736 numberoffullbuckets++;
2737 if ( topofavailables > 0 ) {
2738 SendOneBucket(DOBRACKETS);
2747 while ( topofavailables <= 0 ) {
2750 SendOneBucket(DOBRACKETS);
2759 switch ( e->status ) {
2760 case UNHIDELEXPRESSION:
2761 case UNHIDEGEXPRESSION:
2762 case DROPHLEXPRESSION:
2763 case DROPHGEXPRESSION:
2764 case HIDDENLEXPRESSION:
2765 case HIDDENGEXPRESSION:
2766 curfile = AR0.hidefile;
2769 curfile = AR0.infile;
2772 SetScratch(curfile,&eonfile);
2773 GetTerm(B0,AT0.WorkPointer);
2777 GetTermP = &GetTerm2;
2782 for ( j = 0; j < numthreadbuckets; j++ ) {
2783 switch ( threadbuckets[j]->free ) {
2785 thr = threadbuckets[j];
2787 case BUCKETCOMINGFREE:
2788 thr = threadbuckets[j];
2789 thr->free = BUCKETFREE;
2790 for ( k = j+1; k < numthreadbuckets; k++ )
2791 threadbuckets[k-1] = threadbuckets[k];
2792 threadbuckets[numthreadbuckets-1] = thr;
2799 while ( topofavailables <= 0 ) {
2802 while ( topofavailables > 0 && numberoffullbuckets > 0 ) {
2803 SendOneBucket(DOBRACKETS);
2807 while ( numberoffullbuckets > 0 ) {
2808 while ( topofavailables <= 0 ) {
2811 while ( topofavailables > 0 && numberoffullbuckets > 0 ) {
2812 SendOneBucket(DOBRACKETS);
2821 AN0.lastinindex = -1;
2832 if ( fromspectator ) {
2833 ter = GetFromSpectator(thr->threadbuffer,fromspectator-1);
2834 if ( ter == 0 ) fromspectator = 0;
2837 ter = GetTermP(B0,thr->threadbuffer);
2853 if ( ter < 0 )
break;
2854 if ( ter == 0 ) { endofinput = 1;
goto Finalize; }
2855 dd = AN0.deferskipped;
2856 if ( AR0.DeferFlag ) {
2858 thr->deferbuffer[defcount++] = AR0.DefPosition;
2859 ttco = thr->compressbuffer; t1 = AR0.CompressBuffer; j = *t1;
2860 while ( thr->compressbuffersize <= j ) {
2862 WORD *top = thr->compressbuffer+thr->compressbuffersize;
2863 DoubleBuffer((
void**)&(thr->compressbuffer),(
void**)&(top),
2864 sizeof(*(thr->compressbuffer)),
"double compressbuffer");
2865 ttco = thr->compressbuffer;
2866 thr->compressbuffersize *= 2;
2870 else if ( first && ( AC.CollectFun == 0 ) ) {
2872 t1 = tstop = thr->threadbuffer;
2873 tstop += *tstop; tstop -= ABS(tstop[-1]);
2875 while ( t1 < tstop ) {
2876 if ( t1[0] == HAAKJE ) { bra = 1;
break; }
2879 t1 = thr->threadbuffer;
2884 if ( AC.CollectFun && *(thr->threadbuffer) < (AM.MaxTer/((LONG)
sizeof(WORD))-10) ) {
2885 if ( ( dd = GetMoreTerms(thr->threadbuffer) ) < 0 ) {
2892 if ( topofavailables > 0 && numberoffullbuckets > 0 ) SendOneBucket(LOWESTLEVELGENERATION);
2896 tt = thr->threadbuffer; tt += *tt;
2903 if ( numpasses > 0 ) {
2905 if ( numbucket >= numberofworkers ) {
2908 if ( numpasses == 0 ) thrbufsiz = thrbufsiz0;
2909 else thrbufsiz = thrbufsiz0 / (2 << numpasses);
2911 thrbufsiz2 = thrbufsiz + thrbufsiz/5;
2916 while ( ( dd < thrbufsiz ) &&
2917 ( tt - thr->threadbuffer ) < ( thr->threadbuffersize - AM.MaxTer/((LONG)
sizeof(WORD)) - 2 ) ) {
2921 if ( topofavailables > 0 && numberoffullbuckets > 0 ) SendOneBucket(LOWESTLEVELGENERATION);
2925 if ( GetTermP(B0,tt) == 0 ) { endofinput = 1;
break; }
2928 dd += AN0.deferskipped;
2929 if ( AR0.DeferFlag ) {
2930 thr->deferbuffer[defcount++] = AR0.DefPosition;
2931 t1 = AR0.CompressBuffer; j = *t1;
2932 while ( thr->compressbuffer+thr->compressbuffersize-ttco <= j ) {
2934 const ptrdiff_t oldoffset = ttco - thr->compressbuffer;
2935 WORD *top = thr->compressbuffer+thr->compressbuffersize;
2936 DoubleBuffer((
void**)&(thr->compressbuffer),(
void**)&(top),
2937 sizeof(*(thr->compressbuffer)),
"double compressbuffer");
2938 ttco = thr->compressbuffer + oldoffset;
2939 thr->compressbuffersize *= 2;
2943 if ( AC.CollectFun && *tt < (AM.MaxTer/((LONG)
sizeof(WORD))-10) ) {
2944 if ( ( ddd = GetMoreTerms(tt) ) < 0 ) {
2959 tstop = t1 + *t1; tstop -= ABS(tstop[-1]);
2961 while ( t2 < tstop ) {
2962 if ( t2[0] == HAAKJE ) {
break; }
2965 if ( t2[0] == HAAKJE ) {
2966 t2 += t2[1]; num = t2 - t1;
2967 while ( ( dd < thrbufsiz2 ) &&
2968 ( tt - thr->threadbuffer ) < ( thr->threadbuffersize - AM.MaxTer - 2 ) ) {
2972 if ( topofavailables > 0 && numberoffullbuckets > 0 ) SendOneBucket(LOWESTLEVELGENERATION);
2976 if ( GetTermP(B0,tt) == 0 ) { endofinput = 1;
break; }
2980 tstop = tt + *tt; tstop -= ABS(tstop[-1]);
2981 if ( tstop-tt < num ) {
2985 for ( i = 1; i < num; i++ ) {
2986 if ( t1[i] != tt[i] )
break;
3002 thr->firstterm = AN0.ninterms;
3005 thr->free = BUCKETFILLED;
3006 thr->type = BUCKETDOINGTERMS;
3007 numberoffullbuckets++;
3008 if ( topofavailables <= 0 && endofinput == 0 ) {
3022 for ( j = 0; j < numthreadbuckets; j++ ) {
3023 switch ( threadbuckets[j]->free ) {
3025 thr = threadbuckets[j];
3026 if ( !endofinput )
goto NextBucket;
3032 thr->free = BUCKETATEND;
3034 case BUCKETCOMINGFREE:
3035 thr = threadbuckets[j];
3036 thr->free = BUCKETFREE;
3042 for ( k = j+1; k < numthreadbuckets; k++ )
3043 threadbuckets[k-1] = threadbuckets[k];
3044 threadbuckets[numthreadbuckets-1] = thr;
3060 for ( j = 0; j < numthreadbuckets; j++ ) {
3061 if ( threadbuckets[j]->free == BUCKETFILLED ) {
3062 thr = threadbuckets[j];
3063 for ( k = j+1; k < numthreadbuckets; k++ )
3064 threadbuckets[k-1] = threadbuckets[k];
3065 threadbuckets[numthreadbuckets-1] = thr;
3075 while ( (
id = GetAvailableThread() ) < 0 ) { MasterWait(); }
3079 LoadOneThread(0,
id,thr,0);
3081 thr->busy = BUCKETASSIGNED;
3083 thr->free = BUCKETINUSE;
3084 numberoffullbuckets--;
3092 WakeupThread(
id,LOWESTLEVELGENERATION);
3097 if ( topofavailables > 0 ) {
3098 for ( j = 0; j < numthreadbuckets; j++ ) {
3099 if ( threadbuckets[j]->free == BUCKETFILLED ) {
3100 thr = threadbuckets[j];
3101 for ( k = j+1; k < numthreadbuckets; k++ )
3102 threadbuckets[k-1] = threadbuckets[k];
3103 threadbuckets[numthreadbuckets-1] = thr;
3112 for ( j = 0; j < numthreadbuckets; j++ ) {
3113 switch ( threadbuckets[j]->free ) {
3115 thr = threadbuckets[j];
3116 if ( !endofinput )
goto NextBucket;
3117 thr->free = BUCKETATEND;
3119 case BUCKETCOMINGFREE:
3120 thr = threadbuckets[j];
3122 thr->free = BUCKETATEND;
3125 thr->free = BUCKETFREE;
3126 for ( k = j+1; k < numthreadbuckets; k++ )
3127 threadbuckets[k-1] = threadbuckets[k];
3128 threadbuckets[numthreadbuckets-1] = thr;
3136 if ( j >= numthreadbuckets )
break;
3146 for ( j = 0; j < numthreadbuckets; j++ ) {
3147 switch ( threadbuckets[j]->free ) {
3149 thr = threadbuckets[j];
3150 if ( !endofinput )
goto NextBucket;
3151 thr->free = BUCKETATEND;
3153 case BUCKETCOMINGFREE:
3154 thr = threadbuckets[j];
3155 if ( endofinput ) thr->free = BUCKETATEND;
3157 thr->free = BUCKETFREE;
3158 for ( k = j+1; k < numthreadbuckets; k++ )
3159 threadbuckets[k-1] = threadbuckets[k];
3160 threadbuckets[numthreadbuckets-1] = thr;
3165 if ( still < 0 ) still = j;
3178 thr = threadbuckets[still];
3179 for ( k = still+1; k < numthreadbuckets; k++ )
3180 threadbuckets[k-1] = threadbuckets[k];
3181 threadbuckets[numthreadbuckets-1] = thr;
3194 if ( AC.ThreadBalancing ) {
3195 for (
id = 1;
id <= numberofworkers;
id++ ) {
3196 AB[id]->T.LoadBalancing = 1;
3198 if ( LoadReadjusted() )
goto Finalize;
3199 for (
id = 1;
id <= numberofworkers;
id++ ) {
3200 AB[id]->T.LoadBalancing = 0;
3203 if ( AC.ThreadBalancing ) {
3228 if ( LastExpression ) {
3230 if ( AR0.infile->handle >= 0 ) {
3231 CloseFile(AR0.infile->handle);
3232 AR0.infile->handle = -1;
3233 remove(AR0.infile->name);
3234 PUTZERO(AR0.infile->POposition);
3235 AR0.infile->POfill = AR0.infile->POfull = AR0.infile->PObuffer;
3247 oldgzipCompress = AR0.gzipCompress;
3248 AR0.gzipCompress = 0;
3249 if ( AR0.outtohide ) AR0.outfile = AR0.hidefile;
3250 if ( MasterMerge() < 0 ) {
3251 if ( AR0.outtohide ) AR0.outfile = oldoutfile;
3252 AR0.gzipCompress = oldgzipCompress;
3255 if ( AR0.outtohide ) AR0.outfile = oldoutfile;
3256 AR0.gzipCompress = oldgzipCompress;
3264 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
3265 if ( GetThread(
id) > 0 ) WakeupThread(
id,CLEANUPEXPRESSION);
3268 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
3269 if ( AB[
id]->R.MaxDum - AM.IndDum > e->numdummies )
3270 e->numdummies = AB[id]->R.MaxDum - AM.IndDum;
3271 AR0.expchanged |= AB[id]->R.expchanged;
3277 AT0.WorkPointer = oldworkpointer;
3305int LoadReadjusted(
void)
3307 ALLPRIVATES *B0 = AB[0];
3308 THREADBUCKET *thr = 0, *thrtogo = 0;
3309 int numtogo, numfree, numbusy, n, nperbucket, extra, i, j, u, bus;
3311 WORD *t1, *c1, *t2, *c2, *t3;
3316 while ( topofavailables <= 0 ) MasterWait();
3325 for ( j = 0; j < numthreadbuckets; j++ ) {
3326 thr = threadbuckets[j];
3327 if ( thr->free == BUCKETFREE || thr->free == BUCKETATEND
3328 || thr->free == BUCKETCOMINGFREE ) {
3329 freebuckets[numfree++] = thr;
3331 else if ( thr->type != BUCKETDOINGTERMS ) {}
3332 else if ( thr->totnum > 1 ) {
3336 if ( thr->free == BUCKETINUSE ) {
3337 n = thr->totnum-thr->usenum;
3338 if ( bus == BUCKETASSIGNED ) numbusy++;
3339 else if ( ( bus != BUCKETASSIGNED )
3340 && ( n > numtogo ) ) {
3345 else if ( bus == BUCKETTOBERELEASED
3346 && thr->free == BUCKETRELEASED ) {
3347 freebuckets[numfree++] = thr;
3348 thr->free = BUCKETATEND;
3350 thr->busy = BUCKETPREPARINGTERM;
3355 if ( numfree == 0 )
return(0);
3356 if ( numtogo > 0 ) {
3363 if ( thr->totnum-thr->usenum < numtogo )
goto restart;
3373 if ( thr->busy != BUCKETDOINGTERM ) {
3377 if ( thr->totnum-thr->usenum < numtogo ) {
3381 thr->free = BUCKETTERMINATED;
3388 if ( thr->usenum == thr->totnum ) {
3393 thr->free = BUCKETATEND;
3401 if ( numbusy > 0 ) {
3407 struct timespec sleeptime;
3408 sleeptime.tv_sec = 0;
3409 sleeptime.tv_nsec = 1000L;
3410 nanosleep(&sleeptime, NULL);
3425 numinput = thr->firstterm + thr->usenum;
3426 nperbucket = numtogo / numfree;
3427 extra = numtogo - nperbucket*numfree;
3428 if ( AR0.DeferFlag ) {
3429 t1 = thr->threadbuffer; c1 = thr->compressbuffer; u = thr->usenum;
3430 for ( n = 0; n < thr->usenum; n++ ) { t1 += *t1; c1 += *c1; }
3433 for ( i = 0; i < extra; i++ ) {
3434 thrtogo = freebuckets[i];
3435 t2 = thrtogo->threadbuffer;
3436 c2 = thrtogo->compressbuffer;
3437 thrtogo->free = BUCKETFILLED;
3438 thrtogo->type = BUCKETDOINGTERMS;
3439 thrtogo->totnum = nperbucket+1;
3440 thrtogo->ddterms = 0;
3441 thrtogo->usenum = 0;
3442 thrtogo->busy = BUCKETASSIGNED;
3443 thrtogo->firstterm = numinput;
3444 numinput += nperbucket+1;
3445 for ( n = 0; n <= nperbucket; n++ ) {
3446 j = *t1; NCOPY(t2,t1,j);
3447 j = *c1; NCOPY(c2,c1,j);
3448 thrtogo->deferbuffer[n] = thr->deferbuffer[u++];
3453 if ( nperbucket > 0 ) {
3454 for ( i = extra; i < numfree; i++ ) {
3455 thrtogo = freebuckets[i];
3456 t2 = thrtogo->threadbuffer;
3457 c2 = thrtogo->compressbuffer;
3458 thrtogo->free = BUCKETFILLED;
3459 thrtogo->type = BUCKETDOINGTERMS;
3460 thrtogo->totnum = nperbucket;
3461 thrtogo->ddterms = 0;
3462 thrtogo->usenum = 0;
3463 thrtogo->busy = BUCKETASSIGNED;
3464 thrtogo->firstterm = numinput;
3465 numinput += nperbucket;
3466 for ( n = 0; n < nperbucket; n++ ) {
3467 j = *t1; NCOPY(t2,t1,j);
3468 j = *c1; NCOPY(c2,c1,j);
3469 thrtogo->deferbuffer[n] = thr->deferbuffer[u++];
3476 t1 = thr->threadbuffer;
3477 for ( n = 0; n < thr->usenum; n++ ) { t1 += *t1; }
3480 for ( i = 0; i < extra; i++ ) {
3481 thrtogo = freebuckets[i];
3482 t2 = thrtogo->threadbuffer;
3483 thrtogo->free = BUCKETFILLED;
3484 thrtogo->type = BUCKETDOINGTERMS;
3485 thrtogo->totnum = nperbucket+1;
3486 thrtogo->ddterms = 0;
3487 thrtogo->usenum = 0;
3488 thrtogo->busy = BUCKETASSIGNED;
3489 thrtogo->firstterm = numinput;
3490 numinput += nperbucket+1;
3491 for ( n = 0; n <= nperbucket; n++ ) {
3492 j = *t1; NCOPY(t2,t1,j);
3497 if ( nperbucket > 0 ) {
3498 for ( i = extra; i < numfree; i++ ) {
3499 thrtogo = freebuckets[i];
3500 t2 = thrtogo->threadbuffer;
3501 thrtogo->free = BUCKETFILLED;
3502 thrtogo->type = BUCKETDOINGTERMS;
3503 thrtogo->totnum = nperbucket;
3504 thrtogo->ddterms = 0;
3505 thrtogo->usenum = 0;
3506 thrtogo->busy = BUCKETASSIGNED;
3507 thrtogo->firstterm = numinput;
3508 numinput += nperbucket;
3509 for ( n = 0; n < nperbucket; n++ ) {
3510 j = *t1; NCOPY(t2,t1,j);
3517 if ( thr->free == BUCKETRELEASED && thr->busy == BUCKETTOBERELEASED ) {
3518 thr->free = BUCKETATEND; thr->busy = BUCKETPREPARINGTERM;
3586int PutToMaster(PHEAD WORD *term)
3588 int i,j,nexti,ret = 0;
3590 WORD *t, *fill, *top, zero = 0;
3595 t = term; ret = j = *term;
3596 if ( j == 0 ) { j = 1; }
3598 i = AT.SB.FillBlock;
3599 fill = AT.SB.MasterFill[i];
3600 top = AT.SB.MasterStop[i];
3607 if ( j < top - fill && AT.SB.BlockTerms[i] > MINWRITENUMBEROFTERMS ) {
3608 const int prev = ( i == 1 ? AT.SB.MasterNumBlocks : i-1 );
3609 if ( ! pthread_mutex_trylock(&(AT.SB.MasterBlockLock[prev])) ) {
3610 UNLOCK(AT.SB.MasterBlockLock[prev]);
3619 if ( ( j >= top - fill ) || urgent ) {
3621 if ( nexti > AT.SB.MasterNumBlocks ) {
3624 LOCK(AT.SB.MasterBlockLock[nexti]);
3625 UNLOCK(AT.SB.MasterBlockLock[i]);
3626 AT.SB.MasterFill[i] = AT.SB.MasterStart[i];
3627 AT.SB.FillBlock = i = nexti;
3628 fill = AT.SB.MasterStart[i];
3629 top = AT.SB.MasterStop[i];
3630 if ( AT.SB.BlockTerms[i] != 0 ) {
3635 MLOCK(ErrorMessageLock);
3636 MesPrint(
"!>Error in PutToMaster, starting a block with BlockTerms != 0");
3637 MUNLOCK(ErrorMessageLock);
3644 AT.SB.BlockTerms[i]++;
3645 AT.SB.MasterFill[i] = fill;
3665SortBotOut(PHEAD WORD *term)
3669 if ( AT.identity != 0 )
return(PutToMaster(BHEAD term));
3672 if (
FlushOut(&SortBotPosition,AR.outfile,1) )
return(-1);
3673 ADDPOS(AT.SS->SizeInFile[0],1);
3678 if ( ( im =
PutOut(BHEAD term,&SortBotPosition,AR.outfile,1) ) < 0 ) {
3680 MLOCK(ErrorMessageLock);
3681 MesPrint(
"!>Called from MasterMerge/SortBotOut");
3682 MUNLOCK(ErrorMessageLock);
3686 ADDPOS(AT.SS->SizeInFile[0],im);
3714int MasterMerge(
void)
3716 ALLPRIVATES *B0 = AB[0], *B = 0;
3718 WORD **poin, **poin2, ul, k, i, im, *m1, j;
3719 WORD lpat, mpat, level, l1, l2, r1, r2, r3, c;
3720 WORD *m2, *m3, r31, r33, ki, *rr;
3725 if ( numberofworkers > 2 )
return(SortBotMasterMerge());
3728 if ( AR0.PolyFun == 0 ) { S->PolyFlag = 0; }
3729 else if ( AR0.PolyFunType == 1 ) { S->PolyFlag = 1; }
3730 else if ( AR0.PolyFunType == 2 ) {
3731 if ( AR0.PolyFunExp == 2
3732 || AR0.PolyFunExp == 3 ) S->PolyFlag = 1;
3733 else S->PolyFlag = 2;
3736 coef = AN0.SoScratC;
3737 poin = S->poina; poin2 = S->poin2a;
3738 rr = AR0.CompressPointer;
3743 S->inNum = numberofthreads;
3748 S->lPatch = S->inNum - 1;
3758 for ( i = 1; i <= S->lPatch; i++ ) {
3760 LOCK(AT.SB.MasterBlockLock[0]);
3761 LOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
3769 for ( i = 0; i < S->lPatch; i++ ) {
3771 WakeupThread(i+1,FINISHEXPRESSION);
3776 if ( fout->
handle >= 0 ) {
3778 SeekFile(fout->
handle,&position,SEEK_END);
3779 ADDPOS(position,((fout->POfill-fout->PObuffer)*
sizeof(WORD)));
3782 SETBASEPOSITION(position,(fout->POfill-fout->PObuffer)*
sizeof(WORD));
3787 MasterWaitAllBlocks();
3795 for ( i = 1; i <= S->lPatch; i++ ) {
3797 LOCK(AT.SB.MasterBlockLock[1]);
3798 AT.SB.MasterBlock = 1;
3806 do { lpat <<= 1; }
while ( lpat < S->lPatch );
3807 mpat = ( lpat >> 1 ) - 1;
3808 k = lpat - S->lPatch;
3813 for ( i = 1; i < lpat; i++ ) { S->tree[i] = -1; }
3814 for ( i = 1; i <= k; i++ ) {
3816 poin[im] = AB[i]->T.SB.MasterStart[AB[i]->T.SB.MasterBlock];
3817 poin2[im] = poin[im] + *(poin[im]);
3820 S->tree[mpat+i] = 0;
3821 poin[im-1] = poin2[im-1] = 0;
3823 for ( i = (k*2)+1; i <= lpat; i++ ) {
3826 poin[i] = AB[i-k]->T.SB.MasterStart[AB[i-k]->T.SB.MasterBlock];
3827 poin2[i] = poin[i] + *(poin[i]);
3848 if ( !*(poin[k]) ) {
3852 AB[ki+1]->T.SB.BlockTerms[AB[ki+1]->T.SB.MasterBlock]--;
3854 if ( !( i >>= 1 ) ) {
3857 }
while ( !S->tree[i] );
3858 if ( S->tree[i] == -1 ) {
3871 if ( S->tree[i] > 0 ) {
3872 if ( ( c = CompareTerms(B0, poin[S->tree[i]],poin[k],(WORD)0) ) > 0 ) {
3876 S->used[level] = S->tree[i];
3886 l1 = *( m1 = poin[S->tree[i]] );
3887 l2 = *( m2 = poin[k] );
3888 if ( S->PolyWise ) {
3893 if ( S->PolyFlag == 2 ) {
3895 if ( *tt1 + w[1] - m1[1] > AM.MaxTer/((LONG)
sizeof(WORD)) ) {
3896 MLOCK(ErrorMessageLock);
3897 MesPrint(
"Term too complex in PolyRatFun addition. MaxTermSize of %10l is too small",AM.MaxTer);
3898 MUNLOCK(ErrorMessageLock);
3901 AT0.WorkPointer = w;
3902 if ( w[FUNHEAD] == -SNUMBER && w[FUNHEAD+1] == 0 && w[1] > FUNHEAD ) {
3907 w = AT0.WorkPointer;
3908 if ( w + m1[1] + m2[1] > AT0.WorkTop ) {
3909 MLOCK(ErrorMessageLock);
3910 MesPrint(
"MasterMerge: A WorkSpace of %10l is too small",AM.WorkSize);
3911 MUNLOCK(ErrorMessageLock);
3918 || ( w[FUNHEAD] == -SNUMBER && w[FUNHEAD+1] == 0 ) )
3920 if ( r1 == m1[1] ) {
3923 else if ( r1 < m1[1] ) {
3927 while ( --r1 >= 0 ) *--m1 = *--m2;
3930 while ( --r1 >= 0 ) *--m1 = *--m2;
3932 poin[S->tree[i]] = m1;
3946 poin[S->tree[i]] = m2;
3953 else if ( AT.SortFloatMode ) {
3954 WORD *term1, *term2;
3955 term1 = poin[S->tree[i]];
3957 if ( MergeWithFloat(B0, &term1,&term2) == 0 )
3959 poin[S->tree[i]] = term1;
3963 r1 = *( m1 += l1 - 1 );
3965 r1 = ( ( r1 > 0 ) ? (r1-1) : (r1+1) ) >> 1;
3966 r2 = *( m2 += l2 - 1 );
3968 r2 = ( ( r2 > 0 ) ? (r2-1) : (r2+1) ) >> 1;
3970 if ( AddRat(B0,(UWORD *)m1,r1,(UWORD *)m2,r2,coef,&r3) ) {
3971 MLOCK(ErrorMessageLock);
3972 MesCall(
"MasterMerge");
3973 MUNLOCK(ErrorMessageLock);
3977 if ( AN.ncmod != 0 ) {
3978 if ( ( AC.modmode & POSNEG ) != 0 ) {
3981 else if ( BigLong(coef,r3,(UWORD *)AC.cmod,ABS(AN.ncmod)) >= 0 ) {
3983 SubPLon(coef,r3,(UWORD *)AC.cmod,ABS(AN.ncmod),coef,&r3);
3985 for ( ii = 1; ii < r3; ii++ ) coef[r3+ii] = 0;
3989 r33 = ( r3 > 0 ) ? ( r3 + 1 ) : ( r3 - 1 );
3990 if ( r3 < 0 ) r3 = -r3;
3991 if ( r1 < 0 ) r1 = -r1;
3996 ul = S->used[level] = S->tree[i];
4002 poin[ul] = poin2[ul];
4004 AB[ki+1]->T.SB.BlockTerms[AB[ki+1]->T.SB.MasterBlock]--;
4005 if ( AB[ki+1]->T.SB.BlockTerms[AB[ki+1]->T.SB.MasterBlock] == 0 ) {
4011 i = AT.SB.MasterBlock;
4013 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
4016 UNLOCK(AT.SB.MasterBlockLock[i-1]);
4018 if ( i == AT.SB.MasterNumBlocks ) {
4022 LOCK(AT.SB.MasterBlockLock[i]);
4023 AT.SB.MasterBlock = i;
4024 poin[ul] = AT.SB.MasterStart[i];
4026 poin2[ul] = poin[ul] + im;
4031 S->used[++level] = k;
4036 else if ( r31 < 0 ) {
4045 if( (poin[S->tree[i]]+l1+r31) >= poin2[S->tree[i]] ) {
4051 if ( (l1 + r31)*((LONG)
sizeof(WORD)) >= AM.MaxTer ) {
4052 MLOCK(ErrorMessageLock);
4053 MesPrint(
"MasterMerge: Coefficient overflow during sort");
4054 MUNLOCK(ErrorMessageLock);
4057 m2 = poin[S->tree[i]];
4058 m3 = ( poin[S->tree[i]] -= r31 );
4059 do { *m3++ = *m2++; }
while ( m2 < m1 );
4063 *(poin[S->tree[i]]) += r31;
4065 m2 = (WORD *)coef; im = r3;
4077 AB[ki+1]->T.SB.BlockTerms[AB[ki+1]->T.SB.MasterBlock]--;
4078 if ( AB[ki+1]->T.SB.BlockTerms[AB[ki+1]->T.SB.MasterBlock] == 0 ) {
4084 i = AT.SB.MasterBlock;
4086 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
4089 UNLOCK(AT.SB.MasterBlockLock[i-1]);
4091 if ( i == AT.SB.MasterNumBlocks ) {
4095 LOCK(AT.SB.MasterBlockLock[i]);
4096 AT.SB.MasterBlock = i;
4097 poin[k] = AT.SB.MasterStart[i];
4099 poin2[k] = poin[k] + im;
4107 else if ( S->tree[i] < 0 ) {
4118 if ( ( im =
PutOut(B0,poin[k],&position,fout,1) ) < 0 ) {
4120 MLOCK(ErrorMessageLock);
4121 MesPrint(
"!>Called from MasterMerge with k = %d (stream %d)",k,S->ktoi[k]);
4122 MUNLOCK(ErrorMessageLock);
4126 ADDPOS(S->SizeInFile[0],im);
4129 if (
FlushOut(&position,fout,1) )
goto ReturnError;
4130 ADDPOS(S->SizeInFile[0],1);
4134 position = S->SizeInFile[0];
4135 MULPOS(position,
sizeof(WORD));
4144 for ( j = 1; j <= numberofworkers; j++ ) {
4145 S->GenTerms += AB[j]->T.SS->GenTerms;
4146 S->verbComparisons += AB[j]->T.SS->verbComparisons;
4147 if ( S->verbMaxTermSize < AB[j]->T.SS->verbMaxTermSize )
4148 S->verbMaxTermSize = AB[j]->T.SS->verbMaxTermSize;
4149 S->verbSBsortTerms += AB[j]->T.SS->verbSBsortTerms;
4150 S->verbSBsortCap += AB[j]->T.SS->verbSBsortCap;
4151 S->verbLBsortPatches += AB[j]->T.SS->verbLBsortPatches;
4152 S->verbLBsortCap += AB[j]->T.SS->verbLBsortCap;
4153 S->verbUnsortedSize += AB[j]->T.SS->verbUnsortedSize;
4156 WriteStats(&position,STATSPOSTSORT,NOCHECKLOGTYPE);
4157 Expressions[AR0.CurExpr].counter = S->TermsLeft;
4158 Expressions[AR0.CurExpr].size = position;
4162 for ( i = 1; i <= S->lPatch; i++ ) {
4164 UNLOCK(AT.SB.MasterBlockLock[0]);
4165 if ( AT.SB.MasterBlock == 1 ) {
4166 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
4169 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterBlock-1]);
4171 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterBlock]);
4176 for ( i = 1; i <= S->lPatch; i++ ) {
4178 UNLOCK(AT.SB.MasterBlockLock[0]);
4179 if ( AT.SB.MasterBlock == 1 ) {
4180 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
4183 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterBlock-1]);
4185 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterBlock]);
4213int SortBotMasterMerge(
void)
4216 ALLPRIVATES *B = AB[0], *BB;
4229 topsortbotavailables = 0;
4230 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
4231 WakeupThread(i,INISORTBOT);
4237 AR.CompressPointer[0] = 0;
4239 BB = AB[AT.SortBotIn1];
4240 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
4241 BB = AB[AT.SortBotIn2];
4242 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
4244 MasterWaitAllSortBots();
4249 for ( i = 1; i <= numberofworkers; i++ ) {
4251 WakeupThread(i,FINISHEXPRESSION);
4256 if ( fout->
handle >= 0 ) {
4257 PUTZERO(SortBotPosition);
4258 SeekFile(fout->
handle,&SortBotPosition,SEEK_END);
4259 ADDPOS(SortBotPosition,((fout->POfill-fout->PObuffer)*
sizeof(WORD)));
4262 SETBASEPOSITION(SortBotPosition,(fout->POfill-fout->PObuffer)*
sizeof(WORD));
4264 MasterWaitAllBlocks();
4270 topsortbotavailables = 0;
4271 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
4272 WakeupThread(i,RUNSORTBOT);
4274 if ( SortBotMerge(BHEAD0) ) {
4276 MLOCK(ErrorMessageLock);
4277 MesPrint(
"!>Called from SortBotMasterMerge");
4278 MUNLOCK(ErrorMessageLock);
4286 if ( S->file.
handle >= 0 )
4293 position = S->SizeInFile[0];
4294 MULPOS(position,
sizeof(WORD));
4303 for ( j = 1; j <= numberofworkers; j++ ) {
4304 S->GenTerms += AB[j]->T.SS->GenTerms;
4305 S->verbComparisons += AB[j]->T.SS->verbComparisons;
4306 if ( S->verbMaxTermSize < AB[j]->T.SS->verbMaxTermSize )
4307 S->verbMaxTermSize = AB[j]->T.SS->verbMaxTermSize;
4308 S->verbSBsortTerms += AB[j]->T.SS->verbSBsortTerms;
4309 S->verbSBsortCap += AB[j]->T.SS->verbSBsortCap;
4310 S->verbLBsortPatches += AB[j]->T.SS->verbLBsortPatches;
4311 S->verbLBsortCap += AB[j]->T.SS->verbLBsortCap;
4312 S->verbUnsortedSize += AB[j]->T.SS->verbUnsortedSize;
4314 for ( j = numberofworkers+1; j <= numberofworkers+numberofsortbots; j++ ) {
4315 S->verbComparisons += AB[j]->T.SS->verbComparisons;
4316 if ( S->verbMaxTermSize < AB[j]->T.SS->verbMaxTermSize )
4317 S->verbMaxTermSize = AB[j]->T.SS->verbMaxTermSize;
4320 S->TermsLeft = numberofterms;
4321 WriteStats(&position,STATSPOSTSORT,NOCHECKLOGTYPE);
4322 Expressions[AR.CurExpr].counter = S->TermsLeft;
4323 Expressions[AR.CurExpr].size = position;
4332 MasterWaitAllSortBots();
4351int SortBotMerge(PHEAD0)
4354 ALLPRIVATES *Bin1 = AB[AT.SortBotIn1],*Bin2 = AB[AT.SortBotIn2];
4355 WORD *term1, *term2, *wp;
4358 WORD l1, l2, *m1, *m2, *w, r1, r2, r3, r33, r31, *tt1, ii;
4359 WORD *to, *from, im, c;
4363 WORD *fun1, *fun2, *fun3, *tstop1, *tstop2, size1, size2, size3, l3, jj, *m3;
4371 if ( AT.identity == 0 ) {
4372 wp = AT.WorkPointer;
4375 wp = AT.WorkPointer = AT.WorkSpace;
4382 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4383 LOCK(Bin2->T.SB.MasterBlockLock[blin2]);
4385 term1 = Bin1->T.SB.MasterStart[blin1];
4386 term2 = Bin2->T.SB.MasterStart[blin2];
4387 AT.SB.FillBlock = 1;
4391 while ( *term1 && *term2 ) {
4392 if ( ( c = CompareTerms(BHEAD term1,term2,(WORD)0) ) > 0 ) {
4396 Bin1->T.SB.BlockTerms[blin1]--;
4397 if ( SortBotOut(BHEAD term1) < 0 ) {
4399 MLOCK(ErrorMessageLock);
4400 MesPrint(
"!>Called from SortBotMerge with thread = %d",AT.identity);
4401 MUNLOCK(ErrorMessageLock);
4407 if ( Bin1->T.SB.BlockTerms[blin1] == 0 ) {
4409 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4412 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4414 if ( blin1 == Bin1->T.SB.MasterNumBlocks ) {
4420 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4421 Bin1->T.SB.MasterBlock = blin1;
4422 term1 = Bin1->T.SB.MasterStart[blin1];
4432 Bin2->T.SB.BlockTerms[blin2]--;
4433 if ( SortBotOut(BHEAD term2) < 0 ) {
4435 MLOCK(ErrorMessageLock);
4436 MesPrint(
"!>Called from SortBotMerge with thread = %d",AT.identity);
4437 MUNLOCK(ErrorMessageLock);
4444 if ( Bin2->T.SB.BlockTerms[blin2] == 0 ) {
4446 UNLOCK(Bin2->T.SB.MasterBlockLock[Bin2->T.SB.MasterNumBlocks]);
4449 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2-1]);
4451 if ( blin2 == Bin2->T.SB.MasterNumBlocks ) {
4457 LOCK(Bin2->T.SB.MasterBlockLock[blin2]);
4458 Bin2->T.SB.MasterBlock = blin2;
4459 term2 = Bin2->T.SB.MasterStart[blin2];
4469 Bin1->T.SB.BlockTerms[blin1]--;
4470 Bin2->T.SB.BlockTerms[blin2]--;
4471 l1 = *( m1 = term1 );
4472 l2 = *( m2 = term2 );
4473 if ( S->PolyWise ) {
4477 if ( S->PolyFlag == 2 ) {
4478 AT.WorkPointer = wp;
4480 if ( *tt1 + w[1] - m1[1] > AM.MaxTer/((LONG)
sizeof(WORD)) ) {
4481 MLOCK(ErrorMessageLock);
4482 MesPrint(
"Term too complex in PolyRatFun addition. MaxTermSize of %10l is too small",AM.MaxTer);
4483 MUNLOCK(ErrorMessageLock);
4486 AT.WorkPointer = wp;
4487 if ( w[FUNHEAD] == -SNUMBER && w[FUNHEAD+1] == 0 && w[1] > FUNHEAD ) {
4493 if ( w + m1[1] + m2[1] > AT.WorkTop ) {
4494 MLOCK(ErrorMessageLock);
4495 MesPrint(
"SortBotMerge(%d): A Maxtermsize of %10l is too small",
4496 AT.identity,AM.MaxTer/
sizeof(WORD));
4497 MesPrint(
"m1[1] = %d, m2[1] = %d, Space = %l",m1[1],m2[1],(LONG)(AT.WorkTop-wp));
4498 PrintTerm(term1,
"term1");
4499 PrintTerm(term2,
"term2");
4500 MesPrint(
"PolyWise = %d",S->PolyWise);
4501 MUNLOCK(ErrorMessageLock);
4508 || ( w[FUNHEAD] == -SNUMBER && w[FUNHEAD+1] == 0 ) )
4510 if ( r1 == m1[1] ) {
4513 else if ( r1 < m1[1] ) {
4517 while ( --r1 >= 0 ) *--m1 = *--m2;
4520 while ( --r1 >= 0 ) *--m1 = *--m2;
4543 else if ( AT.SortFloatMode ) {
4551 tstop1 = m1+l1; size1 = tstop1[-1]; tstop1 -= ABS(size1);
4552 tstop2 = m2+l2; size2 = tstop2[-1]; tstop2 -= ABS(size2);
4553 if ( AT.SortFloatMode == 3 ) {
4555 while ( fun1[0] != FLOATFUN && fun1+fun1[1] < tstop1 ) {
4558 if ( size1 < 0 ) fun1[FUNHEAD+3] = -fun1[FUNHEAD+3];
4559 UnpackFloat(aux1,fun1);
4561 while ( fun2[0] != FLOATFUN && fun2+fun2[1] < tstop2 ) {
4564 if ( size2 < 0 ) fun2[FUNHEAD+3] = -fun2[FUNHEAD+3];
4565 UnpackFloat(aux2,fun2);
4567 else if ( AT.SortFloatMode == 1 ) {
4569 while ( fun1[0] != FLOATFUN && fun1+fun1[1] < tstop1 ) {
4572 if ( size1 < 0 ) fun1[FUNHEAD+3] = -fun1[FUNHEAD+3];
4573 UnpackFloat(aux1,fun1);
4575 RatToFloat(aux2,(UWORD *)fun2,size2);
4577 else if ( AT.SortFloatMode == 2 ) {
4579 RatToFloat(aux1,(UWORD *)fun1,size1);
4581 while ( fun2[0] != FLOATFUN && fun2+fun2[1] < tstop2 ) {
4584 if ( size2 < 0 ) fun2[FUNHEAD+3] = -fun2[FUNHEAD+3];
4585 UnpackFloat(aux2,fun2);
4589 MLOCK(ErrorMessageLock);
4590 MesPrint(
"!>Illegal value %d for AT.SortFloatMode in SortBotMerge.",AT.SortFloatMode);
4591 MUNLOCK(ErrorMessageLock);
4596 mpf_add(aux3,aux1,aux2);
4597 size3 = mpf_sgn(aux3);
4601 else if ( size3 < 0 ) mpf_neg(aux3,aux3);
4602 fun3 = TermMalloc(
"MasterMerge");
4603 PackFloat(fun3,aux3);
4604 l3 = fun3[1]+(fun1-m1)+3;
4610 if ( (l3)*((LONG)
sizeof(WORD)) >= AM.MaxTer ) {
4611 MLOCK(ErrorMessageLock);
4612 MesPrint(
"MasterMerge: Coefficient overflow during sort");
4613 MUNLOCK(ErrorMessageLock);
4616 m3 = wp; m2 = term1;
4617 while ( m2 < fun1 ) *m3++ = *m2++;
4618 for ( jj = 0; jj < fun3[1]; jj++ ) *m3++ = fun3[jj];
4619 *m3++ = 1; *m3++ = 1;
4620 *m3++ = size3 < 0 ? -3: 3;
4622 TermFree(fun3,
"MasterMerge");
4625 for ( jj = 0; jj < fun3[1]; jj++ ) fun1[jj] = fun3[jj];
4627 *fun1++ = 1; *fun1++ = 1;
4628 *fun1++ = size3 < 0 ? -3: 3;
4629 *term1 = fun1-term1;
4630 TermFree(fun3,
"MasterMerge");
4634 r1 = *( m1 += l1 - 1 );
4636 r1 = ( ( r1 > 0 ) ? (r1-1) : (r1+1) ) >> 1;
4637 r2 = *( m2 += l2 - 1 );
4639 r2 = ( ( r2 > 0 ) ? (r2-1) : (r2+1) ) >> 1;
4641 if ( AddRat(BHEAD (UWORD *)m1,r1,(UWORD *)m2,r2,coef,&r3) ) {
4642 MLOCK(ErrorMessageLock);
4643 MesCall(
"SortBotMerge");
4644 MUNLOCK(ErrorMessageLock);
4648 if ( AN.ncmod != 0 ) {
4649 if ( ( AC.modmode & POSNEG ) != 0 ) {
4652 else if ( BigLong(coef,r3,(UWORD *)AC.cmod,ABS(AN.ncmod)) >= 0 ) {
4653 SubPLon(coef,r3,(UWORD *)AC.cmod,ABS(AN.ncmod),coef,&r3);
4655 for ( ii = 1; ii < r3; ii++ ) coef[r3+ii] = 0;
4658 if ( !r3 ) {
goto cancelled; }
4660 r33 = ( r3 > 0 ) ? ( r3 + 1 ) : ( r3 - 1 );
4661 if ( r3 < 0 ) r3 = -r3;
4662 if ( r1 < 0 ) r1 = -r1;
4666 m2 = (WORD *)coef; im = r3;
4671 to = wp; from = term1;
4672 while ( from < m1 ) *to++ = *from++;
4673 from = (WORD *)coef; im = r3;
4678 if ( SortBotOut(BHEAD wp) < 0 ) {
4680 MLOCK(ErrorMessageLock);
4681 MesPrint(
"!>Called from SortBotMerge with thread = %d",AT.identity);
4682 MUNLOCK(ErrorMessageLock);
4690 if ( SortBotOut(BHEAD term1) < 0 ) {
4692 MLOCK(ErrorMessageLock);
4693 MesPrint(
"!>Called from SortBotMerge with thread = %d",AT.identity);
4694 MUNLOCK(ErrorMessageLock);
4701 if ( Bin1->T.SB.BlockTerms[blin1] == 0 ) {
4704 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4707 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4709 if ( blin1 == Bin1->T.SB.MasterNumBlocks ) {
4715 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4716 Bin1->T.SB.MasterBlock = blin1;
4717 term1 = Bin1->T.SB.MasterStart[blin1];
4733 Bin1->T.SB.BlockTerms[blin1]--;
4734 if ( SortBotOut(BHEAD term1) < 0 ) {
4736 MLOCK(ErrorMessageLock);
4737 MesPrint(
"!>Called from SortBotMerge with thread = %d",AT.identity);
4738 MUNLOCK(ErrorMessageLock);
4743 if ( Bin1->T.SB.BlockTerms[blin1] == 0 ) {
4746 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4749 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4751 if ( blin1 == Bin1->T.SB.MasterNumBlocks ) {
4757 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4758 Bin1->T.SB.MasterBlock = blin1;
4759 term1 = Bin1->T.SB.MasterStart[blin1];
4769 else if ( *term2 ) {
4774 Bin2->T.SB.BlockTerms[blin2]--;
4775 if ( SortBotOut(BHEAD term2) < 0 ) {
4777 MLOCK(ErrorMessageLock);
4778 MesPrint(
"!>Called from SortBotMerge with thread = %d",AT.identity);
4779 MUNLOCK(ErrorMessageLock);
4784 if ( Bin2->T.SB.BlockTerms[blin2] == 0 ) {
4787 UNLOCK(Bin2->T.SB.MasterBlockLock[Bin2->T.SB.MasterNumBlocks]);
4790 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2-1]);
4792 if ( blin2 == Bin2->T.SB.MasterNumBlocks ) {
4798 LOCK(Bin2->T.SB.MasterBlockLock[blin2]);
4799 Bin2->T.SB.MasterBlock = blin2;
4800 term2 = Bin2->T.SB.MasterStart[blin2];
4814 Bin1->T.SB.BlockTerms[blin1]--;
4815 Bin2->T.SB.BlockTerms[blin2]--;
4817 SortBotOut(BHEAD 0);
4822 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4824 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4827 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4829 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2]);
4831 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2-1]);
4834 UNLOCK(Bin2->T.SB.MasterBlockLock[Bin2->T.SB.MasterNumBlocks]);
4836 if ( AT.identity > 0 ) {
4837 UNLOCK(AT.SB.MasterBlockLock[AT.SB.FillBlock]);
4852static int SortBlocksInitialized = 0;
4860int IniSortBlocks(
int numworkers)
4864 LONG totalsize, workersize, blocksize, numberofterms;
4866 int numberofblocks = NUMBEROFBLOCKSINSORT, numparts;
4869 if ( SortBlocksInitialized )
return(0);
4870 SortBlocksInitialized = 1;
4871 if ( numworkers == 0 )
return(0);
4874 if ( numworkers > 2 ) {
4875 numparts = 2*numworkers - 2;
4876 numberofblocks = numberofblocks/2;
4879 numparts = numworkers;
4882 numparts = numworkers;
4885 totalsize = S->LargeSize + S->SmallEsize;
4886 workersize = totalsize / numparts;
4887 maxter = AM.MaxTer/
sizeof(WORD);
4888 blocksize = ( workersize - maxter )/numberofblocks;
4889 numberofterms = blocksize / maxter;
4890 if ( numberofterms < MINIMUMNUMBEROFTERMS ) {
4895 MesPrint(
"!>We have a problem with the size of the blocks in IniSortBlocks");
4905 if ( w == 0 ) w = S->sBuffer;
4906 for (
id = 1;
id <= numparts;
id++ ) {
4908 AT.SB.MasterBlockLock = (pthread_mutex_t *)Malloc1(
4909 sizeof(pthread_mutex_t)*(numberofblocks+1),
"MasterBlockLock");
4910 AT.SB.MasterStart = (WORD **)Malloc1(
sizeof(WORD *)*(numberofblocks+1)*3,
"MasterBlock");
4911 AT.SB.MasterFill = AT.SB.MasterStart + (numberofblocks+1);
4912 AT.SB.MasterStop = AT.SB.MasterFill + (numberofblocks+1);
4913 AT.SB.MasterNumBlocks = numberofblocks;
4914 AT.SB.BlockTerms = (LONG*)Malloc1(
sizeof(LONG)*(numberofblocks+1),
"BlockTerms");
4915 AT.SB.MasterBlock = 0;
4916 AT.SB.FillBlock = 0;
4917 AT.SB.MasterFill[0] = AT.SB.MasterStart[0] = w;
4918 AT.SB.BlockTerms[0] = 0;
4920 AT.SB.MasterStop[0] = w;
4921 AT.SB.MasterBlockLock[0] = dummylock;
4922 for ( j = 1; j <= numberofblocks; j++ ) {
4923 AT.SB.MasterFill[j] = AT.SB.MasterStart[j] = w;
4924 AT.SB.BlockTerms[j] = 0;
4926 AT.SB.MasterStop[j] = w;
4927 AT.SB.MasterBlockLock[j] = dummylock;
4930 if ( w > S->sTop2 ) {
4932 MesPrint(
"!>Counting problem in IniSortBlocks");
4948int UpdateSortBlocks(
int numworkers)
4952 LONG totalsize, workersize, blocksize, numberofterms;
4954 int numberofblocks = NUMBEROFBLOCKSINSORT, numparts;
4957 if ( numworkers == 0 )
return(0);
4960 if ( numworkers > 2 ) {
4961 numparts = 2*numworkers - 2;
4962 numberofblocks = numberofblocks/2;
4965 numparts = numworkers;
4968 numparts = numworkers;
4971 totalsize = S->LargeSize + S->SmallEsize;
4972 workersize = totalsize / numparts;
4973 maxter = AM.MaxTer/
sizeof(WORD);
4974 blocksize = ( workersize - maxter )/numberofblocks;
4975 numberofterms = blocksize / maxter;
4976 if ( numberofterms < MINIMUMNUMBEROFTERMS ) {
4981 MesPrint(
"!>We have a problem with the size of the blocks in UpdateSortBlocks");
4991 if ( w == 0 ) w = S->sBuffer;
4992 for (
id = 1;
id <= numparts;
id++ ) {
4994 AT.SB.MasterFill[0] = AT.SB.MasterStart[0] = w;
4996 AT.SB.MasterStop[0] = w;
4997 for ( j = 1; j <= numberofblocks; j++ ) {
4998 AT.SB.MasterFill[j] = AT.SB.MasterStart[j] = w;
5000 AT.SB.MasterStop[j] = w;
5003 if ( w > S->sTop2 ) {
5005 MesPrint(
"!>Counting problem in UpdateSortBlocks");
5024void DefineSortBotTree(
void)
5028 if ( numberofworkers <= 2 )
return;
5029 n = numberofworkers*2-2;
5030 for ( i = numberofworkers+1, from = 1; i <= n; i++ ) {
5032 AT.SortBotIn1 = from++;
5033 AT.SortBotIn2 = from++;
5036 AT.SortBotIn1 = from++;
5037 AT.SortBotIn2 = from++;
5052WORD GetTerm2(PHEAD WORD *term)
5054 WORD *ttco, *tt, retval;
5060 POSITION where, eonfile = AS.OldOnFile[e-Expressions], bstart, bnext;
5064 switch ( e->status ) {
5065 case UNHIDELEXPRESSION:
5066 case UNHIDEGEXPRESSION:
5067 case DROPHLEXPRESSION:
5068 case DROPHGEXPRESSION:
5069 case HIDDENLEXPRESSION:
5070 case HIDDENGEXPRESSION:
5077 if ( AR.KeptInHold ) {
5078 retval = GetTerm(BHEAD term);
5081 SeekScratch(fi,&where);
5082 if ( AN.lastinindex < 0 ) {
5086 if ( ( n = TreatIndexEntry(BHEAD 0) ) <= 0 ) {
5088 where = bi[n].start;
5089 ADD2POS(where,eonfile);
5090 SetScratch(fi,&where);
5094 ttco = AR.CompressBuffer;
5098 AR.CompressPointer = ttco;
5099 retval = GetTerm(BHEAD term);
5102 else AN.lastinindex = n-1;
5109 bstart = bi[n].start;
5110 ADD2POS(bstart,eonfile);
5112 ADD2POS(bnext,eonfile);
5113 if ( ISLESSPOS(bstart,where) && ISLESSPOS(where,bnext) ) {
5114 retval = GetTerm(BHEAD term);
5117 for ( n++ ; n < b->indexfill; n++ ) {
5118 i = TreatIndexEntry(BHEAD n);
5123 ttco = AR.CompressBuffer;
5127 AR.CompressPointer = ttco;
5129 where = bi[n].start;
5130 ADD2POS(where,eonfile);
5131 SetScratch(fi,&(where));
5132 retval = GetTerm(BHEAD term);
5152int TreatIndexEntry(PHEAD LONG n)
5155 LONG numbra = b->indexfill - 1, i;
5163 if ( ( numbra - n ) <= numberofworkers )
return(0);
5169 DIFPOS(pos1,bi[numbra].next,bi[n].next);
5170 BASEPOSITION(average) = DIVPOS(pos1,(3*numberofworkers));
5171 DIFPOS(pos1,bi[n].next,bi[n].start);
5172 if ( ISLESSPOS(average,pos1) )
return(0);
5177 totterms = bi->termsinbracket;
5178 if ( totterms > 2*AC.ThreadBucketSize )
return(1);
5179 for ( i = 1; i < numbra-n; i++ ) {
5180 DIFPOS(pos1,bi[n+i].next,bi[n].start);
5181 if ( ISLESSPOS(average,pos1) )
return(i);
5182 totterms += bi->termsinbracket;
5183 if ( totterms > 2*AC.ThreadBucketSize )
return(i+1);
5196void SetHideFiles(
void) {
5198 ALLPRIVATES *B, *B0 = AB[0];
5199 for ( i = 1; i <= numberofworkers; i++ ) {
5201 AR.hidefile->handle = AR0.hidefile->handle;
5202 if ( AR.hidefile->handle < 0 ) {
5203 AR.hidefile->PObuffer = AR0.hidefile->PObuffer;
5204 AR.hidefile->POstop = AR0.hidefile->POstop;
5205 AR.hidefile->POfill = AR0.hidefile->POfill;
5206 AR.hidefile->POfull = AR0.hidefile->POfull;
5207 AR.hidefile->POsize = AR0.hidefile->POsize;
5208 AR.hidefile->POposition = AR0.hidefile->POposition;
5209 AR.hidefile->filesize = AR0.hidefile->filesize;
5212 AR.hidefile->PObuffer = AR.hidefile->wPObuffer;
5213 AR.hidefile->POstop = AR.hidefile->wPOstop;
5214 AR.hidefile->POfill = AR.hidefile->wPOfill;
5215 AR.hidefile->POfull = AR.hidefile->wPOfull;
5216 AR.hidefile->POsize = AR.hidefile->wPOsize;
5217 PUTZERO(AR.hidefile->POposition);
5230 for ( i = 0; i < AM.totalnumberofthreads; i++ ) {
5244 for ( j = 0; j < AM.totalnumberofthreads; j++ ) {
5246 AN.ncmod = AC.ncmod;
5247 if ( AN.cmod != 0 ) M_free(AN.cmod,
"AN.cmod");
5249 AN.cmod = (UWORD *)Malloc1(
sizeof(WORD)*n,
"AN.cmod");
5250 for ( i = 0; i < n; i++ ) AN.cmod[i] = AC.cmod[i];
5263 for ( j = 0; j < AM.totalnumberofthreads; j++ ) {
5265 if ( AN.cmod != 0 ) M_free(AN.cmod,
"AN.cmod");
5275void find_Horner_MCTS_expand_tree_threaded(
void) {
5277 while ((
id = GetAvailableThread() ) < 0)
5279 WakeupThread(
id,MCTSEXPANDTREE);
5287extern void optimize_expression_given_Horner_threaded(
void) {
5289 while ((
id = GetAvailableThread() ) < 0)
5291 WakeupThread(
id,OPTIMIZEEXPRESSION);
void AddArgs(PHEAD WORD *, WORD *, WORD *)
WORD * poly_ratfun_add(PHEAD WORD *, WORD *)
int poly_unfactorize_expression(EXPRESSIONS)
WORD PutOut(PHEAD WORD *, POSITION *, FILEHANDLE *, WORD)
LONG EndSort(PHEAD WORD *, int)
int Generator(PHEAD WORD *, WORD)
void LowerSortLevel(void)
int StoreTerm(PHEAD WORD *)
int poly_factorize_expression(EXPRESSIONS)
void WriteStats(POSITION *, WORD, WORD)
int NormalModulus(UWORD *, WORD *)
int FlushOut(POSITION *, FILEHANDLE *, int)
WORD Compare1(PHEAD WORD *, WORD *, WORD)
void optimize_expression_given_Horner()
BRACKETINDEX * indexbuffer
struct StOrEcAcHe * STORECACHE