73int PackFloat(WORD *,mpf_t);
74int UnpackFloat(mpf_t, WORD *);
75void RatToFloat(mpf_t result, UWORD *formrat,
int ratsize);
78static int numberofthreads;
79static int numberofworkers;
80static int identityofthreads = 0;
81static int *listofavailables;
82static int topofavailables = 0;
83static pthread_key_t identitykey;
84static INILOCK(numberofthreadslock)
85static INILOCK(availabilitylock)
86static pthread_t *threadpointers = 0;
87static pthread_mutex_t *wakeuplocks;
88static pthread_mutex_t *wakeupmasterthreadlocks;
89static pthread_cond_t *wakeupconditions;
90static pthread_condattr_t *wakeupconditionattributes;
92static int *wakeupmasterthread;
93static INILOCK(wakeupmasterlock)
94static pthread_cond_t wakeupmasterconditions = PTHREAD_COND_INITIALIZER;
95static pthread_cond_t *wakeupmasterthreadconditions;
96static int wakeupmaster = 0;
97static int identityretval;
99static LONG *timerinfo;
100static LONG *sumtimerinfo;
101static int numberclaimed;
103static THREADBUCKET **threadbuckets, **freebuckets;
104static int numthreadbuckets;
105static int numberoffullbuckets;
110INIRWLOCK(dummyrwlock)
111static pthread_cond_t dummywakeupcondition = PTHREAD_COND_INITIALIZER;
114static INILOCK(wakeupsortbotlock)
115static pthread_cond_t wakeupsortbotconditions = PTHREAD_COND_INITIALIZER;
116static int topsortbotavailables = 0;
117static LONG numberofterms;
129void StartIdentity(
void)
131 pthread_key_create(&identitykey,FinishIdentity);
142void FinishIdentity(
void *keyp)
156int SetIdentity(
int *identityretval)
164 LOCK(numberofthreadslock);
165 *identityretval = identityofthreads++;
166 UNLOCK(numberofthreadslock);
167 pthread_setspecific(identitykey,(
void *)identityretval);
168 return(*identityretval);
192 if ( identityofthreads <= 1 )
return(0);
201 identity = (
int *)pthread_getspecific(identitykey);
214void BeginIdentities(
void)
217 SetIdentity(&identityretval);
231void StartHandleLock(
void)
233 AM.handlelock = dummyrwlock;
243int GetNumberOfSortBots(
int numberofworkers)
245 if (numberofworkers <= 1)
248 return numberofworkers - 1;
271int StartAllThreads(
int number)
273 int identity, j, dummy, mul;
279 timerinfo = (LONG *)Malloc1(
sizeof(LONG)*number*2,
"timerinfo");
280 sumtimerinfo = (LONG *)Malloc1(
sizeof(LONG)*number*2,
"sumtimerinfo");
281 for ( j = 0; j < number*2; j++ ) { timerinfo[j] = 0; sumtimerinfo[j] = 0; }
284 listofavailables = (
int *)Malloc1(
sizeof(
int)*(number+1),
"listofavailables");
285 threadpointers = (pthread_t *)Malloc1(
sizeof(pthread_t)*number*mul,
"threadpointers");
286 AB = (ALLPRIVATES **)Malloc1(
sizeof(ALLPRIVATES *)*number*mul,
"Private structs");
288 wakeup = (
int *)Malloc1(
sizeof(
int)*number*mul,
"wakeup");
289 wakeuplocks = (pthread_mutex_t *)Malloc1(
sizeof(pthread_mutex_t)*number*mul,
"wakeuplocks");
290 wakeupconditions = (pthread_cond_t *)Malloc1(
sizeof(pthread_cond_t)*number*mul,
"wakeupconditions");
291 wakeupconditionattributes = (pthread_condattr_t *)
292 Malloc1(
sizeof(pthread_condattr_t)*number*mul,
"wakeupconditionattributes");
294 wakeupmasterthread = (
int *)Malloc1(
sizeof(
int)*number*mul,
"wakeupmasterthread");
295 wakeupmasterthreadlocks = (pthread_mutex_t *)Malloc1(
sizeof(pthread_mutex_t)*number*mul,
"wakeupmasterthreadlocks");
296 wakeupmasterthreadconditions = (pthread_cond_t *)Malloc1(
sizeof(pthread_cond_t)*number*mul,
"wakeupmasterthread");
298 numberofthreads = number;
299 numberofworkers = number - 1;
300 threadpointers[identity] = pthread_self();
308 sigemptyset(&sig_set);
309 sigaddset(&sig_set, SIGALRM);
310 pthread_sigmask(SIG_BLOCK, &sig_set, NULL);
313 for ( j = 1; j < number; j++ ) {
314 if ( pthread_create(&thethread,NULL,RunThread,(
void *)(&dummy)) )
320 B = InitializeOneThread(identity);
321 AR.infile = &(AR.Fscr[0]);
322 AR.outfile = &(AR.Fscr[1]);
323 AR.hidefile = &(AR.Fscr[2]);
324 AM.sbuflock = dummylock;
325 AS.inputslock = dummylock;
326 AS.outputslock = dummylock;
327 AS.MaxExprSizeLock = dummylock;
328 AP.PreVarLock = dummylock;
329 AC.halfmodlock = dummylock;
330 MakeThreadBuckets(number,0);
338 for ( j = 0; j < GetNumberOfSortBots(numberofworkers); j++ ) {
339 if ( pthread_create(&thethread,NULL,RunSortBot,(
void *)(&dummy)) )
342 MasterWaitAllSortBots();
344 IniSortBlocks(number-1);
346 AM.storefilelock = dummylock;
350 pthread_sigmask(SIG_UNBLOCK, &sig_set, NULL);
359 MesPrint(
"!>Cannot start %d threads",number);
372UBYTE *scratchname[] = { (UBYTE *)
"scratchsize",
373 (UBYTE *)
"scratchsize",
374 (UBYTE *)
"hidesize" };
401ALLPRIVATES *InitializeOneThread(
int identity)
403 WORD *t, *ScratchBuf;
404 int i, j, bsize, *bp;
405 LONG ScratchSize[3], IOsize;
409 wakeup[identity] = 0;
410 wakeuplocks[identity] = dummylock;
411 pthread_condattr_init(&(wakeupconditionattributes[identity]));
412 pthread_condattr_setpshared(&(wakeupconditionattributes[identity]),PTHREAD_PROCESS_PRIVATE);
413 wakeupconditions[identity] = dummywakeupcondition;
414 pthread_cond_init(&(wakeupconditions[identity]),&(wakeupconditionattributes[identity]));
415 wakeupmasterthread[identity] = 0;
416 wakeupmasterthreadlocks[identity] = dummylock;
417 wakeupmasterthreadconditions[identity] = dummywakeupcondition;
419 bsize =
sizeof(ALLPRIVATES);
420 bsize = (bsize+
sizeof(int)-1)/
sizeof(int);
421 B = (ALLPRIVATES *)Malloc1(
sizeof(
int)*bsize,
"B struct");
422 for ( bp = (
int *)B, j = 0; j < bsize; j++ ) *bp++ = 0;
441 if ( identity > 0 )
TimeCPU(0);
444 if ( identity > numberofworkers ) {
449 LONG length = AM.WorkSize*
sizeof(WORD)/8+AM.MaxTer*2;
450 AT.WorkSpace = (WORD *)Malloc1(length,
"WorkSpace");
451 AT.WorkTop = AT.WorkSpace + length/
sizeof(WORD);
452 AT.WorkPointer = AT.WorkSpace;
453 AT.identity = identity;
458 if ( AN.SoScratC == 0 ) {
459 AN.SoScratC = (UWORD *)Malloc1(2*(AM.MaxTal+2)*
sizeof(UWORD),
"Scratch in SortBot");
465 AT.comsym[1] = SYMBOL;
476 AT.comfun[0] = FUNHEAD+4;
477 AT.comfun[1] = FUNCTION;
478 AT.comfun[2] = FUNHEAD;
481 for ( i = 4; i <= FUNHEAD; i++ )
484 AT.comfun[FUNHEAD+1] = 1;
485 AT.comfun[FUNHEAD+2] = 1;
486 AT.comfun[FUNHEAD+3] = 3;
488 AT.comind[1] = INDEX;
496 AT.sizeprimelist = 0;
500 AR.CompareRoutine = (COMPAREDUMMY)(&
Compare1);
505 AR.wranfnpair1 = NPAIR1;
506 AR.wranfnpair2 = NPAIR2;
510 AN.SplitScratchSize = AN.InScratch = 0;
511 AN.SplitScratch1 = 0;
512 AN.SplitScratchSize1 = AN.InScratch1 = 0;
514 AN.FunSorts = (
SORTING **)Malloc1((AN.NumFunSorts+1)*
sizeof(
SORTING *),
"FunSort pointers");
515 for ( i = 0; i <= AN.NumFunSorts; i++ ) AN.FunSorts[i] = 0;
516 AN.FunSorts[0] = AT.S0 = AT.SS;
517 AN.idfunctionflag = 0;
522 if ( identity == 0 && AN.SoScratC == 0 ) {
523 AN.SoScratC = (UWORD *)Malloc1(2*(AM.MaxTal+2)*
sizeof(UWORD),
"Scratch in SortBot");
525 AR.CurDum = AM.IndDum;
526 for ( j = 0; j < 3; j++ ) {
527 if ( identity == 0 ) {
529 ScratchSize[j] = AM.HideSize;
532 ScratchSize[j] = AM.ScratSize;
534 if ( ScratchSize[j] < 10*AM.MaxTer ) ScratchSize[j] = 10 * AM.MaxTer;
542 if ( j == 1 ) ScratchSize[j] = AM.ThreadScratOutSize;
543 else ScratchSize[j] = AM.ThreadScratSize;
544 if ( ScratchSize[j] < 4*AM.MaxTer ) ScratchSize[j] = 4 * AM.MaxTer;
547 ScratchSize[j] = ( ScratchSize[j] + 255 ) / 256;
548 ScratchSize[j] = ScratchSize[j] * 256;
549 ScratchBuf = (WORD *)Malloc1(ScratchSize[j]*
sizeof(WORD),(
char *)(scratchname[j]));
550 AR.Fscr[j].POsize = ScratchSize[j] *
sizeof(WORD);
551 AR.Fscr[j].POfull = AR.Fscr[j].POfill = AR.Fscr[j].PObuffer = ScratchBuf;
552 AR.Fscr[j].POstop = AR.Fscr[j].PObuffer + ScratchSize[j];
553 PUTZERO(AR.Fscr[j].POposition);
554 AR.Fscr[j].pthreadslock = dummylock;
555 AR.Fscr[j].wPOsize = AR.Fscr[j].POsize;
556 AR.Fscr[j].wPObuffer = AR.Fscr[j].PObuffer;
557 AR.Fscr[j].wPOfill = AR.Fscr[j].POfill;
558 AR.Fscr[j].wPOfull = AR.Fscr[j].POfull;
559 AR.Fscr[j].wPOstop = AR.Fscr[j].POstop;
563 AR.Fscr[0].handle = -1;
564 AR.Fscr[1].handle = -1;
565 AR.Fscr[2].handle = -1;
566 AR.FoStage4[0].handle = -1;
567 AR.FoStage4[1].handle = -1;
568 IOsize = AM.S0->file.POsize;
570 AR.FoStage4[0].ziosize = IOsize;
571 AR.FoStage4[1].ziosize = IOsize;
572 AR.FoStage4[0].ziobuffer = 0;
573 AR.FoStage4[1].ziobuffer = 0;
575 AR.FoStage4[0].POsize = ((IOsize+
sizeof(WORD)-1)/
sizeof(WORD))*
sizeof(WORD);
576 AR.FoStage4[1].POsize = ((IOsize+
sizeof(WORD)-1)/
sizeof(WORD))*
sizeof(WORD);
578 AR.hidefile = &(AR.Fscr[2]);
579 AR.StoreData.Handle = -1;
580 AR.SortType = AC.SortType;
582 AN.IndDum = AM.IndDum;
584 if ( identity > 0 ) {
585 s = (UBYTE *)(FG.fname); i = 0;
586 while ( *s ) { s++; i++; }
587 s = (UBYTE *)Malloc1(
sizeof(
char)*(i+12),
"name for Fscr[0] file");
588 snprintf((
char *)s,i+12,
"%s.%d",FG.fname,identity);
589 s[i-3] =
's'; s[i-2] =
'c'; s[i-1] =
'0';
590 AR.Fscr[0].name = (
char *)s;
591 s = (UBYTE *)(FG.fname); i = 0;
592 while ( *s ) { s++; i++; }
593 s = (UBYTE *)Malloc1(
sizeof(
char)*(i+12),
"name for Fscr[1] file");
594 snprintf((
char *)s,i+12,
"%s.%d",FG.fname,identity);
595 s[i-3] =
's'; s[i-2] =
'c'; s[i-1] =
'1';
596 AR.Fscr[1].name = (
char *)s;
599 AR.CompressBuffer = (WORD *)Malloc1((AM.CompressSize+10)*
sizeof(WORD),
"compresssize");
600 AR.ComprTop = AR.CompressBuffer + AM.CompressSize;
601 AR.CompareRoutine = (COMPAREDUMMY)(&
Compare1);
606 AT.WorkSpace = (WORD *)Malloc1(AM.WorkSize*
sizeof(WORD),
"WorkSpace");
607 AT.WorkTop = AT.WorkSpace + AM.WorkSize;
608 AT.WorkPointer = AT.WorkSpace;
610 AT.Nest = (
NESTING)Malloc1((LONG)
sizeof(
struct NeStInG)*AM.maxFlevels,
"functionlevels");
611 AT.NestStop = AT.Nest + AM.maxFlevels;
612 AT.NestPoin = AT.Nest;
614 AT.WildMask = (WORD *)Malloc1((LONG)AM.MaxWildcards*
sizeof(WORD),
"maxwildcards");
616 LOCK(availabilitylock);
621 UNLOCK(availabilitylock);
623 AT.RepCount = (
int *)Malloc1((LONG)((AM.RepMax+3)*
sizeof(
int)),
"repeat buffers");
624 AN.RepPoint = AT.RepCount;
628 AT.RepTop = AT.RepCount + AM.RepMax;
630 AT.WildArgTaken = (WORD *)Malloc1((LONG)AC.WildcardBufferSize*
sizeof(WORD)/2
631 ,
"argument list names");
632 AT.WildcardBufferSize = AC.WildcardBufferSize;
633 AT.previousEfactor = 0;
635 AT.identity = identity;
636 AT.LoadBalancing = 0;
642 if ( AT.WorkSpace == 0 ||
646 AT.WildArgTaken == 0 )
goto OnError;
651 AT.comsym[1] = SYMBOL;
662 AT.comfun[0] = FUNHEAD+4;
663 AT.comfun[1] = FUNCTION;
664 AT.comfun[2] = FUNHEAD;
667 for ( i = 4; i <= FUNHEAD; i++ )
670 AT.comfun[FUNHEAD+1] = 1;
671 AT.comfun[FUNHEAD+2] = 1;
672 AT.comfun[FUNHEAD+3] = 3;
674 AT.comind[1] = INDEX;
680 AT.locwildvalue[0] = SUBEXPRESSION;
681 AT.locwildvalue[1] = SUBEXPSIZE;
682 for ( i = 2; i < SUBEXPSIZE; i++ ) AT.locwildvalue[i] = 0;
683 AT.mulpat[0] = TYPEMULT;
684 AT.mulpat[1] = SUBEXPSIZE+3;
686 AT.mulpat[3] = SUBEXPRESSION;
687 AT.mulpat[4] = SUBEXPSIZE;
690 for ( i = 7; i < SUBEXPSIZE+5; i++ ) AT.mulpat[i] = 0;
691 AT.proexp[0] = SUBEXPSIZE+4;
692 AT.proexp[1] = EXPRESSION;
693 AT.proexp[2] = SUBEXPSIZE;
696 for ( i = 5; i < SUBEXPSIZE+1; i++ ) AT.proexp[i] = 0;
697 AT.proexp[SUBEXPSIZE+1] = 1;
698 AT.proexp[SUBEXPSIZE+2] = 1;
699 AT.proexp[SUBEXPSIZE+3] = 3;
700 AT.proexp[SUBEXPSIZE+4] = 0;
701 AT.dummysubexp[0] = SUBEXPRESSION;
702 AT.dummysubexp[1] = SUBEXPSIZE+4;
703 for ( i = 2; i < SUBEXPSIZE; i++ ) AT.dummysubexp[i] = 0;
704 AT.dummysubexp[SUBEXPSIZE] = WILDDUMMY;
705 AT.dummysubexp[SUBEXPSIZE+1] = 4;
706 AT.dummysubexp[SUBEXPSIZE+2] = 0;
707 AT.dummysubexp[SUBEXPSIZE+3] = 0;
709 AT.MinVecArg[0] = 7+ARGHEAD;
710 AT.MinVecArg[ARGHEAD] = 7;
711 AT.MinVecArg[1+ARGHEAD] = INDEX;
712 AT.MinVecArg[2+ARGHEAD] = 3;
713 AT.MinVecArg[3+ARGHEAD] = 0;
714 AT.MinVecArg[4+ARGHEAD] = 1;
715 AT.MinVecArg[5+ARGHEAD] = 1;
716 AT.MinVecArg[6+ARGHEAD] = -3;
718 *t++ = 4+ARGHEAD+FUNHEAD;
719 for ( i = 1; i < ARGHEAD; i++ ) *t++ = 0;
723 for ( i = 2; i < FUNHEAD; i++ ) *t++ = 0;
724 *t++ = 1; *t++ = 1; *t++ = 3;
727 AT.sizeprimelist = 0;
729 AT.nfac = AT.nBer = 0;
734 AR.wranfnpair1 = NPAIR1;
735 AR.wranfnpair2 = NPAIR2;
738 AT.NormData = Malloc1(
sizeof(*(AT.NormData)),
"NormData thread pointers");
740 AT.NormData[0] = AllocNormData();
744 AN.SplitScratchSize = AN.InScratch = 0;
745 AN.SplitScratch1 = 0;
746 AN.SplitScratchSize1 = AN.InScratch1 = 0;
751 if ( identity == 0 ) {
759 AT.S0 = AllocSort(AM.S0->LargeSize*
sizeof(WORD)/numberofworkers
760 ,AM.S0->SmallSize*
sizeof(WORD)/numberofworkers
761 ,AM.S0->SmallEsize*
sizeof(WORD)/numberofworkers
765 ,AM.S0->MaxFpatches/numberofworkers
769 AR.CompressPointer = AR.CompressBuffer;
773 AT.StoreCache = AT.StoreCacheAlloc = 0;
774 if ( AM.NumStoreCaches > 0 ) {
777 size =
sizeof(
struct StOrEcAcHe)+AM.SizeStoreCache;
778 size = ((size-1)/
sizeof(
size_t)+1)*
sizeof(
size_t);
779 AT.StoreCacheAlloc = (
STORECACHE)Malloc1(size*AM.NumStoreCaches,
"StoreCaches");
780 sa = AT.StoreCache = AT.StoreCacheAlloc;
781 for ( i = 0; i < AM.NumStoreCaches; i++ ) {
783 if ( i == AM.NumStoreCaches-1 ) {
789 SETBASEPOSITION(sa->position,-1);
790 SETBASEPOSITION(sa->toppos,-1);
799 MLOCK(ErrorMessageLock);
800 MesPrint(
"!>Error initializing thread %d",identity);
801 MUNLOCK(ErrorMessageLock);
821void FinalizeOneThread(
int identity)
823 timerinfo[identity] =
TimeCPU(1);
836void ClearAllThreads(
void)
840 for ( i = 1; i <= numberofworkers; i++ ) {
841 WakeupThread(i,CLEARCLOCK);
843 for ( i = numberofworkers+1; i <= numberofworkers+GetNumberOfSortBots(numberofworkers); i++ ) {
844 WakeupThread(i,CLEARCLOCK);
858void TerminateAllThreads(
void)
861 for ( i = 1; i <= numberofworkers; i++ ) {
863 WakeupThread(i,TERMINATETHREAD);
865 for ( i = numberofworkers+1; i <= numberofworkers+GetNumberOfSortBots(numberofworkers); i++ ) {
866 WakeupThread(i,TERMINATETHREAD);
868 for ( i = 1; i <= numberofworkers; i++ ) {
869 pthread_join(threadpointers[i],NULL);
871 for ( i = numberofworkers+1; i <= numberofworkers+GetNumberOfSortBots(numberofworkers); i++ ) {
872 pthread_join(threadpointers[i],NULL);
905int MakeThreadBuckets(
int number,
int par)
908 LONG sizethreadbuckets;
914 sizethreadbuckets = (AC.ThreadBucketSize*MAXTER)/4;
919 if ( AM.MaxTer/
sizeof(WORD) > MAXTER ) {
920 scale += log(((
float)AM.MaxTer/
sizeof(WORD))/MAXTER);
922 sizethreadbuckets = (LONG)((
float)sizethreadbuckets*scale);
926 sizethreadbuckets = MaX((ULONG)sizethreadbuckets, BUCKETMINTERMS*AM.MaxTer/
sizeof(WORD));
929 numthreadbuckets = 2*(number-1);
930 threadbuckets = (THREADBUCKET **)Malloc1(numthreadbuckets*
sizeof(THREADBUCKET *),
"threadbuckets");
931 freebuckets = (THREADBUCKET **)Malloc1(numthreadbuckets*
sizeof(THREADBUCKET *),
"freebuckets");
934 if ( sizethreadbuckets <= threadbuckets[0]->threadbuffersize )
return(0);
935 for ( i = 0; i < numthreadbuckets; i++ ) {
936 thr = threadbuckets[i];
937 M_free(thr->deferbuffer,
"deferbuffer");
938 M_free(thr->threadbuffer,
"threadbuffer");
939 M_free(thr->compressbuffer,
"compressbuffer");
943 for ( i = 0; i < numthreadbuckets; i++ ) {
944 threadbuckets[i] = (THREADBUCKET *)Malloc1(
sizeof(THREADBUCKET),
"threadbuckets");
945 threadbuckets[i]->lock = dummylock;
948 for ( i = 0; i < numthreadbuckets; i++ ) {
949 thr = threadbuckets[i];
950 thr->threadbuffersize = sizethreadbuckets;
953 thr->compressbuffersize = AM.MaxTer/
sizeof(WORD);
954 thr->free = BUCKETFREE;
955 thr->deferbuffer = (
POSITION *)Malloc1((AC.ThreadBucketSize+1)*
sizeof(
POSITION),
"deferbuffer");
956 thr->threadbuffer = (WORD *)Malloc1(sizethreadbuckets*
sizeof(WORD),
"threadbuffer");
957 thr->compressbuffer = (WORD *)Malloc1(thr->compressbuffersize*
sizeof(WORD),
"compressbuffer");
958 thr->busy = BUCKETPREPARINGTERM;
959 thr->usenum = thr->totnum = 0;
960 thr->type = BUCKETDOINGTERMS;
976int GetTimerInfo(LONG** ti,LONG** sti)
980 return (numberofworkers + GetNumberOfSortBots(numberofworkers) + 1);
993void WriteTimerInfo(LONG* ti,LONG* sti)
996 int max = (numberofworkers + GetNumberOfSortBots(numberofworkers) + 1);
997 for ( i=0; i<max; ++i ) {
998 timerinfo[i] = ti[i];
999 sumtimerinfo[i] = sti[i];
1012LONG GetWorkerTimes(
void)
1016 for ( i = 1; i <= numberofworkers; i++ ) retval += timerinfo[i] + sumtimerinfo[i];
1017 for ( i = numberofworkers+1; i <= numberofworkers+GetNumberOfSortBots(numberofworkers); i++ )
1018 retval += timerinfo[i] + sumtimerinfo[i];
1032int UpdateOneThread(
int identity)
1034 ALLPRIVATES *B = AB[identity], *B0 = AB[0];
1035 AR.GetFile = AR0.GetFile;
1036 AR.KeptInHold = AR0.KeptInHold;
1037 AR.CurExpr = AR0.CurExpr;
1038 AR.SortType = AC.SortType;
1039 if ( AT.WildcardBufferSize < AC.WildcardBufferSize ) {
1040 M_free(AT.WildArgTaken,
"argument list names");
1041 AT.WildcardBufferSize = AC.WildcardBufferSize;
1042 AT.WildArgTaken = (WORD *)Malloc1((LONG)AC.WildcardBufferSize*
sizeof(WORD)/2
1043 ,
"argument list names");
1044 if ( AT.WildArgTaken == 0 )
return(-1);
1066int LoadOneThread(
int from,
int identity, THREADBUCKET *thr,
int par)
1069 ALLPRIVATES *B = AB[identity], *B0 = AB[from];
1071 AR.DefPosition = AR0.DefPosition;
1072 AR.NoCompress = AR0.NoCompress;
1073 AR.gzipCompress = AR0.gzipCompress;
1074 AR.BracketOn = AR0.BracketOn;
1075 AR.CurDum = AR0.CurDum;
1076 AR.DeferFlag = AR0.DeferFlag;
1078 AR.sLevel = AR0.sLevel;
1079 AR.Stage4Name = AR0.Stage4Name;
1080 AR.GetOneFile = AR0.GetOneFile;
1081 AR.PolyFun = AR0.PolyFun;
1082 AR.PolyFunInv = AR0.PolyFunInv;
1083 AR.PolyFunType = AR0.PolyFunType;
1084 AR.PolyFunExp = AR0.PolyFunExp;
1085 AR.PolyFunVar = AR0.PolyFunVar;
1086 AR.PolyFunPow = AR0.PolyFunPow;
1087 AR.Eside = AR0.Eside;
1088 AR.Cnumlhs = AR0.Cnumlhs;
1100 t1 = AR.CompressBuffer; t2 = AR0.CompressBuffer;
1101 while ( t2 < AR0.CompressPointer ) *t1++ = *t2++;
1102 AR.CompressPointer = t1;
1106 AR.CompressPointer = AR.CompressBuffer;
1108 if ( AR.DeferFlag ) {
1109 if ( AR.infile->handle < 0 ) {
1110 AR.infile->POfill = AR0.infile->POfill;
1117 AR.infile->POfull = AR.infile->POfill = AR.infile->PObuffer;
1121 AN.threadbuck = thr;
1122 AN.ninterms = thr->firstterm;
1124 else if ( par == 1 ) {
1126 t1 = thr->threadbuffer; tstop = t1 + *t1;
1127 t2 = AT.WorkPointer;
1128 while ( t1 < tstop ) *t2++ = *t1++;
1129 AN.ninterms = thr->firstterm;
1132 AN.ncmod = AC.ncmod;
1133 AT.BrackBuf = AT0.BrackBuf;
1134 AT.bracketindexflag = AT0.bracketindexflag;
1162int BalanceRunThread(PHEAD
int identity, WORD *term, WORD level)
1169 LoadOneThread(AT.identity,identity,0,2);
1175 BB->R.level = level;
1176 BB->T.TMbuff = AT.TMbuff;
1177 ti = AT.RepCount; tti = BB->T.RepCount;
1178 i = AN.RepPoint - AT.RepCount;
1179 BB->N.RepPoint = BB->T.RepCount + i;
1180 for ( ; i >= 0; i-- ) tti[i] = ti[i];
1182 t = term; i = *term;
1183 tt = BB->T.WorkSpace;
1185 BB->T.WorkPointer = tt;
1187 WakeupThread(identity,HIGHERLEVELGENERATION);
1200void SetWorkerFiles(
void)
1203 ALLPRIVATES *B, *B0 = AB[0];
1204 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
1206 AR.infile = &(AR.Fscr[0]);
1207 AR.outfile = &(AR.Fscr[1]);
1208 AR.hidefile = &(AR.Fscr[2]);
1209 AR.infile->handle = AR0.infile->handle;
1210 AR.hidefile->handle = AR0.hidefile->handle;
1211 if ( AR.infile->handle < 0 ) {
1212 AR.infile->PObuffer = AR0.infile->PObuffer;
1213 AR.infile->POstop = AR0.infile->POstop;
1214 AR.infile->POfill = AR0.infile->POfill;
1215 AR.infile->POfull = AR0.infile->POfull;
1216 AR.infile->POsize = AR0.infile->POsize;
1217 AR.InInBuf = AR0.InInBuf;
1218 AR.infile->POposition = AR0.infile->POposition;
1219 AR.infile->filesize = AR0.infile->filesize;
1222 AR.infile->PObuffer = AR.infile->wPObuffer;
1223 AR.infile->POstop = AR.infile->wPOstop;
1224 AR.infile->POfill = AR.infile->wPOfill;
1225 AR.infile->POfull = AR.infile->wPOfull;
1226 AR.infile->POsize = AR.infile->wPOsize;
1228 PUTZERO(AR.infile->POposition);
1236 AR.outfile->PObuffer = AR.outfile->wPObuffer;
1237 AR.outfile->POstop = AR.outfile->wPOstop;
1238 AR.outfile->POfill = AR.outfile->wPOfill;
1239 AR.outfile->POfull = AR.outfile->wPOfull;
1240 AR.outfile->POsize = AR.outfile->wPOsize;
1241 PUTZERO(AR.outfile->POposition);
1243 if ( AR.hidefile->handle < 0 ) {
1244 AR.hidefile->PObuffer = AR0.hidefile->PObuffer;
1245 AR.hidefile->POstop = AR0.hidefile->POstop;
1246 AR.hidefile->POfill = AR0.hidefile->POfill;
1247 AR.hidefile->POfull = AR0.hidefile->POfull;
1248 AR.hidefile->POsize = AR0.hidefile->POsize;
1249 AR.InHiBuf = AR0.InHiBuf;
1250 AR.hidefile->POposition = AR0.hidefile->POposition;
1251 AR.hidefile->filesize = AR0.hidefile->filesize;
1254 AR.hidefile->PObuffer = AR.hidefile->wPObuffer;
1255 AR.hidefile->POstop = AR.hidefile->wPOstop;
1256 AR.hidefile->POfill = AR.hidefile->wPOfill;
1257 AR.hidefile->POfull = AR.hidefile->wPOfull;
1258 AR.hidefile->POsize = AR.hidefile->wPOsize;
1260 PUTZERO(AR.hidefile->POposition);
1263 if ( AR0.StoreData.dirtyflag ) {
1264 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
1266 AR.StoreData = AR0.StoreData;
1282void *RunThread(
void *dummy)
1284 WORD *term, *ttin, *tt, *ttco, *oldwork;
1285 int identity, wakeupsignal, identityretv, i, tobereleased, errorcode;
1291 identity = SetIdentity(&identityretv);
1292 threadpointers[identity] = pthread_self();
1293 B = InitializeOneThread(identity);
1294 while ( ( wakeupsignal = ThreadWait(identity) ) > 0 ) {
1295 switch ( wakeupsignal ) {
1299 case STARTNEWEXPRESSION:
1304 if ( UpdateOneThread(identity) ) {
1306 MLOCK(ErrorMessageLock);
1307 MesPrint(
"!>Update error in starting expression in thread %d in module %d",identity,AC.CModule);
1308 MUNLOCK(ErrorMessageLock);
1312 AR.DeferFlag = AC.ComDefer;
1313 AR.sLevel = AS.sLevel;
1314 AR.MaxDum = AM.IndDum;
1315 AR.expchanged = AB[0]->R.expchanged;
1316 AR.expflags = AB[0]->R.expflags;
1317 AR.PolyFun = AB[0]->R.PolyFun;
1318 AR.PolyFunInv = AB[0]->R.PolyFunInv;
1319 AR.PolyFunType = AB[0]->R.PolyFunType;
1320 AR.PolyFunExp = AB[0]->R.PolyFunExp;
1321 AR.PolyFunVar = AB[0]->R.PolyFunVar;
1322 AR.PolyFunPow = AB[0]->R.PolyFunPow;
1332 case LOWESTLEVELGENERATION:
1334 if ( AC.InnerTest ) {
1335 if ( StrCmp(AC.TestValue,(UBYTE *)INNERTEST) == 0 ) {
1336 MesPrint(
"Testing(Worker%d): value = %s",AT.identity,AC.TestValue);
1340 e = Expressions + AR.CurExpr;
1341 thr = AN.threadbuck;
1342 ppdef = thr->deferbuffer;
1343 ttin = thr->threadbuffer;
1344 ttco = thr->compressbuffer;
1345 term = AT.WorkPointer;
1348 AN.inputnumber = thr->firstterm;
1349 AN.ninterms = thr->firstterm;
1352 tt = term; i = *ttin;
1354 AT.WorkPointer = tt;
1355 if ( AR.DeferFlag ) {
1356 tt = AR.CompressBuffer; i = *ttco;
1358 AR.CompressPointer = tt;
1359 AR.DefPosition = ppdef[0]; ppdef++;
1361 if ( thr->free == BUCKETTERMINATED ) {
1369 if ( thr->usenum == thr->totnum ) {
1370 thr->free = BUCKETCOMINGFREE;
1373 thr->free = BUCKETRELEASED;
1383 thr->busy = BUCKETDOINGTERM;
1391 AN.RepPoint = AT.RepCount + 1;
1393 if ( ( e->vflags & ISFACTORIZED ) != 0 && term[1] == HAAKJE ) {
1397 if ( AR.DeferFlag ) {
1398 AR.CurDum = AN.IndDum = Expressions[AR.CurExpr].numdummies + AM.IndDum;
1401 AN.IndDum = AM.IndDum;
1402 AR.CurDum = ReNumber(BHEAD term);
1404 if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
1406 if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1407 else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1409 else if ( AC.PolyRatFunChanged ) PolyFunDirty(BHEAD term);
1410 if ( ( AP.PreDebug & THREADSDEBUG ) != 0 ) {
1411 MLOCK(ErrorMessageLock);
1412 MesPrint(
"Thread %w executing term:");
1413 PrintTerm(term,
"LLG");
1414 MUNLOCK(ErrorMessageLock);
1416 if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
1417 && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1418 PolyFunClean(BHEAD term);
1423 MLOCK(ErrorMessageLock);
1424 MesPrint(
"!>Error in processing one term in thread %d in module %d",identity,AC.CModule);
1425 MUNLOCK(ErrorMessageLock);
1433 thr->busy = BUCKETPREPARINGTERM;
1441 if ( thr->free == BUCKETTERMINATED ) {
1442 if ( thr->usenum == thr->totnum ) {
1443 thr->free = BUCKETCOMINGFREE;
1446 thr->free = BUCKETRELEASED;
1450 if ( tobereleased )
goto bucketstolen;
1452 thr->free = BUCKETCOMINGFREE;
1456 thr->busy = BUCKETTOBERELEASED;
1463 AT.WorkPointer = term;
1470 LOCK(AT.SB.MasterBlockLock[1]);
1472 case FINISHEXPRESSION:
1480 LOCK(AT.SB.MasterBlockLock[1]);
1481 ThreadClaimedBlock(identity);
1486 case FINISHEXPRESSION2:
1490 if ( AC.ThreadSortFileSynch ) {
1491 if ( AT.S0->file.handle >= 0 ) {
1492 SynchFile(AT.S0->file.handle);
1495 AT.SB.FillBlock = 1;
1496 AT.SB.MasterFill[1] = AT.SB.MasterStart[1];
1497 errorcode =
EndSort(BHEAD AT.S0->sBuffer,0);
1498 UNLOCK(AT.SB.MasterBlockLock[AT.SB.FillBlock]);
1501 MLOCK(ErrorMessageLock);
1502 MesPrint(
"Error terminating sort in thread %d in module %d",identity,AC.CModule);
1503 MUNLOCK(ErrorMessageLock);
1511 case CLEANUPEXPRESSION:
1515 if ( AR.outfile->handle >= 0 ) {
1516 CloseFile(AR.outfile->handle);
1517 AR.outfile->handle = -1;
1518 remove(AR.outfile->name);
1519 AR.outfile->POfill = AR.outfile->POfull = AR.outfile->PObuffer;
1520 PUTZERO(AR.outfile->POposition);
1521 PUTZERO(AR.outfile->filesize);
1524 AR.outfile->POfill = AR.outfile->POfull = AR.outfile->PObuffer;
1525 PUTZERO(AR.outfile->POposition);
1526 PUTZERO(AR.outfile->filesize);
1529 CBUF *C = cbuf+AT.ebufnum;
1531 if ( C->numrhs > 0 || C->numlhs > 0 ) {
1533 w = C->
rhs; ii = C->numrhs;
1534 do { *w++ = 0; }
while ( --ii > 0 );
1537 w = C->
lhs; ii = C->numlhs;
1538 do { *w++ = 0; }
while ( --ii > 0 );
1540 C->numlhs = C->numrhs = 0;
1541 ClearTree(AT.ebufnum);
1550 case HIGHERLEVELGENERATION:
1555 term = AT.WorkSpace; AT.WorkPointer = term + *term;
1558 MLOCK(ErrorMessageLock);
1559 MesPrint(
"Error in load balancing one term at level %d in thread %d in module %d",AR.level,AT.identity,AC.CModule);
1560 MUNLOCK(ErrorMessageLock);
1563 AT.WorkPointer = term;
1569 case STARTNEWMODULE:
1579 case TERMINATETHREAD:
1597 case DOONEEXPRESSION: {
1602 WORD oldBracketOn = AR.BracketOn;
1603 WORD *oldBrackBuf = AT.BrackBuf;
1604 WORD oldbracketindexflag = AT.bracketindexflag;
1605 WORD fromspectator = 0;
1606 e = Expressions + AR.exprtodo;
1609 AR.SortType = AC.SortType;
1611 if ( ( e->vflags & ISFACTORIZED ) != 0 ) {
1613 AT.BrackBuf = AM.BracketFactors;
1614 AT.bracketindexflag = 1;
1617 position = AS.OldOnFile[i];
1618 if ( e->status == HIDDENLEXPRESSION || e->status == HIDDENGEXPRESSION
1619 || e->status == UNHIDELEXPRESSION || e->status == UNHIDEGEXPRESSION ) {
1620 AR.GetFile = 2; fi = AR.hidefile;
1623 AR.GetFile = 0; fi = AR.infile;
1631 SetScratch(fi,&position);
1632 term = oldwork = AT.WorkPointer;
1633 AR.CompressPointer = AR.CompressBuffer;
1634 AR.CompressPointer[0] = 0;
1636 if ( GetTerm(BHEAD term) <= 0 ) {
1637 MLOCK(ErrorMessageLock);
1638 MesPrint(
"Expression %d has problems in scratchfile (t)",i);
1639 MUNLOCK(ErrorMessageLock);
1642 if ( AT.bracketindexflag > 0 ) OpenBracketIndex(i);
1644 if ( term[5] < 0 ) {
1645 fromspectator = -term[5];
1646 PUTZERO(AM.SpectatorFiles[fromspectator-1].readpos);
1647 term[5] = AC.cbufnum;
1649 PUTZERO(outposition);
1651 fout->POfill = fout->POfull = fout->PObuffer;
1652 fout->POposition = outposition;
1653 if ( fout->
handle >= 0 ) {
1654 fout->POposition = outposition;
1666 if (
PutOut(BHEAD term,&outposition,fout,0) < 0 )
goto ProcErr;
1668 AR.DeferFlag = AC.ComDefer;
1670 AR.sLevel = AB[0]->R.sLevel;
1671 term = AT.WorkPointer;
1673 AR.MaxDum = AM.IndDum;
1675 if ( fromspectator ) {
1676 while ( GetFromSpectator(term,fromspectator-1) ) {
1677 AT.WorkPointer = term + *term;
1678 AN.RepPoint = AT.RepCount + 1;
1679 AN.IndDum = AM.IndDum;
1680 AR.CurDum = ReNumber(BHEAD term);
1681 if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
1683 if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1684 else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1686 else if ( AC.PolyRatFunChanged ) PolyFunDirty(BHEAD term);
1687 if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
1688 && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1689 PolyFunClean(BHEAD term);
1697 while ( GetTerm(BHEAD term) ) {
1698 SeekScratch(fi,&position);
1699 AN.ninterms++; dd = AN.deferskipped;
1700 if ( ( e->vflags & ISFACTORIZED ) != 0 && term[1] == HAAKJE ) {
1704 if ( AC.CollectFun && *term <= (AM.MaxTer/(2*(LONG)
sizeof(WORD))) ) {
1705 if ( GetMoreTerms(term) < 0 ) {
1708 SeekScratch(fi,&position);
1710 AT.WorkPointer = term + *term;
1711 AN.RepPoint = AT.RepCount + 1;
1712 if ( AR.DeferFlag ) {
1713 AR.CurDum = AN.IndDum = Expressions[AR.exprtodo].numdummies;
1716 AN.IndDum = AM.IndDum;
1717 AR.CurDum = ReNumber(BHEAD term);
1719 if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
1721 if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1722 else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1724 else if ( AC.PolyRatFunChanged ) PolyFunDirty(BHEAD term);
1725 if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
1726 && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1727 PolyFunClean(BHEAD term);
1734 SetScratch(fi,&position);
1735 if ( fi == AR.hidefile ) {
1736 AR.InHiBuf = (fi->POfull-fi->PObuffer)
1737 -DIFBASE(position,fi->POposition)/
sizeof(WORD);
1740 AR.InInBuf = (fi->POfull-fi->PObuffer)
1741 -DIFBASE(position,fi->POposition)/
sizeof(WORD);
1746 if (
EndSort(BHEAD AT.S0->sBuffer,0) < 0 )
goto ProcErr;
1747 e->numdummies = AR.MaxDum - AM.IndDum;
1748 AR.BracketOn = oldBracketOn;
1749 AT.BrackBuf = oldBrackBuf;
1750 if ( ( e->vflags & TOBEFACTORED ) != 0 )
1752 else if ( ( ( e->vflags & TOBEUNFACTORED ) != 0 )
1753 && ( ( e->vflags & ISFACTORIZED ) != 0 ) )
1755 if ( AT.S0->TermsLeft ) e->vflags &= ~ISZERO;
1756 else e->vflags |= ISZERO;
1757 if ( AR.expchanged == 0 ) e->vflags |= ISUNMODIFIED;
1758 if ( AT.S0->TermsLeft ) AR.expflags |= ISZERO;
1759 if ( AR.expchanged ) AR.expflags |= ISUNMODIFIED;
1761 AT.bracketindexflag = oldbracketindexflag;
1766 SeekScratch(fout,&outposition);
1767 LOCK(AS.outputslock);
1768 oldoutfile = AB[0]->R.outfile;
1769 if ( e->status == INTOHIDELEXPRESSION || e->status == INTOHIDEGEXPRESSION ) {
1770 AB[0]->R.outfile = AB[0]->R.hidefile;
1772 SeekScratch(AB[0]->R.outfile,&position);
1773 e->onfile = position;
1774 if ( CopyExpression(fout,AB[0]->R.outfile) < 0 ) {
1775 AB[0]->R.outfile = oldoutfile;
1776 UNLOCK(AS.outputslock);
1777 MLOCK(ErrorMessageLock);
1778 MesPrint(
"Error copying output of 'InParallel' expression to master. Thread: %d",identity);
1779 MUNLOCK(ErrorMessageLock);
1782 AB[0]->R.outfile = oldoutfile;
1783 AB[0]->R.expflags = AR.expflags;
1784 UNLOCK(AS.outputslock);
1786 if ( fout->
handle >= 0 ) {
1790 PUTZERO(fout->POposition);
1791 PUTZERO(fout->filesize);
1792 fout->POfill = fout->POfull = fout->PObuffer;
1796 AT.WorkPointer = oldwork;
1820 e = Expressions + AR.CurExpr;
1821 binfo = e->bracketinfo;
1822 thr = AN.threadbuck;
1824 if ( AR.GetFile == 2 ) fi = AR.hidefile;
1825 else fi = AR.infile;
1827 ADD2POS(where,AS.OldOnFile[AR.CurExpr]);
1828 SetScratch(fi,&(where));
1829 stoppos = binfo->
indexbuffer[thr->lastbracket].next;
1830 ADD2POS(stoppos,AS.OldOnFile[AR.CurExpr]);
1831 AN.ninterms = thr->firstterm;
1836 ttco = AR.CompressBuffer;
1840 AR.CompressPointer = ttco;
1841 term = AT.WorkPointer;
1842 while ( GetTerm(BHEAD term) ) {
1843 SeekScratch(fi,&where);
1844 AT.WorkPointer = term + *term;
1845 AN.IndDum = AM.IndDum;
1846 AR.CurDum = ReNumber(BHEAD term);
1847 if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
1849 if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1850 else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1852 else if ( AC.PolyRatFunChanged ) PolyFunDirty(BHEAD term);
1853 if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
1854 && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1855 PolyFunClean(BHEAD term);
1857 if ( ( AP.PreDebug & THREADSDEBUG ) != 0 ) {
1858 MLOCK(ErrorMessageLock);
1859 MesPrint(
"Thread %w executing term:");
1860 PrintTerm(term,
"DoBrackets");
1861 MUNLOCK(ErrorMessageLock);
1863 AT.WorkPointer = term + *term;
1866 MLOCK(ErrorMessageLock);
1867 MesPrint(
"Error in processing one term in thread %d in module %d",identity,AC.CModule);
1868 MUNLOCK(ErrorMessageLock);
1872 SetScratch(fi,&(where));
1873 if ( ISGEPOS(where,stoppos) )
break;
1875 AT.WorkPointer = term;
1876 thr->free = BUCKETCOMINGFREE;
1887 sumtimerinfo[identity] +=
TimeCPU(1);
1888 timerinfo[identity] =
TimeCPU(0);
1895 case MCTSEXPANDTREE:
1896 AT.optimtimes = AB[0]->T.optimtimes;
1897 find_Horner_MCTS_expand_tree();
1903 case OPTIMIZEEXPRESSION:
1911 MLOCK(ErrorMessageLock);
1912 MesPrint(
"!>Illegal wakeup signal %d for thread %d",wakeupsignal,identity);
1913 MUNLOCK(ErrorMessageLock);
1920 timerinfo[identity] =
TimeCPU(1);
1928 flint_final_cleanup_thread();
1930 FinalizeOneThread(identity);
1949void *RunSortBot(
void *dummy)
1951 int identity, wakeupsignal, identityretv;
1952 ALLPRIVATES *B, *BB;
1954 identity = SetIdentity(&identityretv);
1955 threadpointers[identity] = pthread_self();
1956 B = InitializeOneThread(identity);
1957 while ( ( wakeupsignal = SortBotWait(identity) ) > 0 ) {
1958 switch ( wakeupsignal ) {
1963 AR.CompressBuffer = AB[0]->R.CompressBuffer;
1964 AR.ComprTop = AB[0]->R.ComprTop;
1965 AR.CompressPointer = AB[0]->R.CompressPointer;
1966 AR.CurExpr = AB[0]->R.CurExpr;
1967 AR.PolyFun = AB[0]->R.PolyFun;
1968 AR.PolyFunInv = AB[0]->R.PolyFunInv;
1969 AR.PolyFunType = AB[0]->R.PolyFunType;
1970 AR.PolyFunExp = AB[0]->R.PolyFunExp;
1971 AR.PolyFunVar = AB[0]->R.PolyFunVar;
1972 AR.PolyFunPow = AB[0]->R.PolyFunPow;
1973 AR.SortType = AC.SortType;
1974 if ( AR.PolyFun == 0 ) { AT.SS->PolyFlag = 0; }
1975 else if ( AR.PolyFunType == 1 ) { AT.SS->PolyFlag = 1; }
1976 else if ( AR.PolyFunType == 2 ) {
1977 if ( AR.PolyFunExp == 2
1978 || AR.PolyFunExp == 3 ) AT.SS->PolyFlag = 1;
1979 else AT.SS->PolyFlag = 2;
1981 AT.SS->PolyWise = 0;
1982 AN.ncmod = AC.ncmod;
1983 LOCK(AT.SB.MasterBlockLock[1]);
1984 BB = AB[AT.SortBotIn1];
1985 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
1986 if ( AT.SortBotIn2 >= 0 ) {
1987 BB = AB[AT.SortBotIn2];
1988 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
1990 AT.SB.FillBlock = 1;
1991 AT.SB.MasterFill[1] = AT.SB.MasterStart[1];
1992 SETBASEPOSITION(AN.theposition,0);
1994 AT.SS->verbComparisons = 0;
1996 AT.SS->verbMaxTermSize = 0;
2009 case TERMINATETHREAD:
2019 sumtimerinfo[identity] +=
TimeCPU(1);
2020 timerinfo[identity] =
TimeCPU(0);
2028 MLOCK(ErrorMessageLock);
2029 MesPrint(
"!>Illegal wakeup signal %d for thread %d",wakeupsignal,identity);
2030 MUNLOCK(ErrorMessageLock);
2042 flint_final_cleanup_thread();
2044 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]);
2230int SortBotWait(
int identity)
2233 LOCK(wakeuplocks[identity]);
2234 LOCK(availabilitylock);
2235 topsortbotavailables++;
2236 if ( topsortbotavailables >= GetNumberOfSortBots(numberofworkers) ) {
2237 UNLOCK(availabilitylock);
2238 LOCK(wakeupsortbotlock);
2239 wakeupmaster = identity;
2240 pthread_cond_signal(&wakeupsortbotconditions);
2241 UNLOCK(wakeupsortbotlock);
2244 UNLOCK(availabilitylock);
2246 while ( wakeup[identity] == 0 ) {
2247 pthread_cond_wait(&(wakeupconditions[identity]),&(wakeuplocks[identity]));
2249 retval = wakeup[identity];
2250 wakeup[identity] = 0;
2251 UNLOCK(wakeuplocks[identity]);
2270int ThreadClaimedBlock(
int identity)
2272 LOCK(availabilitylock);
2274 if ( numberclaimed >= numberofworkers ) {
2275 UNLOCK(availabilitylock);
2276 LOCK(wakeupmasterlock);
2277 wakeupmaster = identity;
2278 pthread_cond_signal(&wakeupmasterconditions);
2279 UNLOCK(wakeupmasterlock);
2282 UNLOCK(availabilitylock);
2301 LOCK(wakeupmasterlock);
2302 while ( wakeupmaster == 0 ) {
2303 pthread_cond_wait(&wakeupmasterconditions,&wakeupmasterlock);
2305 retval = wakeupmaster;
2307 UNLOCK(wakeupmasterlock);
2321int MasterWaitThread(
int identity)
2324 LOCK(wakeupmasterthreadlocks[identity]);
2325 while ( wakeupmasterthread[identity] == 0 ) {
2326 pthread_cond_wait(&(wakeupmasterthreadconditions[identity])
2327 ,&(wakeupmasterthreadlocks[identity]));
2329 retval = wakeupmasterthread[identity];
2330 wakeupmasterthread[identity] = 0;
2331 UNLOCK(wakeupmasterthreadlocks[identity]);
2345void MasterWaitAll(
void)
2347 LOCK(wakeupmasterlock);
2348 while ( topofavailables < numberofworkers ) {
2349 pthread_cond_wait(&wakeupmasterconditions,&wakeupmasterlock);
2351 UNLOCK(wakeupmasterlock);
2366void MasterWaitAllSortBots(
void)
2368 LOCK(wakeupsortbotlock);
2369 while ( topsortbotavailables < GetNumberOfSortBots(numberofworkers) ) {
2370 pthread_cond_wait(&wakeupsortbotconditions,&wakeupsortbotlock);
2372 UNLOCK(wakeupsortbotlock);
2387void MasterWaitAllBlocks(
void)
2389 LOCK(wakeupmasterlock);
2390 while ( numberclaimed < numberofworkers ) {
2391 pthread_cond_wait(&wakeupmasterconditions,&wakeupmasterlock);
2393 UNLOCK(wakeupmasterlock);
2409void WakeupThread(
int identity,
int signalnumber)
2411 if ( signalnumber == 0 ) {
2413 MLOCK(ErrorMessageLock);
2414 MesPrint(
"!>Illegal wakeup signal for thread %d",identity);
2415 MUNLOCK(ErrorMessageLock);
2419 LOCK(wakeuplocks[identity]);
2420 wakeup[identity] = signalnumber;
2421 pthread_cond_signal(&(wakeupconditions[identity]));
2422 UNLOCK(wakeuplocks[identity]);
2437void WakeupMasterFromThread(
int identity,
int signalnumber)
2439 if ( signalnumber == 0 ) {
2441 MLOCK(ErrorMessageLock);
2442 MesPrint(
"!>Illegal wakeup signal for master %d",identity);
2443 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;
2644 if ( ! fromspectator && ( e->counter / ( numberofworkers * 5 ) ) < thrbufsiz ) {
2645 thrbufsiz = e->counter / ( numberofworkers * 5 ) - 1;
2646 if ( thrbufsiz < 0 ) thrbufsiz = 0;
2648 thrbufsiz0 = thrbufsiz;
2650 thrbufsiz = thrbufsiz0 / (2 << numpasses);
2654 for ( j = 0; j < numthreadbuckets; j++ )
2655 threadbuckets[j]->free = BUCKETFREE;
2656 thr = threadbuckets[0];
2665 if ( e->bracketinfo && AC.CollectFun == 0 && AR0.DeferFlag == 0 ) {
2670 for ( n = 0; n < e->bracketinfo->indexfill; n++ ) {
2671 num = TreatIndexEntry(B0,n);
2679 for ( j = 0; j < numthreadbuckets; j++ ) {
2680 switch ( threadbuckets[j]->free ) {
2682 thr = threadbuckets[j];
2684 case BUCKETCOMINGFREE:
2685 thr = threadbuckets[j];
2686 thr->free = BUCKETFREE;
2687 for ( k = j+1; k < numthreadbuckets; k++ )
2688 threadbuckets[k-1] = threadbuckets[k];
2689 threadbuckets[numthreadbuckets-1] = thr;
2697 if ( j < numthreadbuckets ) {
2701 thr->firstbracket = n;
2702 thr->lastbracket = n + num - 1;
2703 thr->type = BUCKETDOINGBRACKET;
2704 thr->free = BUCKETFILLED;
2705 thr->firstterm = AN0.ninterms;
2706 for ( j = n; j < n+num; j++ ) {
2707 AN0.ninterms += e->bracketinfo->
indexbuffer[j].termsinbracket;
2710 numberoffullbuckets++;
2711 if ( topofavailables > 0 ) {
2712 SendOneBucket(DOBRACKETS);
2721 while ( topofavailables <= 0 ) {
2724 SendOneBucket(DOBRACKETS);
2733 switch ( e->status ) {
2734 case UNHIDELEXPRESSION:
2735 case UNHIDEGEXPRESSION:
2736 case DROPHLEXPRESSION:
2737 case DROPHGEXPRESSION:
2738 case HIDDENLEXPRESSION:
2739 case HIDDENGEXPRESSION:
2740 curfile = AR0.hidefile;
2743 curfile = AR0.infile;
2746 SetScratch(curfile,&eonfile);
2747 GetTerm(B0,AT0.WorkPointer);
2751 GetTermP = &GetTerm2;
2756 for ( j = 0; j < numthreadbuckets; j++ ) {
2757 switch ( threadbuckets[j]->free ) {
2759 thr = threadbuckets[j];
2761 case BUCKETCOMINGFREE:
2762 thr = threadbuckets[j];
2763 thr->free = BUCKETFREE;
2764 for ( k = j+1; k < numthreadbuckets; k++ )
2765 threadbuckets[k-1] = threadbuckets[k];
2766 threadbuckets[numthreadbuckets-1] = thr;
2773 while ( topofavailables <= 0 ) {
2776 while ( topofavailables > 0 && numberoffullbuckets > 0 ) {
2777 SendOneBucket(DOBRACKETS);
2781 while ( numberoffullbuckets > 0 ) {
2782 while ( topofavailables <= 0 ) {
2785 while ( topofavailables > 0 && numberoffullbuckets > 0 ) {
2786 SendOneBucket(DOBRACKETS);
2795 AN0.lastinindex = -1;
2806 if ( fromspectator ) {
2807 ter = GetFromSpectator(thr->threadbuffer,fromspectator-1);
2808 if ( ter == 0 ) fromspectator = 0;
2811 ter = GetTermP(B0,thr->threadbuffer);
2827 if ( ter < 0 )
break;
2828 if ( ter == 0 ) { endofinput = 1;
goto Finalize; }
2829 dd = AN0.deferskipped;
2830 if ( AR0.DeferFlag ) {
2832 thr->deferbuffer[defcount++] = AR0.DefPosition;
2833 ttco = thr->compressbuffer; t1 = AR0.CompressBuffer; j = *t1;
2834 while ( thr->compressbuffersize <= j ) {
2836 WORD *top = thr->compressbuffer+thr->compressbuffersize;
2837 DoubleBuffer((
void**)&(thr->compressbuffer),(
void**)&(top),
2838 sizeof(*(thr->compressbuffer)),
"double compressbuffer");
2839 ttco = thr->compressbuffer;
2840 thr->compressbuffersize *= 2;
2844 else if ( first && ( AC.CollectFun == 0 ) ) {
2846 t1 = tstop = thr->threadbuffer;
2847 tstop += *tstop; tstop -= ABS(tstop[-1]);
2849 while ( t1 < tstop ) {
2850 if ( t1[0] == HAAKJE ) { bra = 1;
break; }
2853 t1 = thr->threadbuffer;
2858 if ( AC.CollectFun && *(thr->threadbuffer) < (AM.MaxTer/((LONG)
sizeof(WORD))-10) ) {
2859 if ( ( dd = GetMoreTerms(thr->threadbuffer) ) < 0 ) {
2866 if ( topofavailables > 0 && numberoffullbuckets > 0 ) SendOneBucket(LOWESTLEVELGENERATION);
2870 tt = thr->threadbuffer; tt += *tt;
2877 if ( numpasses > 0 ) {
2879 if ( numbucket >= numberofworkers ) {
2882 if ( numpasses == 0 ) thrbufsiz = thrbufsiz0;
2883 else thrbufsiz = thrbufsiz0 / (2 << numpasses);
2885 thrbufsiz2 = thrbufsiz + thrbufsiz/5;
2890 while ( ( dd < thrbufsiz ) &&
2891 ( tt - thr->threadbuffer ) < ( thr->threadbuffersize - AM.MaxTer/((LONG)
sizeof(WORD)) - 2 ) ) {
2895 if ( topofavailables > 0 && numberoffullbuckets > 0 ) SendOneBucket(LOWESTLEVELGENERATION);
2899 if ( ( fromspectator
2900 ? GetFromSpectator(tt,fromspectator-1)
2901 : GetTermP(B0,tt) ) == 0 ) { endofinput = 1;
break; }
2904 dd += AN0.deferskipped;
2905 if ( AR0.DeferFlag ) {
2906 thr->deferbuffer[defcount++] = AR0.DefPosition;
2907 t1 = AR0.CompressBuffer; j = *t1;
2908 while ( thr->compressbuffer+thr->compressbuffersize-ttco <= j ) {
2910 const ptrdiff_t oldoffset = ttco - thr->compressbuffer;
2911 WORD *top = thr->compressbuffer+thr->compressbuffersize;
2912 DoubleBuffer((
void**)&(thr->compressbuffer),(
void**)&(top),
2913 sizeof(*(thr->compressbuffer)),
"double compressbuffer");
2914 ttco = thr->compressbuffer + oldoffset;
2915 thr->compressbuffersize *= 2;
2919 if ( AC.CollectFun && *tt < (AM.MaxTer/((LONG)
sizeof(WORD))-10) ) {
2920 if ( ( ddd = GetMoreTerms(tt) ) < 0 ) {
2935 tstop = t1 + *t1; tstop -= ABS(tstop[-1]);
2937 while ( t2 < tstop ) {
2938 if ( t2[0] == HAAKJE ) {
break; }
2941 if ( t2[0] == HAAKJE ) {
2942 t2 += t2[1]; num = t2 - t1;
2943 while ( ( dd < thrbufsiz2 ) &&
2944 ( tt - thr->threadbuffer ) < ( thr->threadbuffersize - AM.MaxTer - 2 ) ) {
2948 if ( topofavailables > 0 && numberoffullbuckets > 0 ) SendOneBucket(LOWESTLEVELGENERATION);
2952 if ( ( fromspectator
2953 ? GetFromSpectator(tt,fromspectator-1)
2954 : GetTermP(B0,tt) ) == 0 ) { endofinput = 1;
break; }
2958 tstop = tt + *tt; tstop -= ABS(tstop[-1]);
2959 if ( tstop-tt < num ) {
2963 for ( i = 1; i < num; i++ ) {
2964 if ( t1[i] != tt[i] )
break;
2980 thr->firstterm = AN0.ninterms;
2983 thr->free = BUCKETFILLED;
2984 thr->type = BUCKETDOINGTERMS;
2985 numberoffullbuckets++;
2986 if ( topofavailables <= 0 && endofinput == 0 ) {
3000 for ( j = 0; j < numthreadbuckets; j++ ) {
3001 switch ( threadbuckets[j]->free ) {
3003 thr = threadbuckets[j];
3004 if ( !endofinput )
goto NextBucket;
3010 thr->free = BUCKETATEND;
3012 case BUCKETCOMINGFREE:
3013 thr = threadbuckets[j];
3014 thr->free = BUCKETFREE;
3020 for ( k = j+1; k < numthreadbuckets; k++ )
3021 threadbuckets[k-1] = threadbuckets[k];
3022 threadbuckets[numthreadbuckets-1] = thr;
3038 for ( j = 0; j < numthreadbuckets; j++ ) {
3039 if ( threadbuckets[j]->free == BUCKETFILLED ) {
3040 thr = threadbuckets[j];
3041 for ( k = j+1; k < numthreadbuckets; k++ )
3042 threadbuckets[k-1] = threadbuckets[k];
3043 threadbuckets[numthreadbuckets-1] = thr;
3053 while ( (
id = GetAvailableThread() ) < 0 ) { MasterWait(); }
3057 LoadOneThread(0,
id,thr,0);
3059 thr->busy = BUCKETASSIGNED;
3061 thr->free = BUCKETINUSE;
3062 numberoffullbuckets--;
3070 WakeupThread(
id,LOWESTLEVELGENERATION);
3075 if ( topofavailables > 0 ) {
3076 for ( j = 0; j < numthreadbuckets; j++ ) {
3077 if ( threadbuckets[j]->free == BUCKETFILLED ) {
3078 thr = threadbuckets[j];
3079 for ( k = j+1; k < numthreadbuckets; k++ )
3080 threadbuckets[k-1] = threadbuckets[k];
3081 threadbuckets[numthreadbuckets-1] = thr;
3090 for ( j = 0; j < numthreadbuckets; j++ ) {
3091 switch ( threadbuckets[j]->free ) {
3093 thr = threadbuckets[j];
3094 if ( !endofinput )
goto NextBucket;
3095 thr->free = BUCKETATEND;
3097 case BUCKETCOMINGFREE:
3098 thr = threadbuckets[j];
3100 thr->free = BUCKETATEND;
3103 thr->free = BUCKETFREE;
3104 for ( k = j+1; k < numthreadbuckets; k++ )
3105 threadbuckets[k-1] = threadbuckets[k];
3106 threadbuckets[numthreadbuckets-1] = thr;
3114 if ( j >= numthreadbuckets )
break;
3124 for ( j = 0; j < numthreadbuckets; j++ ) {
3125 switch ( threadbuckets[j]->free ) {
3127 thr = threadbuckets[j];
3128 if ( !endofinput )
goto NextBucket;
3129 thr->free = BUCKETATEND;
3131 case BUCKETCOMINGFREE:
3132 thr = threadbuckets[j];
3133 if ( endofinput ) thr->free = BUCKETATEND;
3135 thr->free = BUCKETFREE;
3136 for ( k = j+1; k < numthreadbuckets; k++ )
3137 threadbuckets[k-1] = threadbuckets[k];
3138 threadbuckets[numthreadbuckets-1] = thr;
3143 if ( still < 0 ) still = j;
3156 thr = threadbuckets[still];
3157 for ( k = still+1; k < numthreadbuckets; k++ )
3158 threadbuckets[k-1] = threadbuckets[k];
3159 threadbuckets[numthreadbuckets-1] = thr;
3172 if ( AC.ThreadBalancing ) {
3173 for (
id = 1;
id <= numberofworkers;
id++ ) {
3174 AB[id]->T.LoadBalancing = 1;
3176 if ( LoadReadjusted() )
goto Finalize;
3177 for (
id = 1;
id <= numberofworkers;
id++ ) {
3178 AB[id]->T.LoadBalancing = 0;
3181 if ( AC.ThreadBalancing ) {
3206 if ( LastExpression ) {
3208 if ( AR0.infile->handle >= 0 ) {
3209 CloseFile(AR0.infile->handle);
3210 AR0.infile->handle = -1;
3211 remove(AR0.infile->name);
3212 PUTZERO(AR0.infile->POposition);
3213 AR0.infile->POfill = AR0.infile->POfull = AR0.infile->PObuffer;
3225 oldgzipCompress = AR0.gzipCompress;
3226 AR0.gzipCompress = 0;
3227 if ( AR0.outtohide ) AR0.outfile = AR0.hidefile;
3228 if ( SortBotMasterMerge() < 0 ) {
3229 if ( AR0.outtohide ) AR0.outfile = oldoutfile;
3230 AR0.gzipCompress = oldgzipCompress;
3233 if ( AR0.outtohide ) AR0.outfile = oldoutfile;
3234 AR0.gzipCompress = oldgzipCompress;
3242 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
3243 if ( GetThread(
id) > 0 ) WakeupThread(
id,CLEANUPEXPRESSION);
3246 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
3247 if ( AB[
id]->R.MaxDum - AM.IndDum > e->numdummies )
3248 e->numdummies = AB[id]->R.MaxDum - AM.IndDum;
3249 AR0.expchanged |= AB[id]->R.expchanged;
3255 AT0.WorkPointer = oldworkpointer;
3283int LoadReadjusted(
void)
3285 ALLPRIVATES *B0 = AB[0];
3286 THREADBUCKET *thr = 0, *thrtogo = 0;
3287 int numtogo, numfree, numbusy, n, nperbucket, extra, i, j, u, bus;
3289 WORD *t1, *c1, *t2, *c2, *t3;
3294 while ( topofavailables <= 0 ) MasterWait();
3303 for ( j = 0; j < numthreadbuckets; j++ ) {
3304 thr = threadbuckets[j];
3305 if ( thr->free == BUCKETFREE || thr->free == BUCKETATEND
3306 || thr->free == BUCKETCOMINGFREE ) {
3307 freebuckets[numfree++] = thr;
3309 else if ( thr->type != BUCKETDOINGTERMS ) {}
3310 else if ( thr->totnum > 1 ) {
3314 if ( thr->free == BUCKETINUSE ) {
3315 n = thr->totnum-thr->usenum;
3316 if ( bus == BUCKETASSIGNED ) numbusy++;
3317 else if ( ( bus != BUCKETASSIGNED )
3318 && ( n > numtogo ) ) {
3323 else if ( bus == BUCKETTOBERELEASED
3324 && thr->free == BUCKETRELEASED ) {
3325 freebuckets[numfree++] = thr;
3326 thr->free = BUCKETATEND;
3328 thr->busy = BUCKETPREPARINGTERM;
3333 if ( numfree == 0 )
return(0);
3334 if ( numtogo > 0 ) {
3341 if ( thr->totnum-thr->usenum < numtogo )
goto restart;
3351 if ( thr->busy != BUCKETDOINGTERM ) {
3355 if ( thr->totnum-thr->usenum < numtogo ) {
3359 thr->free = BUCKETTERMINATED;
3366 if ( thr->usenum == thr->totnum ) {
3371 thr->free = BUCKETATEND;
3379 if ( numbusy > 0 ) {
3385 struct timespec sleeptime;
3386 sleeptime.tv_sec = 0;
3387 sleeptime.tv_nsec = 1000L;
3388 nanosleep(&sleeptime, NULL);
3403 numinput = thr->firstterm + thr->usenum;
3404 nperbucket = numtogo / numfree;
3405 extra = numtogo - nperbucket*numfree;
3406 if ( AR0.DeferFlag ) {
3407 t1 = thr->threadbuffer; c1 = thr->compressbuffer; u = thr->usenum;
3408 for ( n = 0; n < thr->usenum; n++ ) { t1 += *t1; c1 += *c1; }
3411 for ( i = 0; i < extra; i++ ) {
3412 thrtogo = freebuckets[i];
3413 t2 = thrtogo->threadbuffer;
3414 c2 = thrtogo->compressbuffer;
3415 thrtogo->free = BUCKETFILLED;
3416 thrtogo->type = BUCKETDOINGTERMS;
3417 thrtogo->totnum = nperbucket+1;
3418 thrtogo->ddterms = 0;
3419 thrtogo->usenum = 0;
3420 thrtogo->busy = BUCKETASSIGNED;
3421 thrtogo->firstterm = numinput;
3422 numinput += nperbucket+1;
3423 for ( n = 0; n <= nperbucket; n++ ) {
3424 j = *t1; NCOPY(t2,t1,j);
3425 j = *c1; NCOPY(c2,c1,j);
3426 thrtogo->deferbuffer[n] = thr->deferbuffer[u++];
3431 if ( nperbucket > 0 ) {
3432 for ( i = extra; i < numfree; i++ ) {
3433 thrtogo = freebuckets[i];
3434 t2 = thrtogo->threadbuffer;
3435 c2 = thrtogo->compressbuffer;
3436 thrtogo->free = BUCKETFILLED;
3437 thrtogo->type = BUCKETDOINGTERMS;
3438 thrtogo->totnum = nperbucket;
3439 thrtogo->ddterms = 0;
3440 thrtogo->usenum = 0;
3441 thrtogo->busy = BUCKETASSIGNED;
3442 thrtogo->firstterm = numinput;
3443 numinput += nperbucket;
3444 for ( n = 0; n < nperbucket; n++ ) {
3445 j = *t1; NCOPY(t2,t1,j);
3446 j = *c1; NCOPY(c2,c1,j);
3447 thrtogo->deferbuffer[n] = thr->deferbuffer[u++];
3454 t1 = thr->threadbuffer;
3455 for ( n = 0; n < thr->usenum; n++ ) { t1 += *t1; }
3458 for ( i = 0; i < extra; i++ ) {
3459 thrtogo = freebuckets[i];
3460 t2 = thrtogo->threadbuffer;
3461 thrtogo->free = BUCKETFILLED;
3462 thrtogo->type = BUCKETDOINGTERMS;
3463 thrtogo->totnum = nperbucket+1;
3464 thrtogo->ddterms = 0;
3465 thrtogo->usenum = 0;
3466 thrtogo->busy = BUCKETASSIGNED;
3467 thrtogo->firstterm = numinput;
3468 numinput += nperbucket+1;
3469 for ( n = 0; n <= nperbucket; n++ ) {
3470 j = *t1; NCOPY(t2,t1,j);
3475 if ( nperbucket > 0 ) {
3476 for ( i = extra; i < numfree; i++ ) {
3477 thrtogo = freebuckets[i];
3478 t2 = thrtogo->threadbuffer;
3479 thrtogo->free = BUCKETFILLED;
3480 thrtogo->type = BUCKETDOINGTERMS;
3481 thrtogo->totnum = nperbucket;
3482 thrtogo->ddterms = 0;
3483 thrtogo->usenum = 0;
3484 thrtogo->busy = BUCKETASSIGNED;
3485 thrtogo->firstterm = numinput;
3486 numinput += nperbucket;
3487 for ( n = 0; n < nperbucket; n++ ) {
3488 j = *t1; NCOPY(t2,t1,j);
3495 if ( thr->free == BUCKETRELEASED && thr->busy == BUCKETTOBERELEASED ) {
3496 thr->free = BUCKETATEND; thr->busy = BUCKETPREPARINGTERM;
3560int PutToMaster(PHEAD WORD *term)
3562 int i,j,nexti,ret = 0;
3564 WORD *t, *fill, *top, zero = 0;
3569 t = term; ret = j = *term;
3570 if ( j == 0 ) { j = 1; }
3572 i = AT.SB.FillBlock;
3573 fill = AT.SB.MasterFill[i];
3574 top = AT.SB.MasterStop[i];
3581 if ( j < top - fill && AT.SB.BlockTerms[i] > MINWRITENUMBEROFTERMS ) {
3582 const int prev = ( i == 1 ? AT.SB.MasterNumBlocks : i-1 );
3583 if ( ! pthread_mutex_trylock(&(AT.SB.MasterBlockLock[prev])) ) {
3584 UNLOCK(AT.SB.MasterBlockLock[prev]);
3593 if ( ( j >= top - fill ) || urgent ) {
3595 if ( nexti > AT.SB.MasterNumBlocks ) {
3598 LOCK(AT.SB.MasterBlockLock[nexti]);
3599 UNLOCK(AT.SB.MasterBlockLock[i]);
3600 AT.SB.MasterFill[i] = AT.SB.MasterStart[i];
3601 AT.SB.FillBlock = i = nexti;
3602 fill = AT.SB.MasterStart[i];
3603 top = AT.SB.MasterStop[i];
3604 if ( AT.SB.BlockTerms[i] != 0 ) {
3609 MLOCK(ErrorMessageLock);
3610 MesPrint(
"!>Error in PutToMaster, starting a block with BlockTerms != 0");
3611 MUNLOCK(ErrorMessageLock);
3618 AT.SB.BlockTerms[i]++;
3619 AT.SB.MasterFill[i] = fill;
3638SortBotOut(PHEAD WORD *term)
3642 if ( AT.identity != 0 )
return(PutToMaster(BHEAD term));
3645 if (
FlushOut(&SortBotPosition,AR.outfile,1) )
return(-1);
3646 ADDPOS(AT.SS->SizeInFile[0],1);
3651 if ( ( im =
PutOut(BHEAD term,&SortBotPosition,AR.outfile,1) ) < 0 ) {
3653 MLOCK(ErrorMessageLock);
3654 MesPrint(
"Called from SortBotMasterMerge/SortBotOut");
3655 MUNLOCK(ErrorMessageLock);
3659 ADDPOS(AT.SS->SizeInFile[0],im);
3685int SortBotMasterMerge(
void)
3688 ALLPRIVATES *B = AB[0], *BB;
3701 topsortbotavailables = 0;
3702 for ( i = numberofworkers+1; i <= numberofworkers+GetNumberOfSortBots(numberofworkers); i++ ) {
3703 WakeupThread(i,INISORTBOT);
3709 AR.CompressPointer[0] = 0;
3711 BB = AB[AT.SortBotIn1];
3712 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
3713 if ( AT.SortBotIn2 >= 0 ) {
3714 BB = AB[AT.SortBotIn2];
3715 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
3718 MasterWaitAllSortBots();
3723 for ( i = 1; i <= numberofworkers; i++ ) {
3725 WakeupThread(i,FINISHEXPRESSION);
3730 if ( fout->
handle >= 0 ) {
3731 PUTZERO(SortBotPosition);
3732 SeekFile(fout->
handle,&SortBotPosition,SEEK_END);
3733 ADDPOS(SortBotPosition,((fout->POfill-fout->PObuffer)*
sizeof(WORD)));
3736 SETBASEPOSITION(SortBotPosition,(fout->POfill-fout->PObuffer)*
sizeof(WORD));
3738 MasterWaitAllBlocks();
3744 topsortbotavailables = 0;
3745 for ( i = numberofworkers+1; i <= numberofworkers+GetNumberOfSortBots(numberofworkers); i++ ) {
3746 WakeupThread(i,RUNSORTBOT);
3748 if ( SortBotMerge(BHEAD0) ) {
3750 MLOCK(ErrorMessageLock);
3751 MesPrint(
"!>Called from SortBotMasterMerge");
3752 MUNLOCK(ErrorMessageLock);
3760 if ( S->file.
handle >= 0 )
3767 position = S->SizeInFile[0];
3768 MULPOS(position,
sizeof(WORD));
3777 for ( j = 1; j <= numberofworkers; j++ ) {
3778 S->GenTerms += AB[j]->T.SS->GenTerms;
3779 S->verbComparisons += AB[j]->T.SS->verbComparisons;
3780 if ( S->verbMaxTermSize < AB[j]->T.SS->verbMaxTermSize )
3781 S->verbMaxTermSize = AB[j]->T.SS->verbMaxTermSize;
3782 S->verbSBsortTerms += AB[j]->T.SS->verbSBsortTerms;
3783 S->verbSBsortCap += AB[j]->T.SS->verbSBsortCap;
3784 S->verbLBsortPatches += AB[j]->T.SS->verbLBsortPatches;
3785 S->verbLBsortCap += AB[j]->T.SS->verbLBsortCap;
3786 S->verbUnsortedSize += AB[j]->T.SS->verbUnsortedSize;
3788 for ( j = numberofworkers+1; j <= numberofworkers+GetNumberOfSortBots(numberofworkers); j++ ) {
3789 S->verbComparisons += AB[j]->T.SS->verbComparisons;
3790 if ( S->verbMaxTermSize < AB[j]->T.SS->verbMaxTermSize )
3791 S->verbMaxTermSize = AB[j]->T.SS->verbMaxTermSize;
3794 S->TermsLeft = numberofterms;
3795 WriteStats(&position,STATSPOSTSORT,NOCHECKLOGTYPE);
3796 Expressions[AR.CurExpr].counter = S->TermsLeft;
3797 Expressions[AR.CurExpr].size = position;
3806 MasterWaitAllSortBots();
3823int SortBotMerge(PHEAD0)
3826 ALLPRIVATES *Bin1, *Bin2;
3827 Bin1 = AB[AT.SortBotIn1];
3828 if ( AT.SortBotIn2 >= 0 ) {
3829 Bin2 = AB[AT.SortBotIn2];
3836 WORD *term1, *term2, *wp;
3839 WORD l1, l2, *m1, *m2, *w, r1, r2, r3, r33, r31, *tt1, ii;
3840 WORD *to, *from, im, c;
3844 WORD *fun1, *fun2, *fun3, *tstop1, *tstop2, size1, size2, size3, l3, jj, *m3;
3852 if ( AT.identity == 0 ) {
3853 wp = AT.WorkPointer;
3856 wp = AT.WorkPointer = AT.WorkSpace;
3863 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
3864 if ( AT.SortBotIn2 >= 0 ) {
3865 LOCK(Bin2->T.SB.MasterBlockLock[blin2]);
3867 term1 = Bin1->T.SB.MasterStart[blin1];
3870 if ( AT.SortBotIn2 >= 0 ) {
3871 term2 = Bin2->T.SB.MasterStart[blin2];
3873 AT.SB.FillBlock = 1;
3877 while ( *term1 && *term2 ) {
3878 if ( ( c = CompareTerms(BHEAD term1,term2,(WORD)0) ) > 0 ) {
3882 Bin1->T.SB.BlockTerms[blin1]--;
3883 if ( SortBotOut(BHEAD term1) < 0 ) {
3885 MLOCK(ErrorMessageLock);
3886 MesPrint(
"!>Called from SortBotMerge with thread = %d",AT.identity);
3887 MUNLOCK(ErrorMessageLock);
3893 if ( Bin1->T.SB.BlockTerms[blin1] == 0 ) {
3895 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
3898 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
3900 if ( blin1 == Bin1->T.SB.MasterNumBlocks ) {
3906 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
3907 Bin1->T.SB.MasterBlock = blin1;
3908 term1 = Bin1->T.SB.MasterStart[blin1];
3918 Bin2->T.SB.BlockTerms[blin2]--;
3919 if ( SortBotOut(BHEAD term2) < 0 ) {
3921 MLOCK(ErrorMessageLock);
3922 MesPrint(
"!>Called from SortBotMerge with thread = %d",AT.identity);
3923 MUNLOCK(ErrorMessageLock);
3930 if ( Bin2->T.SB.BlockTerms[blin2] == 0 ) {
3932 UNLOCK(Bin2->T.SB.MasterBlockLock[Bin2->T.SB.MasterNumBlocks]);
3935 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2-1]);
3937 if ( blin2 == Bin2->T.SB.MasterNumBlocks ) {
3943 LOCK(Bin2->T.SB.MasterBlockLock[blin2]);
3944 Bin2->T.SB.MasterBlock = blin2;
3945 term2 = Bin2->T.SB.MasterStart[blin2];
3955 Bin1->T.SB.BlockTerms[blin1]--;
3956 Bin2->T.SB.BlockTerms[blin2]--;
3957 l1 = *( m1 = term1 );
3958 l2 = *( m2 = term2 );
3959 if ( S->PolyWise ) {
3963 if ( S->PolyFlag == 2 ) {
3964 AT.WorkPointer = wp;
3966 if ( *tt1 + w[1] - m1[1] > AM.MaxTer/((LONG)
sizeof(WORD)) ) {
3967 MLOCK(ErrorMessageLock);
3968 MesPrint(
"Term too complex in PolyRatFun addition. MaxTermSize of %10l is too small",AM.MaxTer);
3969 MUNLOCK(ErrorMessageLock);
3972 AT.WorkPointer = wp;
3973 if ( w[FUNHEAD] == -SNUMBER && w[FUNHEAD+1] == 0 && w[1] > FUNHEAD ) {
3979 if ( w + m1[1] + m2[1] > AT.WorkTop ) {
3980 MLOCK(ErrorMessageLock);
3981 MesPrint(
"SortBotMerge(%d): A Maxtermsize of %10l is too small",
3982 AT.identity,AM.MaxTer/
sizeof(WORD));
3983 MesPrint(
"m1[1] = %d, m2[1] = %d, Space = %l",m1[1],m2[1],(LONG)(AT.WorkTop-wp));
3984 PrintTerm(term1,
"term1");
3985 PrintTerm(term2,
"term2");
3986 MesPrint(
"PolyWise = %d",S->PolyWise);
3987 MUNLOCK(ErrorMessageLock);
3994 || ( w[FUNHEAD] == -SNUMBER && w[FUNHEAD+1] == 0 ) )
3996 if ( r1 == m1[1] ) {
3999 else if ( r1 < m1[1] ) {
4003 while ( --r1 >= 0 ) *--m1 = *--m2;
4006 while ( --r1 >= 0 ) *--m1 = *--m2;
4029 else if ( AT.SortFloatMode ) {
4037 tstop1 = m1+l1; size1 = tstop1[-1]; tstop1 -= ABS(size1);
4038 tstop2 = m2+l2; size2 = tstop2[-1]; tstop2 -= ABS(size2);
4039 if ( AT.SortFloatMode == 3 ) {
4041 while ( fun1[0] != FLOATFUN && fun1+fun1[1] < tstop1 ) {
4044 if ( size1 < 0 ) fun1[FUNHEAD+3] = -fun1[FUNHEAD+3];
4045 UnpackFloat(aux1,fun1);
4047 while ( fun2[0] != FLOATFUN && fun2+fun2[1] < tstop2 ) {
4050 if ( size2 < 0 ) fun2[FUNHEAD+3] = -fun2[FUNHEAD+3];
4051 UnpackFloat(aux2,fun2);
4053 else if ( AT.SortFloatMode == 1 ) {
4055 while ( fun1[0] != FLOATFUN && fun1+fun1[1] < tstop1 ) {
4058 if ( size1 < 0 ) fun1[FUNHEAD+3] = -fun1[FUNHEAD+3];
4059 UnpackFloat(aux1,fun1);
4061 RatToFloat(aux2,(UWORD *)fun2,size2);
4063 else if ( AT.SortFloatMode == 2 ) {
4065 RatToFloat(aux1,(UWORD *)fun1,size1);
4067 while ( fun2[0] != FLOATFUN && fun2+fun2[1] < tstop2 ) {
4070 if ( size2 < 0 ) fun2[FUNHEAD+3] = -fun2[FUNHEAD+3];
4071 UnpackFloat(aux2,fun2);
4075 MLOCK(ErrorMessageLock);
4076 MesPrint(
"!>Illegal value %d for AT.SortFloatMode in SortBotMerge.",AT.SortFloatMode);
4077 MUNLOCK(ErrorMessageLock);
4082 mpf_add(aux3,aux1,aux2);
4083 size3 = mpf_sgn(aux3);
4087 else if ( size3 < 0 ) mpf_neg(aux3,aux3);
4088 fun3 = TermMalloc(
"SortBotMasterMerge");
4089 PackFloat(fun3,aux3);
4090 l3 = fun3[1]+(fun1-m1)+3;
4096 if ( (l3)*((LONG)
sizeof(WORD)) >= AM.MaxTer ) {
4097 MLOCK(ErrorMessageLock);
4098 MesPrint(
"SortBotMasterMerge: Coefficient overflow during sort");
4099 MUNLOCK(ErrorMessageLock);
4102 m3 = wp; m2 = term1;
4103 while ( m2 < fun1 ) *m3++ = *m2++;
4104 for ( jj = 0; jj < fun3[1]; jj++ ) *m3++ = fun3[jj];
4105 *m3++ = 1; *m3++ = 1;
4106 *m3++ = size3 < 0 ? -3: 3;
4108 TermFree(fun3,
"SortBotMasterMerge");
4111 for ( jj = 0; jj < fun3[1]; jj++ ) fun1[jj] = fun3[jj];
4113 *fun1++ = 1; *fun1++ = 1;
4114 *fun1++ = size3 < 0 ? -3: 3;
4115 *term1 = fun1-term1;
4116 TermFree(fun3,
"SortBotMasterMerge");
4120 r1 = *( m1 += l1 - 1 );
4122 r1 = ( ( r1 > 0 ) ? (r1-1) : (r1+1) ) >> 1;
4123 r2 = *( m2 += l2 - 1 );
4125 r2 = ( ( r2 > 0 ) ? (r2-1) : (r2+1) ) >> 1;
4127 if ( AddRat(BHEAD (UWORD *)m1,r1,(UWORD *)m2,r2,coef,&r3) ) {
4128 MLOCK(ErrorMessageLock);
4129 MesCall(
"SortBotMerge");
4130 MUNLOCK(ErrorMessageLock);
4134 if ( AN.ncmod != 0 ) {
4135 if ( ( AC.modmode & POSNEG ) != 0 ) {
4138 else if ( BigLong(coef,r3,(UWORD *)AC.cmod,ABS(AN.ncmod)) >= 0 ) {
4139 SubPLon(coef,r3,(UWORD *)AC.cmod,ABS(AN.ncmod),coef,&r3);
4141 for ( ii = 1; ii < r3; ii++ ) coef[r3+ii] = 0;
4144 if ( !r3 ) {
goto cancelled; }
4146 r33 = ( r3 > 0 ) ? ( r3 + 1 ) : ( r3 - 1 );
4147 if ( r3 < 0 ) r3 = -r3;
4148 if ( r1 < 0 ) r1 = -r1;
4152 m2 = (WORD *)coef; im = r3;
4157 to = wp; from = term1;
4158 while ( from < m1 ) *to++ = *from++;
4159 from = (WORD *)coef; im = r3;
4164 if ( SortBotOut(BHEAD wp) < 0 ) {
4166 MLOCK(ErrorMessageLock);
4167 MesPrint(
"!>Called from SortBotMerge with thread = %d",AT.identity);
4168 MUNLOCK(ErrorMessageLock);
4176 if ( SortBotOut(BHEAD term1) < 0 ) {
4178 MLOCK(ErrorMessageLock);
4179 MesPrint(
"!>Called from SortBotMerge with thread = %d",AT.identity);
4180 MUNLOCK(ErrorMessageLock);
4187 if ( Bin1->T.SB.BlockTerms[blin1] == 0 ) {
4190 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4193 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4195 if ( blin1 == Bin1->T.SB.MasterNumBlocks ) {
4201 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4202 Bin1->T.SB.MasterBlock = blin1;
4203 term1 = Bin1->T.SB.MasterStart[blin1];
4219 Bin1->T.SB.BlockTerms[blin1]--;
4220 if ( SortBotOut(BHEAD term1) < 0 ) {
4222 MLOCK(ErrorMessageLock);
4223 MesPrint(
"!>Called from SortBotMerge with thread = %d",AT.identity);
4224 MUNLOCK(ErrorMessageLock);
4229 if ( Bin1->T.SB.BlockTerms[blin1] == 0 ) {
4232 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4235 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4237 if ( blin1 == Bin1->T.SB.MasterNumBlocks ) {
4243 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4244 Bin1->T.SB.MasterBlock = blin1;
4245 term1 = Bin1->T.SB.MasterStart[blin1];
4255 else if ( *term2 ) {
4260 Bin2->T.SB.BlockTerms[blin2]--;
4261 if ( SortBotOut(BHEAD term2) < 0 ) {
4263 MLOCK(ErrorMessageLock);
4264 MesPrint(
"!>Called from SortBotMerge with thread = %d",AT.identity);
4265 MUNLOCK(ErrorMessageLock);
4270 if ( Bin2->T.SB.BlockTerms[blin2] == 0 ) {
4273 UNLOCK(Bin2->T.SB.MasterBlockLock[Bin2->T.SB.MasterNumBlocks]);
4276 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2-1]);
4278 if ( blin2 == Bin2->T.SB.MasterNumBlocks ) {
4284 LOCK(Bin2->T.SB.MasterBlockLock[blin2]);
4285 Bin2->T.SB.MasterBlock = blin2;
4286 term2 = Bin2->T.SB.MasterStart[blin2];
4300 Bin1->T.SB.BlockTerms[blin1]--;
4301 if ( AT.SortBotIn2 >= 0 ) {
4302 Bin2->T.SB.BlockTerms[blin2]--;
4305 SortBotOut(BHEAD 0);
4310 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4312 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4315 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4317 if ( AT.SortBotIn2 >= 0 ) {
4318 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2]);
4320 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2-1]);
4323 UNLOCK(Bin2->T.SB.MasterBlockLock[Bin2->T.SB.MasterNumBlocks]);
4326 if ( AT.identity > 0 ) {
4327 UNLOCK(AT.SB.MasterBlockLock[AT.SB.FillBlock]);
4341static int SortBlocksInitialized = 0;
4349int IniSortBlocks(
int numworkers)
4353 LONG totalsize, workersize, blocksize, numberofterms;
4355 int numberofblocks = NUMBEROFBLOCKSINSORT, numparts;
4358 if ( SortBlocksInitialized )
return(0);
4359 SortBlocksInitialized = 1;
4360 if ( numworkers == 0 )
return(0);
4362 if ( GetNumberOfSortBots(numworkers) > 0 ) {
4363 numparts = numworkers + GetNumberOfSortBots(numberofworkers);
4364 numberofblocks = numberofblocks/2;
4367 numparts = numworkers;
4370 totalsize = S->LargeSize + S->SmallEsize;
4371 workersize = totalsize / numparts;
4372 maxter = AM.MaxTer/
sizeof(WORD);
4373 blocksize = ( workersize - maxter )/numberofblocks;
4374 numberofterms = blocksize / maxter;
4375 if ( numberofterms < MINIMUMNUMBEROFTERMS ) {
4380 MesPrint(
"!>We have a problem with the size of the blocks in IniSortBlocks");
4390 if ( w == 0 ) w = S->sBuffer;
4391 for (
id = 1;
id <= numparts;
id++ ) {
4393 AT.SB.MasterBlockLock = (pthread_mutex_t *)Malloc1(
4394 sizeof(pthread_mutex_t)*(numberofblocks+1),
"MasterBlockLock");
4395 AT.SB.MasterStart = (WORD **)Malloc1(
sizeof(WORD *)*(numberofblocks+1)*3,
"MasterBlock");
4396 AT.SB.MasterFill = AT.SB.MasterStart + (numberofblocks+1);
4397 AT.SB.MasterStop = AT.SB.MasterFill + (numberofblocks+1);
4398 AT.SB.MasterNumBlocks = numberofblocks;
4399 AT.SB.BlockTerms = (LONG*)Malloc1(
sizeof(LONG)*(numberofblocks+1),
"BlockTerms");
4400 AT.SB.MasterBlock = 0;
4401 AT.SB.FillBlock = 0;
4402 AT.SB.MasterFill[0] = AT.SB.MasterStart[0] = w;
4403 AT.SB.BlockTerms[0] = 0;
4405 AT.SB.MasterStop[0] = w;
4406 AT.SB.MasterBlockLock[0] = dummylock;
4407 for ( j = 1; j <= numberofblocks; j++ ) {
4408 AT.SB.MasterFill[j] = AT.SB.MasterStart[j] = w;
4409 AT.SB.BlockTerms[j] = 0;
4411 AT.SB.MasterStop[j] = w;
4412 AT.SB.MasterBlockLock[j] = dummylock;
4415 if ( w > S->sTop2 ) {
4417 MesPrint(
"!>Counting problem in IniSortBlocks");
4433int UpdateSortBlocks(
int numworkers)
4437 LONG totalsize, workersize, blocksize, numberofterms;
4439 int numberofblocks = NUMBEROFBLOCKSINSORT, numparts;
4442 if ( numworkers == 0 )
return(0);
4444 if ( GetNumberOfSortBots(numworkers) > 0) {
4445 numparts = numworkers + GetNumberOfSortBots(numberofworkers);
4446 numberofblocks = numberofblocks/2;
4449 numparts = numworkers;
4452 totalsize = S->LargeSize + S->SmallEsize;
4453 workersize = totalsize / numparts;
4454 maxter = AM.MaxTer/
sizeof(WORD);
4455 blocksize = ( workersize - maxter )/numberofblocks;
4456 numberofterms = blocksize / maxter;
4457 if ( numberofterms < MINIMUMNUMBEROFTERMS ) {
4462 MesPrint(
"!>We have a problem with the size of the blocks in UpdateSortBlocks");
4472 if ( w == 0 ) w = S->sBuffer;
4473 for (
id = 1;
id <= numparts;
id++ ) {
4475 AT.SB.MasterFill[0] = AT.SB.MasterStart[0] = w;
4477 AT.SB.MasterStop[0] = w;
4478 for ( j = 1; j <= numberofblocks; j++ ) {
4479 AT.SB.MasterFill[j] = AT.SB.MasterStart[j] = w;
4481 AT.SB.MasterStop[j] = w;
4484 if ( w > S->sTop2 ) {
4486 MesPrint(
"!>Counting problem in UpdateSortBlocks");
4504void DefineSortBotTree(
void)
4508 n = numberofworkers+GetNumberOfSortBots(numberofworkers);
4509 for ( i = numberofworkers+1, from = 1; i <= n; i++ ) {
4511 AT.SortBotIn1 = from++;
4512 AT.SortBotIn2 = from++;
4515 AT.SortBotIn1 = from++;
4530WORD GetTerm2(PHEAD WORD *term)
4532 WORD *ttco, *tt, retval;
4538 POSITION where, eonfile = AS.OldOnFile[e-Expressions], bstart, bnext;
4542 switch ( e->status ) {
4543 case UNHIDELEXPRESSION:
4544 case UNHIDEGEXPRESSION:
4545 case DROPHLEXPRESSION:
4546 case DROPHGEXPRESSION:
4547 case HIDDENLEXPRESSION:
4548 case HIDDENGEXPRESSION:
4555 if ( AR.KeptInHold ) {
4556 retval = GetTerm(BHEAD term);
4559 SeekScratch(fi,&where);
4560 if ( AN.lastinindex < 0 ) {
4564 if ( ( n = TreatIndexEntry(BHEAD 0) ) <= 0 ) {
4566 where = bi[n].start;
4567 ADD2POS(where,eonfile);
4568 SetScratch(fi,&where);
4572 ttco = AR.CompressBuffer;
4576 AR.CompressPointer = ttco;
4577 retval = GetTerm(BHEAD term);
4580 else AN.lastinindex = n-1;
4587 bstart = bi[n].start;
4588 ADD2POS(bstart,eonfile);
4590 ADD2POS(bnext,eonfile);
4591 if ( ISLESSPOS(bstart,where) && ISLESSPOS(where,bnext) ) {
4592 retval = GetTerm(BHEAD term);
4595 for ( n++ ; n < b->indexfill; n++ ) {
4596 i = TreatIndexEntry(BHEAD n);
4601 ttco = AR.CompressBuffer;
4605 AR.CompressPointer = ttco;
4607 where = bi[n].start;
4608 ADD2POS(where,eonfile);
4609 SetScratch(fi,&(where));
4610 retval = GetTerm(BHEAD term);
4630int TreatIndexEntry(PHEAD LONG n)
4633 LONG numbra = b->indexfill - 1, i;
4641 if ( ( numbra - n ) <= numberofworkers )
return(0);
4647 DIFPOS(pos1,bi[numbra].next,bi[n].next);
4648 BASEPOSITION(average) = DIVPOS(pos1,(3*numberofworkers));
4649 DIFPOS(pos1,bi[n].next,bi[n].start);
4650 if ( ISLESSPOS(average,pos1) )
return(0);
4655 totterms = bi->termsinbracket;
4656 if ( totterms > 2*AC.ThreadBucketSize )
return(1);
4657 for ( i = 1; i < numbra-n; i++ ) {
4658 DIFPOS(pos1,bi[n+i].next,bi[n].start);
4659 if ( ISLESSPOS(average,pos1) )
return(i);
4660 totterms += bi->termsinbracket;
4661 if ( totterms > 2*AC.ThreadBucketSize )
return(i+1);
4674void SetHideFiles(
void) {
4676 ALLPRIVATES *B, *B0 = AB[0];
4677 for ( i = 1; i <= numberofworkers; i++ ) {
4679 AR.hidefile->handle = AR0.hidefile->handle;
4680 if ( AR.hidefile->handle < 0 ) {
4681 AR.hidefile->PObuffer = AR0.hidefile->PObuffer;
4682 AR.hidefile->POstop = AR0.hidefile->POstop;
4683 AR.hidefile->POfill = AR0.hidefile->POfill;
4684 AR.hidefile->POfull = AR0.hidefile->POfull;
4685 AR.hidefile->POsize = AR0.hidefile->POsize;
4686 AR.hidefile->POposition = AR0.hidefile->POposition;
4687 AR.hidefile->filesize = AR0.hidefile->filesize;
4690 AR.hidefile->PObuffer = AR.hidefile->wPObuffer;
4691 AR.hidefile->POstop = AR.hidefile->wPOstop;
4692 AR.hidefile->POfill = AR.hidefile->wPOfill;
4693 AR.hidefile->POfull = AR.hidefile->wPOfull;
4694 AR.hidefile->POsize = AR.hidefile->wPOsize;
4695 PUTZERO(AR.hidefile->POposition);
4708 for ( i = 0; i < AM.totalnumberofthreads; i++ ) {
4722 for ( j = 0; j < AM.totalnumberofthreads; j++ ) {
4724 AN.ncmod = AC.ncmod;
4725 if ( AN.cmod != 0 ) M_free(AN.cmod,
"AN.cmod");
4727 AN.cmod = (UWORD *)Malloc1(
sizeof(WORD)*n,
"AN.cmod");
4728 for ( i = 0; i < n; i++ ) AN.cmod[i] = AC.cmod[i];
4741 for ( j = 0; j < AM.totalnumberofthreads; j++ ) {
4743 if ( AN.cmod != 0 ) M_free(AN.cmod,
"AN.cmod");
4753void find_Horner_MCTS_expand_tree_threaded(
void) {
4755 while ((
id = GetAvailableThread() ) < 0)
4757 WakeupThread(
id,MCTSEXPANDTREE);
4765extern void optimize_expression_given_Horner_threaded(
void) {
4767 while ((
id = GetAvailableThread() ) < 0)
4769 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