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);
362 MesPrint(
"Cannot start %d threads",number);
374UBYTE *scratchname[] = { (UBYTE *)
"scratchsize",
375 (UBYTE *)
"scratchsize",
376 (UBYTE *)
"hidesize" };
403ALLPRIVATES *InitializeOneThread(
int identity)
405 WORD *t, *ScratchBuf;
406 int i, j, bsize, *bp;
407 LONG ScratchSize[3], IOsize;
411 wakeup[identity] = 0;
412 wakeuplocks[identity] = dummylock;
413 pthread_condattr_init(&(wakeupconditionattributes[identity]));
414 pthread_condattr_setpshared(&(wakeupconditionattributes[identity]),PTHREAD_PROCESS_PRIVATE);
415 wakeupconditions[identity] = dummywakeupcondition;
416 pthread_cond_init(&(wakeupconditions[identity]),&(wakeupconditionattributes[identity]));
417 wakeupmasterthread[identity] = 0;
418 wakeupmasterthreadlocks[identity] = dummylock;
419 wakeupmasterthreadconditions[identity] = dummywakeupcondition;
421 bsize =
sizeof(ALLPRIVATES);
422 bsize = (bsize+
sizeof(int)-1)/
sizeof(int);
423 B = (ALLPRIVATES *)Malloc1(
sizeof(
int)*bsize,
"B struct");
424 for ( bp = (
int *)B, j = 0; j < bsize; j++ ) *bp++ = 0;
443 if ( identity > 0 )
TimeCPU(0);
447 if ( identity > numberofworkers ) {
452 LONG length = AM.WorkSize*
sizeof(WORD)/8+AM.MaxTer*2;
453 AT.WorkSpace = (WORD *)Malloc1(length,
"WorkSpace");
454 AT.WorkTop = AT.WorkSpace + length/
sizeof(WORD);
455 AT.WorkPointer = AT.WorkSpace;
456 AT.identity = identity;
461 if ( AN.SoScratC == 0 ) {
462 AN.SoScratC = (UWORD *)Malloc1(2*(AM.MaxTal+2)*
sizeof(UWORD),
"Scratch in SortBot");
468 AT.comsym[1] = SYMBOL;
479 AT.comfun[0] = FUNHEAD+4;
480 AT.comfun[1] = FUNCTION;
481 AT.comfun[2] = FUNHEAD;
484 for ( i = 4; i <= FUNHEAD; i++ )
487 AT.comfun[FUNHEAD+1] = 1;
488 AT.comfun[FUNHEAD+2] = 1;
489 AT.comfun[FUNHEAD+3] = 3;
491 AT.comind[1] = INDEX;
499 AT.sizeprimelist = 0;
503 AR.CompareRoutine = (COMPAREDUMMY)(&
Compare1);
508 AR.wranfnpair1 = NPAIR1;
509 AR.wranfnpair2 = NPAIR2;
513 AN.SplitScratchSize = AN.InScratch = 0;
514 AN.SplitScratch1 = 0;
515 AN.SplitScratchSize1 = AN.InScratch1 = 0;
517 AN.FunSorts = (
SORTING **)Malloc1((AN.NumFunSorts+1)*
sizeof(
SORTING *),
"FunSort pointers");
518 for ( i = 0; i <= AN.NumFunSorts; i++ ) AN.FunSorts[i] = 0;
519 AN.FunSorts[0] = AT.S0 = AT.SS;
520 AN.idfunctionflag = 0;
525 if ( identity == 0 && AN.SoScratC == 0 ) {
526 AN.SoScratC = (UWORD *)Malloc1(2*(AM.MaxTal+2)*
sizeof(UWORD),
"Scratch in SortBot");
529 AR.CurDum = AM.IndDum;
530 for ( j = 0; j < 3; j++ ) {
531 if ( identity == 0 ) {
533 ScratchSize[j] = AM.HideSize;
536 ScratchSize[j] = AM.ScratSize;
538 if ( ScratchSize[j] < 10*AM.MaxTer ) ScratchSize[j] = 10 * AM.MaxTer;
546 if ( j == 1 ) ScratchSize[j] = AM.ThreadScratOutSize;
547 else ScratchSize[j] = AM.ThreadScratSize;
548 if ( ScratchSize[j] < 4*AM.MaxTer ) ScratchSize[j] = 4 * AM.MaxTer;
551 ScratchSize[j] = ( ScratchSize[j] + 255 ) / 256;
552 ScratchSize[j] = ScratchSize[j] * 256;
553 ScratchBuf = (WORD *)Malloc1(ScratchSize[j]*
sizeof(WORD),(
char *)(scratchname[j]));
554 AR.Fscr[j].POsize = ScratchSize[j] *
sizeof(WORD);
555 AR.Fscr[j].POfull = AR.Fscr[j].POfill = AR.Fscr[j].PObuffer = ScratchBuf;
556 AR.Fscr[j].POstop = AR.Fscr[j].PObuffer + ScratchSize[j];
557 PUTZERO(AR.Fscr[j].POposition);
558 AR.Fscr[j].pthreadslock = dummylock;
559 AR.Fscr[j].wPOsize = AR.Fscr[j].POsize;
560 AR.Fscr[j].wPObuffer = AR.Fscr[j].PObuffer;
561 AR.Fscr[j].wPOfill = AR.Fscr[j].POfill;
562 AR.Fscr[j].wPOfull = AR.Fscr[j].POfull;
563 AR.Fscr[j].wPOstop = AR.Fscr[j].POstop;
567 AR.Fscr[0].handle = -1;
568 AR.Fscr[1].handle = -1;
569 AR.Fscr[2].handle = -1;
570 AR.FoStage4[0].handle = -1;
571 AR.FoStage4[1].handle = -1;
572 IOsize = AM.S0->file.POsize;
574 AR.FoStage4[0].ziosize = IOsize;
575 AR.FoStage4[1].ziosize = IOsize;
576 AR.FoStage4[0].ziobuffer = 0;
577 AR.FoStage4[1].ziobuffer = 0;
579 AR.FoStage4[0].POsize = ((IOsize+
sizeof(WORD)-1)/
sizeof(WORD))*
sizeof(WORD);
580 AR.FoStage4[1].POsize = ((IOsize+
sizeof(WORD)-1)/
sizeof(WORD))*
sizeof(WORD);
582 AR.hidefile = &(AR.Fscr[2]);
583 AR.StoreData.Handle = -1;
584 AR.SortType = AC.SortType;
586 AN.IndDum = AM.IndDum;
588 if ( identity > 0 ) {
589 s = (UBYTE *)(FG.fname); i = 0;
590 while ( *s ) { s++; i++; }
591 s = (UBYTE *)Malloc1(
sizeof(
char)*(i+12),
"name for Fscr[0] file");
592 snprintf((
char *)s,i+12,
"%s.%d",FG.fname,identity);
593 s[i-3] =
's'; s[i-2] =
'c'; s[i-1] =
'0';
594 AR.Fscr[0].name = (
char *)s;
595 s = (UBYTE *)(FG.fname); i = 0;
596 while ( *s ) { s++; i++; }
597 s = (UBYTE *)Malloc1(
sizeof(
char)*(i+12),
"name for Fscr[1] file");
598 snprintf((
char *)s,i+12,
"%s.%d",FG.fname,identity);
599 s[i-3] =
's'; s[i-2] =
'c'; s[i-1] =
'1';
600 AR.Fscr[1].name = (
char *)s;
603 AR.CompressBuffer = (WORD *)Malloc1((AM.CompressSize+10)*
sizeof(WORD),
"compresssize");
604 AR.ComprTop = AR.CompressBuffer + AM.CompressSize;
605 AR.CompareRoutine = (COMPAREDUMMY)(&
Compare1);
610 AT.WorkSpace = (WORD *)Malloc1(AM.WorkSize*
sizeof(WORD),
"WorkSpace");
611 AT.WorkTop = AT.WorkSpace + AM.WorkSize;
612 AT.WorkPointer = AT.WorkSpace;
614 AT.Nest = (
NESTING)Malloc1((LONG)
sizeof(
struct NeStInG)*AM.maxFlevels,
"functionlevels");
615 AT.NestStop = AT.Nest + AM.maxFlevels;
616 AT.NestPoin = AT.Nest;
618 AT.WildMask = (WORD *)Malloc1((LONG)AM.MaxWildcards*
sizeof(WORD),
"maxwildcards");
620 LOCK(availabilitylock);
625 UNLOCK(availabilitylock);
627 AT.RepCount = (
int *)Malloc1((LONG)((AM.RepMax+3)*
sizeof(
int)),
"repeat buffers");
628 AN.RepPoint = AT.RepCount;
632 AT.RepTop = AT.RepCount + AM.RepMax;
634 AT.WildArgTaken = (WORD *)Malloc1((LONG)AC.WildcardBufferSize*
sizeof(WORD)/2
635 ,
"argument list names");
636 AT.WildcardBufferSize = AC.WildcardBufferSize;
637 AT.previousEfactor = 0;
639 AT.identity = identity;
640 AT.LoadBalancing = 0;
646 if ( AT.WorkSpace == 0 ||
650 AT.WildArgTaken == 0 )
goto OnError;
655 AT.comsym[1] = SYMBOL;
666 AT.comfun[0] = FUNHEAD+4;
667 AT.comfun[1] = FUNCTION;
668 AT.comfun[2] = FUNHEAD;
671 for ( i = 4; i <= FUNHEAD; i++ )
674 AT.comfun[FUNHEAD+1] = 1;
675 AT.comfun[FUNHEAD+2] = 1;
676 AT.comfun[FUNHEAD+3] = 3;
678 AT.comind[1] = INDEX;
684 AT.locwildvalue[0] = SUBEXPRESSION;
685 AT.locwildvalue[1] = SUBEXPSIZE;
686 for ( i = 2; i < SUBEXPSIZE; i++ ) AT.locwildvalue[i] = 0;
687 AT.mulpat[0] = TYPEMULT;
688 AT.mulpat[1] = SUBEXPSIZE+3;
690 AT.mulpat[3] = SUBEXPRESSION;
691 AT.mulpat[4] = SUBEXPSIZE;
694 for ( i = 7; i < SUBEXPSIZE+5; i++ ) AT.mulpat[i] = 0;
695 AT.proexp[0] = SUBEXPSIZE+4;
696 AT.proexp[1] = EXPRESSION;
697 AT.proexp[2] = SUBEXPSIZE;
700 for ( i = 5; i < SUBEXPSIZE+1; i++ ) AT.proexp[i] = 0;
701 AT.proexp[SUBEXPSIZE+1] = 1;
702 AT.proexp[SUBEXPSIZE+2] = 1;
703 AT.proexp[SUBEXPSIZE+3] = 3;
704 AT.proexp[SUBEXPSIZE+4] = 0;
705 AT.dummysubexp[0] = SUBEXPRESSION;
706 AT.dummysubexp[1] = SUBEXPSIZE+4;
707 for ( i = 2; i < SUBEXPSIZE; i++ ) AT.dummysubexp[i] = 0;
708 AT.dummysubexp[SUBEXPSIZE] = WILDDUMMY;
709 AT.dummysubexp[SUBEXPSIZE+1] = 4;
710 AT.dummysubexp[SUBEXPSIZE+2] = 0;
711 AT.dummysubexp[SUBEXPSIZE+3] = 0;
713 AT.MinVecArg[0] = 7+ARGHEAD;
714 AT.MinVecArg[ARGHEAD] = 7;
715 AT.MinVecArg[1+ARGHEAD] = INDEX;
716 AT.MinVecArg[2+ARGHEAD] = 3;
717 AT.MinVecArg[3+ARGHEAD] = 0;
718 AT.MinVecArg[4+ARGHEAD] = 1;
719 AT.MinVecArg[5+ARGHEAD] = 1;
720 AT.MinVecArg[6+ARGHEAD] = -3;
722 *t++ = 4+ARGHEAD+FUNHEAD;
723 for ( i = 1; i < ARGHEAD; i++ ) *t++ = 0;
727 for ( i = 2; i < FUNHEAD; i++ ) *t++ = 0;
728 *t++ = 1; *t++ = 1; *t++ = 3;
731 AT.sizeprimelist = 0;
733 AT.nfac = AT.nBer = 0;
738 AR.wranfnpair1 = NPAIR1;
739 AR.wranfnpair2 = NPAIR2;
742 AT.NormData = Malloc1(
sizeof(*(AT.NormData)),
"NormData thread pointers");
744 AT.NormData[0] = AllocNormData();
748 AN.SplitScratchSize = AN.InScratch = 0;
749 AN.SplitScratch1 = 0;
750 AN.SplitScratchSize1 = AN.InScratch1 = 0;
755 if ( identity == 0 ) {
763 AT.S0 = AllocSort(AM.S0->LargeSize*
sizeof(WORD)/numberofworkers
764 ,AM.S0->SmallSize*
sizeof(WORD)/numberofworkers
765 ,AM.S0->SmallEsize*
sizeof(WORD)/numberofworkers
769 ,AM.S0->MaxFpatches/numberofworkers
773 AR.CompressPointer = AR.CompressBuffer;
777 AT.StoreCache = AT.StoreCacheAlloc = 0;
778 if ( AM.NumStoreCaches > 0 ) {
781 size =
sizeof(
struct StOrEcAcHe)+AM.SizeStoreCache;
782 size = ((size-1)/
sizeof(
size_t)+1)*
sizeof(
size_t);
783 AT.StoreCacheAlloc = (
STORECACHE)Malloc1(size*AM.NumStoreCaches,
"StoreCaches");
784 sa = AT.StoreCache = AT.StoreCacheAlloc;
785 for ( i = 0; i < AM.NumStoreCaches; i++ ) {
787 if ( i == AM.NumStoreCaches-1 ) {
793 SETBASEPOSITION(sa->position,-1);
794 SETBASEPOSITION(sa->toppos,-1);
802 MLOCK(ErrorMessageLock);
803 MesPrint(
"Error initializing thread %d",identity);
804 MUNLOCK(ErrorMessageLock);
823void FinalizeOneThread(
int identity)
825 timerinfo[identity] =
TimeCPU(1);
838void ClearAllThreads(
void)
842 for ( i = 1; i <= numberofworkers; i++ ) {
843 WakeupThread(i,CLEARCLOCK);
846 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
847 WakeupThread(i,CLEARCLOCK);
862void TerminateAllThreads(
void)
865 for ( i = 1; i <= numberofworkers; i++ ) {
867 WakeupThread(i,TERMINATETHREAD);
870 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
871 WakeupThread(i,TERMINATETHREAD);
874 for ( i = 1; i <= numberofworkers; i++ ) {
875 pthread_join(threadpointers[i],NULL);
878 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
879 pthread_join(threadpointers[i],NULL);
913int MakeThreadBuckets(
int number,
int par)
916 LONG sizethreadbuckets;
922 sizethreadbuckets = (AC.ThreadBucketSize*MAXTER)/4;
927 if ( AM.MaxTer/
sizeof(WORD) > MAXTER ) {
928 scale += log(((
float)AM.MaxTer/
sizeof(WORD))/MAXTER);
930 sizethreadbuckets = (LONG)((
float)sizethreadbuckets*scale);
934 sizethreadbuckets = MaX((ULONG)sizethreadbuckets, BUCKETMINTERMS*AM.MaxTer/
sizeof(WORD));
937 numthreadbuckets = 2*(number-1);
938 threadbuckets = (THREADBUCKET **)Malloc1(numthreadbuckets*
sizeof(THREADBUCKET *),
"threadbuckets");
939 freebuckets = (THREADBUCKET **)Malloc1(numthreadbuckets*
sizeof(THREADBUCKET *),
"freebuckets");
942 if ( sizethreadbuckets <= threadbuckets[0]->threadbuffersize )
return(0);
943 for ( i = 0; i < numthreadbuckets; i++ ) {
944 thr = threadbuckets[i];
945 M_free(thr->deferbuffer,
"deferbuffer");
946 M_free(thr->threadbuffer,
"threadbuffer");
947 M_free(thr->compressbuffer,
"compressbuffer");
951 for ( i = 0; i < numthreadbuckets; i++ ) {
952 threadbuckets[i] = (THREADBUCKET *)Malloc1(
sizeof(THREADBUCKET),
"threadbuckets");
953 threadbuckets[i]->lock = dummylock;
956 for ( i = 0; i < numthreadbuckets; i++ ) {
957 thr = threadbuckets[i];
958 thr->threadbuffersize = sizethreadbuckets;
961 thr->compressbuffersize = AM.MaxTer/
sizeof(WORD);
962 thr->free = BUCKETFREE;
963 thr->deferbuffer = (
POSITION *)Malloc1((AC.ThreadBucketSize+1)*
sizeof(
POSITION),
"deferbuffer");
964 thr->threadbuffer = (WORD *)Malloc1(sizethreadbuckets*
sizeof(WORD),
"threadbuffer");
965 thr->compressbuffer = (WORD *)Malloc1(thr->compressbuffersize*
sizeof(WORD),
"compressbuffer");
966 thr->busy = BUCKETPREPARINGTERM;
967 thr->usenum = thr->totnum = 0;
968 thr->type = BUCKETDOINGTERMS;
984int GetTimerInfo(LONG** ti,LONG** sti)
989 return AM.totalnumberofthreads*2;
991 return AM.totalnumberofthreads;
1005void WriteTimerInfo(LONG* ti,LONG* sti)
1009 int max = AM.totalnumberofthreads*2;
1011 int max = AM.totalnumberofthreads;
1013 for ( i=0; i<max; ++i ) {
1014 timerinfo[i] = ti[i];
1015 sumtimerinfo[i] = sti[i];
1028LONG GetWorkerTimes(
void)
1032 for ( i = 1; i <= numberofworkers; i++ ) retval += timerinfo[i] + sumtimerinfo[i];
1034 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ )
1035 retval += timerinfo[i] + sumtimerinfo[i];
1050int UpdateOneThread(
int identity)
1052 ALLPRIVATES *B = AB[identity], *B0 = AB[0];
1053 AR.GetFile = AR0.GetFile;
1054 AR.KeptInHold = AR0.KeptInHold;
1055 AR.CurExpr = AR0.CurExpr;
1056 AR.SortType = AC.SortType;
1057 if ( AT.WildcardBufferSize < AC.WildcardBufferSize ) {
1058 M_free(AT.WildArgTaken,
"argument list names");
1059 AT.WildcardBufferSize = AC.WildcardBufferSize;
1060 AT.WildArgTaken = (WORD *)Malloc1((LONG)AC.WildcardBufferSize*
sizeof(WORD)/2
1061 ,
"argument list names");
1062 if ( AT.WildArgTaken == 0 )
return(-1);
1084int LoadOneThread(
int from,
int identity, THREADBUCKET *thr,
int par)
1087 ALLPRIVATES *B = AB[identity], *B0 = AB[from];
1089 AR.DefPosition = AR0.DefPosition;
1090 AR.NoCompress = AR0.NoCompress;
1091 AR.gzipCompress = AR0.gzipCompress;
1092 AR.BracketOn = AR0.BracketOn;
1093 AR.CurDum = AR0.CurDum;
1094 AR.DeferFlag = AR0.DeferFlag;
1096 AR.sLevel = AR0.sLevel;
1097 AR.Stage4Name = AR0.Stage4Name;
1098 AR.GetOneFile = AR0.GetOneFile;
1099 AR.PolyFun = AR0.PolyFun;
1100 AR.PolyFunInv = AR0.PolyFunInv;
1101 AR.PolyFunType = AR0.PolyFunType;
1102 AR.PolyFunExp = AR0.PolyFunExp;
1103 AR.PolyFunVar = AR0.PolyFunVar;
1104 AR.PolyFunPow = AR0.PolyFunPow;
1105 AR.Eside = AR0.Eside;
1106 AR.Cnumlhs = AR0.Cnumlhs;
1118 t1 = AR.CompressBuffer; t2 = AR0.CompressBuffer;
1119 while ( t2 < AR0.CompressPointer ) *t1++ = *t2++;
1120 AR.CompressPointer = t1;
1124 AR.CompressPointer = AR.CompressBuffer;
1126 if ( AR.DeferFlag ) {
1127 if ( AR.infile->handle < 0 ) {
1128 AR.infile->POfill = AR0.infile->POfill;
1135 AR.infile->POfull = AR.infile->POfill = AR.infile->PObuffer;
1139 AN.threadbuck = thr;
1140 AN.ninterms = thr->firstterm;
1142 else if ( par == 1 ) {
1144 t1 = thr->threadbuffer; tstop = t1 + *t1;
1145 t2 = AT.WorkPointer;
1146 while ( t1 < tstop ) *t2++ = *t1++;
1147 AN.ninterms = thr->firstterm;
1150 AN.ncmod = AC.ncmod;
1151 AT.BrackBuf = AT0.BrackBuf;
1152 AT.bracketindexflag = AT0.bracketindexflag;
1180int BalanceRunThread(PHEAD
int identity, WORD *term, WORD level)
1187 LoadOneThread(AT.identity,identity,0,2);
1193 BB->R.level = level;
1194 BB->T.TMbuff = AT.TMbuff;
1195 ti = AT.RepCount; tti = BB->T.RepCount;
1196 i = AN.RepPoint - AT.RepCount;
1197 BB->N.RepPoint = BB->T.RepCount + i;
1198 for ( ; i >= 0; i-- ) tti[i] = ti[i];
1200 t = term; i = *term;
1201 tt = BB->T.WorkSpace;
1203 BB->T.WorkPointer = tt;
1205 WakeupThread(identity,HIGHERLEVELGENERATION);
1218void SetWorkerFiles(
void)
1221 ALLPRIVATES *B, *B0 = AB[0];
1222 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
1224 AR.infile = &(AR.Fscr[0]);
1225 AR.outfile = &(AR.Fscr[1]);
1226 AR.hidefile = &(AR.Fscr[2]);
1227 AR.infile->handle = AR0.infile->handle;
1228 AR.hidefile->handle = AR0.hidefile->handle;
1229 if ( AR.infile->handle < 0 ) {
1230 AR.infile->PObuffer = AR0.infile->PObuffer;
1231 AR.infile->POstop = AR0.infile->POstop;
1232 AR.infile->POfill = AR0.infile->POfill;
1233 AR.infile->POfull = AR0.infile->POfull;
1234 AR.infile->POsize = AR0.infile->POsize;
1235 AR.InInBuf = AR0.InInBuf;
1236 AR.infile->POposition = AR0.infile->POposition;
1237 AR.infile->filesize = AR0.infile->filesize;
1240 AR.infile->PObuffer = AR.infile->wPObuffer;
1241 AR.infile->POstop = AR.infile->wPOstop;
1242 AR.infile->POfill = AR.infile->wPOfill;
1243 AR.infile->POfull = AR.infile->wPOfull;
1244 AR.infile->POsize = AR.infile->wPOsize;
1246 PUTZERO(AR.infile->POposition);
1254 AR.outfile->PObuffer = AR.outfile->wPObuffer;
1255 AR.outfile->POstop = AR.outfile->wPOstop;
1256 AR.outfile->POfill = AR.outfile->wPOfill;
1257 AR.outfile->POfull = AR.outfile->wPOfull;
1258 AR.outfile->POsize = AR.outfile->wPOsize;
1259 PUTZERO(AR.outfile->POposition);
1261 if ( AR.hidefile->handle < 0 ) {
1262 AR.hidefile->PObuffer = AR0.hidefile->PObuffer;
1263 AR.hidefile->POstop = AR0.hidefile->POstop;
1264 AR.hidefile->POfill = AR0.hidefile->POfill;
1265 AR.hidefile->POfull = AR0.hidefile->POfull;
1266 AR.hidefile->POsize = AR0.hidefile->POsize;
1267 AR.InHiBuf = AR0.InHiBuf;
1268 AR.hidefile->POposition = AR0.hidefile->POposition;
1269 AR.hidefile->filesize = AR0.hidefile->filesize;
1272 AR.hidefile->PObuffer = AR.hidefile->wPObuffer;
1273 AR.hidefile->POstop = AR.hidefile->wPOstop;
1274 AR.hidefile->POfill = AR.hidefile->wPOfill;
1275 AR.hidefile->POfull = AR.hidefile->wPOfull;
1276 AR.hidefile->POsize = AR.hidefile->wPOsize;
1278 PUTZERO(AR.hidefile->POposition);
1281 if ( AR0.StoreData.dirtyflag ) {
1282 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
1284 AR.StoreData = AR0.StoreData;
1300void *RunThread(
void *dummy)
1302 WORD *term, *ttin, *tt, *ttco, *oldwork;
1303 int identity, wakeupsignal, identityretv, i, tobereleased, errorcode;
1309 identity = SetIdentity(&identityretv);
1310 threadpointers[identity] = pthread_self();
1311 B = InitializeOneThread(identity);
1312 while ( ( wakeupsignal = ThreadWait(identity) ) > 0 ) {
1313 switch ( wakeupsignal ) {
1317 case STARTNEWEXPRESSION:
1322 if ( UpdateOneThread(identity) ) {
1323 MLOCK(ErrorMessageLock);
1324 MesPrint(
"Update error in starting expression in thread %d in module %d",identity,AC.CModule);
1325 MUNLOCK(ErrorMessageLock);
1328 AR.DeferFlag = AC.ComDefer;
1329 AR.sLevel = AS.sLevel;
1330 AR.MaxDum = AM.IndDum;
1331 AR.expchanged = AB[0]->R.expchanged;
1332 AR.expflags = AB[0]->R.expflags;
1333 AR.PolyFun = AB[0]->R.PolyFun;
1334 AR.PolyFunInv = AB[0]->R.PolyFunInv;
1335 AR.PolyFunType = AB[0]->R.PolyFunType;
1336 AR.PolyFunExp = AB[0]->R.PolyFunExp;
1337 AR.PolyFunVar = AB[0]->R.PolyFunVar;
1338 AR.PolyFunPow = AB[0]->R.PolyFunPow;
1348 case LOWESTLEVELGENERATION:
1350 if ( AC.InnerTest ) {
1351 if ( StrCmp(AC.TestValue,(UBYTE *)INNERTEST) == 0 ) {
1352 MesPrint(
"Testing(Worker%d): value = %s",AT.identity,AC.TestValue);
1356 e = Expressions + AR.CurExpr;
1357 thr = AN.threadbuck;
1358 ppdef = thr->deferbuffer;
1359 ttin = thr->threadbuffer;
1360 ttco = thr->compressbuffer;
1361 term = AT.WorkPointer;
1364 AN.inputnumber = thr->firstterm;
1365 AN.ninterms = thr->firstterm;
1368 tt = term; i = *ttin;
1370 AT.WorkPointer = tt;
1371 if ( AR.DeferFlag ) {
1372 tt = AR.CompressBuffer; i = *ttco;
1374 AR.CompressPointer = tt;
1375 AR.DefPosition = ppdef[0]; ppdef++;
1377 if ( thr->free == BUCKETTERMINATED ) {
1385 if ( thr->usenum == thr->totnum ) {
1386 thr->free = BUCKETCOMINGFREE;
1389 thr->free = BUCKETRELEASED;
1399 thr->busy = BUCKETDOINGTERM;
1407 AN.RepPoint = AT.RepCount + 1;
1409 if ( ( e->vflags & ISFACTORIZED ) != 0 && term[1] == HAAKJE ) {
1413 if ( AR.DeferFlag ) {
1414 AR.CurDum = AN.IndDum = Expressions[AR.CurExpr].numdummies + AM.IndDum;
1417 AN.IndDum = AM.IndDum;
1418 AR.CurDum = ReNumber(BHEAD term);
1420 if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
1422 if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1423 else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1425 else if ( AC.PolyRatFunChanged ) PolyFunDirty(BHEAD term);
1426 if ( ( AP.PreDebug & THREADSDEBUG ) != 0 ) {
1427 MLOCK(ErrorMessageLock);
1428 MesPrint(
"Thread %w executing term:");
1429 PrintTerm(term,
"LLG");
1430 MUNLOCK(ErrorMessageLock);
1432 if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
1433 && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1434 PolyFunClean(BHEAD term);
1438 MLOCK(ErrorMessageLock);
1439 MesPrint(
"Error in processing one term in thread %d in module %d",identity,AC.CModule);
1440 MUNLOCK(ErrorMessageLock);
1447 thr->busy = BUCKETPREPARINGTERM;
1455 if ( thr->free == BUCKETTERMINATED ) {
1456 if ( thr->usenum == thr->totnum ) {
1457 thr->free = BUCKETCOMINGFREE;
1460 thr->free = BUCKETRELEASED;
1464 if ( tobereleased )
goto bucketstolen;
1466 thr->free = BUCKETCOMINGFREE;
1470 thr->busy = BUCKETTOBERELEASED;
1477 AT.WorkPointer = term;
1485 LOCK(AT.SB.MasterBlockLock[1]);
1488 case FINISHEXPRESSION:
1496 LOCK(AT.SB.MasterBlockLock[1]);
1497 ThreadClaimedBlock(identity);
1503 case FINISHEXPRESSION2:
1508 if ( AC.ThreadSortFileSynch ) {
1509 if ( AT.S0->file.handle >= 0 ) {
1510 SynchFile(AT.S0->file.handle);
1513 AT.SB.FillBlock = 1;
1514 AT.SB.MasterFill[1] = AT.SB.MasterStart[1];
1515 errorcode =
EndSort(BHEAD AT.S0->sBuffer,0);
1516 UNLOCK(AT.SB.MasterBlockLock[AT.SB.FillBlock]);
1519 MLOCK(ErrorMessageLock);
1520 MesPrint(
"Error terminating sort in thread %d in module %d",identity,AC.CModule);
1521 MUNLOCK(ErrorMessageLock);
1529 case CLEANUPEXPRESSION:
1533 if ( AR.outfile->handle >= 0 ) {
1534 CloseFile(AR.outfile->handle);
1535 AR.outfile->handle = -1;
1536 remove(AR.outfile->name);
1537 AR.outfile->POfill = AR.outfile->POfull = AR.outfile->PObuffer;
1538 PUTZERO(AR.outfile->POposition);
1539 PUTZERO(AR.outfile->filesize);
1542 AR.outfile->POfill = AR.outfile->POfull = AR.outfile->PObuffer;
1543 PUTZERO(AR.outfile->POposition);
1544 PUTZERO(AR.outfile->filesize);
1547 CBUF *C = cbuf+AT.ebufnum;
1549 if ( C->numrhs > 0 || C->numlhs > 0 ) {
1551 w = C->
rhs; ii = C->numrhs;
1552 do { *w++ = 0; }
while ( --ii > 0 );
1555 w = C->
lhs; ii = C->numlhs;
1556 do { *w++ = 0; }
while ( --ii > 0 );
1558 C->numlhs = C->numrhs = 0;
1559 ClearTree(AT.ebufnum);
1568 case HIGHERLEVELGENERATION:
1573 term = AT.WorkSpace; AT.WorkPointer = term + *term;
1576 MLOCK(ErrorMessageLock);
1577 MesPrint(
"Error in load balancing one term at level %d in thread %d in module %d",AR.level,AT.identity,AC.CModule);
1578 MUNLOCK(ErrorMessageLock);
1581 AT.WorkPointer = term;
1587 case STARTNEWMODULE:
1597 case TERMINATETHREAD:
1615 case DOONEEXPRESSION: {
1620 WORD oldBracketOn = AR.BracketOn;
1621 WORD *oldBrackBuf = AT.BrackBuf;
1622 WORD oldbracketindexflag = AT.bracketindexflag;
1623 WORD fromspectator = 0;
1624 e = Expressions + AR.exprtodo;
1627 AR.SortType = AC.SortType;
1629 if ( ( e->vflags & ISFACTORIZED ) != 0 ) {
1631 AT.BrackBuf = AM.BracketFactors;
1632 AT.bracketindexflag = 1;
1635 position = AS.OldOnFile[i];
1636 if ( e->status == HIDDENLEXPRESSION || e->status == HIDDENGEXPRESSION
1637 || e->status == UNHIDELEXPRESSION || e->status == UNHIDEGEXPRESSION ) {
1638 AR.GetFile = 2; fi = AR.hidefile;
1641 AR.GetFile = 0; fi = AR.infile;
1649 SetScratch(fi,&position);
1650 term = oldwork = AT.WorkPointer;
1651 AR.CompressPointer = AR.CompressBuffer;
1652 AR.CompressPointer[0] = 0;
1654 if ( GetTerm(BHEAD term) <= 0 ) {
1655 MLOCK(ErrorMessageLock);
1656 MesPrint(
"Expression %d has problems in scratchfile (t)",i);
1657 MUNLOCK(ErrorMessageLock);
1660 if ( AT.bracketindexflag > 0 ) OpenBracketIndex(i);
1662 if ( term[5] < 0 ) {
1663 fromspectator = -term[5];
1664 PUTZERO(AM.SpectatorFiles[fromspectator-1].readpos);
1665 term[5] = AC.cbufnum;
1667 PUTZERO(outposition);
1669 fout->POfill = fout->POfull = fout->PObuffer;
1670 fout->POposition = outposition;
1671 if ( fout->
handle >= 0 ) {
1672 fout->POposition = outposition;
1684 if (
PutOut(BHEAD term,&outposition,fout,0) < 0 )
goto ProcErr;
1686 AR.DeferFlag = AC.ComDefer;
1688 AR.sLevel = AB[0]->R.sLevel;
1689 term = AT.WorkPointer;
1691 AR.MaxDum = AM.IndDum;
1693 if ( fromspectator ) {
1694 while ( GetFromSpectator(term,fromspectator-1) ) {
1695 AT.WorkPointer = term + *term;
1696 AN.RepPoint = AT.RepCount + 1;
1697 AN.IndDum = AM.IndDum;
1698 AR.CurDum = ReNumber(BHEAD term);
1699 if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
1701 if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1702 else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1704 else if ( AC.PolyRatFunChanged ) PolyFunDirty(BHEAD term);
1705 if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
1706 && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1707 PolyFunClean(BHEAD term);
1715 while ( GetTerm(BHEAD term) ) {
1716 SeekScratch(fi,&position);
1717 AN.ninterms++; dd = AN.deferskipped;
1718 if ( ( e->vflags & ISFACTORIZED ) != 0 && term[1] == HAAKJE ) {
1722 if ( AC.CollectFun && *term <= (AM.MaxTer/(2*(LONG)
sizeof(WORD))) ) {
1723 if ( GetMoreTerms(term) < 0 ) {
1726 SeekScratch(fi,&position);
1728 AT.WorkPointer = term + *term;
1729 AN.RepPoint = AT.RepCount + 1;
1730 if ( AR.DeferFlag ) {
1731 AR.CurDum = AN.IndDum = Expressions[AR.exprtodo].numdummies;
1734 AN.IndDum = AM.IndDum;
1735 AR.CurDum = ReNumber(BHEAD term);
1737 if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
1739 if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1740 else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1742 else if ( AC.PolyRatFunChanged ) PolyFunDirty(BHEAD term);
1743 if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
1744 && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1745 PolyFunClean(BHEAD term);
1752 SetScratch(fi,&position);
1753 if ( fi == AR.hidefile ) {
1754 AR.InHiBuf = (fi->POfull-fi->PObuffer)
1755 -DIFBASE(position,fi->POposition)/
sizeof(WORD);
1758 AR.InInBuf = (fi->POfull-fi->PObuffer)
1759 -DIFBASE(position,fi->POposition)/
sizeof(WORD);
1764 if (
EndSort(BHEAD AT.S0->sBuffer,0) < 0 )
goto ProcErr;
1765 e->numdummies = AR.MaxDum - AM.IndDum;
1766 AR.BracketOn = oldBracketOn;
1767 AT.BrackBuf = oldBrackBuf;
1768 if ( ( e->vflags & TOBEFACTORED ) != 0 )
1770 else if ( ( ( e->vflags & TOBEUNFACTORED ) != 0 )
1771 && ( ( e->vflags & ISFACTORIZED ) != 0 ) )
1773 if ( AT.S0->TermsLeft ) e->vflags &= ~ISZERO;
1774 else e->vflags |= ISZERO;
1775 if ( AR.expchanged == 0 ) e->vflags |= ISUNMODIFIED;
1776 if ( AT.S0->TermsLeft ) AR.expflags |= ISZERO;
1777 if ( AR.expchanged ) AR.expflags |= ISUNMODIFIED;
1779 AT.bracketindexflag = oldbracketindexflag;
1784 SeekScratch(fout,&outposition);
1785 LOCK(AS.outputslock);
1786 oldoutfile = AB[0]->R.outfile;
1787 if ( e->status == INTOHIDELEXPRESSION || e->status == INTOHIDEGEXPRESSION ) {
1788 AB[0]->R.outfile = AB[0]->R.hidefile;
1790 SeekScratch(AB[0]->R.outfile,&position);
1791 e->onfile = position;
1792 if ( CopyExpression(fout,AB[0]->R.outfile) < 0 ) {
1793 AB[0]->R.outfile = oldoutfile;
1794 UNLOCK(AS.outputslock);
1795 MLOCK(ErrorMessageLock);
1796 MesPrint(
"Error copying output of 'InParallel' expression to master. Thread: %d",identity);
1797 MUNLOCK(ErrorMessageLock);
1800 AB[0]->R.outfile = oldoutfile;
1801 AB[0]->R.expflags = AR.expflags;
1802 UNLOCK(AS.outputslock);
1804 if ( fout->
handle >= 0 ) {
1808 PUTZERO(fout->POposition);
1809 PUTZERO(fout->filesize);
1810 fout->POfill = fout->POfull = fout->PObuffer;
1814 AT.WorkPointer = oldwork;
1838 e = Expressions + AR.CurExpr;
1839 binfo = e->bracketinfo;
1840 thr = AN.threadbuck;
1842 if ( AR.GetFile == 2 ) fi = AR.hidefile;
1843 else fi = AR.infile;
1845 ADD2POS(where,AS.OldOnFile[AR.CurExpr]);
1846 SetScratch(fi,&(where));
1847 stoppos = binfo->
indexbuffer[thr->lastbracket].next;
1848 ADD2POS(stoppos,AS.OldOnFile[AR.CurExpr]);
1849 AN.ninterms = thr->firstterm;
1854 ttco = AR.CompressBuffer;
1858 AR.CompressPointer = ttco;
1859 term = AT.WorkPointer;
1860 while ( GetTerm(BHEAD term) ) {
1861 SeekScratch(fi,&where);
1862 AT.WorkPointer = term + *term;
1863 AN.IndDum = AM.IndDum;
1864 AR.CurDum = ReNumber(BHEAD term);
1865 if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
1867 if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1868 else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1870 else if ( AC.PolyRatFunChanged ) PolyFunDirty(BHEAD term);
1871 if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
1872 && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1873 PolyFunClean(BHEAD term);
1875 if ( ( AP.PreDebug & THREADSDEBUG ) != 0 ) {
1876 MLOCK(ErrorMessageLock);
1877 MesPrint(
"Thread %w executing term:");
1878 PrintTerm(term,
"DoBrackets");
1879 MUNLOCK(ErrorMessageLock);
1881 AT.WorkPointer = term + *term;
1884 MLOCK(ErrorMessageLock);
1885 MesPrint(
"Error in processing one term in thread %d in module %d",identity,AC.CModule);
1886 MUNLOCK(ErrorMessageLock);
1890 SetScratch(fi,&(where));
1891 if ( ISGEPOS(where,stoppos) )
break;
1893 AT.WorkPointer = term;
1894 thr->free = BUCKETCOMINGFREE;
1905 sumtimerinfo[identity] +=
TimeCPU(1);
1906 timerinfo[identity] =
TimeCPU(0);
1913 case MCTSEXPANDTREE:
1914 AT.optimtimes = AB[0]->T.optimtimes;
1915 find_Horner_MCTS_expand_tree();
1921 case OPTIMIZEEXPRESSION:
1928 MLOCK(ErrorMessageLock);
1929 MesPrint(
"Illegal wakeup signal %d for thread %d",wakeupsignal,identity);
1930 MUNLOCK(ErrorMessageLock);
1936 timerinfo[identity] =
TimeCPU(1);
1944 flint_final_cleanup_thread();
1946 FinalizeOneThread(identity);
1966void *RunSortBot(
void *dummy)
1968 int identity, wakeupsignal, identityretv;
1969 ALLPRIVATES *B, *BB;
1971 identity = SetIdentity(&identityretv);
1972 threadpointers[identity] = pthread_self();
1973 B = InitializeOneThread(identity);
1974 while ( ( wakeupsignal = SortBotWait(identity) ) > 0 ) {
1975 switch ( wakeupsignal ) {
1980 AR.CompressBuffer = AB[0]->R.CompressBuffer;
1981 AR.ComprTop = AB[0]->R.ComprTop;
1982 AR.CompressPointer = AB[0]->R.CompressPointer;
1983 AR.CurExpr = AB[0]->R.CurExpr;
1984 AR.PolyFun = AB[0]->R.PolyFun;
1985 AR.PolyFunInv = AB[0]->R.PolyFunInv;
1986 AR.PolyFunType = AB[0]->R.PolyFunType;
1987 AR.PolyFunExp = AB[0]->R.PolyFunExp;
1988 AR.PolyFunVar = AB[0]->R.PolyFunVar;
1989 AR.PolyFunPow = AB[0]->R.PolyFunPow;
1990 AR.SortType = AC.SortType;
1991 if ( AR.PolyFun == 0 ) { AT.SS->PolyFlag = 0; }
1992 else if ( AR.PolyFunType == 1 ) { AT.SS->PolyFlag = 1; }
1993 else if ( AR.PolyFunType == 2 ) {
1994 if ( AR.PolyFunExp == 2
1995 || AR.PolyFunExp == 3 ) AT.SS->PolyFlag = 1;
1996 else AT.SS->PolyFlag = 2;
1998 AT.SS->PolyWise = 0;
1999 AN.ncmod = AC.ncmod;
2000 LOCK(AT.SB.MasterBlockLock[1]);
2001 BB = AB[AT.SortBotIn1];
2002 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
2003 BB = AB[AT.SortBotIn2];
2004 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
2005 AT.SB.FillBlock = 1;
2006 AT.SB.MasterFill[1] = AT.SB.MasterStart[1];
2007 SETBASEPOSITION(AN.theposition,0);
2009 AT.SS->verbComparisons = 0;
2011 AT.SS->verbMaxTermSize = 0;
2024 case TERMINATETHREAD:
2034 sumtimerinfo[identity] +=
TimeCPU(1);
2035 timerinfo[identity] =
TimeCPU(0);
2042 MLOCK(ErrorMessageLock);
2043 MesPrint(
"Illegal wakeup signal %d for thread %d",wakeupsignal,identity);
2044 MUNLOCK(ErrorMessageLock);
2055 flint_final_cleanup_thread();
2057 FinalizeOneThread(identity);
2078void IAmAvailable(
int identity)
2081 LOCK(availabilitylock);
2082 top = topofavailables;
2083 listofavailables[topofavailables++] = identity;
2085 UNLOCK(availabilitylock);
2086 LOCK(wakeupmasterlock);
2087 wakeupmaster = identity;
2088 pthread_cond_signal(&wakeupmasterconditions);
2089 UNLOCK(wakeupmasterlock);
2092 UNLOCK(availabilitylock);
2108int GetAvailableThread(
void)
2111 LOCK(availabilitylock);
2112 if ( topofavailables > 0 ) retval = listofavailables[--topofavailables];
2113 UNLOCK(availabilitylock);
2114 if ( retval >= 0 ) {
2119 LOCK(wakeuplocks[retval]);
2120 UNLOCK(wakeuplocks[retval]);
2136int ConditionalGetAvailableThread(
void)
2139 if ( topofavailables > 0 ) {
2140 LOCK(availabilitylock);
2141 if ( topofavailables > 0 ) {
2142 retval = listofavailables[--topofavailables];
2144 UNLOCK(availabilitylock);
2145 if ( retval >= 0 ) {
2150 LOCK(wakeuplocks[retval]);
2151 UNLOCK(wakeuplocks[retval]);
2170int GetThread(
int identity)
2173 LOCK(availabilitylock);
2174 for ( j = 0; j < topofavailables; j++ ) {
2175 if ( identity == listofavailables[j] )
break;
2177 if ( j < topofavailables ) {
2179 for ( ; j < topofavailables; j++ ) {
2180 listofavailables[j] = listofavailables[j+1];
2184 UNLOCK(availabilitylock);
2201int ThreadWait(
int identity)
2204 LOCK(wakeuplocks[identity]);
2205 LOCK(availabilitylock);
2206 top = topofavailables;
2207 for ( j = topofavailables; j > 0; j-- )
2208 listofavailables[j] = listofavailables[j-1];
2209 listofavailables[0] = identity;
2211 if ( top == 0 || topofavailables == numberofworkers ) {
2212 UNLOCK(availabilitylock);
2213 LOCK(wakeupmasterlock);
2214 wakeupmaster = identity;
2215 pthread_cond_signal(&wakeupmasterconditions);
2216 UNLOCK(wakeupmasterlock);
2219 UNLOCK(availabilitylock);
2221 while ( wakeup[identity] == 0 ) {
2222 pthread_cond_wait(&(wakeupconditions[identity]),&(wakeuplocks[identity]));
2224 retval = wakeup[identity];
2225 wakeup[identity] = 0;
2226 UNLOCK(wakeuplocks[identity]);
2245int SortBotWait(
int identity)
2248 LOCK(wakeuplocks[identity]);
2249 LOCK(availabilitylock);
2250 topsortbotavailables++;
2251 if ( topsortbotavailables >= numberofsortbots ) {
2252 UNLOCK(availabilitylock);
2253 LOCK(wakeupsortbotlock);
2254 wakeupmaster = identity;
2255 pthread_cond_signal(&wakeupsortbotconditions);
2256 UNLOCK(wakeupsortbotlock);
2259 UNLOCK(availabilitylock);
2261 while ( wakeup[identity] == 0 ) {
2262 pthread_cond_wait(&(wakeupconditions[identity]),&(wakeuplocks[identity]));
2264 retval = wakeup[identity];
2265 wakeup[identity] = 0;
2266 UNLOCK(wakeuplocks[identity]);
2286int ThreadClaimedBlock(
int identity)
2288 LOCK(availabilitylock);
2290 if ( numberclaimed >= numberofworkers ) {
2291 UNLOCK(availabilitylock);
2292 LOCK(wakeupmasterlock);
2293 wakeupmaster = identity;
2294 pthread_cond_signal(&wakeupmasterconditions);
2295 UNLOCK(wakeupmasterlock);
2298 UNLOCK(availabilitylock);
2317 LOCK(wakeupmasterlock);
2318 while ( wakeupmaster == 0 ) {
2319 pthread_cond_wait(&wakeupmasterconditions,&wakeupmasterlock);
2321 retval = wakeupmaster;
2323 UNLOCK(wakeupmasterlock);
2337int MasterWaitThread(
int identity)
2340 LOCK(wakeupmasterthreadlocks[identity]);
2341 while ( wakeupmasterthread[identity] == 0 ) {
2342 pthread_cond_wait(&(wakeupmasterthreadconditions[identity])
2343 ,&(wakeupmasterthreadlocks[identity]));
2345 retval = wakeupmasterthread[identity];
2346 wakeupmasterthread[identity] = 0;
2347 UNLOCK(wakeupmasterthreadlocks[identity]);
2361void MasterWaitAll(
void)
2363 LOCK(wakeupmasterlock);
2364 while ( topofavailables < numberofworkers ) {
2365 pthread_cond_wait(&wakeupmasterconditions,&wakeupmasterlock);
2367 UNLOCK(wakeupmasterlock);
2383void MasterWaitAllSortBots(
void)
2385 LOCK(wakeupsortbotlock);
2386 while ( topsortbotavailables < numberofsortbots ) {
2387 pthread_cond_wait(&wakeupsortbotconditions,&wakeupsortbotlock);
2389 UNLOCK(wakeupsortbotlock);
2405void MasterWaitAllBlocks(
void)
2407 LOCK(wakeupmasterlock);
2408 while ( numberclaimed < numberofworkers ) {
2409 pthread_cond_wait(&wakeupmasterconditions,&wakeupmasterlock);
2411 UNLOCK(wakeupmasterlock);
2427void WakeupThread(
int identity,
int signalnumber)
2429 if ( signalnumber == 0 ) {
2430 MLOCK(ErrorMessageLock);
2431 MesPrint(
"Illegal wakeup signal for thread %d",identity);
2432 MUNLOCK(ErrorMessageLock);
2435 LOCK(wakeuplocks[identity]);
2436 wakeup[identity] = signalnumber;
2437 pthread_cond_signal(&(wakeupconditions[identity]));
2438 UNLOCK(wakeuplocks[identity]);
2453void WakeupMasterFromThread(
int identity,
int signalnumber)
2455 if ( signalnumber == 0 ) {
2456 MLOCK(ErrorMessageLock);
2457 MesPrint(
"Illegal wakeup signal for master %d",identity);
2458 MUNLOCK(ErrorMessageLock);
2461 LOCK(wakeupmasterthreadlocks[identity]);
2462 wakeupmasterthread[identity] = signalnumber;
2463 pthread_cond_signal(&(wakeupmasterthreadconditions[identity]));
2464 UNLOCK(wakeupmasterthreadlocks[identity]);
2476int SendOneBucket(
int type)
2478 ALLPRIVATES *B0 = AB[0];
2479 THREADBUCKET *thr = 0;
2481 for ( j = 0; j < numthreadbuckets; j++ ) {
2482 if ( threadbuckets[j]->free == BUCKETFILLED ) {
2483 thr = threadbuckets[j];
2484 for ( k = j+1; k < numthreadbuckets; k++ )
2485 threadbuckets[k-1] = threadbuckets[k];
2486 threadbuckets[numthreadbuckets-1] = thr;
2491 while ( (
id = GetAvailableThread() ) < 0 ) { MasterWait(); }
2495 LoadOneThread(0,
id,thr,0);
2496 thr->busy = BUCKETASSIGNED;
2497 thr->free = BUCKETINUSE;
2498 numberoffullbuckets--;
2506 WakeupThread(
id,type);
2534int InParallelProcessor(
void)
2537 int i, id, retval = 0, num = 0;
2539 if ( numberofworkers >= 2 ) {
2541 for ( i = 0; i < NumExpressions; i++ ) {
2543 if ( e->partodo <= 0 )
continue;
2544 if ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION
2545 || e->status == UNHIDELEXPRESSION || e->status == UNHIDEGEXPRESSION
2546 || e->status == INTOHIDELEXPRESSION || e->status == INTOHIDEGEXPRESSION ) {
2552 if ( e->counter == 0 ) {
2559 while ( (
id = GetAvailableThread() ) < 0 ) { MasterWait(); }
2560 LoadOneThread(0,
id,0,-1);
2561 AB[id]->R.exprtodo = i;
2562 WakeupThread(
id,DOONEEXPRESSION);
2568 if ( num > 0 ) MasterWaitAll();
2570 if ( AC.CollectFun ) AR.DeferFlag = 0;
2573 for ( i = 0; i < NumExpressions; i++ ) {
2574 Expressions[i].partodo = 0;
2608int ThreadsProcessor(
EXPRESSIONS e, WORD LastExpression, WORD fromspectator)
2610 ALLPRIVATES *B0 = AB[0], *B = B0;
2611 int id, oldgzipCompress, endofinput = 0, j, still, k, defcount = 0, bra = 0, first = 1;
2612 LONG dd = 0, ddd, thrbufsiz, thrbufsiz0, thrbufsiz2, numbucket = 0, numpasses;
2614 WORD *oldworkpointer = AT0.WorkPointer, *tt, *ttco = 0, *t1 = 0, ter, *tstop = 0, *t2;
2615 THREADBUCKET *thr = 0;
2617 GETTERM GetTermP = &GetTerm;
2618 POSITION eonfile = AS.OldOnFile[e-Expressions];
2619 numberoffullbuckets = 0;
2625 AM.tracebackflag = 1;
2627 AS.sLevel = AR0.sLevel;
2628 LOCK(availabilitylock);
2629 topofavailables = 0;
2630 for (
id = 1;
id <= numberofworkers;
id++ ) {
2631 WakeupThread(
id,STARTNEWEXPRESSION);
2633 UNLOCK(availabilitylock);
2639 if ( AC.numpfirstnum > 0 ) {
2640 for ( j = 0; j < AC.numpfirstnum; j++ ) {
2641 AC.inputnumbers[j] = -1;
2653 thrbufsiz2 = thrbufsiz = AC.ThreadBucketSize-1;
2654 if ( ( e->counter / ( numberofworkers * 5 ) ) < thrbufsiz ) {
2655 thrbufsiz = e->counter / ( numberofworkers * 5 ) - 1;
2656 if ( thrbufsiz < 0 ) thrbufsiz = 0;
2658 thrbufsiz0 = thrbufsiz;
2660 thrbufsiz = thrbufsiz0 / (2 << numpasses);
2664 for ( j = 0; j < numthreadbuckets; j++ )
2665 threadbuckets[j]->free = BUCKETFREE;
2666 thr = threadbuckets[0];
2675 if ( e->bracketinfo && AC.CollectFun == 0 && AR0.DeferFlag == 0 ) {
2680 for ( n = 0; n < e->bracketinfo->indexfill; n++ ) {
2681 num = TreatIndexEntry(B0,n);
2689 for ( j = 0; j < numthreadbuckets; j++ ) {
2690 switch ( threadbuckets[j]->free ) {
2692 thr = threadbuckets[j];
2694 case BUCKETCOMINGFREE:
2695 thr = threadbuckets[j];
2696 thr->free = BUCKETFREE;
2697 for ( k = j+1; k < numthreadbuckets; k++ )
2698 threadbuckets[k-1] = threadbuckets[k];
2699 threadbuckets[numthreadbuckets-1] = thr;
2707 if ( j < numthreadbuckets ) {
2711 thr->firstbracket = n;
2712 thr->lastbracket = n + num - 1;
2713 thr->type = BUCKETDOINGBRACKET;
2714 thr->free = BUCKETFILLED;
2715 thr->firstterm = AN0.ninterms;
2716 for ( j = n; j < n+num; j++ ) {
2717 AN0.ninterms += e->bracketinfo->
indexbuffer[j].termsinbracket;
2720 numberoffullbuckets++;
2721 if ( topofavailables > 0 ) {
2722 SendOneBucket(DOBRACKETS);
2731 while ( topofavailables <= 0 ) {
2734 SendOneBucket(DOBRACKETS);
2743 switch ( e->status ) {
2744 case UNHIDELEXPRESSION:
2745 case UNHIDEGEXPRESSION:
2746 case DROPHLEXPRESSION:
2747 case DROPHGEXPRESSION:
2748 case HIDDENLEXPRESSION:
2749 case HIDDENGEXPRESSION:
2750 curfile = AR0.hidefile;
2753 curfile = AR0.infile;
2756 SetScratch(curfile,&eonfile);
2757 GetTerm(B0,AT0.WorkPointer);
2761 GetTermP = &GetTerm2;
2766 for ( j = 0; j < numthreadbuckets; j++ ) {
2767 switch ( threadbuckets[j]->free ) {
2769 thr = threadbuckets[j];
2771 case BUCKETCOMINGFREE:
2772 thr = threadbuckets[j];
2773 thr->free = BUCKETFREE;
2774 for ( k = j+1; k < numthreadbuckets; k++ )
2775 threadbuckets[k-1] = threadbuckets[k];
2776 threadbuckets[numthreadbuckets-1] = thr;
2783 while ( topofavailables <= 0 ) {
2786 while ( topofavailables > 0 && numberoffullbuckets > 0 ) {
2787 SendOneBucket(DOBRACKETS);
2791 while ( numberoffullbuckets > 0 ) {
2792 while ( topofavailables <= 0 ) {
2795 while ( topofavailables > 0 && numberoffullbuckets > 0 ) {
2796 SendOneBucket(DOBRACKETS);
2805 AN0.lastinindex = -1;
2816 if ( fromspectator ) {
2817 ter = GetFromSpectator(thr->threadbuffer,fromspectator-1);
2818 if ( ter == 0 ) fromspectator = 0;
2821 ter = GetTermP(B0,thr->threadbuffer);
2837 if ( ter < 0 )
break;
2838 if ( ter == 0 ) { endofinput = 1;
goto Finalize; }
2839 dd = AN0.deferskipped;
2840 if ( AR0.DeferFlag ) {
2842 thr->deferbuffer[defcount++] = AR0.DefPosition;
2843 ttco = thr->compressbuffer; t1 = AR0.CompressBuffer; j = *t1;
2844 while ( thr->compressbuffersize <= j ) {
2846 WORD *top = thr->compressbuffer+thr->compressbuffersize;
2847 DoubleBuffer((
void**)&(thr->compressbuffer),(
void**)&(top),
2848 sizeof(*(thr->compressbuffer)),
"double compressbuffer");
2849 ttco = thr->compressbuffer;
2850 thr->compressbuffersize *= 2;
2854 else if ( first && ( AC.CollectFun == 0 ) ) {
2856 t1 = tstop = thr->threadbuffer;
2857 tstop += *tstop; tstop -= ABS(tstop[-1]);
2859 while ( t1 < tstop ) {
2860 if ( t1[0] == HAAKJE ) { bra = 1;
break; }
2863 t1 = thr->threadbuffer;
2868 if ( AC.CollectFun && *(thr->threadbuffer) < (AM.MaxTer/((LONG)
sizeof(WORD))-10) ) {
2869 if ( ( dd = GetMoreTerms(thr->threadbuffer) ) < 0 ) {
2876 if ( topofavailables > 0 && numberoffullbuckets > 0 ) SendOneBucket(LOWESTLEVELGENERATION);
2880 tt = thr->threadbuffer; tt += *tt;
2887 if ( numpasses > 0 ) {
2889 if ( numbucket >= numberofworkers ) {
2892 if ( numpasses == 0 ) thrbufsiz = thrbufsiz0;
2893 else thrbufsiz = thrbufsiz0 / (2 << numpasses);
2895 thrbufsiz2 = thrbufsiz + thrbufsiz/5;
2900 while ( ( dd < thrbufsiz ) &&
2901 ( tt - thr->threadbuffer ) < ( thr->threadbuffersize - AM.MaxTer/((LONG)
sizeof(WORD)) - 2 ) ) {
2905 if ( topofavailables > 0 && numberoffullbuckets > 0 ) SendOneBucket(LOWESTLEVELGENERATION);
2909 if ( GetTermP(B0,tt) == 0 ) { endofinput = 1;
break; }
2912 dd += AN0.deferskipped;
2913 if ( AR0.DeferFlag ) {
2914 thr->deferbuffer[defcount++] = AR0.DefPosition;
2915 t1 = AR0.CompressBuffer; j = *t1;
2916 while ( thr->compressbuffer+thr->compressbuffersize-ttco <= j ) {
2918 const ptrdiff_t oldoffset = ttco - thr->compressbuffer;
2919 WORD *top = thr->compressbuffer+thr->compressbuffersize;
2920 DoubleBuffer((
void**)&(thr->compressbuffer),(
void**)&(top),
2921 sizeof(*(thr->compressbuffer)),
"double compressbuffer");
2922 ttco = thr->compressbuffer + oldoffset;
2923 thr->compressbuffersize *= 2;
2927 if ( AC.CollectFun && *tt < (AM.MaxTer/((LONG)
sizeof(WORD))-10) ) {
2928 if ( ( ddd = GetMoreTerms(tt) ) < 0 ) {
2943 tstop = t1 + *t1; tstop -= ABS(tstop[-1]);
2945 while ( t2 < tstop ) {
2946 if ( t2[0] == HAAKJE ) {
break; }
2949 if ( t2[0] == HAAKJE ) {
2950 t2 += t2[1]; num = t2 - t1;
2951 while ( ( dd < thrbufsiz2 ) &&
2952 ( tt - thr->threadbuffer ) < ( thr->threadbuffersize - AM.MaxTer - 2 ) ) {
2956 if ( topofavailables > 0 && numberoffullbuckets > 0 ) SendOneBucket(LOWESTLEVELGENERATION);
2960 if ( GetTermP(B0,tt) == 0 ) { endofinput = 1;
break; }
2964 tstop = tt + *tt; tstop -= ABS(tstop[-1]);
2965 if ( tstop-tt < num ) {
2969 for ( i = 1; i < num; i++ ) {
2970 if ( t1[i] != tt[i] )
break;
2986 thr->firstterm = AN0.ninterms;
2989 thr->free = BUCKETFILLED;
2990 thr->type = BUCKETDOINGTERMS;
2991 numberoffullbuckets++;
2992 if ( topofavailables <= 0 && endofinput == 0 ) {
3006 for ( j = 0; j < numthreadbuckets; j++ ) {
3007 switch ( threadbuckets[j]->free ) {
3009 thr = threadbuckets[j];
3010 if ( !endofinput )
goto NextBucket;
3016 thr->free = BUCKETATEND;
3018 case BUCKETCOMINGFREE:
3019 thr = threadbuckets[j];
3020 thr->free = BUCKETFREE;
3026 for ( k = j+1; k < numthreadbuckets; k++ )
3027 threadbuckets[k-1] = threadbuckets[k];
3028 threadbuckets[numthreadbuckets-1] = thr;
3044 for ( j = 0; j < numthreadbuckets; j++ ) {
3045 if ( threadbuckets[j]->free == BUCKETFILLED ) {
3046 thr = threadbuckets[j];
3047 for ( k = j+1; k < numthreadbuckets; k++ )
3048 threadbuckets[k-1] = threadbuckets[k];
3049 threadbuckets[numthreadbuckets-1] = thr;
3059 while ( (
id = GetAvailableThread() ) < 0 ) { MasterWait(); }
3063 LoadOneThread(0,
id,thr,0);
3065 thr->busy = BUCKETASSIGNED;
3067 thr->free = BUCKETINUSE;
3068 numberoffullbuckets--;
3076 WakeupThread(
id,LOWESTLEVELGENERATION);
3081 if ( topofavailables > 0 ) {
3082 for ( j = 0; j < numthreadbuckets; j++ ) {
3083 if ( threadbuckets[j]->free == BUCKETFILLED ) {
3084 thr = threadbuckets[j];
3085 for ( k = j+1; k < numthreadbuckets; k++ )
3086 threadbuckets[k-1] = threadbuckets[k];
3087 threadbuckets[numthreadbuckets-1] = thr;
3096 for ( j = 0; j < numthreadbuckets; j++ ) {
3097 switch ( threadbuckets[j]->free ) {
3099 thr = threadbuckets[j];
3100 if ( !endofinput )
goto NextBucket;
3101 thr->free = BUCKETATEND;
3103 case BUCKETCOMINGFREE:
3104 thr = threadbuckets[j];
3106 thr->free = BUCKETATEND;
3109 thr->free = BUCKETFREE;
3110 for ( k = j+1; k < numthreadbuckets; k++ )
3111 threadbuckets[k-1] = threadbuckets[k];
3112 threadbuckets[numthreadbuckets-1] = thr;
3120 if ( j >= numthreadbuckets )
break;
3130 for ( j = 0; j < numthreadbuckets; j++ ) {
3131 switch ( threadbuckets[j]->free ) {
3133 thr = threadbuckets[j];
3134 if ( !endofinput )
goto NextBucket;
3135 thr->free = BUCKETATEND;
3137 case BUCKETCOMINGFREE:
3138 thr = threadbuckets[j];
3139 if ( endofinput ) thr->free = BUCKETATEND;
3141 thr->free = BUCKETFREE;
3142 for ( k = j+1; k < numthreadbuckets; k++ )
3143 threadbuckets[k-1] = threadbuckets[k];
3144 threadbuckets[numthreadbuckets-1] = thr;
3149 if ( still < 0 ) still = j;
3162 thr = threadbuckets[still];
3163 for ( k = still+1; k < numthreadbuckets; k++ )
3164 threadbuckets[k-1] = threadbuckets[k];
3165 threadbuckets[numthreadbuckets-1] = thr;
3178 if ( AC.ThreadBalancing ) {
3179 for (
id = 1;
id <= numberofworkers;
id++ ) {
3180 AB[id]->T.LoadBalancing = 1;
3182 if ( LoadReadjusted() )
goto Finalize;
3183 for (
id = 1;
id <= numberofworkers;
id++ ) {
3184 AB[id]->T.LoadBalancing = 0;
3187 if ( AC.ThreadBalancing ) {
3212 if ( LastExpression ) {
3214 if ( AR0.infile->handle >= 0 ) {
3215 CloseFile(AR0.infile->handle);
3216 AR0.infile->handle = -1;
3217 remove(AR0.infile->name);
3218 PUTZERO(AR0.infile->POposition);
3219 AR0.infile->POfill = AR0.infile->POfull = AR0.infile->PObuffer;
3231 oldgzipCompress = AR0.gzipCompress;
3232 AR0.gzipCompress = 0;
3233 if ( AR0.outtohide ) AR0.outfile = AR0.hidefile;
3234 if ( MasterMerge() < 0 ) {
3235 if ( AR0.outtohide ) AR0.outfile = oldoutfile;
3236 AR0.gzipCompress = oldgzipCompress;
3239 if ( AR0.outtohide ) AR0.outfile = oldoutfile;
3240 AR0.gzipCompress = oldgzipCompress;
3248 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
3249 if ( GetThread(
id) > 0 ) WakeupThread(
id,CLEANUPEXPRESSION);
3252 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
3253 if ( AB[
id]->R.MaxDum - AM.IndDum > e->numdummies )
3254 e->numdummies = AB[id]->R.MaxDum - AM.IndDum;
3255 AR0.expchanged |= AB[id]->R.expchanged;
3261 AT0.WorkPointer = oldworkpointer;
3289int LoadReadjusted(
void)
3291 ALLPRIVATES *B0 = AB[0];
3292 THREADBUCKET *thr = 0, *thrtogo = 0;
3293 int numtogo, numfree, numbusy, n, nperbucket, extra, i, j, u, bus;
3295 WORD *t1, *c1, *t2, *c2, *t3;
3300 while ( topofavailables <= 0 ) MasterWait();
3309 for ( j = 0; j < numthreadbuckets; j++ ) {
3310 thr = threadbuckets[j];
3311 if ( thr->free == BUCKETFREE || thr->free == BUCKETATEND
3312 || thr->free == BUCKETCOMINGFREE ) {
3313 freebuckets[numfree++] = thr;
3315 else if ( thr->type != BUCKETDOINGTERMS ) {}
3316 else if ( thr->totnum > 1 ) {
3320 if ( thr->free == BUCKETINUSE ) {
3321 n = thr->totnum-thr->usenum;
3322 if ( bus == BUCKETASSIGNED ) numbusy++;
3323 else if ( ( bus != BUCKETASSIGNED )
3324 && ( n > numtogo ) ) {
3329 else if ( bus == BUCKETTOBERELEASED
3330 && thr->free == BUCKETRELEASED ) {
3331 freebuckets[numfree++] = thr;
3332 thr->free = BUCKETATEND;
3334 thr->busy = BUCKETPREPARINGTERM;
3339 if ( numfree == 0 )
return(0);
3340 if ( numtogo > 0 ) {
3347 if ( thr->totnum-thr->usenum < numtogo )
goto restart;
3357 if ( thr->busy != BUCKETDOINGTERM ) {
3361 if ( thr->totnum-thr->usenum < numtogo ) {
3365 thr->free = BUCKETTERMINATED;
3372 if ( thr->usenum == thr->totnum ) {
3377 thr->free = BUCKETATEND;
3385 if ( numbusy > 0 ) {
3391 struct timespec sleeptime;
3392 sleeptime.tv_sec = 0;
3393 sleeptime.tv_nsec = 1000L;
3394 nanosleep(&sleeptime, NULL);
3409 numinput = thr->firstterm + thr->usenum;
3410 nperbucket = numtogo / numfree;
3411 extra = numtogo - nperbucket*numfree;
3412 if ( AR0.DeferFlag ) {
3413 t1 = thr->threadbuffer; c1 = thr->compressbuffer; u = thr->usenum;
3414 for ( n = 0; n < thr->usenum; n++ ) { t1 += *t1; c1 += *c1; }
3417 for ( i = 0; i < extra; i++ ) {
3418 thrtogo = freebuckets[i];
3419 t2 = thrtogo->threadbuffer;
3420 c2 = thrtogo->compressbuffer;
3421 thrtogo->free = BUCKETFILLED;
3422 thrtogo->type = BUCKETDOINGTERMS;
3423 thrtogo->totnum = nperbucket+1;
3424 thrtogo->ddterms = 0;
3425 thrtogo->usenum = 0;
3426 thrtogo->busy = BUCKETASSIGNED;
3427 thrtogo->firstterm = numinput;
3428 numinput += nperbucket+1;
3429 for ( n = 0; n <= nperbucket; n++ ) {
3430 j = *t1; NCOPY(t2,t1,j);
3431 j = *c1; NCOPY(c2,c1,j);
3432 thrtogo->deferbuffer[n] = thr->deferbuffer[u++];
3437 if ( nperbucket > 0 ) {
3438 for ( i = extra; i < numfree; i++ ) {
3439 thrtogo = freebuckets[i];
3440 t2 = thrtogo->threadbuffer;
3441 c2 = thrtogo->compressbuffer;
3442 thrtogo->free = BUCKETFILLED;
3443 thrtogo->type = BUCKETDOINGTERMS;
3444 thrtogo->totnum = nperbucket;
3445 thrtogo->ddterms = 0;
3446 thrtogo->usenum = 0;
3447 thrtogo->busy = BUCKETASSIGNED;
3448 thrtogo->firstterm = numinput;
3449 numinput += nperbucket;
3450 for ( n = 0; n < nperbucket; n++ ) {
3451 j = *t1; NCOPY(t2,t1,j);
3452 j = *c1; NCOPY(c2,c1,j);
3453 thrtogo->deferbuffer[n] = thr->deferbuffer[u++];
3460 t1 = thr->threadbuffer;
3461 for ( n = 0; n < thr->usenum; n++ ) { t1 += *t1; }
3464 for ( i = 0; i < extra; i++ ) {
3465 thrtogo = freebuckets[i];
3466 t2 = thrtogo->threadbuffer;
3467 thrtogo->free = BUCKETFILLED;
3468 thrtogo->type = BUCKETDOINGTERMS;
3469 thrtogo->totnum = nperbucket+1;
3470 thrtogo->ddterms = 0;
3471 thrtogo->usenum = 0;
3472 thrtogo->busy = BUCKETASSIGNED;
3473 thrtogo->firstterm = numinput;
3474 numinput += nperbucket+1;
3475 for ( n = 0; n <= nperbucket; n++ ) {
3476 j = *t1; NCOPY(t2,t1,j);
3481 if ( nperbucket > 0 ) {
3482 for ( i = extra; i < numfree; i++ ) {
3483 thrtogo = freebuckets[i];
3484 t2 = thrtogo->threadbuffer;
3485 thrtogo->free = BUCKETFILLED;
3486 thrtogo->type = BUCKETDOINGTERMS;
3487 thrtogo->totnum = nperbucket;
3488 thrtogo->ddterms = 0;
3489 thrtogo->usenum = 0;
3490 thrtogo->busy = BUCKETASSIGNED;
3491 thrtogo->firstterm = numinput;
3492 numinput += nperbucket;
3493 for ( n = 0; n < nperbucket; n++ ) {
3494 j = *t1; NCOPY(t2,t1,j);
3501 if ( thr->free == BUCKETRELEASED && thr->busy == BUCKETTOBERELEASED ) {
3502 thr->free = BUCKETATEND; thr->busy = BUCKETPREPARINGTERM;
3570int PutToMaster(PHEAD WORD *term)
3572 int i,j,nexti,ret = 0;
3574 WORD *t, *fill, *top, zero = 0;
3579 t = term; ret = j = *term;
3580 if ( j == 0 ) { j = 1; }
3582 i = AT.SB.FillBlock;
3583 fill = AT.SB.MasterFill[i];
3584 top = AT.SB.MasterStop[i];
3591 if ( j < top - fill && AT.SB.BlockTerms[i] > MINWRITENUMBEROFTERMS ) {
3592 const int prev = ( i == 1 ? AT.SB.MasterNumBlocks : i-1 );
3593 if ( ! pthread_mutex_trylock(&(AT.SB.MasterBlockLock[prev])) ) {
3594 UNLOCK(AT.SB.MasterBlockLock[prev]);
3603 if ( ( j >= top - fill ) || urgent ) {
3605 if ( nexti > AT.SB.MasterNumBlocks ) {
3608 LOCK(AT.SB.MasterBlockLock[nexti]);
3609 UNLOCK(AT.SB.MasterBlockLock[i]);
3610 AT.SB.MasterFill[i] = AT.SB.MasterStart[i];
3611 AT.SB.FillBlock = i = nexti;
3612 fill = AT.SB.MasterStart[i];
3613 top = AT.SB.MasterStop[i];
3614 if ( AT.SB.BlockTerms[i] != 0 ) {
3618 MLOCK(ErrorMessageLock);
3619 MesPrint(
"Error in PutToMaster, starting a block with BlockTerms != 0");
3620 MUNLOCK(ErrorMessageLock);
3626 AT.SB.BlockTerms[i]++;
3627 AT.SB.MasterFill[i] = fill;
3647SortBotOut(PHEAD WORD *term)
3651 if ( AT.identity != 0 )
return(PutToMaster(BHEAD term));
3654 if (
FlushOut(&SortBotPosition,AR.outfile,1) )
return(-1);
3655 ADDPOS(AT.SS->SizeInFile[0],1);
3660 if ( ( im =
PutOut(BHEAD term,&SortBotPosition,AR.outfile,1) ) < 0 ) {
3661 MLOCK(ErrorMessageLock);
3662 MesPrint(
"Called from MasterMerge/SortBotOut");
3663 MUNLOCK(ErrorMessageLock);
3666 ADDPOS(AT.SS->SizeInFile[0],im);
3694int MasterMerge(
void)
3696 ALLPRIVATES *B0 = AB[0], *B = 0;
3698 WORD **poin, **poin2, ul, k, i, im, *m1, j;
3699 WORD lpat, mpat, level, l1, l2, r1, r2, r3, c;
3700 WORD *m2, *m3, r31, r33, ki, *rr;
3705 if ( numberofworkers > 2 )
return(SortBotMasterMerge());
3708 if ( AR0.PolyFun == 0 ) { S->PolyFlag = 0; }
3709 else if ( AR0.PolyFunType == 1 ) { S->PolyFlag = 1; }
3710 else if ( AR0.PolyFunType == 2 ) {
3711 if ( AR0.PolyFunExp == 2
3712 || AR0.PolyFunExp == 3 ) S->PolyFlag = 1;
3713 else S->PolyFlag = 2;
3716 coef = AN0.SoScratC;
3717 poin = S->poina; poin2 = S->poin2a;
3718 rr = AR0.CompressPointer;
3723 S->inNum = numberofthreads;
3728 S->lPatch = S->inNum - 1;
3738 for ( i = 1; i <= S->lPatch; i++ ) {
3740 LOCK(AT.SB.MasterBlockLock[0]);
3741 LOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
3749 for ( i = 0; i < S->lPatch; i++ ) {
3751 WakeupThread(i+1,FINISHEXPRESSION);
3756 if ( fout->
handle >= 0 ) {
3758 SeekFile(fout->
handle,&position,SEEK_END);
3759 ADDPOS(position,((fout->POfill-fout->PObuffer)*
sizeof(WORD)));
3762 SETBASEPOSITION(position,(fout->POfill-fout->PObuffer)*
sizeof(WORD));
3767 MasterWaitAllBlocks();
3775 for ( i = 1; i <= S->lPatch; i++ ) {
3777 LOCK(AT.SB.MasterBlockLock[1]);
3778 AT.SB.MasterBlock = 1;
3786 do { lpat <<= 1; }
while ( lpat < S->lPatch );
3787 mpat = ( lpat >> 1 ) - 1;
3788 k = lpat - S->lPatch;
3793 for ( i = 1; i < lpat; i++ ) { S->tree[i] = -1; }
3794 for ( i = 1; i <= k; i++ ) {
3796 poin[im] = AB[i]->T.SB.MasterStart[AB[i]->T.SB.MasterBlock];
3797 poin2[im] = poin[im] + *(poin[im]);
3800 S->tree[mpat+i] = 0;
3801 poin[im-1] = poin2[im-1] = 0;
3803 for ( i = (k*2)+1; i <= lpat; i++ ) {
3806 poin[i] = AB[i-k]->T.SB.MasterStart[AB[i-k]->T.SB.MasterBlock];
3807 poin2[i] = poin[i] + *(poin[i]);
3828 if ( !*(poin[k]) ) {
3832 AB[ki+1]->T.SB.BlockTerms[AB[ki+1]->T.SB.MasterBlock]--;
3834 if ( !( i >>= 1 ) ) {
3837 }
while ( !S->tree[i] );
3838 if ( S->tree[i] == -1 ) {
3851 if ( S->tree[i] > 0 ) {
3852 if ( ( c = CompareTerms(B0, poin[S->tree[i]],poin[k],(WORD)0) ) > 0 ) {
3856 S->used[level] = S->tree[i];
3866 l1 = *( m1 = poin[S->tree[i]] );
3867 l2 = *( m2 = poin[k] );
3868 if ( S->PolyWise ) {
3873 if ( S->PolyFlag == 2 ) {
3875 if ( *tt1 + w[1] - m1[1] > AM.MaxTer/((LONG)
sizeof(WORD)) ) {
3876 MLOCK(ErrorMessageLock);
3877 MesPrint(
"Term too complex in PolyRatFun addition. MaxTermSize of %10l is too small",AM.MaxTer);
3878 MUNLOCK(ErrorMessageLock);
3881 AT0.WorkPointer = w;
3882 if ( w[FUNHEAD] == -SNUMBER && w[FUNHEAD+1] == 0 && w[1] > FUNHEAD ) {
3887 w = AT0.WorkPointer;
3888 if ( w + m1[1] + m2[1] > AT0.WorkTop ) {
3889 MLOCK(ErrorMessageLock);
3890 MesPrint(
"MasterMerge: A WorkSpace of %10l is too small",AM.WorkSize);
3891 MUNLOCK(ErrorMessageLock);
3898 || ( w[FUNHEAD] == -SNUMBER && w[FUNHEAD+1] == 0 ) )
3900 if ( r1 == m1[1] ) {
3903 else if ( r1 < m1[1] ) {
3907 while ( --r1 >= 0 ) *--m1 = *--m2;
3910 while ( --r1 >= 0 ) *--m1 = *--m2;
3912 poin[S->tree[i]] = m1;
3926 poin[S->tree[i]] = m2;
3933 else if ( AT.SortFloatMode ) {
3934 WORD *term1, *term2;
3935 term1 = poin[S->tree[i]];
3937 if ( MergeWithFloat(B0, &term1,&term2) == 0 )
3939 poin[S->tree[i]] = term1;
3943 r1 = *( m1 += l1 - 1 );
3945 r1 = ( ( r1 > 0 ) ? (r1-1) : (r1+1) ) >> 1;
3946 r2 = *( m2 += l2 - 1 );
3948 r2 = ( ( r2 > 0 ) ? (r2-1) : (r2+1) ) >> 1;
3950 if ( AddRat(B0,(UWORD *)m1,r1,(UWORD *)m2,r2,coef,&r3) ) {
3951 MLOCK(ErrorMessageLock);
3952 MesCall(
"MasterMerge");
3953 MUNLOCK(ErrorMessageLock);
3957 if ( AN.ncmod != 0 ) {
3958 if ( ( AC.modmode & POSNEG ) != 0 ) {
3961 else if ( BigLong(coef,r3,(UWORD *)AC.cmod,ABS(AN.ncmod)) >= 0 ) {
3963 SubPLon(coef,r3,(UWORD *)AC.cmod,ABS(AN.ncmod),coef,&r3);
3965 for ( ii = 1; ii < r3; ii++ ) coef[r3+ii] = 0;
3969 r33 = ( r3 > 0 ) ? ( r3 + 1 ) : ( r3 - 1 );
3970 if ( r3 < 0 ) r3 = -r3;
3971 if ( r1 < 0 ) r1 = -r1;
3976 ul = S->used[level] = S->tree[i];
3982 poin[ul] = poin2[ul];
3984 AB[ki+1]->T.SB.BlockTerms[AB[ki+1]->T.SB.MasterBlock]--;
3985 if ( AB[ki+1]->T.SB.BlockTerms[AB[ki+1]->T.SB.MasterBlock] == 0 ) {
3991 i = AT.SB.MasterBlock;
3993 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
3996 UNLOCK(AT.SB.MasterBlockLock[i-1]);
3998 if ( i == AT.SB.MasterNumBlocks ) {
4002 LOCK(AT.SB.MasterBlockLock[i]);
4003 AT.SB.MasterBlock = i;
4004 poin[ul] = AT.SB.MasterStart[i];
4006 poin2[ul] = poin[ul] + im;
4011 S->used[++level] = k;
4016 else if ( r31 < 0 ) {
4025 if( (poin[S->tree[i]]+l1+r31) >= poin2[S->tree[i]] ) {
4031 if ( (l1 + r31)*((LONG)
sizeof(WORD)) >= AM.MaxTer ) {
4032 MLOCK(ErrorMessageLock);
4033 MesPrint(
"MasterMerge: Coefficient overflow during sort");
4034 MUNLOCK(ErrorMessageLock);
4037 m2 = poin[S->tree[i]];
4038 m3 = ( poin[S->tree[i]] -= r31 );
4039 do { *m3++ = *m2++; }
while ( m2 < m1 );
4043 *(poin[S->tree[i]]) += r31;
4045 m2 = (WORD *)coef; im = r3;
4057 AB[ki+1]->T.SB.BlockTerms[AB[ki+1]->T.SB.MasterBlock]--;
4058 if ( AB[ki+1]->T.SB.BlockTerms[AB[ki+1]->T.SB.MasterBlock] == 0 ) {
4064 i = AT.SB.MasterBlock;
4066 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
4069 UNLOCK(AT.SB.MasterBlockLock[i-1]);
4071 if ( i == AT.SB.MasterNumBlocks ) {
4075 LOCK(AT.SB.MasterBlockLock[i]);
4076 AT.SB.MasterBlock = i;
4077 poin[k] = AT.SB.MasterStart[i];
4079 poin2[k] = poin[k] + im;
4087 else if ( S->tree[i] < 0 ) {
4098 if ( ( im =
PutOut(B0,poin[k],&position,fout,1) ) < 0 ) {
4099 MLOCK(ErrorMessageLock);
4100 MesPrint(
"Called from MasterMerge with k = %d (stream %d)",k,S->ktoi[k]);
4101 MUNLOCK(ErrorMessageLock);
4104 ADDPOS(S->SizeInFile[0],im);
4107 if (
FlushOut(&position,fout,1) )
goto ReturnError;
4108 ADDPOS(S->SizeInFile[0],1);
4112 position = S->SizeInFile[0];
4113 MULPOS(position,
sizeof(WORD));
4122 for ( j = 1; j <= numberofworkers; j++ ) {
4123 S->GenTerms += AB[j]->T.SS->GenTerms;
4124 S->verbComparisons += AB[j]->T.SS->verbComparisons;
4125 if ( S->verbMaxTermSize < AB[j]->T.SS->verbMaxTermSize )
4126 S->verbMaxTermSize = AB[j]->T.SS->verbMaxTermSize;
4127 S->verbSBsortTerms += AB[j]->T.SS->verbSBsortTerms;
4128 S->verbSBsortCap += AB[j]->T.SS->verbSBsortCap;
4129 S->verbLBsortPatches += AB[j]->T.SS->verbLBsortPatches;
4130 S->verbLBsortCap += AB[j]->T.SS->verbLBsortCap;
4131 S->verbUnsortedSize += AB[j]->T.SS->verbUnsortedSize;
4134 WriteStats(&position,STATSPOSTSORT,NOCHECKLOGTYPE);
4135 Expressions[AR0.CurExpr].counter = S->TermsLeft;
4136 Expressions[AR0.CurExpr].size = position;
4140 for ( i = 1; i <= S->lPatch; i++ ) {
4142 UNLOCK(AT.SB.MasterBlockLock[0]);
4143 if ( AT.SB.MasterBlock == 1 ) {
4144 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
4147 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterBlock-1]);
4149 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterBlock]);
4154 for ( i = 1; i <= S->lPatch; i++ ) {
4156 UNLOCK(AT.SB.MasterBlockLock[0]);
4157 if ( AT.SB.MasterBlock == 1 ) {
4158 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
4161 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterBlock-1]);
4163 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterBlock]);
4191int SortBotMasterMerge(
void)
4194 ALLPRIVATES *B = AB[0], *BB;
4207 topsortbotavailables = 0;
4208 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
4209 WakeupThread(i,INISORTBOT);
4215 AR.CompressPointer[0] = 0;
4217 BB = AB[AT.SortBotIn1];
4218 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
4219 BB = AB[AT.SortBotIn2];
4220 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
4222 MasterWaitAllSortBots();
4227 for ( i = 1; i <= numberofworkers; i++ ) {
4229 WakeupThread(i,FINISHEXPRESSION);
4234 if ( fout->
handle >= 0 ) {
4235 PUTZERO(SortBotPosition);
4236 SeekFile(fout->
handle,&SortBotPosition,SEEK_END);
4237 ADDPOS(SortBotPosition,((fout->POfill-fout->PObuffer)*
sizeof(WORD)));
4240 SETBASEPOSITION(SortBotPosition,(fout->POfill-fout->PObuffer)*
sizeof(WORD));
4242 MasterWaitAllBlocks();
4248 topsortbotavailables = 0;
4249 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
4250 WakeupThread(i,RUNSORTBOT);
4252 if ( SortBotMerge(BHEAD0) ) {
4253 MLOCK(ErrorMessageLock);
4254 MesPrint(
"Called from SortBotMasterMerge");
4255 MUNLOCK(ErrorMessageLock);
4262 if ( S->file.
handle >= 0 )
4269 position = S->SizeInFile[0];
4270 MULPOS(position,
sizeof(WORD));
4279 for ( j = 1; j <= numberofworkers; j++ ) {
4280 S->GenTerms += AB[j]->T.SS->GenTerms;
4281 S->verbComparisons += AB[j]->T.SS->verbComparisons;
4282 if ( S->verbMaxTermSize < AB[j]->T.SS->verbMaxTermSize )
4283 S->verbMaxTermSize = AB[j]->T.SS->verbMaxTermSize;
4284 S->verbSBsortTerms += AB[j]->T.SS->verbSBsortTerms;
4285 S->verbSBsortCap += AB[j]->T.SS->verbSBsortCap;
4286 S->verbLBsortPatches += AB[j]->T.SS->verbLBsortPatches;
4287 S->verbLBsortCap += AB[j]->T.SS->verbLBsortCap;
4288 S->verbUnsortedSize += AB[j]->T.SS->verbUnsortedSize;
4290 for ( j = numberofworkers+1; j <= numberofworkers+numberofsortbots; j++ ) {
4291 S->verbComparisons += AB[j]->T.SS->verbComparisons;
4292 if ( S->verbMaxTermSize < AB[j]->T.SS->verbMaxTermSize )
4293 S->verbMaxTermSize = AB[j]->T.SS->verbMaxTermSize;
4296 S->TermsLeft = numberofterms;
4297 WriteStats(&position,STATSPOSTSORT,NOCHECKLOGTYPE);
4298 Expressions[AR.CurExpr].counter = S->TermsLeft;
4299 Expressions[AR.CurExpr].size = position;
4308 MasterWaitAllSortBots();
4327int SortBotMerge(PHEAD0)
4330 ALLPRIVATES *Bin1 = AB[AT.SortBotIn1],*Bin2 = AB[AT.SortBotIn2];
4331 WORD *term1, *term2, *wp;
4334 WORD l1, l2, *m1, *m2, *w, r1, r2, r3, r33, r31, *tt1, ii;
4335 WORD *to, *from, im, c;
4339 WORD *fun1, *fun2, *fun3, *tstop1, *tstop2, size1, size2, size3, l3, jj, *m3;
4347 if ( AT.identity == 0 ) {
4348 wp = AT.WorkPointer;
4351 wp = AT.WorkPointer = AT.WorkSpace;
4358 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4359 LOCK(Bin2->T.SB.MasterBlockLock[blin2]);
4361 term1 = Bin1->T.SB.MasterStart[blin1];
4362 term2 = Bin2->T.SB.MasterStart[blin2];
4363 AT.SB.FillBlock = 1;
4367 while ( *term1 && *term2 ) {
4368 if ( ( c = CompareTerms(BHEAD term1,term2,(WORD)0) ) > 0 ) {
4372 Bin1->T.SB.BlockTerms[blin1]--;
4373 if ( SortBotOut(BHEAD term1) < 0 ) {
4374 MLOCK(ErrorMessageLock);
4375 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4376 MUNLOCK(ErrorMessageLock);
4381 if ( Bin1->T.SB.BlockTerms[blin1] == 0 ) {
4383 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4386 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4388 if ( blin1 == Bin1->T.SB.MasterNumBlocks ) {
4394 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4395 Bin1->T.SB.MasterBlock = blin1;
4396 term1 = Bin1->T.SB.MasterStart[blin1];
4406 Bin2->T.SB.BlockTerms[blin2]--;
4407 if ( SortBotOut(BHEAD term2) < 0 ) {
4408 MLOCK(ErrorMessageLock);
4409 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4410 MUNLOCK(ErrorMessageLock);
4416 if ( Bin2->T.SB.BlockTerms[blin2] == 0 ) {
4418 UNLOCK(Bin2->T.SB.MasterBlockLock[Bin2->T.SB.MasterNumBlocks]);
4421 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2-1]);
4423 if ( blin2 == Bin2->T.SB.MasterNumBlocks ) {
4429 LOCK(Bin2->T.SB.MasterBlockLock[blin2]);
4430 Bin2->T.SB.MasterBlock = blin2;
4431 term2 = Bin2->T.SB.MasterStart[blin2];
4441 Bin1->T.SB.BlockTerms[blin1]--;
4442 Bin2->T.SB.BlockTerms[blin2]--;
4443 l1 = *( m1 = term1 );
4444 l2 = *( m2 = term2 );
4445 if ( S->PolyWise ) {
4449 if ( S->PolyFlag == 2 ) {
4450 AT.WorkPointer = wp;
4452 if ( *tt1 + w[1] - m1[1] > AM.MaxTer/((LONG)
sizeof(WORD)) ) {
4453 MLOCK(ErrorMessageLock);
4454 MesPrint(
"Term too complex in PolyRatFun addition. MaxTermSize of %10l is too small",AM.MaxTer);
4455 MUNLOCK(ErrorMessageLock);
4458 AT.WorkPointer = wp;
4459 if ( w[FUNHEAD] == -SNUMBER && w[FUNHEAD+1] == 0 && w[1] > FUNHEAD ) {
4465 if ( w + m1[1] + m2[1] > AT.WorkTop ) {
4466 MLOCK(ErrorMessageLock);
4467 MesPrint(
"SortBotMerge(%d): A Maxtermsize of %10l is too small",
4468 AT.identity,AM.MaxTer/
sizeof(WORD));
4469 MesPrint(
"m1[1] = %d, m2[1] = %d, Space = %l",m1[1],m2[1],(LONG)(AT.WorkTop-wp));
4470 PrintTerm(term1,
"term1");
4471 PrintTerm(term2,
"term2");
4472 MesPrint(
"PolyWise = %d",S->PolyWise);
4473 MUNLOCK(ErrorMessageLock);
4480 || ( w[FUNHEAD] == -SNUMBER && w[FUNHEAD+1] == 0 ) )
4482 if ( r1 == m1[1] ) {
4485 else if ( r1 < m1[1] ) {
4489 while ( --r1 >= 0 ) *--m1 = *--m2;
4492 while ( --r1 >= 0 ) *--m1 = *--m2;
4515 else if ( AT.SortFloatMode ) {
4523 tstop1 = m1+l1; size1 = tstop1[-1]; tstop1 -= ABS(size1);
4524 tstop2 = m2+l2; size2 = tstop2[-1]; tstop2 -= ABS(size2);
4525 if ( AT.SortFloatMode == 3 ) {
4527 while ( fun1[0] != FLOATFUN && fun1+fun1[1] < tstop1 ) {
4530 if ( size1 < 0 ) fun1[FUNHEAD+3] = -fun1[FUNHEAD+3];
4531 UnpackFloat(aux1,fun1);
4533 while ( fun2[0] != FLOATFUN && fun2+fun2[1] < tstop2 ) {
4536 if ( size2 < 0 ) fun2[FUNHEAD+3] = -fun2[FUNHEAD+3];
4537 UnpackFloat(aux2,fun2);
4539 else if ( AT.SortFloatMode == 1 ) {
4541 while ( fun1[0] != FLOATFUN && fun1+fun1[1] < tstop1 ) {
4544 if ( size1 < 0 ) fun1[FUNHEAD+3] = -fun1[FUNHEAD+3];
4545 UnpackFloat(aux1,fun1);
4547 RatToFloat(aux2,(UWORD *)fun2,size2);
4549 else if ( AT.SortFloatMode == 2 ) {
4551 RatToFloat(aux1,(UWORD *)fun1,size1);
4553 while ( fun2[0] != FLOATFUN && fun2+fun2[1] < tstop2 ) {
4556 if ( size2 < 0 ) fun2[FUNHEAD+3] = -fun2[FUNHEAD+3];
4557 UnpackFloat(aux2,fun2);
4560 MLOCK(ErrorMessageLock);
4561 MesPrint(
"Illegal value %d for AT.SortFloatMode in SortBotMerge.",AT.SortFloatMode);
4562 MUNLOCK(ErrorMessageLock);
4566 mpf_add(aux3,aux1,aux2);
4567 size3 = mpf_sgn(aux3);
4571 else if ( size3 < 0 ) mpf_neg(aux3,aux3);
4572 fun3 = TermMalloc(
"MasterMerge");
4573 PackFloat(fun3,aux3);
4574 l3 = fun3[1]+(fun1-m1)+3;
4580 if ( (l3)*((LONG)
sizeof(WORD)) >= AM.MaxTer ) {
4581 MLOCK(ErrorMessageLock);
4582 MesPrint(
"MasterMerge: Coefficient overflow during sort");
4583 MUNLOCK(ErrorMessageLock);
4586 m3 = wp; m2 = term1;
4587 while ( m2 < fun1 ) *m3++ = *m2++;
4588 for ( jj = 0; jj < fun3[1]; jj++ ) *m3++ = fun3[jj];
4589 *m3++ = 1; *m3++ = 1;
4590 *m3++ = size3 < 0 ? -3: 3;
4592 TermFree(fun3,
"MasterMerge");
4595 for ( jj = 0; jj < fun3[1]; jj++ ) fun1[jj] = fun3[jj];
4597 *fun1++ = 1; *fun1++ = 1;
4598 *fun1++ = size3 < 0 ? -3: 3;
4599 *term1 = fun1-term1;
4600 TermFree(fun3,
"MasterMerge");
4604 r1 = *( m1 += l1 - 1 );
4606 r1 = ( ( r1 > 0 ) ? (r1-1) : (r1+1) ) >> 1;
4607 r2 = *( m2 += l2 - 1 );
4609 r2 = ( ( r2 > 0 ) ? (r2-1) : (r2+1) ) >> 1;
4611 if ( AddRat(BHEAD (UWORD *)m1,r1,(UWORD *)m2,r2,coef,&r3) ) {
4612 MLOCK(ErrorMessageLock);
4613 MesCall(
"SortBotMerge");
4614 MUNLOCK(ErrorMessageLock);
4618 if ( AN.ncmod != 0 ) {
4619 if ( ( AC.modmode & POSNEG ) != 0 ) {
4622 else if ( BigLong(coef,r3,(UWORD *)AC.cmod,ABS(AN.ncmod)) >= 0 ) {
4623 SubPLon(coef,r3,(UWORD *)AC.cmod,ABS(AN.ncmod),coef,&r3);
4625 for ( ii = 1; ii < r3; ii++ ) coef[r3+ii] = 0;
4628 if ( !r3 ) {
goto cancelled; }
4630 r33 = ( r3 > 0 ) ? ( r3 + 1 ) : ( r3 - 1 );
4631 if ( r3 < 0 ) r3 = -r3;
4632 if ( r1 < 0 ) r1 = -r1;
4636 m2 = (WORD *)coef; im = r3;
4641 to = wp; from = term1;
4642 while ( from < m1 ) *to++ = *from++;
4643 from = (WORD *)coef; im = r3;
4648 if ( SortBotOut(BHEAD wp) < 0 ) {
4649 MLOCK(ErrorMessageLock);
4650 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4651 MUNLOCK(ErrorMessageLock);
4658 if ( SortBotOut(BHEAD term1) < 0 ) {
4659 MLOCK(ErrorMessageLock);
4660 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4661 MUNLOCK(ErrorMessageLock);
4667 if ( Bin1->T.SB.BlockTerms[blin1] == 0 ) {
4670 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4673 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4675 if ( blin1 == Bin1->T.SB.MasterNumBlocks ) {
4681 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4682 Bin1->T.SB.MasterBlock = blin1;
4683 term1 = Bin1->T.SB.MasterStart[blin1];
4699 Bin1->T.SB.BlockTerms[blin1]--;
4700 if ( SortBotOut(BHEAD term1) < 0 ) {
4701 MLOCK(ErrorMessageLock);
4702 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4703 MUNLOCK(ErrorMessageLock);
4707 if ( Bin1->T.SB.BlockTerms[blin1] == 0 ) {
4710 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4713 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4715 if ( blin1 == Bin1->T.SB.MasterNumBlocks ) {
4721 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4722 Bin1->T.SB.MasterBlock = blin1;
4723 term1 = Bin1->T.SB.MasterStart[blin1];
4733 else if ( *term2 ) {
4738 Bin2->T.SB.BlockTerms[blin2]--;
4739 if ( SortBotOut(BHEAD term2) < 0 ) {
4740 MLOCK(ErrorMessageLock);
4741 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4742 MUNLOCK(ErrorMessageLock);
4746 if ( Bin2->T.SB.BlockTerms[blin2] == 0 ) {
4749 UNLOCK(Bin2->T.SB.MasterBlockLock[Bin2->T.SB.MasterNumBlocks]);
4752 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2-1]);
4754 if ( blin2 == Bin2->T.SB.MasterNumBlocks ) {
4760 LOCK(Bin2->T.SB.MasterBlockLock[blin2]);
4761 Bin2->T.SB.MasterBlock = blin2;
4762 term2 = Bin2->T.SB.MasterStart[blin2];
4776 Bin1->T.SB.BlockTerms[blin1]--;
4777 Bin2->T.SB.BlockTerms[blin2]--;
4779 SortBotOut(BHEAD 0);
4784 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4786 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4789 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4791 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2]);
4793 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2-1]);
4796 UNLOCK(Bin2->T.SB.MasterBlockLock[Bin2->T.SB.MasterNumBlocks]);
4798 if ( AT.identity > 0 ) {
4799 UNLOCK(AT.SB.MasterBlockLock[AT.SB.FillBlock]);
4814static int SortBlocksInitialized = 0;
4822int IniSortBlocks(
int numworkers)
4826 LONG totalsize, workersize, blocksize, numberofterms;
4828 int numberofblocks = NUMBEROFBLOCKSINSORT, numparts;
4831 if ( SortBlocksInitialized )
return(0);
4832 SortBlocksInitialized = 1;
4833 if ( numworkers == 0 )
return(0);
4836 if ( numworkers > 2 ) {
4837 numparts = 2*numworkers - 2;
4838 numberofblocks = numberofblocks/2;
4841 numparts = numworkers;
4844 numparts = numworkers;
4847 totalsize = S->LargeSize + S->SmallEsize;
4848 workersize = totalsize / numparts;
4849 maxter = AM.MaxTer/
sizeof(WORD);
4850 blocksize = ( workersize - maxter )/numberofblocks;
4851 numberofterms = blocksize / maxter;
4852 if ( numberofterms < MINIMUMNUMBEROFTERMS ) {
4856 MesPrint(
"We have a problem with the size of the blocks in IniSortBlocks");
4865 if ( w == 0 ) w = S->sBuffer;
4866 for (
id = 1;
id <= numparts;
id++ ) {
4868 AT.SB.MasterBlockLock = (pthread_mutex_t *)Malloc1(
4869 sizeof(pthread_mutex_t)*(numberofblocks+1),
"MasterBlockLock");
4870 AT.SB.MasterStart = (WORD **)Malloc1(
sizeof(WORD *)*(numberofblocks+1)*3,
"MasterBlock");
4871 AT.SB.MasterFill = AT.SB.MasterStart + (numberofblocks+1);
4872 AT.SB.MasterStop = AT.SB.MasterFill + (numberofblocks+1);
4873 AT.SB.MasterNumBlocks = numberofblocks;
4874 AT.SB.BlockTerms = (LONG*)Malloc1(
sizeof(LONG)*(numberofblocks+1),
"BlockTerms");
4875 AT.SB.MasterBlock = 0;
4876 AT.SB.FillBlock = 0;
4877 AT.SB.MasterFill[0] = AT.SB.MasterStart[0] = w;
4878 AT.SB.BlockTerms[0] = 0;
4880 AT.SB.MasterStop[0] = w;
4881 AT.SB.MasterBlockLock[0] = dummylock;
4882 for ( j = 1; j <= numberofblocks; j++ ) {
4883 AT.SB.MasterFill[j] = AT.SB.MasterStart[j] = w;
4884 AT.SB.BlockTerms[j] = 0;
4886 AT.SB.MasterStop[j] = w;
4887 AT.SB.MasterBlockLock[j] = dummylock;
4890 if ( w > S->sTop2 ) {
4891 MesPrint(
"Counting problem in IniSortBlocks");
4906int UpdateSortBlocks(
int numworkers)
4910 LONG totalsize, workersize, blocksize, numberofterms;
4912 int numberofblocks = NUMBEROFBLOCKSINSORT, numparts;
4915 if ( numworkers == 0 )
return(0);
4918 if ( numworkers > 2 ) {
4919 numparts = 2*numworkers - 2;
4920 numberofblocks = numberofblocks/2;
4923 numparts = numworkers;
4926 numparts = numworkers;
4929 totalsize = S->LargeSize + S->SmallEsize;
4930 workersize = totalsize / numparts;
4931 maxter = AM.MaxTer/
sizeof(WORD);
4932 blocksize = ( workersize - maxter )/numberofblocks;
4933 numberofterms = blocksize / maxter;
4934 if ( numberofterms < MINIMUMNUMBEROFTERMS ) {
4938 MesPrint(
"We have a problem with the size of the blocks in UpdateSortBlocks");
4947 if ( w == 0 ) w = S->sBuffer;
4948 for (
id = 1;
id <= numparts;
id++ ) {
4950 AT.SB.MasterFill[0] = AT.SB.MasterStart[0] = w;
4952 AT.SB.MasterStop[0] = w;
4953 for ( j = 1; j <= numberofblocks; j++ ) {
4954 AT.SB.MasterFill[j] = AT.SB.MasterStart[j] = w;
4956 AT.SB.MasterStop[j] = w;
4959 if ( w > S->sTop2 ) {
4960 MesPrint(
"Counting problem in UpdateSortBlocks");
4978void DefineSortBotTree(
void)
4982 if ( numberofworkers <= 2 )
return;
4983 n = numberofworkers*2-2;
4984 for ( i = numberofworkers+1, from = 1; i <= n; i++ ) {
4986 AT.SortBotIn1 = from++;
4987 AT.SortBotIn2 = from++;
4990 AT.SortBotIn1 = from++;
4991 AT.SortBotIn2 = from++;
5006WORD GetTerm2(PHEAD WORD *term)
5008 WORD *ttco, *tt, retval;
5014 POSITION where, eonfile = AS.OldOnFile[e-Expressions], bstart, bnext;
5018 switch ( e->status ) {
5019 case UNHIDELEXPRESSION:
5020 case UNHIDEGEXPRESSION:
5021 case DROPHLEXPRESSION:
5022 case DROPHGEXPRESSION:
5023 case HIDDENLEXPRESSION:
5024 case HIDDENGEXPRESSION:
5031 if ( AR.KeptInHold ) {
5032 retval = GetTerm(BHEAD term);
5035 SeekScratch(fi,&where);
5036 if ( AN.lastinindex < 0 ) {
5040 if ( ( n = TreatIndexEntry(BHEAD 0) ) <= 0 ) {
5042 where = bi[n].start;
5043 ADD2POS(where,eonfile);
5044 SetScratch(fi,&where);
5048 ttco = AR.CompressBuffer;
5052 AR.CompressPointer = ttco;
5053 retval = GetTerm(BHEAD term);
5056 else AN.lastinindex = n-1;
5063 bstart = bi[n].start;
5064 ADD2POS(bstart,eonfile);
5066 ADD2POS(bnext,eonfile);
5067 if ( ISLESSPOS(bstart,where) && ISLESSPOS(where,bnext) ) {
5068 retval = GetTerm(BHEAD term);
5071 for ( n++ ; n < b->indexfill; n++ ) {
5072 i = TreatIndexEntry(BHEAD n);
5077 ttco = AR.CompressBuffer;
5081 AR.CompressPointer = ttco;
5083 where = bi[n].start;
5084 ADD2POS(where,eonfile);
5085 SetScratch(fi,&(where));
5086 retval = GetTerm(BHEAD term);
5106int TreatIndexEntry(PHEAD LONG n)
5109 LONG numbra = b->indexfill - 1, i;
5117 if ( ( numbra - n ) <= numberofworkers )
return(0);
5123 DIFPOS(pos1,bi[numbra].next,bi[n].next);
5124 BASEPOSITION(average) = DIVPOS(pos1,(3*numberofworkers));
5125 DIFPOS(pos1,bi[n].next,bi[n].start);
5126 if ( ISLESSPOS(average,pos1) )
return(0);
5131 totterms = bi->termsinbracket;
5132 if ( totterms > 2*AC.ThreadBucketSize )
return(1);
5133 for ( i = 1; i < numbra-n; i++ ) {
5134 DIFPOS(pos1,bi[n+i].next,bi[n].start);
5135 if ( ISLESSPOS(average,pos1) )
return(i);
5136 totterms += bi->termsinbracket;
5137 if ( totterms > 2*AC.ThreadBucketSize )
return(i+1);
5150void SetHideFiles(
void) {
5152 ALLPRIVATES *B, *B0 = AB[0];
5153 for ( i = 1; i <= numberofworkers; i++ ) {
5155 AR.hidefile->handle = AR0.hidefile->handle;
5156 if ( AR.hidefile->handle < 0 ) {
5157 AR.hidefile->PObuffer = AR0.hidefile->PObuffer;
5158 AR.hidefile->POstop = AR0.hidefile->POstop;
5159 AR.hidefile->POfill = AR0.hidefile->POfill;
5160 AR.hidefile->POfull = AR0.hidefile->POfull;
5161 AR.hidefile->POsize = AR0.hidefile->POsize;
5162 AR.hidefile->POposition = AR0.hidefile->POposition;
5163 AR.hidefile->filesize = AR0.hidefile->filesize;
5166 AR.hidefile->PObuffer = AR.hidefile->wPObuffer;
5167 AR.hidefile->POstop = AR.hidefile->wPOstop;
5168 AR.hidefile->POfill = AR.hidefile->wPOfill;
5169 AR.hidefile->POfull = AR.hidefile->wPOfull;
5170 AR.hidefile->POsize = AR.hidefile->wPOsize;
5171 PUTZERO(AR.hidefile->POposition);
5184 for ( i = 0; i < AM.totalnumberofthreads; i++ ) {
5198 for ( j = 0; j < AM.totalnumberofthreads; j++ ) {
5200 AN.ncmod = AC.ncmod;
5201 if ( AN.cmod != 0 ) M_free(AN.cmod,
"AN.cmod");
5203 AN.cmod = (UWORD *)Malloc1(
sizeof(WORD)*n,
"AN.cmod");
5204 for ( i = 0; i < n; i++ ) AN.cmod[i] = AC.cmod[i];
5217 for ( j = 0; j < AM.totalnumberofthreads; j++ ) {
5219 if ( AN.cmod != 0 ) M_free(AN.cmod,
"AN.cmod");
5229void find_Horner_MCTS_expand_tree_threaded(
void) {
5231 while ((
id = GetAvailableThread() ) < 0)
5233 WakeupThread(
id,MCTSEXPANDTREE);
5241extern void optimize_expression_given_Horner_threaded(
void) {
5243 while ((
id = GetAvailableThread() ) < 0)
5245 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