74int PackFloat(WORD *,mpf_t);
75int UnpackFloat(mpf_t, WORD *);
76void RatToFloat(mpf_t result, UWORD *formrat,
int ratsize);
79static int numberofthreads;
80static int numberofworkers;
81static int identityofthreads = 0;
82static int *listofavailables;
83static int topofavailables = 0;
84static pthread_key_t identitykey;
85static INILOCK(numberofthreadslock)
86static INILOCK(availabilitylock)
87static pthread_t *threadpointers = 0;
88static pthread_mutex_t *wakeuplocks;
89static pthread_mutex_t *wakeupmasterthreadlocks;
90static pthread_cond_t *wakeupconditions;
91static pthread_condattr_t *wakeupconditionattributes;
93static int *wakeupmasterthread;
94static INILOCK(wakeupmasterlock)
95static pthread_cond_t wakeupmasterconditions = PTHREAD_COND_INITIALIZER;
96static pthread_cond_t *wakeupmasterthreadconditions;
97static int wakeupmaster = 0;
98static int identityretval;
100static LONG *timerinfo;
101static LONG *sumtimerinfo;
102static int numberclaimed;
104static THREADBUCKET **threadbuckets, **freebuckets;
105static int numthreadbuckets;
106static int numberoffullbuckets;
111INIRWLOCK(dummyrwlock)
112static pthread_cond_t dummywakeupcondition = PTHREAD_COND_INITIALIZER;
116static int numberofsortbots;
117static INILOCK(wakeupsortbotlock)
118static pthread_cond_t wakeupsortbotconditions = PTHREAD_COND_INITIALIZER;
119static int topsortbotavailables = 0;
120static LONG numberofterms;
133void StartIdentity(
void)
135 pthread_key_create(&identitykey,FinishIdentity);
146void FinishIdentity(
void *keyp)
160int SetIdentity(
int *identityretval)
168 LOCK(numberofthreadslock);
169 *identityretval = identityofthreads++;
170 UNLOCK(numberofthreadslock);
171 pthread_setspecific(identitykey,(
void *)identityretval);
172 return(*identityretval);
196 if ( identityofthreads <= 1 )
return(0);
205 identity = (
int *)pthread_getspecific(identitykey);
218void BeginIdentities(
void)
221 SetIdentity(&identityretval);
235void StartHandleLock(
void)
237 AM.handlelock = dummyrwlock;
261int StartAllThreads(
int number)
263 int identity, j, dummy, mul;
269 timerinfo = (LONG *)Malloc1(
sizeof(LONG)*number*2,
"timerinfo");
270 sumtimerinfo = (LONG *)Malloc1(
sizeof(LONG)*number*2,
"sumtimerinfo");
271 for ( j = 0; j < number*2; j++ ) { timerinfo[j] = 0; sumtimerinfo[j] = 0; }
274 timerinfo = (LONG *)Malloc1(
sizeof(LONG)*number,
"timerinfo");
275 sumtimerinfo = (LONG *)Malloc1(
sizeof(LONG)*number,
"sumtimerinfo");
276 for ( j = 0; j < number; j++ ) { timerinfo[j] = 0; sumtimerinfo[j] = 0; }
280 listofavailables = (
int *)Malloc1(
sizeof(
int)*(number+1),
"listofavailables");
281 threadpointers = (pthread_t *)Malloc1(
sizeof(pthread_t)*number*mul,
"threadpointers");
282 AB = (ALLPRIVATES **)Malloc1(
sizeof(ALLPRIVATES *)*number*mul,
"Private structs");
284 wakeup = (
int *)Malloc1(
sizeof(
int)*number*mul,
"wakeup");
285 wakeuplocks = (pthread_mutex_t *)Malloc1(
sizeof(pthread_mutex_t)*number*mul,
"wakeuplocks");
286 wakeupconditions = (pthread_cond_t *)Malloc1(
sizeof(pthread_cond_t)*number*mul,
"wakeupconditions");
287 wakeupconditionattributes = (pthread_condattr_t *)
288 Malloc1(
sizeof(pthread_condattr_t)*number*mul,
"wakeupconditionattributes");
290 wakeupmasterthread = (
int *)Malloc1(
sizeof(
int)*number*mul,
"wakeupmasterthread");
291 wakeupmasterthreadlocks = (pthread_mutex_t *)Malloc1(
sizeof(pthread_mutex_t)*number*mul,
"wakeupmasterthreadlocks");
292 wakeupmasterthreadconditions = (pthread_cond_t *)Malloc1(
sizeof(pthread_cond_t)*number*mul,
"wakeupmasterthread");
294 numberofthreads = number;
295 numberofworkers = number - 1;
296 threadpointers[identity] = pthread_self();
304 sigemptyset(&sig_set);
305 sigaddset(&sig_set, SIGALRM);
306 pthread_sigmask(SIG_BLOCK, &sig_set, NULL);
309 for ( j = 1; j < number; j++ ) {
310 if ( pthread_create(&thethread,NULL,RunThread,(
void *)(&dummy)) )
316 B = InitializeOneThread(identity);
317 AR.infile = &(AR.Fscr[0]);
318 AR.outfile = &(AR.Fscr[1]);
319 AR.hidefile = &(AR.Fscr[2]);
320 AM.sbuflock = dummylock;
321 AS.inputslock = dummylock;
322 AS.outputslock = dummylock;
323 AS.MaxExprSizeLock = dummylock;
324 AP.PreVarLock = dummylock;
325 AC.halfmodlock = dummylock;
326 MakeThreadBuckets(number,0);
334 if ( numberofworkers > 2 ) {
335 numberofsortbots = numberofworkers-2;
336 for ( j = numberofworkers+1; j < 2*numberofworkers-1; j++ ) {
337 if ( pthread_create(&thethread,NULL,RunSortBot,(
void *)(&dummy)) )
342 numberofsortbots = 0;
344 MasterWaitAllSortBots();
347 IniSortBlocks(number-1);
349 AM.storefilelock = dummylock;
353 pthread_sigmask(SIG_UNBLOCK, &sig_set, NULL);
361 MesPrint(
"Cannot start %d threads",number);
373UBYTE *scratchname[] = { (UBYTE *)
"scratchsize",
374 (UBYTE *)
"scratchsize",
375 (UBYTE *)
"hidesize" };
402ALLPRIVATES *InitializeOneThread(
int identity)
404 WORD *t, *ScratchBuf;
405 int i, j, bsize, *bp;
406 LONG ScratchSize[3], IOsize;
410 wakeup[identity] = 0;
411 wakeuplocks[identity] = dummylock;
412 pthread_condattr_init(&(wakeupconditionattributes[identity]));
413 pthread_condattr_setpshared(&(wakeupconditionattributes[identity]),PTHREAD_PROCESS_PRIVATE);
414 wakeupconditions[identity] = dummywakeupcondition;
415 pthread_cond_init(&(wakeupconditions[identity]),&(wakeupconditionattributes[identity]));
416 wakeupmasterthread[identity] = 0;
417 wakeupmasterthreadlocks[identity] = dummylock;
418 wakeupmasterthreadconditions[identity] = dummywakeupcondition;
420 bsize =
sizeof(ALLPRIVATES);
421 bsize = (bsize+
sizeof(int)-1)/
sizeof(int);
422 B = (ALLPRIVATES *)Malloc1(
sizeof(
int)*bsize,
"B struct");
423 for ( bp = (
int *)B, j = 0; j < bsize; j++ ) *bp++ = 0;
442 if ( identity > 0 )
TimeCPU(0);
446 if ( identity > numberofworkers ) {
451 LONG length = AM.WorkSize*
sizeof(WORD)/8+AM.MaxTer*2;
452 AT.WorkSpace = (WORD *)Malloc1(length,
"WorkSpace");
453 AT.WorkTop = AT.WorkSpace + length/
sizeof(WORD);
454 AT.WorkPointer = AT.WorkSpace;
455 AT.identity = identity;
460 if ( AN.SoScratC == 0 ) {
461 AN.SoScratC = (UWORD *)Malloc1(2*(AM.MaxTal+2)*
sizeof(UWORD),
"Scratch in SortBot");
467 AT.comsym[1] = SYMBOL;
478 AT.comfun[0] = FUNHEAD+4;
479 AT.comfun[1] = FUNCTION;
480 AT.comfun[2] = FUNHEAD;
483 for ( i = 4; i <= FUNHEAD; i++ )
486 AT.comfun[FUNHEAD+1] = 1;
487 AT.comfun[FUNHEAD+2] = 1;
488 AT.comfun[FUNHEAD+3] = 3;
490 AT.comind[1] = INDEX;
498 AT.sizeprimelist = 0;
502 AR.CompareRoutine = (COMPAREDUMMY)(&
Compare1);
507 AR.wranfnpair1 = NPAIR1;
508 AR.wranfnpair2 = NPAIR2;
512 AN.SplitScratchSize = AN.InScratch = 0;
513 AN.SplitScratch1 = 0;
514 AN.SplitScratchSize1 = AN.InScratch1 = 0;
516 AN.FunSorts = (
SORTING **)Malloc1((AN.NumFunSorts+1)*
sizeof(
SORTING *),
"FunSort pointers");
517 for ( i = 0; i <= AN.NumFunSorts; i++ ) AN.FunSorts[i] = 0;
518 AN.FunSorts[0] = AT.S0 = AT.SS;
519 AN.idfunctionflag = 0;
524 if ( identity == 0 && AN.SoScratC == 0 ) {
525 AN.SoScratC = (UWORD *)Malloc1(2*(AM.MaxTal+2)*
sizeof(UWORD),
"Scratch in SortBot");
528 AR.CurDum = AM.IndDum;
529 for ( j = 0; j < 3; j++ ) {
530 if ( identity == 0 ) {
532 ScratchSize[j] = AM.HideSize;
535 ScratchSize[j] = AM.ScratSize;
537 if ( ScratchSize[j] < 10*AM.MaxTer ) ScratchSize[j] = 10 * AM.MaxTer;
545 if ( j == 1 ) ScratchSize[j] = AM.ThreadScratOutSize;
546 else ScratchSize[j] = AM.ThreadScratSize;
547 if ( ScratchSize[j] < 4*AM.MaxTer ) ScratchSize[j] = 4 * AM.MaxTer;
550 ScratchSize[j] = ( ScratchSize[j] + 255 ) / 256;
551 ScratchSize[j] = ScratchSize[j] * 256;
552 ScratchBuf = (WORD *)Malloc1(ScratchSize[j]*
sizeof(WORD),(
char *)(scratchname[j]));
553 AR.Fscr[j].POsize = ScratchSize[j] *
sizeof(WORD);
554 AR.Fscr[j].POfull = AR.Fscr[j].POfill = AR.Fscr[j].PObuffer = ScratchBuf;
555 AR.Fscr[j].POstop = AR.Fscr[j].PObuffer + ScratchSize[j];
556 PUTZERO(AR.Fscr[j].POposition);
557 AR.Fscr[j].pthreadslock = dummylock;
558 AR.Fscr[j].wPOsize = AR.Fscr[j].POsize;
559 AR.Fscr[j].wPObuffer = AR.Fscr[j].PObuffer;
560 AR.Fscr[j].wPOfill = AR.Fscr[j].POfill;
561 AR.Fscr[j].wPOfull = AR.Fscr[j].POfull;
562 AR.Fscr[j].wPOstop = AR.Fscr[j].POstop;
566 AR.Fscr[0].handle = -1;
567 AR.Fscr[1].handle = -1;
568 AR.Fscr[2].handle = -1;
569 AR.FoStage4[0].handle = -1;
570 AR.FoStage4[1].handle = -1;
571 IOsize = AM.S0->file.POsize;
573 AR.FoStage4[0].ziosize = IOsize;
574 AR.FoStage4[1].ziosize = IOsize;
575 AR.FoStage4[0].ziobuffer = 0;
576 AR.FoStage4[1].ziobuffer = 0;
578 AR.FoStage4[0].POsize = ((IOsize+
sizeof(WORD)-1)/
sizeof(WORD))*
sizeof(WORD);
579 AR.FoStage4[1].POsize = ((IOsize+
sizeof(WORD)-1)/
sizeof(WORD))*
sizeof(WORD);
581 AR.hidefile = &(AR.Fscr[2]);
582 AR.StoreData.Handle = -1;
583 AR.SortType = AC.SortType;
585 AN.IndDum = AM.IndDum;
587 if ( identity > 0 ) {
588 s = (UBYTE *)(FG.fname); i = 0;
589 while ( *s ) { s++; i++; }
590 s = (UBYTE *)Malloc1(
sizeof(
char)*(i+12),
"name for Fscr[0] file");
591 snprintf((
char *)s,i+12,
"%s.%d",FG.fname,identity);
592 s[i-3] =
's'; s[i-2] =
'c'; s[i-1] =
'0';
593 AR.Fscr[0].name = (
char *)s;
594 s = (UBYTE *)(FG.fname); i = 0;
595 while ( *s ) { s++; i++; }
596 s = (UBYTE *)Malloc1(
sizeof(
char)*(i+12),
"name for Fscr[1] file");
597 snprintf((
char *)s,i+12,
"%s.%d",FG.fname,identity);
598 s[i-3] =
's'; s[i-2] =
'c'; s[i-1] =
'1';
599 AR.Fscr[1].name = (
char *)s;
602 AR.CompressBuffer = (WORD *)Malloc1((AM.CompressSize+10)*
sizeof(WORD),
"compresssize");
603 AR.ComprTop = AR.CompressBuffer + AM.CompressSize;
604 AR.CompareRoutine = (COMPAREDUMMY)(&
Compare1);
609 AT.WorkSpace = (WORD *)Malloc1(AM.WorkSize*
sizeof(WORD),
"WorkSpace");
610 AT.WorkTop = AT.WorkSpace + AM.WorkSize;
611 AT.WorkPointer = AT.WorkSpace;
613 AT.Nest = (
NESTING)Malloc1((LONG)
sizeof(
struct NeStInG)*AM.maxFlevels,
"functionlevels");
614 AT.NestStop = AT.Nest + AM.maxFlevels;
615 AT.NestPoin = AT.Nest;
617 AT.WildMask = (WORD *)Malloc1((LONG)AM.MaxWildcards*
sizeof(WORD),
"maxwildcards");
619 LOCK(availabilitylock);
624 UNLOCK(availabilitylock);
626 AT.RepCount = (
int *)Malloc1((LONG)((AM.RepMax+3)*
sizeof(
int)),
"repeat buffers");
627 AN.RepPoint = AT.RepCount;
631 AT.RepTop = AT.RepCount + AM.RepMax;
633 AT.WildArgTaken = (WORD *)Malloc1((LONG)AC.WildcardBufferSize*
sizeof(WORD)/2
634 ,
"argument list names");
635 AT.WildcardBufferSize = AC.WildcardBufferSize;
636 AT.previousEfactor = 0;
638 AT.identity = identity;
639 AT.LoadBalancing = 0;
645 if ( AT.WorkSpace == 0 ||
649 AT.WildArgTaken == 0 )
goto OnError;
654 AT.comsym[1] = SYMBOL;
665 AT.comfun[0] = FUNHEAD+4;
666 AT.comfun[1] = FUNCTION;
667 AT.comfun[2] = FUNHEAD;
670 for ( i = 4; i <= FUNHEAD; i++ )
673 AT.comfun[FUNHEAD+1] = 1;
674 AT.comfun[FUNHEAD+2] = 1;
675 AT.comfun[FUNHEAD+3] = 3;
677 AT.comind[1] = INDEX;
683 AT.locwildvalue[0] = SUBEXPRESSION;
684 AT.locwildvalue[1] = SUBEXPSIZE;
685 for ( i = 2; i < SUBEXPSIZE; i++ ) AT.locwildvalue[i] = 0;
686 AT.mulpat[0] = TYPEMULT;
687 AT.mulpat[1] = SUBEXPSIZE+3;
689 AT.mulpat[3] = SUBEXPRESSION;
690 AT.mulpat[4] = SUBEXPSIZE;
693 for ( i = 7; i < SUBEXPSIZE+5; i++ ) AT.mulpat[i] = 0;
694 AT.proexp[0] = SUBEXPSIZE+4;
695 AT.proexp[1] = EXPRESSION;
696 AT.proexp[2] = SUBEXPSIZE;
699 for ( i = 5; i < SUBEXPSIZE+1; i++ ) AT.proexp[i] = 0;
700 AT.proexp[SUBEXPSIZE+1] = 1;
701 AT.proexp[SUBEXPSIZE+2] = 1;
702 AT.proexp[SUBEXPSIZE+3] = 3;
703 AT.proexp[SUBEXPSIZE+4] = 0;
704 AT.dummysubexp[0] = SUBEXPRESSION;
705 AT.dummysubexp[1] = SUBEXPSIZE+4;
706 for ( i = 2; i < SUBEXPSIZE; i++ ) AT.dummysubexp[i] = 0;
707 AT.dummysubexp[SUBEXPSIZE] = WILDDUMMY;
708 AT.dummysubexp[SUBEXPSIZE+1] = 4;
709 AT.dummysubexp[SUBEXPSIZE+2] = 0;
710 AT.dummysubexp[SUBEXPSIZE+3] = 0;
712 AT.MinVecArg[0] = 7+ARGHEAD;
713 AT.MinVecArg[ARGHEAD] = 7;
714 AT.MinVecArg[1+ARGHEAD] = INDEX;
715 AT.MinVecArg[2+ARGHEAD] = 3;
716 AT.MinVecArg[3+ARGHEAD] = 0;
717 AT.MinVecArg[4+ARGHEAD] = 1;
718 AT.MinVecArg[5+ARGHEAD] = 1;
719 AT.MinVecArg[6+ARGHEAD] = -3;
721 *t++ = 4+ARGHEAD+FUNHEAD;
722 for ( i = 1; i < ARGHEAD; i++ ) *t++ = 0;
726 for ( i = 2; i < FUNHEAD; i++ ) *t++ = 0;
727 *t++ = 1; *t++ = 1; *t++ = 3;
730 AT.sizeprimelist = 0;
732 AT.nfac = AT.nBer = 0;
737 AR.wranfnpair1 = NPAIR1;
738 AR.wranfnpair2 = NPAIR2;
741 AT.NormData = Malloc1(
sizeof(*(AT.NormData)),
"NormData thread pointers");
743 AT.NormData[0] = AllocNormData();
747 AN.SplitScratchSize = AN.InScratch = 0;
748 AN.SplitScratch1 = 0;
749 AN.SplitScratchSize1 = AN.InScratch1 = 0;
754 if ( identity == 0 ) {
762 AT.S0 = AllocSort(AM.S0->LargeSize*
sizeof(WORD)/numberofworkers
763 ,AM.S0->SmallSize*
sizeof(WORD)/numberofworkers
764 ,AM.S0->SmallEsize*
sizeof(WORD)/numberofworkers
768 ,AM.S0->MaxFpatches/numberofworkers
772 AR.CompressPointer = AR.CompressBuffer;
776 AT.StoreCache = AT.StoreCacheAlloc = 0;
777 if ( AM.NumStoreCaches > 0 ) {
780 size =
sizeof(
struct StOrEcAcHe)+AM.SizeStoreCache;
781 size = ((size-1)/
sizeof(
size_t)+1)*
sizeof(
size_t);
782 AT.StoreCacheAlloc = (
STORECACHE)Malloc1(size*AM.NumStoreCaches,
"StoreCaches");
783 sa = AT.StoreCache = AT.StoreCacheAlloc;
784 for ( i = 0; i < AM.NumStoreCaches; i++ ) {
786 if ( i == AM.NumStoreCaches-1 ) {
792 SETBASEPOSITION(sa->position,-1);
793 SETBASEPOSITION(sa->toppos,-1);
801 MLOCK(ErrorMessageLock);
802 MesPrint(
"Error initializing thread %d",identity);
803 MUNLOCK(ErrorMessageLock);
822void FinalizeOneThread(
int identity)
824 timerinfo[identity] =
TimeCPU(1);
837void ClearAllThreads(
void)
841 for ( i = 1; i <= numberofworkers; i++ ) {
842 WakeupThread(i,CLEARCLOCK);
845 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
846 WakeupThread(i,CLEARCLOCK);
861void TerminateAllThreads(
void)
864 for ( i = 1; i <= numberofworkers; i++ ) {
866 WakeupThread(i,TERMINATETHREAD);
869 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
870 WakeupThread(i,TERMINATETHREAD);
873 for ( i = 1; i <= numberofworkers; i++ ) {
874 pthread_join(threadpointers[i],NULL);
877 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
878 pthread_join(threadpointers[i],NULL);
912int MakeThreadBuckets(
int number,
int par)
915 LONG sizethreadbuckets;
923 sizethreadbuckets = ( AC.ThreadBucketSize + 1 ) * AM.MaxTer + 2*
sizeof(WORD);
924 if ( AC.ThreadBucketSize >= 250 ) sizethreadbuckets /= 4;
925 else if ( AC.ThreadBucketSize >= 90 ) sizethreadbuckets /= 3;
926 else if ( AC.ThreadBucketSize >= 40 ) sizethreadbuckets /= 2;
927 sizethreadbuckets /=
sizeof(WORD);
930 numthreadbuckets = 2*(number-1);
931 threadbuckets = (THREADBUCKET **)Malloc1(numthreadbuckets*
sizeof(THREADBUCKET *),
"threadbuckets");
932 freebuckets = (THREADBUCKET **)Malloc1(numthreadbuckets*
sizeof(THREADBUCKET *),
"threadbuckets");
935 if ( sizethreadbuckets <= threadbuckets[0]->threadbuffersize )
return(0);
936 for ( i = 0; i < numthreadbuckets; i++ ) {
937 thr = threadbuckets[i];
938 M_free(thr->deferbuffer,
"deferbuffer");
942 for ( i = 0; i < numthreadbuckets; i++ ) {
943 threadbuckets[i] = (THREADBUCKET *)Malloc1(
sizeof(THREADBUCKET),
"threadbuckets");
944 threadbuckets[i]->lock = dummylock;
947 for ( i = 0; i < numthreadbuckets; i++ ) {
948 thr = threadbuckets[i];
949 thr->threadbuffersize = sizethreadbuckets;
950 thr->free = BUCKETFREE;
951 thr->deferbuffer = (
POSITION *)Malloc1(2*sizethreadbuckets*
sizeof(WORD)
952 +(AC.ThreadBucketSize+1)*
sizeof(
POSITION),
"deferbuffer");
953 thr->threadbuffer = (WORD *)(thr->deferbuffer+AC.ThreadBucketSize+1);
954 thr->compressbuffer = (WORD *)(thr->threadbuffer+sizethreadbuckets);
955 thr->busy = BUCKETPREPARINGTERM;
956 thr->usenum = thr->totnum = 0;
957 thr->type = BUCKETDOINGTERMS;
972int GetTimerInfo(LONG** ti,LONG** sti)
977 return AM.totalnumberofthreads*2;
979 return AM.totalnumberofthreads;
992void WriteTimerInfo(LONG* ti,LONG* sti)
996 int max = AM.totalnumberofthreads*2;
998 int max = AM.totalnumberofthreads;
1000 for ( i=0; i<max; ++i ) {
1001 timerinfo[i] = ti[i];
1002 sumtimerinfo[i] = sti[i];
1015LONG GetWorkerTimes(
void)
1019 for ( i = 1; i <= numberofworkers; i++ ) retval += timerinfo[i] + sumtimerinfo[i];
1021 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ )
1022 retval += timerinfo[i] + sumtimerinfo[i];
1037int UpdateOneThread(
int identity)
1039 ALLPRIVATES *B = AB[identity], *B0 = AB[0];
1040 AR.GetFile = AR0.GetFile;
1041 AR.KeptInHold = AR0.KeptInHold;
1042 AR.CurExpr = AR0.CurExpr;
1043 AR.SortType = AC.SortType;
1044 if ( AT.WildcardBufferSize < AC.WildcardBufferSize ) {
1045 M_free(AT.WildArgTaken,
"argument list names");
1046 AT.WildcardBufferSize = AC.WildcardBufferSize;
1047 AT.WildArgTaken = (WORD *)Malloc1((LONG)AC.WildcardBufferSize*
sizeof(WORD)/2
1048 ,
"argument list names");
1049 if ( AT.WildArgTaken == 0 )
return(-1);
1071int LoadOneThread(
int from,
int identity, THREADBUCKET *thr,
int par)
1074 ALLPRIVATES *B = AB[identity], *B0 = AB[from];
1076 AR.DefPosition = AR0.DefPosition;
1077 AR.NoCompress = AR0.NoCompress;
1078 AR.gzipCompress = AR0.gzipCompress;
1079 AR.BracketOn = AR0.BracketOn;
1080 AR.CurDum = AR0.CurDum;
1081 AR.DeferFlag = AR0.DeferFlag;
1083 AR.sLevel = AR0.sLevel;
1084 AR.Stage4Name = AR0.Stage4Name;
1085 AR.GetOneFile = AR0.GetOneFile;
1086 AR.PolyFun = AR0.PolyFun;
1087 AR.PolyFunInv = AR0.PolyFunInv;
1088 AR.PolyFunType = AR0.PolyFunType;
1089 AR.PolyFunExp = AR0.PolyFunExp;
1090 AR.PolyFunVar = AR0.PolyFunVar;
1091 AR.PolyFunPow = AR0.PolyFunPow;
1092 AR.Eside = AR0.Eside;
1093 AR.Cnumlhs = AR0.Cnumlhs;
1105 t1 = AR.CompressBuffer; t2 = AR0.CompressBuffer;
1106 while ( t2 < AR0.CompressPointer ) *t1++ = *t2++;
1107 AR.CompressPointer = t1;
1111 AR.CompressPointer = AR.CompressBuffer;
1113 if ( AR.DeferFlag ) {
1114 if ( AR.infile->handle < 0 ) {
1115 AR.infile->POfill = AR0.infile->POfill;
1122 AR.infile->POfull = AR.infile->POfill = AR.infile->PObuffer;
1126 AN.threadbuck = thr;
1127 AN.ninterms = thr->firstterm;
1129 else if ( par == 1 ) {
1131 t1 = thr->threadbuffer; tstop = t1 + *t1;
1132 t2 = AT.WorkPointer;
1133 while ( t1 < tstop ) *t2++ = *t1++;
1134 AN.ninterms = thr->firstterm;
1137 AN.ncmod = AC.ncmod;
1138 AT.BrackBuf = AT0.BrackBuf;
1139 AT.bracketindexflag = AT0.bracketindexflag;
1167int BalanceRunThread(PHEAD
int identity, WORD *term, WORD level)
1174 LoadOneThread(AT.identity,identity,0,2);
1180 BB->R.level = level;
1181 BB->T.TMbuff = AT.TMbuff;
1182 ti = AT.RepCount; tti = BB->T.RepCount;
1183 i = AN.RepPoint - AT.RepCount;
1184 BB->N.RepPoint = BB->T.RepCount + i;
1185 for ( ; i >= 0; i-- ) tti[i] = ti[i];
1187 t = term; i = *term;
1188 tt = BB->T.WorkSpace;
1190 BB->T.WorkPointer = tt;
1192 WakeupThread(identity,HIGHERLEVELGENERATION);
1205void SetWorkerFiles(
void)
1208 ALLPRIVATES *B, *B0 = AB[0];
1209 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
1211 AR.infile = &(AR.Fscr[0]);
1212 AR.outfile = &(AR.Fscr[1]);
1213 AR.hidefile = &(AR.Fscr[2]);
1214 AR.infile->handle = AR0.infile->handle;
1215 AR.hidefile->handle = AR0.hidefile->handle;
1216 if ( AR.infile->handle < 0 ) {
1217 AR.infile->PObuffer = AR0.infile->PObuffer;
1218 AR.infile->POstop = AR0.infile->POstop;
1219 AR.infile->POfill = AR0.infile->POfill;
1220 AR.infile->POfull = AR0.infile->POfull;
1221 AR.infile->POsize = AR0.infile->POsize;
1222 AR.InInBuf = AR0.InInBuf;
1223 AR.infile->POposition = AR0.infile->POposition;
1224 AR.infile->filesize = AR0.infile->filesize;
1227 AR.infile->PObuffer = AR.infile->wPObuffer;
1228 AR.infile->POstop = AR.infile->wPOstop;
1229 AR.infile->POfill = AR.infile->wPOfill;
1230 AR.infile->POfull = AR.infile->wPOfull;
1231 AR.infile->POsize = AR.infile->wPOsize;
1233 PUTZERO(AR.infile->POposition);
1241 AR.outfile->PObuffer = AR.outfile->wPObuffer;
1242 AR.outfile->POstop = AR.outfile->wPOstop;
1243 AR.outfile->POfill = AR.outfile->wPOfill;
1244 AR.outfile->POfull = AR.outfile->wPOfull;
1245 AR.outfile->POsize = AR.outfile->wPOsize;
1246 PUTZERO(AR.outfile->POposition);
1248 if ( AR.hidefile->handle < 0 ) {
1249 AR.hidefile->PObuffer = AR0.hidefile->PObuffer;
1250 AR.hidefile->POstop = AR0.hidefile->POstop;
1251 AR.hidefile->POfill = AR0.hidefile->POfill;
1252 AR.hidefile->POfull = AR0.hidefile->POfull;
1253 AR.hidefile->POsize = AR0.hidefile->POsize;
1254 AR.InHiBuf = AR0.InHiBuf;
1255 AR.hidefile->POposition = AR0.hidefile->POposition;
1256 AR.hidefile->filesize = AR0.hidefile->filesize;
1259 AR.hidefile->PObuffer = AR.hidefile->wPObuffer;
1260 AR.hidefile->POstop = AR.hidefile->wPOstop;
1261 AR.hidefile->POfill = AR.hidefile->wPOfill;
1262 AR.hidefile->POfull = AR.hidefile->wPOfull;
1263 AR.hidefile->POsize = AR.hidefile->wPOsize;
1265 PUTZERO(AR.hidefile->POposition);
1268 if ( AR0.StoreData.dirtyflag ) {
1269 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
1271 AR.StoreData = AR0.StoreData;
1287void *RunThread(
void *dummy)
1289 WORD *term, *ttin, *tt, *ttco, *oldwork;
1290 int identity, wakeupsignal, identityretv, i, tobereleased, errorcode;
1296 identity = SetIdentity(&identityretv);
1297 threadpointers[identity] = pthread_self();
1298 B = InitializeOneThread(identity);
1299 while ( ( wakeupsignal = ThreadWait(identity) ) > 0 ) {
1300 switch ( wakeupsignal ) {
1304 case STARTNEWEXPRESSION:
1309 if ( UpdateOneThread(identity) ) {
1310 MLOCK(ErrorMessageLock);
1311 MesPrint(
"Update error in starting expression in thread %d in module %d",identity,AC.CModule);
1312 MUNLOCK(ErrorMessageLock);
1315 AR.DeferFlag = AC.ComDefer;
1316 AR.sLevel = AS.sLevel;
1317 AR.MaxDum = AM.IndDum;
1318 AR.expchanged = AB[0]->R.expchanged;
1319 AR.expflags = AB[0]->R.expflags;
1320 AR.PolyFun = AB[0]->R.PolyFun;
1321 AR.PolyFunInv = AB[0]->R.PolyFunInv;
1322 AR.PolyFunType = AB[0]->R.PolyFunType;
1323 AR.PolyFunExp = AB[0]->R.PolyFunExp;
1324 AR.PolyFunVar = AB[0]->R.PolyFunVar;
1325 AR.PolyFunPow = AB[0]->R.PolyFunPow;
1335 case LOWESTLEVELGENERATION:
1337 if ( AC.InnerTest ) {
1338 if ( StrCmp(AC.TestValue,(UBYTE *)INNERTEST) == 0 ) {
1339 MesPrint(
"Testing(Worker%d): value = %s",AT.identity,AC.TestValue);
1343 e = Expressions + AR.CurExpr;
1344 thr = AN.threadbuck;
1345 ppdef = thr->deferbuffer;
1346 ttin = thr->threadbuffer;
1347 ttco = thr->compressbuffer;
1348 term = AT.WorkPointer;
1351 AN.inputnumber = thr->firstterm;
1352 AN.ninterms = thr->firstterm;
1355 tt = term; i = *ttin;
1357 AT.WorkPointer = tt;
1358 if ( AR.DeferFlag ) {
1359 tt = AR.CompressBuffer; i = *ttco;
1361 AR.CompressPointer = tt;
1362 AR.DefPosition = ppdef[0]; ppdef++;
1364 if ( thr->free == BUCKETTERMINATED ) {
1372 if ( thr->usenum == thr->totnum ) {
1373 thr->free = BUCKETCOMINGFREE;
1376 thr->free = BUCKETRELEASED;
1386 thr->busy = BUCKETDOINGTERM;
1394 AN.RepPoint = AT.RepCount + 1;
1396 if ( ( e->vflags & ISFACTORIZED ) != 0 && term[1] == HAAKJE ) {
1400 if ( AR.DeferFlag ) {
1401 AR.CurDum = AN.IndDum = Expressions[AR.CurExpr].numdummies + AM.IndDum;
1404 AN.IndDum = AM.IndDum;
1405 AR.CurDum = ReNumber(BHEAD term);
1407 if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
1409 if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1410 else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1412 else if ( AC.PolyRatFunChanged ) PolyFunDirty(BHEAD term);
1413 if ( ( AP.PreDebug & THREADSDEBUG ) != 0 ) {
1414 MLOCK(ErrorMessageLock);
1415 MesPrint(
"Thread %w executing term:");
1416 PrintTerm(term,
"LLG");
1417 MUNLOCK(ErrorMessageLock);
1419 if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
1420 && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1421 PolyFunClean(BHEAD term);
1425 MLOCK(ErrorMessageLock);
1426 MesPrint(
"Error in processing one term in thread %d in module %d",identity,AC.CModule);
1427 MUNLOCK(ErrorMessageLock);
1434 thr->busy = BUCKETPREPARINGTERM;
1442 if ( thr->free == BUCKETTERMINATED ) {
1443 if ( thr->usenum == thr->totnum ) {
1444 thr->free = BUCKETCOMINGFREE;
1447 thr->free = BUCKETRELEASED;
1451 if ( tobereleased )
goto bucketstolen;
1453 thr->free = BUCKETCOMINGFREE;
1457 thr->busy = BUCKETTOBERELEASED;
1464 AT.WorkPointer = term;
1472 LOCK(AT.SB.MasterBlockLock[1]);
1475 case FINISHEXPRESSION:
1483 LOCK(AT.SB.MasterBlockLock[1]);
1484 ThreadClaimedBlock(identity);
1490 case FINISHEXPRESSION2:
1495 if ( AC.ThreadSortFileSynch ) {
1496 if ( AT.S0->file.handle >= 0 ) {
1497 SynchFile(AT.S0->file.handle);
1500 AT.SB.FillBlock = 1;
1501 AT.SB.MasterFill[1] = AT.SB.MasterStart[1];
1502 errorcode =
EndSort(BHEAD AT.S0->sBuffer,0);
1503 UNLOCK(AT.SB.MasterBlockLock[AT.SB.FillBlock]);
1506 MLOCK(ErrorMessageLock);
1507 MesPrint(
"Error terminating sort in thread %d in module %d",identity,AC.CModule);
1508 MUNLOCK(ErrorMessageLock);
1516 case CLEANUPEXPRESSION:
1520 if ( AR.outfile->handle >= 0 ) {
1521 CloseFile(AR.outfile->handle);
1522 AR.outfile->handle = -1;
1523 remove(AR.outfile->name);
1524 AR.outfile->POfill = AR.outfile->POfull = AR.outfile->PObuffer;
1525 PUTZERO(AR.outfile->POposition);
1526 PUTZERO(AR.outfile->filesize);
1529 AR.outfile->POfill = AR.outfile->POfull = AR.outfile->PObuffer;
1530 PUTZERO(AR.outfile->POposition);
1531 PUTZERO(AR.outfile->filesize);
1534 CBUF *C = cbuf+AT.ebufnum;
1536 if ( C->numrhs > 0 || C->numlhs > 0 ) {
1538 w = C->
rhs; ii = C->numrhs;
1539 do { *w++ = 0; }
while ( --ii > 0 );
1542 w = C->
lhs; ii = C->numlhs;
1543 do { *w++ = 0; }
while ( --ii > 0 );
1545 C->numlhs = C->numrhs = 0;
1546 ClearTree(AT.ebufnum);
1555 case HIGHERLEVELGENERATION:
1560 term = AT.WorkSpace; AT.WorkPointer = term + *term;
1563 MLOCK(ErrorMessageLock);
1564 MesPrint(
"Error in load balancing one term at level %d in thread %d in module %d",AR.level,AT.identity,AC.CModule);
1565 MUNLOCK(ErrorMessageLock);
1568 AT.WorkPointer = term;
1574 case STARTNEWMODULE:
1584 case TERMINATETHREAD:
1602 case DOONEEXPRESSION: {
1607 WORD oldBracketOn = AR.BracketOn;
1608 WORD *oldBrackBuf = AT.BrackBuf;
1609 WORD oldbracketindexflag = AT.bracketindexflag;
1610 WORD fromspectator = 0;
1611 e = Expressions + AR.exprtodo;
1614 AR.SortType = AC.SortType;
1616 if ( ( e->vflags & ISFACTORIZED ) != 0 ) {
1618 AT.BrackBuf = AM.BracketFactors;
1619 AT.bracketindexflag = 1;
1622 position = AS.OldOnFile[i];
1623 if ( e->status == HIDDENLEXPRESSION || e->status == HIDDENGEXPRESSION
1624 || e->status == UNHIDELEXPRESSION || e->status == UNHIDEGEXPRESSION ) {
1625 AR.GetFile = 2; fi = AR.hidefile;
1628 AR.GetFile = 0; fi = AR.infile;
1636 SetScratch(fi,&position);
1637 term = oldwork = AT.WorkPointer;
1638 AR.CompressPointer = AR.CompressBuffer;
1639 AR.CompressPointer[0] = 0;
1641 if ( GetTerm(BHEAD term) <= 0 ) {
1642 MLOCK(ErrorMessageLock);
1643 MesPrint(
"Expression %d has problems in scratchfile (t)",i);
1644 MUNLOCK(ErrorMessageLock);
1647 if ( AT.bracketindexflag > 0 ) OpenBracketIndex(i);
1649 if ( term[5] < 0 ) {
1650 fromspectator = -term[5];
1651 PUTZERO(AM.SpectatorFiles[fromspectator-1].readpos);
1652 term[5] = AC.cbufnum;
1654 PUTZERO(outposition);
1656 fout->POfill = fout->POfull = fout->PObuffer;
1657 fout->POposition = outposition;
1658 if ( fout->
handle >= 0 ) {
1659 fout->POposition = outposition;
1671 if (
PutOut(BHEAD term,&outposition,fout,0) < 0 )
goto ProcErr;
1673 AR.DeferFlag = AC.ComDefer;
1675 AR.sLevel = AB[0]->R.sLevel;
1676 term = AT.WorkPointer;
1678 AR.MaxDum = AM.IndDum;
1680 if ( fromspectator ) {
1681 while ( GetFromSpectator(term,fromspectator-1) ) {
1682 AT.WorkPointer = term + *term;
1683 AN.RepPoint = AT.RepCount + 1;
1684 AN.IndDum = AM.IndDum;
1685 AR.CurDum = ReNumber(BHEAD term);
1686 if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
1688 if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1689 else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1691 else if ( AC.PolyRatFunChanged ) PolyFunDirty(BHEAD term);
1692 if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
1693 && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1694 PolyFunClean(BHEAD term);
1702 while ( GetTerm(BHEAD term) ) {
1703 SeekScratch(fi,&position);
1704 AN.ninterms++; dd = AN.deferskipped;
1705 if ( ( e->vflags & ISFACTORIZED ) != 0 && term[1] == HAAKJE ) {
1709 if ( AC.CollectFun && *term <= (AM.MaxTer/(2*(LONG)
sizeof(WORD))) ) {
1710 if ( GetMoreTerms(term) < 0 ) {
1713 SeekScratch(fi,&position);
1715 AT.WorkPointer = term + *term;
1716 AN.RepPoint = AT.RepCount + 1;
1717 if ( AR.DeferFlag ) {
1718 AR.CurDum = AN.IndDum = Expressions[AR.exprtodo].numdummies;
1721 AN.IndDum = AM.IndDum;
1722 AR.CurDum = ReNumber(BHEAD term);
1724 if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
1726 if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1727 else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1729 else if ( AC.PolyRatFunChanged ) PolyFunDirty(BHEAD term);
1730 if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
1731 && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1732 PolyFunClean(BHEAD term);
1739 SetScratch(fi,&position);
1740 if ( fi == AR.hidefile ) {
1741 AR.InHiBuf = (fi->POfull-fi->PObuffer)
1742 -DIFBASE(position,fi->POposition)/
sizeof(WORD);
1745 AR.InInBuf = (fi->POfull-fi->PObuffer)
1746 -DIFBASE(position,fi->POposition)/
sizeof(WORD);
1751 if (
EndSort(BHEAD AT.S0->sBuffer,0) < 0 )
goto ProcErr;
1752 e->numdummies = AR.MaxDum - AM.IndDum;
1753 AR.BracketOn = oldBracketOn;
1754 AT.BrackBuf = oldBrackBuf;
1755 if ( ( e->vflags & TOBEFACTORED ) != 0 )
1757 else if ( ( ( e->vflags & TOBEUNFACTORED ) != 0 )
1758 && ( ( e->vflags & ISFACTORIZED ) != 0 ) )
1760 if ( AT.S0->TermsLeft ) e->vflags &= ~ISZERO;
1761 else e->vflags |= ISZERO;
1762 if ( AR.expchanged == 0 ) e->vflags |= ISUNMODIFIED;
1763 if ( AT.S0->TermsLeft ) AR.expflags |= ISZERO;
1764 if ( AR.expchanged ) AR.expflags |= ISUNMODIFIED;
1766 AT.bracketindexflag = oldbracketindexflag;
1771 SeekScratch(fout,&outposition);
1772 LOCK(AS.outputslock);
1773 oldoutfile = AB[0]->R.outfile;
1774 if ( e->status == INTOHIDELEXPRESSION || e->status == INTOHIDEGEXPRESSION ) {
1775 AB[0]->R.outfile = AB[0]->R.hidefile;
1777 SeekScratch(AB[0]->R.outfile,&position);
1778 e->onfile = position;
1779 if ( CopyExpression(fout,AB[0]->R.outfile) < 0 ) {
1780 AB[0]->R.outfile = oldoutfile;
1781 UNLOCK(AS.outputslock);
1782 MLOCK(ErrorMessageLock);
1783 MesPrint(
"Error copying output of 'InParallel' expression to master. Thread: %d",identity);
1784 MUNLOCK(ErrorMessageLock);
1787 AB[0]->R.outfile = oldoutfile;
1788 AB[0]->R.hidefile->POfull = AB[0]->R.hidefile->POfill;
1789 AB[0]->R.expflags = AR.expflags;
1790 UNLOCK(AS.outputslock);
1792 if ( fout->
handle >= 0 ) {
1796 PUTZERO(fout->POposition);
1797 PUTZERO(fout->filesize);
1798 fout->POfill = fout->POfull = fout->PObuffer;
1802 AT.WorkPointer = oldwork;
1826 e = Expressions + AR.CurExpr;
1827 binfo = e->bracketinfo;
1828 thr = AN.threadbuck;
1830 if ( AR.GetFile == 2 ) fi = AR.hidefile;
1831 else fi = AR.infile;
1833 ADD2POS(where,AS.OldOnFile[AR.CurExpr]);
1834 SetScratch(fi,&(where));
1835 stoppos = binfo->
indexbuffer[thr->lastbracket].next;
1836 ADD2POS(stoppos,AS.OldOnFile[AR.CurExpr]);
1837 AN.ninterms = thr->firstterm;
1842 ttco = AR.CompressBuffer;
1846 AR.CompressPointer = ttco;
1847 term = AT.WorkPointer;
1848 while ( GetTerm(BHEAD term) ) {
1849 SeekScratch(fi,&where);
1850 AT.WorkPointer = term + *term;
1851 AN.IndDum = AM.IndDum;
1852 AR.CurDum = ReNumber(BHEAD term);
1853 if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
1855 if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1856 else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1858 else if ( AC.PolyRatFunChanged ) PolyFunDirty(BHEAD term);
1859 if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
1860 && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1861 PolyFunClean(BHEAD term);
1863 if ( ( AP.PreDebug & THREADSDEBUG ) != 0 ) {
1864 MLOCK(ErrorMessageLock);
1865 MesPrint(
"Thread %w executing term:");
1866 PrintTerm(term,
"DoBrackets");
1867 MUNLOCK(ErrorMessageLock);
1869 AT.WorkPointer = term + *term;
1872 MLOCK(ErrorMessageLock);
1873 MesPrint(
"Error in processing one term in thread %d in module %d",identity,AC.CModule);
1874 MUNLOCK(ErrorMessageLock);
1878 SetScratch(fi,&(where));
1879 if ( ISGEPOS(where,stoppos) )
break;
1881 AT.WorkPointer = term;
1882 thr->free = BUCKETCOMINGFREE;
1893 sumtimerinfo[identity] +=
TimeCPU(1);
1894 timerinfo[identity] =
TimeCPU(0);
1901 case MCTSEXPANDTREE:
1902 AT.optimtimes = AB[0]->T.optimtimes;
1903 find_Horner_MCTS_expand_tree();
1909 case OPTIMIZEEXPRESSION:
1916 MLOCK(ErrorMessageLock);
1917 MesPrint(
"Illegal wakeup signal %d for thread %d",wakeupsignal,identity);
1918 MUNLOCK(ErrorMessageLock);
1924 timerinfo[identity] =
TimeCPU(1);
1932 flint_final_cleanup_thread();
1934 FinalizeOneThread(identity);
1954void *RunSortBot(
void *dummy)
1956 int identity, wakeupsignal, identityretv;
1957 ALLPRIVATES *B, *BB;
1959 identity = SetIdentity(&identityretv);
1960 threadpointers[identity] = pthread_self();
1961 B = InitializeOneThread(identity);
1962 while ( ( wakeupsignal = SortBotWait(identity) ) > 0 ) {
1963 switch ( wakeupsignal ) {
1968 AR.CompressBuffer = AB[0]->R.CompressBuffer;
1969 AR.ComprTop = AB[0]->R.ComprTop;
1970 AR.CompressPointer = AB[0]->R.CompressPointer;
1971 AR.CurExpr = AB[0]->R.CurExpr;
1972 AR.PolyFun = AB[0]->R.PolyFun;
1973 AR.PolyFunInv = AB[0]->R.PolyFunInv;
1974 AR.PolyFunType = AB[0]->R.PolyFunType;
1975 AR.PolyFunExp = AB[0]->R.PolyFunExp;
1976 AR.PolyFunVar = AB[0]->R.PolyFunVar;
1977 AR.PolyFunPow = AB[0]->R.PolyFunPow;
1978 AR.SortType = AC.SortType;
1979 if ( AR.PolyFun == 0 ) { AT.SS->PolyFlag = 0; }
1980 else if ( AR.PolyFunType == 1 ) { AT.SS->PolyFlag = 1; }
1981 else if ( AR.PolyFunType == 2 ) {
1982 if ( AR.PolyFunExp == 2
1983 || AR.PolyFunExp == 3 ) AT.SS->PolyFlag = 1;
1984 else AT.SS->PolyFlag = 2;
1986 AT.SS->PolyWise = 0;
1987 AN.ncmod = AC.ncmod;
1988 LOCK(AT.SB.MasterBlockLock[1]);
1989 BB = AB[AT.SortBotIn1];
1990 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
1991 BB = AB[AT.SortBotIn2];
1992 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
1993 AT.SB.FillBlock = 1;
1994 AT.SB.MasterFill[1] = AT.SB.MasterStart[1];
1995 SETBASEPOSITION(AN.theposition,0);
1997 AT.SS->verbComparisons = 0;
2010 case TERMINATETHREAD:
2020 sumtimerinfo[identity] +=
TimeCPU(1);
2021 timerinfo[identity] =
TimeCPU(0);
2028 MLOCK(ErrorMessageLock);
2029 MesPrint(
"Illegal wakeup signal %d for thread %d",wakeupsignal,identity);
2030 MUNLOCK(ErrorMessageLock);
2041 flint_final_cleanup_thread();
2043 FinalizeOneThread(identity);
2064void IAmAvailable(
int identity)
2067 LOCK(availabilitylock);
2068 top = topofavailables;
2069 listofavailables[topofavailables++] = identity;
2071 UNLOCK(availabilitylock);
2072 LOCK(wakeupmasterlock);
2073 wakeupmaster = identity;
2074 pthread_cond_signal(&wakeupmasterconditions);
2075 UNLOCK(wakeupmasterlock);
2078 UNLOCK(availabilitylock);
2094int GetAvailableThread(
void)
2097 LOCK(availabilitylock);
2098 if ( topofavailables > 0 ) retval = listofavailables[--topofavailables];
2099 UNLOCK(availabilitylock);
2100 if ( retval >= 0 ) {
2105 LOCK(wakeuplocks[retval]);
2106 UNLOCK(wakeuplocks[retval]);
2122int ConditionalGetAvailableThread(
void)
2125 if ( topofavailables > 0 ) {
2126 LOCK(availabilitylock);
2127 if ( topofavailables > 0 ) {
2128 retval = listofavailables[--topofavailables];
2130 UNLOCK(availabilitylock);
2131 if ( retval >= 0 ) {
2136 LOCK(wakeuplocks[retval]);
2137 UNLOCK(wakeuplocks[retval]);
2156int GetThread(
int identity)
2159 LOCK(availabilitylock);
2160 for ( j = 0; j < topofavailables; j++ ) {
2161 if ( identity == listofavailables[j] )
break;
2163 if ( j < topofavailables ) {
2165 for ( ; j < topofavailables; j++ ) {
2166 listofavailables[j] = listofavailables[j+1];
2170 UNLOCK(availabilitylock);
2187int ThreadWait(
int identity)
2190 LOCK(wakeuplocks[identity]);
2191 LOCK(availabilitylock);
2192 top = topofavailables;
2193 for ( j = topofavailables; j > 0; j-- )
2194 listofavailables[j] = listofavailables[j-1];
2195 listofavailables[0] = identity;
2197 if ( top == 0 || topofavailables == numberofworkers ) {
2198 UNLOCK(availabilitylock);
2199 LOCK(wakeupmasterlock);
2200 wakeupmaster = identity;
2201 pthread_cond_signal(&wakeupmasterconditions);
2202 UNLOCK(wakeupmasterlock);
2205 UNLOCK(availabilitylock);
2207 while ( wakeup[identity] == 0 ) {
2208 pthread_cond_wait(&(wakeupconditions[identity]),&(wakeuplocks[identity]));
2210 retval = wakeup[identity];
2211 wakeup[identity] = 0;
2212 UNLOCK(wakeuplocks[identity]);
2231int SortBotWait(
int identity)
2234 LOCK(wakeuplocks[identity]);
2235 LOCK(availabilitylock);
2236 topsortbotavailables++;
2237 if ( topsortbotavailables >= numberofsortbots ) {
2238 UNLOCK(availabilitylock);
2239 LOCK(wakeupsortbotlock);
2240 wakeupmaster = identity;
2241 pthread_cond_signal(&wakeupsortbotconditions);
2242 UNLOCK(wakeupsortbotlock);
2245 UNLOCK(availabilitylock);
2247 while ( wakeup[identity] == 0 ) {
2248 pthread_cond_wait(&(wakeupconditions[identity]),&(wakeuplocks[identity]));
2250 retval = wakeup[identity];
2251 wakeup[identity] = 0;
2252 UNLOCK(wakeuplocks[identity]);
2272int ThreadClaimedBlock(
int identity)
2274 LOCK(availabilitylock);
2276 if ( numberclaimed >= numberofworkers ) {
2277 UNLOCK(availabilitylock);
2278 LOCK(wakeupmasterlock);
2279 wakeupmaster = identity;
2280 pthread_cond_signal(&wakeupmasterconditions);
2281 UNLOCK(wakeupmasterlock);
2284 UNLOCK(availabilitylock);
2303 LOCK(wakeupmasterlock);
2304 while ( wakeupmaster == 0 ) {
2305 pthread_cond_wait(&wakeupmasterconditions,&wakeupmasterlock);
2307 retval = wakeupmaster;
2309 UNLOCK(wakeupmasterlock);
2323int MasterWaitThread(
int identity)
2326 LOCK(wakeupmasterthreadlocks[identity]);
2327 while ( wakeupmasterthread[identity] == 0 ) {
2328 pthread_cond_wait(&(wakeupmasterthreadconditions[identity])
2329 ,&(wakeupmasterthreadlocks[identity]));
2331 retval = wakeupmasterthread[identity];
2332 wakeupmasterthread[identity] = 0;
2333 UNLOCK(wakeupmasterthreadlocks[identity]);
2347void MasterWaitAll(
void)
2349 LOCK(wakeupmasterlock);
2350 while ( topofavailables < numberofworkers ) {
2351 pthread_cond_wait(&wakeupmasterconditions,&wakeupmasterlock);
2353 UNLOCK(wakeupmasterlock);
2369void MasterWaitAllSortBots(
void)
2371 LOCK(wakeupsortbotlock);
2372 while ( topsortbotavailables < numberofsortbots ) {
2373 pthread_cond_wait(&wakeupsortbotconditions,&wakeupsortbotlock);
2375 UNLOCK(wakeupsortbotlock);
2391void MasterWaitAllBlocks(
void)
2393 LOCK(wakeupmasterlock);
2394 while ( numberclaimed < numberofworkers ) {
2395 pthread_cond_wait(&wakeupmasterconditions,&wakeupmasterlock);
2397 UNLOCK(wakeupmasterlock);
2413void WakeupThread(
int identity,
int signalnumber)
2415 if ( signalnumber == 0 ) {
2416 MLOCK(ErrorMessageLock);
2417 MesPrint(
"Illegal wakeup signal for thread %d",identity);
2418 MUNLOCK(ErrorMessageLock);
2421 LOCK(wakeuplocks[identity]);
2422 wakeup[identity] = signalnumber;
2423 pthread_cond_signal(&(wakeupconditions[identity]));
2424 UNLOCK(wakeuplocks[identity]);
2439void WakeupMasterFromThread(
int identity,
int signalnumber)
2441 if ( signalnumber == 0 ) {
2442 MLOCK(ErrorMessageLock);
2443 MesPrint(
"Illegal wakeup signal for master %d",identity);
2444 MUNLOCK(ErrorMessageLock);
2447 LOCK(wakeupmasterthreadlocks[identity]);
2448 wakeupmasterthread[identity] = signalnumber;
2449 pthread_cond_signal(&(wakeupmasterthreadconditions[identity]));
2450 UNLOCK(wakeupmasterthreadlocks[identity]);
2462int SendOneBucket(
int type)
2464 ALLPRIVATES *B0 = AB[0];
2465 THREADBUCKET *thr = 0;
2467 for ( j = 0; j < numthreadbuckets; j++ ) {
2468 if ( threadbuckets[j]->free == BUCKETFILLED ) {
2469 thr = threadbuckets[j];
2470 for ( k = j+1; k < numthreadbuckets; k++ )
2471 threadbuckets[k-1] = threadbuckets[k];
2472 threadbuckets[numthreadbuckets-1] = thr;
2477 while ( (
id = GetAvailableThread() ) < 0 ) { MasterWait(); }
2481 LoadOneThread(0,
id,thr,0);
2482 thr->busy = BUCKETASSIGNED;
2483 thr->free = BUCKETINUSE;
2484 numberoffullbuckets--;
2492 WakeupThread(
id,type);
2520int InParallelProcessor(
void)
2523 int i, id, retval = 0, num = 0;
2525 if ( numberofworkers >= 2 ) {
2527 for ( i = 0; i < NumExpressions; i++ ) {
2529 if ( e->partodo <= 0 )
continue;
2530 if ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION
2531 || e->status == UNHIDELEXPRESSION || e->status == UNHIDEGEXPRESSION
2532 || e->status == INTOHIDELEXPRESSION || e->status == INTOHIDEGEXPRESSION ) {
2538 if ( e->counter == 0 ) {
2545 while ( (
id = GetAvailableThread() ) < 0 ) { MasterWait(); }
2546 LoadOneThread(0,
id,0,-1);
2547 AB[id]->R.exprtodo = i;
2548 WakeupThread(
id,DOONEEXPRESSION);
2554 if ( num > 0 ) MasterWaitAll();
2556 if ( AC.CollectFun ) AR.DeferFlag = 0;
2559 for ( i = 0; i < NumExpressions; i++ ) {
2560 Expressions[i].partodo = 0;
2594int ThreadsProcessor(
EXPRESSIONS e, WORD LastExpression, WORD fromspectator)
2596 ALLPRIVATES *B0 = AB[0], *B = B0;
2597 int id, oldgzipCompress, endofinput = 0, j, still, k, defcount = 0, bra = 0, first = 1;
2598 LONG dd = 0, ddd, thrbufsiz, thrbufsiz0, thrbufsiz2, numbucket = 0, numpasses;
2600 WORD *oldworkpointer = AT0.WorkPointer, *tt, *ttco = 0, *t1 = 0, ter, *tstop = 0, *t2;
2601 THREADBUCKET *thr = 0;
2603 GETTERM GetTermP = &GetTerm;
2604 POSITION eonfile = AS.OldOnFile[e-Expressions];
2605 numberoffullbuckets = 0;
2611 AM.tracebackflag = 1;
2613 AS.sLevel = AR0.sLevel;
2614 LOCK(availabilitylock);
2615 topofavailables = 0;
2616 for (
id = 1;
id <= numberofworkers;
id++ ) {
2617 WakeupThread(
id,STARTNEWEXPRESSION);
2619 UNLOCK(availabilitylock);
2625 if ( AC.numpfirstnum > 0 ) {
2626 for ( j = 0; j < AC.numpfirstnum; j++ ) {
2627 AC.inputnumbers[j] = -1;
2639 thrbufsiz2 = thrbufsiz = AC.ThreadBucketSize-1;
2640 if ( ( e->counter / ( numberofworkers * 5 ) ) < thrbufsiz ) {
2641 thrbufsiz = e->counter / ( numberofworkers * 5 ) - 1;
2642 if ( thrbufsiz < 0 ) thrbufsiz = 0;
2644 thrbufsiz0 = thrbufsiz;
2646 thrbufsiz = thrbufsiz0 / (2 << numpasses);
2650 for ( j = 0; j < numthreadbuckets; j++ )
2651 threadbuckets[j]->free = BUCKETFREE;
2652 thr = threadbuckets[0];
2661 if ( e->bracketinfo && AC.CollectFun == 0 && AR0.DeferFlag == 0 ) {
2666 for ( n = 0; n < e->bracketinfo->indexfill; n++ ) {
2667 num = TreatIndexEntry(B0,n);
2675 for ( j = 0; j < numthreadbuckets; j++ ) {
2676 switch ( threadbuckets[j]->free ) {
2678 thr = threadbuckets[j];
2680 case BUCKETCOMINGFREE:
2681 thr = threadbuckets[j];
2682 thr->free = BUCKETFREE;
2683 for ( k = j+1; k < numthreadbuckets; k++ )
2684 threadbuckets[k-1] = threadbuckets[k];
2685 threadbuckets[numthreadbuckets-1] = thr;
2693 if ( j < numthreadbuckets ) {
2697 thr->firstbracket = n;
2698 thr->lastbracket = n + num - 1;
2699 thr->type = BUCKETDOINGBRACKET;
2700 thr->free = BUCKETFILLED;
2701 thr->firstterm = AN0.ninterms;
2702 for ( j = n; j < n+num; j++ ) {
2703 AN0.ninterms += e->bracketinfo->
indexbuffer[j].termsinbracket;
2706 numberoffullbuckets++;
2707 if ( topofavailables > 0 ) {
2708 SendOneBucket(DOBRACKETS);
2717 while ( topofavailables <= 0 ) {
2720 SendOneBucket(DOBRACKETS);
2729 switch ( e->status ) {
2730 case UNHIDELEXPRESSION:
2731 case UNHIDEGEXPRESSION:
2732 case DROPHLEXPRESSION:
2733 case DROPHGEXPRESSION:
2734 case HIDDENLEXPRESSION:
2735 case HIDDENGEXPRESSION:
2736 curfile = AR0.hidefile;
2739 curfile = AR0.infile;
2742 SetScratch(curfile,&eonfile);
2743 GetTerm(B0,AT0.WorkPointer);
2747 GetTermP = &GetTerm2;
2752 for ( j = 0; j < numthreadbuckets; j++ ) {
2753 switch ( threadbuckets[j]->free ) {
2755 thr = threadbuckets[j];
2757 case BUCKETCOMINGFREE:
2758 thr = threadbuckets[j];
2759 thr->free = BUCKETFREE;
2760 for ( k = j+1; k < numthreadbuckets; k++ )
2761 threadbuckets[k-1] = threadbuckets[k];
2762 threadbuckets[numthreadbuckets-1] = thr;
2769 while ( topofavailables <= 0 ) {
2772 while ( topofavailables > 0 && numberoffullbuckets > 0 ) {
2773 SendOneBucket(DOBRACKETS);
2777 while ( numberoffullbuckets > 0 ) {
2778 while ( topofavailables <= 0 ) {
2781 while ( topofavailables > 0 && numberoffullbuckets > 0 ) {
2782 SendOneBucket(DOBRACKETS);
2791 AN0.lastinindex = -1;
2802 if ( fromspectator ) {
2803 ter = GetFromSpectator(thr->threadbuffer,fromspectator-1);
2804 if ( ter == 0 ) fromspectator = 0;
2807 ter = GetTermP(B0,thr->threadbuffer);
2823 if ( ter < 0 )
break;
2824 if ( ter == 0 ) { endofinput = 1;
goto Finalize; }
2825 dd = AN0.deferskipped;
2826 if ( AR0.DeferFlag ) {
2828 thr->deferbuffer[defcount++] = AR0.DefPosition;
2829 ttco = thr->compressbuffer; t1 = AR0.CompressBuffer; j = *t1;
2832 else if ( first && ( AC.CollectFun == 0 ) ) {
2834 t1 = tstop = thr->threadbuffer;
2835 tstop += *tstop; tstop -= ABS(tstop[-1]);
2837 while ( t1 < tstop ) {
2838 if ( t1[0] == HAAKJE ) { bra = 1;
break; }
2841 t1 = thr->threadbuffer;
2846 if ( AC.CollectFun && *(thr->threadbuffer) < (AM.MaxTer/((LONG)
sizeof(WORD))-10) ) {
2847 if ( ( dd = GetMoreTerms(thr->threadbuffer) ) < 0 ) {
2854 if ( topofavailables > 0 && numberoffullbuckets > 0 ) SendOneBucket(LOWESTLEVELGENERATION);
2858 tt = thr->threadbuffer; tt += *tt;
2865 if ( numpasses > 0 ) {
2867 if ( numbucket >= numberofworkers ) {
2870 if ( numpasses == 0 ) thrbufsiz = thrbufsiz0;
2871 else thrbufsiz = thrbufsiz0 / (2 << numpasses);
2873 thrbufsiz2 = thrbufsiz + thrbufsiz/5;
2878 while ( ( dd < thrbufsiz ) &&
2879 ( tt - thr->threadbuffer ) < ( thr->threadbuffersize - AM.MaxTer/((LONG)
sizeof(WORD)) - 2 ) ) {
2883 if ( topofavailables > 0 && numberoffullbuckets > 0 ) SendOneBucket(LOWESTLEVELGENERATION);
2887 if ( GetTermP(B0,tt) == 0 ) { endofinput = 1;
break; }
2890 dd += AN0.deferskipped;
2891 if ( AR0.DeferFlag ) {
2892 thr->deferbuffer[defcount++] = AR0.DefPosition;
2893 t1 = AR0.CompressBuffer; j = *t1;
2896 if ( AC.CollectFun && *tt < (AM.MaxTer/((LONG)
sizeof(WORD))-10) ) {
2897 if ( ( ddd = GetMoreTerms(tt) ) < 0 ) {
2912 tstop = t1 + *t1; tstop -= ABS(tstop[-1]);
2914 while ( t2 < tstop ) {
2915 if ( t2[0] == HAAKJE ) {
break; }
2918 if ( t2[0] == HAAKJE ) {
2919 t2 += t2[1]; num = t2 - t1;
2920 while ( ( dd < thrbufsiz2 ) &&
2921 ( tt - thr->threadbuffer ) < ( thr->threadbuffersize - AM.MaxTer - 2 ) ) {
2925 if ( topofavailables > 0 && numberoffullbuckets > 0 ) SendOneBucket(LOWESTLEVELGENERATION);
2929 if ( GetTermP(B0,tt) == 0 ) { endofinput = 1;
break; }
2933 tstop = tt + *tt; tstop -= ABS(tstop[-1]);
2934 if ( tstop-tt < num ) {
2938 for ( i = 1; i < num; i++ ) {
2939 if ( t1[i] != tt[i] )
break;
2955 thr->firstterm = AN0.ninterms;
2958 thr->free = BUCKETFILLED;
2959 thr->type = BUCKETDOINGTERMS;
2960 numberoffullbuckets++;
2961 if ( topofavailables <= 0 && endofinput == 0 ) {
2975 for ( j = 0; j < numthreadbuckets; j++ ) {
2976 switch ( threadbuckets[j]->free ) {
2978 thr = threadbuckets[j];
2979 if ( !endofinput )
goto NextBucket;
2985 thr->free = BUCKETATEND;
2987 case BUCKETCOMINGFREE:
2988 thr = threadbuckets[j];
2989 thr->free = BUCKETFREE;
2995 for ( k = j+1; k < numthreadbuckets; k++ )
2996 threadbuckets[k-1] = threadbuckets[k];
2997 threadbuckets[numthreadbuckets-1] = thr;
3013 for ( j = 0; j < numthreadbuckets; j++ ) {
3014 if ( threadbuckets[j]->free == BUCKETFILLED ) {
3015 thr = threadbuckets[j];
3016 for ( k = j+1; k < numthreadbuckets; k++ )
3017 threadbuckets[k-1] = threadbuckets[k];
3018 threadbuckets[numthreadbuckets-1] = thr;
3028 while ( (
id = GetAvailableThread() ) < 0 ) { MasterWait(); }
3032 LoadOneThread(0,
id,thr,0);
3034 thr->busy = BUCKETASSIGNED;
3036 thr->free = BUCKETINUSE;
3037 numberoffullbuckets--;
3045 WakeupThread(
id,LOWESTLEVELGENERATION);
3050 if ( topofavailables > 0 ) {
3051 for ( j = 0; j < numthreadbuckets; j++ ) {
3052 if ( threadbuckets[j]->free == BUCKETFILLED ) {
3053 thr = threadbuckets[j];
3054 for ( k = j+1; k < numthreadbuckets; k++ )
3055 threadbuckets[k-1] = threadbuckets[k];
3056 threadbuckets[numthreadbuckets-1] = thr;
3065 for ( j = 0; j < numthreadbuckets; j++ ) {
3066 switch ( threadbuckets[j]->free ) {
3068 thr = threadbuckets[j];
3069 if ( !endofinput )
goto NextBucket;
3070 thr->free = BUCKETATEND;
3072 case BUCKETCOMINGFREE:
3073 thr = threadbuckets[j];
3075 thr->free = BUCKETATEND;
3078 thr->free = BUCKETFREE;
3079 for ( k = j+1; k < numthreadbuckets; k++ )
3080 threadbuckets[k-1] = threadbuckets[k];
3081 threadbuckets[numthreadbuckets-1] = thr;
3089 if ( j >= numthreadbuckets )
break;
3099 for ( j = 0; j < numthreadbuckets; j++ ) {
3100 switch ( threadbuckets[j]->free ) {
3102 thr = threadbuckets[j];
3103 if ( !endofinput )
goto NextBucket;
3104 thr->free = BUCKETATEND;
3106 case BUCKETCOMINGFREE:
3107 thr = threadbuckets[j];
3108 if ( endofinput ) thr->free = BUCKETATEND;
3110 thr->free = BUCKETFREE;
3111 for ( k = j+1; k < numthreadbuckets; k++ )
3112 threadbuckets[k-1] = threadbuckets[k];
3113 threadbuckets[numthreadbuckets-1] = thr;
3118 if ( still < 0 ) still = j;
3131 thr = threadbuckets[still];
3132 for ( k = still+1; k < numthreadbuckets; k++ )
3133 threadbuckets[k-1] = threadbuckets[k];
3134 threadbuckets[numthreadbuckets-1] = thr;
3147 if ( AC.ThreadBalancing ) {
3148 for (
id = 1;
id <= numberofworkers;
id++ ) {
3149 AB[id]->T.LoadBalancing = 1;
3151 if ( LoadReadjusted() )
goto Finalize;
3152 for (
id = 1;
id <= numberofworkers;
id++ ) {
3153 AB[id]->T.LoadBalancing = 0;
3156 if ( AC.ThreadBalancing ) {
3181 if ( LastExpression ) {
3183 if ( AR0.infile->handle >= 0 ) {
3184 CloseFile(AR0.infile->handle);
3185 AR0.infile->handle = -1;
3186 remove(AR0.infile->name);
3187 PUTZERO(AR0.infile->POposition);
3188 AR0.infile->POfill = AR0.infile->POfull = AR0.infile->PObuffer;
3200 oldgzipCompress = AR0.gzipCompress;
3201 AR0.gzipCompress = 0;
3202 if ( AR0.outtohide ) AR0.outfile = AR0.hidefile;
3203 if ( MasterMerge() < 0 ) {
3204 if ( AR0.outtohide ) AR0.outfile = oldoutfile;
3205 AR0.gzipCompress = oldgzipCompress;
3208 if ( AR0.outtohide ) AR0.outfile = oldoutfile;
3209 AR0.gzipCompress = oldgzipCompress;
3217 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
3218 if ( GetThread(
id) > 0 ) WakeupThread(
id,CLEANUPEXPRESSION);
3221 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
3222 if ( AB[
id]->R.MaxDum - AM.IndDum > e->numdummies )
3223 e->numdummies = AB[id]->R.MaxDum - AM.IndDum;
3224 AR0.expchanged |= AB[id]->R.expchanged;
3230 AT0.WorkPointer = oldworkpointer;
3258int LoadReadjusted(
void)
3260 ALLPRIVATES *B0 = AB[0];
3261 THREADBUCKET *thr = 0, *thrtogo = 0;
3262 int numtogo, numfree, numbusy, n, nperbucket, extra, i, j, u, bus;
3264 WORD *t1, *c1, *t2, *c2, *t3;
3269 while ( topofavailables <= 0 ) MasterWait();
3278 for ( j = 0; j < numthreadbuckets; j++ ) {
3279 thr = threadbuckets[j];
3280 if ( thr->free == BUCKETFREE || thr->free == BUCKETATEND
3281 || thr->free == BUCKETCOMINGFREE ) {
3282 freebuckets[numfree++] = thr;
3284 else if ( thr->type != BUCKETDOINGTERMS ) {}
3285 else if ( thr->totnum > 1 ) {
3289 if ( thr->free == BUCKETINUSE ) {
3290 n = thr->totnum-thr->usenum;
3291 if ( bus == BUCKETASSIGNED ) numbusy++;
3292 else if ( ( bus != BUCKETASSIGNED )
3293 && ( n > numtogo ) ) {
3298 else if ( bus == BUCKETTOBERELEASED
3299 && thr->free == BUCKETRELEASED ) {
3300 freebuckets[numfree++] = thr;
3301 thr->free = BUCKETATEND;
3303 thr->busy = BUCKETPREPARINGTERM;
3308 if ( numfree == 0 )
return(0);
3309 if ( numtogo > 0 ) {
3316 if ( thr->totnum-thr->usenum < numtogo )
goto restart;
3326 if ( thr->busy != BUCKETDOINGTERM ) {
3330 if ( thr->totnum-thr->usenum < numtogo ) {
3334 thr->free = BUCKETTERMINATED;
3341 if ( thr->usenum == thr->totnum ) {
3346 thr->free = BUCKETATEND;
3354 if ( numbusy > 0 ) {
3360 struct timespec sleeptime;
3361 sleeptime.tv_sec = 0;
3362 sleeptime.tv_nsec = 1000L;
3363 nanosleep(&sleeptime, NULL);
3378 numinput = thr->firstterm + thr->usenum;
3379 nperbucket = numtogo / numfree;
3380 extra = numtogo - nperbucket*numfree;
3381 if ( AR0.DeferFlag ) {
3382 t1 = thr->threadbuffer; c1 = thr->compressbuffer; u = thr->usenum;
3383 for ( n = 0; n < thr->usenum; n++ ) { t1 += *t1; c1 += *c1; }
3386 for ( i = 0; i < extra; i++ ) {
3387 thrtogo = freebuckets[i];
3388 t2 = thrtogo->threadbuffer;
3389 c2 = thrtogo->compressbuffer;
3390 thrtogo->free = BUCKETFILLED;
3391 thrtogo->type = BUCKETDOINGTERMS;
3392 thrtogo->totnum = nperbucket+1;
3393 thrtogo->ddterms = 0;
3394 thrtogo->usenum = 0;
3395 thrtogo->busy = BUCKETASSIGNED;
3396 thrtogo->firstterm = numinput;
3397 numinput += nperbucket+1;
3398 for ( n = 0; n <= nperbucket; n++ ) {
3399 j = *t1; NCOPY(t2,t1,j);
3400 j = *c1; NCOPY(c2,c1,j);
3401 thrtogo->deferbuffer[n] = thr->deferbuffer[u++];
3406 if ( nperbucket > 0 ) {
3407 for ( i = extra; i < numfree; i++ ) {
3408 thrtogo = freebuckets[i];
3409 t2 = thrtogo->threadbuffer;
3410 c2 = thrtogo->compressbuffer;
3411 thrtogo->free = BUCKETFILLED;
3412 thrtogo->type = BUCKETDOINGTERMS;
3413 thrtogo->totnum = nperbucket;
3414 thrtogo->ddterms = 0;
3415 thrtogo->usenum = 0;
3416 thrtogo->busy = BUCKETASSIGNED;
3417 thrtogo->firstterm = numinput;
3418 numinput += nperbucket;
3419 for ( n = 0; n < nperbucket; n++ ) {
3420 j = *t1; NCOPY(t2,t1,j);
3421 j = *c1; NCOPY(c2,c1,j);
3422 thrtogo->deferbuffer[n] = thr->deferbuffer[u++];
3429 t1 = thr->threadbuffer;
3430 for ( n = 0; n < thr->usenum; n++ ) { t1 += *t1; }
3433 for ( i = 0; i < extra; i++ ) {
3434 thrtogo = freebuckets[i];
3435 t2 = thrtogo->threadbuffer;
3436 thrtogo->free = BUCKETFILLED;
3437 thrtogo->type = BUCKETDOINGTERMS;
3438 thrtogo->totnum = nperbucket+1;
3439 thrtogo->ddterms = 0;
3440 thrtogo->usenum = 0;
3441 thrtogo->busy = BUCKETASSIGNED;
3442 thrtogo->firstterm = numinput;
3443 numinput += nperbucket+1;
3444 for ( n = 0; n <= nperbucket; n++ ) {
3445 j = *t1; NCOPY(t2,t1,j);
3450 if ( nperbucket > 0 ) {
3451 for ( i = extra; i < numfree; i++ ) {
3452 thrtogo = freebuckets[i];
3453 t2 = thrtogo->threadbuffer;
3454 thrtogo->free = BUCKETFILLED;
3455 thrtogo->type = BUCKETDOINGTERMS;
3456 thrtogo->totnum = nperbucket;
3457 thrtogo->ddterms = 0;
3458 thrtogo->usenum = 0;
3459 thrtogo->busy = BUCKETASSIGNED;
3460 thrtogo->firstterm = numinput;
3461 numinput += nperbucket;
3462 for ( n = 0; n < nperbucket; n++ ) {
3463 j = *t1; NCOPY(t2,t1,j);
3470 if ( thr->free == BUCKETRELEASED && thr->busy == BUCKETTOBERELEASED ) {
3471 thr->free = BUCKETATEND; thr->busy = BUCKETPREPARINGTERM;
3539int PutToMaster(PHEAD WORD *term)
3541 int i,j,nexti,ret = 0;
3543 WORD *t, *fill, *top, zero = 0;
3548 t = term; ret = j = *term;
3549 if ( j == 0 ) { j = 1; }
3551 i = AT.SB.FillBlock;
3552 fill = AT.SB.MasterFill[i];
3553 top = AT.SB.MasterStop[i];
3560 if ( j < top - fill && AT.SB.BlockTerms[i] > MINWRITENUMBEROFTERMS ) {
3561 const int prev = ( i == 1 ? AT.SB.MasterNumBlocks : i-1 );
3562 if ( ! pthread_mutex_trylock(&(AT.SB.MasterBlockLock[prev])) ) {
3563 UNLOCK(AT.SB.MasterBlockLock[prev]);
3572 if ( ( j >= top - fill ) || urgent ) {
3574 if ( nexti > AT.SB.MasterNumBlocks ) {
3577 LOCK(AT.SB.MasterBlockLock[nexti]);
3578 UNLOCK(AT.SB.MasterBlockLock[i]);
3579 AT.SB.MasterFill[i] = AT.SB.MasterStart[i];
3580 AT.SB.FillBlock = i = nexti;
3581 fill = AT.SB.MasterStart[i];
3582 top = AT.SB.MasterStop[i];
3583 if ( AT.SB.BlockTerms[i] != 0 ) {
3587 MLOCK(ErrorMessageLock);
3588 MesPrint(
"Error in PutToMaster, starting a block with BlockTerms != 0");
3589 MUNLOCK(ErrorMessageLock);
3595 AT.SB.BlockTerms[i]++;
3596 AT.SB.MasterFill[i] = fill;
3616SortBotOut(PHEAD WORD *term)
3620 if ( AT.identity != 0 )
return(PutToMaster(BHEAD term));
3623 if (
FlushOut(&SortBotPosition,AR.outfile,1) )
return(-1);
3624 ADDPOS(AT.SS->SizeInFile[0],1);
3629 if ( ( im =
PutOut(BHEAD term,&SortBotPosition,AR.outfile,1) ) < 0 ) {
3630 MLOCK(ErrorMessageLock);
3631 MesPrint(
"Called from MasterMerge/SortBotOut");
3632 MUNLOCK(ErrorMessageLock);
3635 ADDPOS(AT.SS->SizeInFile[0],im);
3663int MasterMerge(
void)
3665 ALLPRIVATES *B0 = AB[0], *B = 0;
3667 WORD **poin, **poin2, ul, k, i, im, *m1, j;
3668 WORD lpat, mpat, level, l1, l2, r1, r2, r3, c;
3669 WORD *m2, *m3, r31, r33, ki, *rr;
3674 if ( numberofworkers > 2 )
return(SortBotMasterMerge());
3677 if ( AR0.PolyFun == 0 ) { S->PolyFlag = 0; }
3678 else if ( AR0.PolyFunType == 1 ) { S->PolyFlag = 1; }
3679 else if ( AR0.PolyFunType == 2 ) {
3680 if ( AR0.PolyFunExp == 2
3681 || AR0.PolyFunExp == 3 ) S->PolyFlag = 1;
3682 else S->PolyFlag = 2;
3685 coef = AN0.SoScratC;
3686 poin = S->poina; poin2 = S->poin2a;
3687 rr = AR0.CompressPointer;
3692 S->inNum = numberofthreads;
3697 S->lPatch = S->inNum - 1;
3707 for ( i = 1; i <= S->lPatch; i++ ) {
3709 LOCK(AT.SB.MasterBlockLock[0]);
3710 LOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
3718 for ( i = 0; i < S->lPatch; i++ ) {
3720 WakeupThread(i+1,FINISHEXPRESSION);
3725 if ( fout->
handle >= 0 ) {
3727 SeekFile(fout->
handle,&position,SEEK_END);
3728 ADDPOS(position,((fout->POfill-fout->PObuffer)*
sizeof(WORD)));
3731 SETBASEPOSITION(position,(fout->POfill-fout->PObuffer)*
sizeof(WORD));
3736 MasterWaitAllBlocks();
3744 for ( i = 1; i <= S->lPatch; i++ ) {
3746 LOCK(AT.SB.MasterBlockLock[1]);
3747 AT.SB.MasterBlock = 1;
3755 do { lpat <<= 1; }
while ( lpat < S->lPatch );
3756 mpat = ( lpat >> 1 ) - 1;
3757 k = lpat - S->lPatch;
3762 for ( i = 1; i < lpat; i++ ) { S->tree[i] = -1; }
3763 for ( i = 1; i <= k; i++ ) {
3765 poin[im] = AB[i]->T.SB.MasterStart[AB[i]->T.SB.MasterBlock];
3766 poin2[im] = poin[im] + *(poin[im]);
3769 S->tree[mpat+i] = 0;
3770 poin[im-1] = poin2[im-1] = 0;
3772 for ( i = (k*2)+1; i <= lpat; i++ ) {
3775 poin[i] = AB[i-k]->T.SB.MasterStart[AB[i-k]->T.SB.MasterBlock];
3776 poin2[i] = poin[i] + *(poin[i]);
3797 if ( !*(poin[k]) ) {
3801 AB[ki+1]->T.SB.BlockTerms[AB[ki+1]->T.SB.MasterBlock]--;
3803 if ( !( i >>= 1 ) ) {
3806 }
while ( !S->tree[i] );
3807 if ( S->tree[i] == -1 ) {
3820 if ( S->tree[i] > 0 ) {
3821 if ( ( c = CompareTerms(B0, poin[S->tree[i]],poin[k],(WORD)0) ) > 0 ) {
3825 S->used[level] = S->tree[i];
3835 l1 = *( m1 = poin[S->tree[i]] );
3836 l2 = *( m2 = poin[k] );
3837 if ( S->PolyWise ) {
3842 if ( S->PolyFlag == 2 ) {
3844 if ( *tt1 + w[1] - m1[1] > AM.MaxTer/((LONG)
sizeof(WORD)) ) {
3845 MLOCK(ErrorMessageLock);
3846 MesPrint(
"Term too complex in PolyRatFun addition. MaxTermSize of %10l is too small",AM.MaxTer);
3847 MUNLOCK(ErrorMessageLock);
3850 AT0.WorkPointer = w;
3851 if ( w[FUNHEAD] == -SNUMBER && w[FUNHEAD+1] == 0 && w[1] > FUNHEAD ) {
3856 w = AT0.WorkPointer;
3857 if ( w + m1[1] + m2[1] > AT0.WorkTop ) {
3858 MLOCK(ErrorMessageLock);
3859 MesPrint(
"MasterMerge: A WorkSpace of %10l is too small",AM.WorkSize);
3860 MUNLOCK(ErrorMessageLock);
3867 || ( w[FUNHEAD] == -SNUMBER && w[FUNHEAD+1] == 0 ) )
3869 if ( r1 == m1[1] ) {
3872 else if ( r1 < m1[1] ) {
3876 while ( --r1 >= 0 ) *--m1 = *--m2;
3879 while ( --r1 >= 0 ) *--m1 = *--m2;
3881 poin[S->tree[i]] = m1;
3895 poin[S->tree[i]] = m2;
3902 else if ( AT.SortFloatMode ) {
3903 WORD *term1, *term2;
3904 term1 = poin[S->tree[i]];
3906 if ( MergeWithFloat(B0, &term1,&term2) == 0 )
3908 poin[S->tree[i]] = term1;
3912 r1 = *( m1 += l1 - 1 );
3914 r1 = ( ( r1 > 0 ) ? (r1-1) : (r1+1) ) >> 1;
3915 r2 = *( m2 += l2 - 1 );
3917 r2 = ( ( r2 > 0 ) ? (r2-1) : (r2+1) ) >> 1;
3919 if ( AddRat(B0,(UWORD *)m1,r1,(UWORD *)m2,r2,coef,&r3) ) {
3920 MLOCK(ErrorMessageLock);
3921 MesCall(
"MasterMerge");
3922 MUNLOCK(ErrorMessageLock);
3926 if ( AN.ncmod != 0 ) {
3927 if ( ( AC.modmode & POSNEG ) != 0 ) {
3930 else if ( BigLong(coef,r3,(UWORD *)AC.cmod,ABS(AN.ncmod)) >= 0 ) {
3932 SubPLon(coef,r3,(UWORD *)AC.cmod,ABS(AN.ncmod),coef,&r3);
3934 for ( ii = 1; ii < r3; ii++ ) coef[r3+ii] = 0;
3938 r33 = ( r3 > 0 ) ? ( r3 + 1 ) : ( r3 - 1 );
3939 if ( r3 < 0 ) r3 = -r3;
3940 if ( r1 < 0 ) r1 = -r1;
3945 ul = S->used[level] = S->tree[i];
3951 poin[ul] = poin2[ul];
3953 AB[ki+1]->T.SB.BlockTerms[AB[ki+1]->T.SB.MasterBlock]--;
3954 if ( AB[ki+1]->T.SB.BlockTerms[AB[ki+1]->T.SB.MasterBlock] == 0 ) {
3960 i = AT.SB.MasterBlock;
3962 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
3965 UNLOCK(AT.SB.MasterBlockLock[i-1]);
3967 if ( i == AT.SB.MasterNumBlocks ) {
3971 LOCK(AT.SB.MasterBlockLock[i]);
3972 AT.SB.MasterBlock = i;
3973 poin[ul] = AT.SB.MasterStart[i];
3975 poin2[ul] = poin[ul] + im;
3980 S->used[++level] = k;
3985 else if ( r31 < 0 ) {
3994 if( (poin[S->tree[i]]+l1+r31) >= poin2[S->tree[i]] ) {
4000 if ( (l1 + r31)*((LONG)
sizeof(WORD)) >= AM.MaxTer ) {
4001 MLOCK(ErrorMessageLock);
4002 MesPrint(
"MasterMerge: Coefficient overflow during sort");
4003 MUNLOCK(ErrorMessageLock);
4006 m2 = poin[S->tree[i]];
4007 m3 = ( poin[S->tree[i]] -= r31 );
4008 do { *m3++ = *m2++; }
while ( m2 < m1 );
4012 *(poin[S->tree[i]]) += r31;
4014 m2 = (WORD *)coef; im = r3;
4026 AB[ki+1]->T.SB.BlockTerms[AB[ki+1]->T.SB.MasterBlock]--;
4027 if ( AB[ki+1]->T.SB.BlockTerms[AB[ki+1]->T.SB.MasterBlock] == 0 ) {
4033 i = AT.SB.MasterBlock;
4035 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
4038 UNLOCK(AT.SB.MasterBlockLock[i-1]);
4040 if ( i == AT.SB.MasterNumBlocks ) {
4044 LOCK(AT.SB.MasterBlockLock[i]);
4045 AT.SB.MasterBlock = i;
4046 poin[k] = AT.SB.MasterStart[i];
4048 poin2[k] = poin[k] + im;
4056 else if ( S->tree[i] < 0 ) {
4067 if ( ( im =
PutOut(B0,poin[k],&position,fout,1) ) < 0 ) {
4068 MLOCK(ErrorMessageLock);
4069 MesPrint(
"Called from MasterMerge with k = %d (stream %d)",k,S->ktoi[k]);
4070 MUNLOCK(ErrorMessageLock);
4073 ADDPOS(S->SizeInFile[0],im);
4076 if (
FlushOut(&position,fout,1) )
goto ReturnError;
4077 ADDPOS(S->SizeInFile[0],1);
4081 position = S->SizeInFile[0];
4082 MULPOS(position,
sizeof(WORD));
4090 for ( j = 1; j <= numberofworkers; j++ ) {
4091 S->GenTerms += AB[j]->T.SS->GenTerms;
4092 S->verbComparisons += AB[j]->T.SS->verbComparisons;
4093 S->verbSBsortTerms += AB[j]->T.SS->verbSBsortTerms;
4094 S->verbSBsortCap += AB[j]->T.SS->verbSBsortCap;
4095 S->verbLBsortPatches += AB[j]->T.SS->verbLBsortPatches;
4096 S->verbLBsortCap += AB[j]->T.SS->verbLBsortCap;
4097 S->verbUnsortedSize += AB[j]->T.SS->verbUnsortedSize;
4100 WriteStats(&position,STATSPOSTSORT,NOCHECKLOGTYPE);
4101 Expressions[AR0.CurExpr].counter = S->TermsLeft;
4102 Expressions[AR0.CurExpr].size = position;
4106 for ( i = 1; i <= S->lPatch; i++ ) {
4108 UNLOCK(AT.SB.MasterBlockLock[0]);
4109 if ( AT.SB.MasterBlock == 1 ) {
4110 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
4113 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterBlock-1]);
4115 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterBlock]);
4120 for ( i = 1; i <= S->lPatch; i++ ) {
4122 UNLOCK(AT.SB.MasterBlockLock[0]);
4123 if ( AT.SB.MasterBlock == 1 ) {
4124 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
4127 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterBlock-1]);
4129 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterBlock]);
4157int SortBotMasterMerge(
void)
4160 ALLPRIVATES *B = AB[0], *BB;
4173 topsortbotavailables = 0;
4174 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
4175 WakeupThread(i,INISORTBOT);
4181 AR.CompressPointer[0] = 0;
4183 BB = AB[AT.SortBotIn1];
4184 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
4185 BB = AB[AT.SortBotIn2];
4186 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
4188 MasterWaitAllSortBots();
4193 for ( i = 1; i <= numberofworkers; i++ ) {
4195 WakeupThread(i,FINISHEXPRESSION);
4200 if ( fout->
handle >= 0 ) {
4201 PUTZERO(SortBotPosition);
4202 SeekFile(fout->
handle,&SortBotPosition,SEEK_END);
4203 ADDPOS(SortBotPosition,((fout->POfill-fout->PObuffer)*
sizeof(WORD)));
4206 SETBASEPOSITION(SortBotPosition,(fout->POfill-fout->PObuffer)*
sizeof(WORD));
4208 MasterWaitAllBlocks();
4214 topsortbotavailables = 0;
4215 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
4216 WakeupThread(i,RUNSORTBOT);
4218 if ( SortBotMerge(BHEAD0) ) {
4219 MLOCK(ErrorMessageLock);
4220 MesPrint(
"Called from SortBotMasterMerge");
4221 MUNLOCK(ErrorMessageLock);
4228 if ( S->file.
handle >= 0 )
4235 position = S->SizeInFile[0];
4236 MULPOS(position,
sizeof(WORD));
4244 for ( j = 1; j <= numberofworkers; j++ ) {
4245 S->GenTerms += AB[j]->T.SS->GenTerms;
4246 S->verbComparisons += AB[j]->T.SS->verbComparisons;
4247 S->verbSBsortTerms += AB[j]->T.SS->verbSBsortTerms;
4248 S->verbSBsortCap += AB[j]->T.SS->verbSBsortCap;
4249 S->verbLBsortPatches += AB[j]->T.SS->verbLBsortPatches;
4250 S->verbLBsortCap += AB[j]->T.SS->verbLBsortCap;
4251 S->verbUnsortedSize += AB[j]->T.SS->verbUnsortedSize;
4253 for ( j = numberofworkers+1; j <= numberofworkers+numberofsortbots; j++ ) {
4254 S->verbComparisons += AB[j]->T.SS->verbComparisons;
4257 S->TermsLeft = numberofterms;
4258 WriteStats(&position,STATSPOSTSORT,NOCHECKLOGTYPE);
4259 Expressions[AR.CurExpr].counter = S->TermsLeft;
4260 Expressions[AR.CurExpr].size = position;
4269 MasterWaitAllSortBots();
4288int SortBotMerge(PHEAD0)
4291 ALLPRIVATES *Bin1 = AB[AT.SortBotIn1],*Bin2 = AB[AT.SortBotIn2];
4292 WORD *term1, *term2, *wp;
4295 WORD l1, l2, *m1, *m2, *w, r1, r2, r3, r33, r31, *tt1, ii;
4296 WORD *to, *from, im, c;
4300 WORD *fun1, *fun2, *fun3, *tstop1, *tstop2, size1, size2, size3, l3, jj, *m3;
4308 if ( AT.identity == 0 ) {
4309 wp = AT.WorkPointer;
4312 wp = AT.WorkPointer = AT.WorkSpace;
4319 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4320 LOCK(Bin2->T.SB.MasterBlockLock[blin2]);
4322 term1 = Bin1->T.SB.MasterStart[blin1];
4323 term2 = Bin2->T.SB.MasterStart[blin2];
4324 AT.SB.FillBlock = 1;
4328 while ( *term1 && *term2 ) {
4329 if ( ( c = CompareTerms(BHEAD term1,term2,(WORD)0) ) > 0 ) {
4333 Bin1->T.SB.BlockTerms[blin1]--;
4334 if ( SortBotOut(BHEAD term1) < 0 ) {
4335 MLOCK(ErrorMessageLock);
4336 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4337 MUNLOCK(ErrorMessageLock);
4342 if ( Bin1->T.SB.BlockTerms[blin1] == 0 ) {
4344 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4347 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4349 if ( blin1 == Bin1->T.SB.MasterNumBlocks ) {
4355 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4356 Bin1->T.SB.MasterBlock = blin1;
4357 term1 = Bin1->T.SB.MasterStart[blin1];
4367 Bin2->T.SB.BlockTerms[blin2]--;
4368 if ( SortBotOut(BHEAD term2) < 0 ) {
4369 MLOCK(ErrorMessageLock);
4370 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4371 MUNLOCK(ErrorMessageLock);
4377 if ( Bin2->T.SB.BlockTerms[blin2] == 0 ) {
4379 UNLOCK(Bin2->T.SB.MasterBlockLock[Bin2->T.SB.MasterNumBlocks]);
4382 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2-1]);
4384 if ( blin2 == Bin2->T.SB.MasterNumBlocks ) {
4390 LOCK(Bin2->T.SB.MasterBlockLock[blin2]);
4391 Bin2->T.SB.MasterBlock = blin2;
4392 term2 = Bin2->T.SB.MasterStart[blin2];
4402 Bin1->T.SB.BlockTerms[blin1]--;
4403 Bin2->T.SB.BlockTerms[blin2]--;
4404 l1 = *( m1 = term1 );
4405 l2 = *( m2 = term2 );
4406 if ( S->PolyWise ) {
4410 if ( S->PolyFlag == 2 ) {
4411 AT.WorkPointer = wp;
4413 if ( *tt1 + w[1] - m1[1] > AM.MaxTer/((LONG)
sizeof(WORD)) ) {
4414 MLOCK(ErrorMessageLock);
4415 MesPrint(
"Term too complex in PolyRatFun addition. MaxTermSize of %10l is too small",AM.MaxTer);
4416 MUNLOCK(ErrorMessageLock);
4419 AT.WorkPointer = wp;
4420 if ( w[FUNHEAD] == -SNUMBER && w[FUNHEAD+1] == 0 && w[1] > FUNHEAD ) {
4426 if ( w + m1[1] + m2[1] > AT.WorkTop ) {
4427 MLOCK(ErrorMessageLock);
4428 MesPrint(
"SortBotMerge(%d): A Maxtermsize of %10l is too small",
4429 AT.identity,AM.MaxTer/
sizeof(WORD));
4430 MesPrint(
"m1[1] = %d, m2[1] = %d, Space = %l",m1[1],m2[1],(LONG)(AT.WorkTop-wp));
4431 PrintTerm(term1,
"term1");
4432 PrintTerm(term2,
"term2");
4433 MesPrint(
"PolyWise = %d",S->PolyWise);
4434 MUNLOCK(ErrorMessageLock);
4441 || ( w[FUNHEAD] == -SNUMBER && w[FUNHEAD+1] == 0 ) )
4443 if ( r1 == m1[1] ) {
4446 else if ( r1 < m1[1] ) {
4450 while ( --r1 >= 0 ) *--m1 = *--m2;
4453 while ( --r1 >= 0 ) *--m1 = *--m2;
4476 else if ( AT.SortFloatMode ) {
4484 tstop1 = m1+l1; size1 = tstop1[-1]; tstop1 -= ABS(size1);
4485 tstop2 = m2+l2; size2 = tstop2[-1]; tstop2 -= ABS(size2);
4486 if ( AT.SortFloatMode == 3 ) {
4488 while ( fun1[0] != FLOATFUN && fun1+fun1[1] < tstop1 ) {
4491 if ( size1 < 0 ) fun1[FUNHEAD+3] = -fun1[FUNHEAD+3];
4492 UnpackFloat(aux1,fun1);
4494 while ( fun2[0] != FLOATFUN && fun2+fun2[1] < tstop2 ) {
4497 if ( size2 < 0 ) fun2[FUNHEAD+3] = -fun2[FUNHEAD+3];
4498 UnpackFloat(aux2,fun2);
4500 else if ( AT.SortFloatMode == 1 ) {
4502 while ( fun1[0] != FLOATFUN && fun1+fun1[1] < tstop1 ) {
4505 if ( size1 < 0 ) fun1[FUNHEAD+3] = -fun1[FUNHEAD+3];
4506 UnpackFloat(aux1,fun1);
4508 RatToFloat(aux2,(UWORD *)fun2,size2);
4510 else if ( AT.SortFloatMode == 2 ) {
4512 RatToFloat(aux1,(UWORD *)fun1,size1);
4514 while ( fun2[0] != FLOATFUN && fun2+fun2[1] < tstop2 ) {
4517 if ( size2 < 0 ) fun2[FUNHEAD+3] = -fun2[FUNHEAD+3];
4518 UnpackFloat(aux2,fun2);
4521 MLOCK(ErrorMessageLock);
4522 MesPrint(
"Illegal value %d for AT.SortFloatMode in SortBotMerge.",AT.SortFloatMode);
4523 MUNLOCK(ErrorMessageLock);
4527 mpf_add(aux3,aux1,aux2);
4528 size3 = mpf_sgn(aux3);
4532 else if ( size3 < 0 ) mpf_neg(aux3,aux3);
4533 fun3 = TermMalloc(
"MasterMerge");
4534 PackFloat(fun3,aux3);
4535 l3 = fun3[1]+(fun1-m1)+3;
4541 if ( (l3)*((LONG)
sizeof(WORD)) >= AM.MaxTer ) {
4542 MLOCK(ErrorMessageLock);
4543 MesPrint(
"MasterMerge: Coefficient overflow during sort");
4544 MUNLOCK(ErrorMessageLock);
4547 m3 = wp; m2 = term1;
4548 while ( m2 < fun1 ) *m3++ = *m2++;
4549 for ( jj = 0; jj < fun3[1]; jj++ ) *m3++ = fun3[jj];
4550 *m3++ = 1; *m3++ = 1;
4551 *m3++ = size3 < 0 ? -3: 3;
4553 TermFree(fun3,
"MasterMerge");
4556 for ( jj = 0; jj < fun3[1]; jj++ ) fun1[jj] = fun3[jj];
4558 *fun1++ = 1; *fun1++ = 1;
4559 *fun1++ = size3 < 0 ? -3: 3;
4560 *term1 = fun1-term1;
4561 TermFree(fun3,
"MasterMerge");
4565 r1 = *( m1 += l1 - 1 );
4567 r1 = ( ( r1 > 0 ) ? (r1-1) : (r1+1) ) >> 1;
4568 r2 = *( m2 += l2 - 1 );
4570 r2 = ( ( r2 > 0 ) ? (r2-1) : (r2+1) ) >> 1;
4572 if ( AddRat(BHEAD (UWORD *)m1,r1,(UWORD *)m2,r2,coef,&r3) ) {
4573 MLOCK(ErrorMessageLock);
4574 MesCall(
"SortBotMerge");
4575 MUNLOCK(ErrorMessageLock);
4579 if ( AN.ncmod != 0 ) {
4580 if ( ( AC.modmode & POSNEG ) != 0 ) {
4583 else if ( BigLong(coef,r3,(UWORD *)AC.cmod,ABS(AN.ncmod)) >= 0 ) {
4584 SubPLon(coef,r3,(UWORD *)AC.cmod,ABS(AN.ncmod),coef,&r3);
4586 for ( ii = 1; ii < r3; ii++ ) coef[r3+ii] = 0;
4589 if ( !r3 ) {
goto cancelled; }
4591 r33 = ( r3 > 0 ) ? ( r3 + 1 ) : ( r3 - 1 );
4592 if ( r3 < 0 ) r3 = -r3;
4593 if ( r1 < 0 ) r1 = -r1;
4597 m2 = (WORD *)coef; im = r3;
4602 to = wp; from = term1;
4603 while ( from < m1 ) *to++ = *from++;
4604 from = (WORD *)coef; im = r3;
4609 if ( SortBotOut(BHEAD wp) < 0 ) {
4610 MLOCK(ErrorMessageLock);
4611 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4612 MUNLOCK(ErrorMessageLock);
4619 if ( SortBotOut(BHEAD term1) < 0 ) {
4620 MLOCK(ErrorMessageLock);
4621 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4622 MUNLOCK(ErrorMessageLock);
4628 if ( Bin1->T.SB.BlockTerms[blin1] == 0 ) {
4631 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4634 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4636 if ( blin1 == Bin1->T.SB.MasterNumBlocks ) {
4642 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4643 Bin1->T.SB.MasterBlock = blin1;
4644 term1 = Bin1->T.SB.MasterStart[blin1];
4660 Bin1->T.SB.BlockTerms[blin1]--;
4661 if ( SortBotOut(BHEAD term1) < 0 ) {
4662 MLOCK(ErrorMessageLock);
4663 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4664 MUNLOCK(ErrorMessageLock);
4668 if ( Bin1->T.SB.BlockTerms[blin1] == 0 ) {
4671 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4674 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4676 if ( blin1 == Bin1->T.SB.MasterNumBlocks ) {
4682 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4683 Bin1->T.SB.MasterBlock = blin1;
4684 term1 = Bin1->T.SB.MasterStart[blin1];
4694 else if ( *term2 ) {
4699 Bin2->T.SB.BlockTerms[blin2]--;
4700 if ( SortBotOut(BHEAD term2) < 0 ) {
4701 MLOCK(ErrorMessageLock);
4702 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4703 MUNLOCK(ErrorMessageLock);
4707 if ( Bin2->T.SB.BlockTerms[blin2] == 0 ) {
4710 UNLOCK(Bin2->T.SB.MasterBlockLock[Bin2->T.SB.MasterNumBlocks]);
4713 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2-1]);
4715 if ( blin2 == Bin2->T.SB.MasterNumBlocks ) {
4721 LOCK(Bin2->T.SB.MasterBlockLock[blin2]);
4722 Bin2->T.SB.MasterBlock = blin2;
4723 term2 = Bin2->T.SB.MasterStart[blin2];
4737 Bin1->T.SB.BlockTerms[blin1]--;
4738 Bin2->T.SB.BlockTerms[blin2]--;
4740 SortBotOut(BHEAD 0);
4745 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4747 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4750 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4752 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2]);
4754 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2-1]);
4757 UNLOCK(Bin2->T.SB.MasterBlockLock[Bin2->T.SB.MasterNumBlocks]);
4759 if ( AT.identity > 0 ) {
4760 UNLOCK(AT.SB.MasterBlockLock[AT.SB.FillBlock]);
4775static int SortBlocksInitialized = 0;
4783int IniSortBlocks(
int numworkers)
4787 LONG totalsize, workersize, blocksize, numberofterms;
4789 int numberofblocks = NUMBEROFBLOCKSINSORT, numparts;
4792 if ( SortBlocksInitialized )
return(0);
4793 SortBlocksInitialized = 1;
4794 if ( numworkers == 0 )
return(0);
4797 if ( numworkers > 2 ) {
4798 numparts = 2*numworkers - 2;
4799 numberofblocks = numberofblocks/2;
4802 numparts = numworkers;
4805 numparts = numworkers;
4808 totalsize = S->LargeSize + S->SmallEsize;
4809 workersize = totalsize / numparts;
4810 maxter = AM.MaxTer/
sizeof(WORD);
4811 blocksize = ( workersize - maxter )/numberofblocks;
4812 numberofterms = blocksize / maxter;
4813 if ( numberofterms < MINIMUMNUMBEROFTERMS ) {
4817 MesPrint(
"We have a problem with the size of the blocks in IniSortBlocks");
4826 if ( w == 0 ) w = S->sBuffer;
4827 for (
id = 1;
id <= numparts;
id++ ) {
4829 AT.SB.MasterBlockLock = (pthread_mutex_t *)Malloc1(
4830 sizeof(pthread_mutex_t)*(numberofblocks+1),
"MasterBlockLock");
4831 AT.SB.MasterStart = (WORD **)Malloc1(
sizeof(WORD *)*(numberofblocks+1)*3,
"MasterBlock");
4832 AT.SB.MasterFill = AT.SB.MasterStart + (numberofblocks+1);
4833 AT.SB.MasterStop = AT.SB.MasterFill + (numberofblocks+1);
4834 AT.SB.MasterNumBlocks = numberofblocks;
4835 AT.SB.BlockTerms = (LONG*)Malloc1(
sizeof(LONG)*(numberofblocks+1),
"BlockTerms");
4836 AT.SB.MasterBlock = 0;
4837 AT.SB.FillBlock = 0;
4838 AT.SB.MasterFill[0] = AT.SB.MasterStart[0] = w;
4839 AT.SB.BlockTerms[0] = 0;
4841 AT.SB.MasterStop[0] = w;
4842 AT.SB.MasterBlockLock[0] = dummylock;
4843 for ( j = 1; j <= numberofblocks; j++ ) {
4844 AT.SB.MasterFill[j] = AT.SB.MasterStart[j] = w;
4845 AT.SB.BlockTerms[j] = 0;
4847 AT.SB.MasterStop[j] = w;
4848 AT.SB.MasterBlockLock[j] = dummylock;
4851 if ( w > S->sTop2 ) {
4852 MesPrint(
"Counting problem in IniSortBlocks");
4867int UpdateSortBlocks(
int numworkers)
4871 LONG totalsize, workersize, blocksize, numberofterms;
4873 int numberofblocks = NUMBEROFBLOCKSINSORT, numparts;
4876 if ( numworkers == 0 )
return(0);
4879 if ( numworkers > 2 ) {
4880 numparts = 2*numworkers - 2;
4881 numberofblocks = numberofblocks/2;
4884 numparts = numworkers;
4887 numparts = numworkers;
4890 totalsize = S->LargeSize + S->SmallEsize;
4891 workersize = totalsize / numparts;
4892 maxter = AM.MaxTer/
sizeof(WORD);
4893 blocksize = ( workersize - maxter )/numberofblocks;
4894 numberofterms = blocksize / maxter;
4895 if ( numberofterms < MINIMUMNUMBEROFTERMS ) {
4899 MesPrint(
"We have a problem with the size of the blocks in UpdateSortBlocks");
4908 if ( w == 0 ) w = S->sBuffer;
4909 for (
id = 1;
id <= numparts;
id++ ) {
4911 AT.SB.MasterFill[0] = AT.SB.MasterStart[0] = w;
4913 AT.SB.MasterStop[0] = w;
4914 for ( j = 1; j <= numberofblocks; j++ ) {
4915 AT.SB.MasterFill[j] = AT.SB.MasterStart[j] = w;
4917 AT.SB.MasterStop[j] = w;
4920 if ( w > S->sTop2 ) {
4921 MesPrint(
"Counting problem in UpdateSortBlocks");
4939void DefineSortBotTree(
void)
4943 if ( numberofworkers <= 2 )
return;
4944 n = numberofworkers*2-2;
4945 for ( i = numberofworkers+1, from = 1; i <= n; i++ ) {
4947 AT.SortBotIn1 = from++;
4948 AT.SortBotIn2 = from++;
4951 AT.SortBotIn1 = from++;
4952 AT.SortBotIn2 = from++;
4967WORD GetTerm2(PHEAD WORD *term)
4969 WORD *ttco, *tt, retval;
4975 POSITION where, eonfile = AS.OldOnFile[e-Expressions], bstart, bnext;
4979 switch ( e->status ) {
4980 case UNHIDELEXPRESSION:
4981 case UNHIDEGEXPRESSION:
4982 case DROPHLEXPRESSION:
4983 case DROPHGEXPRESSION:
4984 case HIDDENLEXPRESSION:
4985 case HIDDENGEXPRESSION:
4992 if ( AR.KeptInHold ) {
4993 retval = GetTerm(BHEAD term);
4996 SeekScratch(fi,&where);
4997 if ( AN.lastinindex < 0 ) {
5001 if ( ( n = TreatIndexEntry(BHEAD 0) ) <= 0 ) {
5003 where = bi[n].start;
5004 ADD2POS(where,eonfile);
5005 SetScratch(fi,&where);
5009 ttco = AR.CompressBuffer;
5013 AR.CompressPointer = ttco;
5014 retval = GetTerm(BHEAD term);
5017 else AN.lastinindex = n-1;
5024 bstart = bi[n].start;
5025 ADD2POS(bstart,eonfile);
5027 ADD2POS(bnext,eonfile);
5028 if ( ISLESSPOS(bstart,where) && ISLESSPOS(where,bnext) ) {
5029 retval = GetTerm(BHEAD term);
5032 for ( n++ ; n < b->indexfill; n++ ) {
5033 i = TreatIndexEntry(BHEAD n);
5038 ttco = AR.CompressBuffer;
5042 AR.CompressPointer = ttco;
5044 where = bi[n].start;
5045 ADD2POS(where,eonfile);
5046 SetScratch(fi,&(where));
5047 retval = GetTerm(BHEAD term);
5067int TreatIndexEntry(PHEAD LONG n)
5070 LONG numbra = b->indexfill - 1, i;
5078 if ( ( numbra - n ) <= numberofworkers )
return(0);
5084 DIFPOS(pos1,bi[numbra].next,bi[n].next);
5085 BASEPOSITION(average) = DIVPOS(pos1,(3*numberofworkers));
5086 DIFPOS(pos1,bi[n].next,bi[n].start);
5087 if ( ISLESSPOS(average,pos1) )
return(0);
5092 totterms = bi->termsinbracket;
5093 if ( totterms > 2*AC.ThreadBucketSize )
return(1);
5094 for ( i = 1; i < numbra-n; i++ ) {
5095 DIFPOS(pos1,bi[n+i].next,bi[n].start);
5096 if ( ISLESSPOS(average,pos1) )
return(i);
5097 totterms += bi->termsinbracket;
5098 if ( totterms > 2*AC.ThreadBucketSize )
return(i+1);
5111void SetHideFiles(
void) {
5113 ALLPRIVATES *B, *B0 = AB[0];
5114 for ( i = 1; i <= numberofworkers; i++ ) {
5116 AR.hidefile->handle = AR0.hidefile->handle;
5117 if ( AR.hidefile->handle < 0 ) {
5118 AR.hidefile->PObuffer = AR0.hidefile->PObuffer;
5119 AR.hidefile->POstop = AR0.hidefile->POstop;
5120 AR.hidefile->POfill = AR0.hidefile->POfill;
5121 AR.hidefile->POfull = AR0.hidefile->POfull;
5122 AR.hidefile->POsize = AR0.hidefile->POsize;
5123 AR.hidefile->POposition = AR0.hidefile->POposition;
5124 AR.hidefile->filesize = AR0.hidefile->filesize;
5127 AR.hidefile->PObuffer = AR.hidefile->wPObuffer;
5128 AR.hidefile->POstop = AR.hidefile->wPOstop;
5129 AR.hidefile->POfill = AR.hidefile->wPOfill;
5130 AR.hidefile->POfull = AR.hidefile->wPOfull;
5131 AR.hidefile->POsize = AR.hidefile->wPOsize;
5132 PUTZERO(AR.hidefile->POposition);
5145 for ( i = 0; i < AM.totalnumberofthreads; i++ ) {
5159 for ( j = 0; j < AM.totalnumberofthreads; j++ ) {
5161 AN.ncmod = AC.ncmod;
5162 if ( AN.cmod != 0 ) M_free(AN.cmod,
"AN.cmod");
5164 AN.cmod = (UWORD *)Malloc1(
sizeof(WORD)*n,
"AN.cmod");
5165 for ( i = 0; i < n; i++ ) AN.cmod[i] = AC.cmod[i];
5178 for ( j = 0; j < AM.totalnumberofthreads; j++ ) {
5180 if ( AN.cmod != 0 ) M_free(AN.cmod,
"AN.cmod");
5190void find_Horner_MCTS_expand_tree_threaded(
void) {
5192 while ((
id = GetAvailableThread() ) < 0)
5194 WakeupThread(
id,MCTSEXPANDTREE);
5202extern void optimize_expression_given_Horner_threaded(
void) {
5204 while ((
id = GetAvailableThread() ) < 0)
5206 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