66static int numberofthreads;
67static int numberofworkers;
68static int identityofthreads = 0;
69static int *listofavailables;
70static int topofavailables = 0;
71static pthread_key_t identitykey;
72static INILOCK(numberofthreadslock)
73static INILOCK(availabilitylock)
74static pthread_t *threadpointers = 0;
75static pthread_mutex_t *wakeuplocks;
76static pthread_mutex_t *wakeupmasterthreadlocks;
77static pthread_cond_t *wakeupconditions;
78static pthread_condattr_t *wakeupconditionattributes;
80static int *wakeupmasterthread;
81static INILOCK(wakeupmasterlock)
82static pthread_cond_t wakeupmasterconditions = PTHREAD_COND_INITIALIZER;
83static pthread_cond_t *wakeupmasterthreadconditions;
84static int wakeupmaster = 0;
85static int identityretval;
87static LONG *timerinfo;
88static LONG *sumtimerinfo;
89static int numberclaimed;
91static THREADBUCKET **threadbuckets, **freebuckets;
92static int numthreadbuckets;
93static int numberoffullbuckets;
99static pthread_cond_t dummywakeupcondition = PTHREAD_COND_INITIALIZER;
102static POSITION SortBotPosition;
103static int numberofsortbots;
104static INILOCK(wakeupsortbotlock)
105static pthread_cond_t wakeupsortbotconditions = PTHREAD_COND_INITIALIZER;
106static int topsortbotavailables = 0;
107static LONG numberofterms;
122 pthread_key_create(&identitykey,FinishIdentity);
133void FinishIdentity(
void *keyp)
147int SetIdentity(
int *identityretval)
155 LOCK(numberofthreadslock);
156 *identityretval = identityofthreads++;
157 UNLOCK(numberofthreadslock);
158 pthread_setspecific(identitykey,(
void *)identityretval);
159 return(*identityretval);
183 if ( identityofthreads <= 1 )
return(0);
192 identity = (
int *)pthread_getspecific(identitykey);
205VOID BeginIdentities()
208 SetIdentity(&identityretval);
222void StartHandleLock()
224 AM.handlelock = dummyrwlock;
248int StartAllThreads(
int number)
250 int identity, j, dummy, mul;
256 timerinfo = (LONG *)Malloc1(
sizeof(LONG)*number*2,
"timerinfo");
257 sumtimerinfo = (LONG *)Malloc1(
sizeof(LONG)*number*2,
"sumtimerinfo");
258 for ( j = 0; j < number*2; j++ ) { timerinfo[j] = 0; sumtimerinfo[j] = 0; }
261 timerinfo = (LONG *)Malloc1(
sizeof(LONG)*number,
"timerinfo");
262 sumtimerinfo = (LONG *)Malloc1(
sizeof(LONG)*number,
"sumtimerinfo");
263 for ( j = 0; j < number; j++ ) { timerinfo[j] = 0; sumtimerinfo[j] = 0; }
267 listofavailables = (
int *)Malloc1(
sizeof(
int)*(number+1),
"listofavailables");
268 threadpointers = (pthread_t *)Malloc1(
sizeof(pthread_t)*number*mul,
"threadpointers");
269 AB = (ALLPRIVATES **)Malloc1(
sizeof(ALLPRIVATES *)*number*mul,
"Private structs");
271 wakeup = (
int *)Malloc1(
sizeof(
int)*number*mul,
"wakeup");
272 wakeuplocks = (pthread_mutex_t *)Malloc1(
sizeof(pthread_mutex_t)*number*mul,
"wakeuplocks");
273 wakeupconditions = (pthread_cond_t *)Malloc1(
sizeof(pthread_cond_t)*number*mul,
"wakeupconditions");
274 wakeupconditionattributes = (pthread_condattr_t *)
275 Malloc1(
sizeof(pthread_condattr_t)*number*mul,
"wakeupconditionattributes");
277 wakeupmasterthread = (
int *)Malloc1(
sizeof(
int)*number*mul,
"wakeupmasterthread");
278 wakeupmasterthreadlocks = (pthread_mutex_t *)Malloc1(
sizeof(pthread_mutex_t)*number*mul,
"wakeupmasterthreadlocks");
279 wakeupmasterthreadconditions = (pthread_cond_t *)Malloc1(
sizeof(pthread_cond_t)*number*mul,
"wakeupmasterthread");
281 numberofthreads = number;
282 numberofworkers = number - 1;
283 threadpointers[identity] = pthread_self();
285 for ( j = 1; j < number; j++ ) {
286 if ( pthread_create(&thethread,NULL,RunThread,(
void *)(&dummy)) )
292 B = InitializeOneThread(identity);
293 AR.infile = &(AR.Fscr[0]);
294 AR.outfile = &(AR.Fscr[1]);
295 AR.hidefile = &(AR.Fscr[2]);
296 AM.sbuflock = dummylock;
297 AS.inputslock = dummylock;
298 AS.outputslock = dummylock;
299 AS.MaxExprSizeLock = dummylock;
300 AP.PreVarLock = dummylock;
301 AC.halfmodlock = dummylock;
302 MakeThreadBuckets(number,0);
310 if ( numberofworkers > 2 ) {
311 numberofsortbots = numberofworkers-2;
312 for ( j = numberofworkers+1; j < 2*numberofworkers-1; j++ ) {
313 if ( pthread_create(&thethread,NULL,RunSortBot,(
void *)(&dummy)) )
318 numberofsortbots = 0;
320 MasterWaitAllSortBots();
323 IniSortBlocks(number-1);
325 AM.storefilelock = dummylock;
331 MesPrint(
"Cannot start %d threads",number);
343UBYTE *scratchname[] = { (UBYTE *)
"scratchsize",
344 (UBYTE *)
"scratchsize",
345 (UBYTE *)
"hidesize" };
372ALLPRIVATES *InitializeOneThread(
int identity)
374 WORD *t, *ScratchBuf;
375 int i, j, bsize, *bp;
376 LONG ScratchSize[3], IOsize;
380 wakeup[identity] = 0;
381 wakeuplocks[identity] = dummylock;
382 pthread_condattr_init(&(wakeupconditionattributes[identity]));
383 pthread_condattr_setpshared(&(wakeupconditionattributes[identity]),PTHREAD_PROCESS_PRIVATE);
384 wakeupconditions[identity] = dummywakeupcondition;
385 pthread_cond_init(&(wakeupconditions[identity]),&(wakeupconditionattributes[identity]));
386 wakeupmasterthread[identity] = 0;
387 wakeupmasterthreadlocks[identity] = dummylock;
388 wakeupmasterthreadconditions[identity] = dummywakeupcondition;
390 bsize =
sizeof(ALLPRIVATES);
391 bsize = (bsize+
sizeof(int)-1)/
sizeof(
int);
392 B = (ALLPRIVATES *)Malloc1(
sizeof(
int)*bsize,
"B struct");
393 for ( bp = (
int *)B, j = 0; j < bsize; j++ ) *bp++ = 0;
412 if ( identity > 0 )
TimeCPU(0);
416 if ( identity > numberofworkers ) {
421 LONG length = AM.WorkSize*
sizeof(WORD)/8+AM.MaxTer*2;
422 AT.WorkSpace = (WORD *)Malloc1(length,
"WorkSpace");
423 AT.WorkTop = AT.WorkSpace + length/
sizeof(WORD);
424 AT.WorkPointer = AT.WorkSpace;
425 AT.identity = identity;
430 if ( AN.SoScratC == 0 ) {
431 AN.SoScratC = (UWORD *)Malloc1(2*(AM.MaxTal+2)*
sizeof(UWORD),
"Scratch in SortBot");
437 AT.comsym[1] = SYMBOL;
448 AT.comfun[0] = FUNHEAD+4;
449 AT.comfun[1] = FUNCTION;
450 AT.comfun[2] = FUNHEAD;
453 for ( i = 4; i <= FUNHEAD; i++ )
456 AT.comfun[FUNHEAD+1] = 1;
457 AT.comfun[FUNHEAD+2] = 1;
458 AT.comfun[FUNHEAD+3] = 3;
460 AT.comind[1] = INDEX;
468 AT.sizeprimelist = 0;
477 AR.wranfnpair1 = NPAIR1;
478 AR.wranfnpair2 = NPAIR2;
482 AN.SplitScratchSize = AN.InScratch = 0;
483 AN.SplitScratch1 = 0;
484 AN.SplitScratchSize1 = AN.InScratch1 = 0;
486 AN.FunSorts = (
SORTING **)Malloc1((AN.NumFunSorts+1)*
sizeof(
SORTING *),
"FunSort pointers");
487 for ( i = 0; i <= AN.NumFunSorts; i++ ) AN.FunSorts[i] = 0;
488 AN.FunSorts[0] = AT.S0 = AT.SS;
489 AN.idfunctionflag = 0;
494 if ( identity == 0 && AN.SoScratC == 0 ) {
495 AN.SoScratC = (UWORD *)Malloc1(2*(AM.MaxTal+2)*
sizeof(UWORD),
"Scratch in SortBot");
498 AR.CurDum = AM.IndDum;
499 for ( j = 0; j < 3; j++ ) {
500 if ( identity == 0 ) {
502 ScratchSize[j] = AM.HideSize;
505 ScratchSize[j] = AM.ScratSize;
507 if ( ScratchSize[j] < 10*AM.MaxTer ) ScratchSize[j] = 10 * AM.MaxTer;
515 if ( j == 1 ) ScratchSize[j] = AM.ThreadScratOutSize;
516 else ScratchSize[j] = AM.ThreadScratSize;
517 if ( ScratchSize[j] < 4*AM.MaxTer ) ScratchSize[j] = 4 * AM.MaxTer;
520 ScratchSize[j] = ( ScratchSize[j] + 255 ) / 256;
521 ScratchSize[j] = ScratchSize[j] * 256;
522 ScratchBuf = (WORD *)Malloc1(ScratchSize[j]*
sizeof(WORD),(
char *)(scratchname[j]));
523 AR.Fscr[j].POsize = ScratchSize[j] *
sizeof(WORD);
524 AR.Fscr[j].POfull = AR.Fscr[j].POfill = AR.Fscr[j].PObuffer = ScratchBuf;
525 AR.Fscr[j].POstop = AR.Fscr[j].PObuffer + ScratchSize[j];
526 PUTZERO(AR.Fscr[j].POposition);
527 AR.Fscr[j].pthreadslock = dummylock;
528 AR.Fscr[j].wPOsize = AR.Fscr[j].POsize;
529 AR.Fscr[j].wPObuffer = AR.Fscr[j].PObuffer;
530 AR.Fscr[j].wPOfill = AR.Fscr[j].POfill;
531 AR.Fscr[j].wPOfull = AR.Fscr[j].POfull;
532 AR.Fscr[j].wPOstop = AR.Fscr[j].POstop;
536 AR.Fscr[0].handle = -1;
537 AR.Fscr[1].handle = -1;
538 AR.Fscr[2].handle = -1;
539 AR.FoStage4[0].handle = -1;
540 AR.FoStage4[1].handle = -1;
541 IOsize = AM.S0->file.POsize;
543 AR.FoStage4[0].ziosize = IOsize;
544 AR.FoStage4[1].ziosize = IOsize;
545 AR.FoStage4[0].ziobuffer = 0;
546 AR.FoStage4[1].ziobuffer = 0;
548 AR.FoStage4[0].POsize = ((IOsize+
sizeof(WORD)-1)/
sizeof(WORD))*
sizeof(WORD);
549 AR.FoStage4[1].POsize = ((IOsize+
sizeof(WORD)-1)/
sizeof(WORD))*
sizeof(WORD);
551 AR.hidefile = &(AR.Fscr[2]);
552 AR.StoreData.Handle = -1;
553 AR.SortType = AC.SortType;
555 AN.IndDum = AM.IndDum;
557 if ( identity > 0 ) {
558 s = (UBYTE *)(FG.fname); i = 0;
559 while ( *s ) { s++; i++; }
560 s = (UBYTE *)Malloc1(
sizeof(
char)*(i+12),
"name for Fscr[0] file");
561 sprintf((
char *)s,
"%s.%d",FG.fname,identity);
562 s[i-3] =
's'; s[i-2] =
'c'; s[i-1] =
'0';
563 AR.Fscr[0].name = (
char *)s;
564 s = (UBYTE *)(FG.fname); i = 0;
565 while ( *s ) { s++; i++; }
566 s = (UBYTE *)Malloc1(
sizeof(
char)*(i+12),
"name for Fscr[1] file");
567 sprintf((
char *)s,
"%s.%d",FG.fname,identity);
568 s[i-3] =
's'; s[i-2] =
'c'; s[i-1] =
'1';
569 AR.Fscr[1].name = (
char *)s;
572 AR.CompressBuffer = (WORD *)Malloc1((AM.CompressSize+10)*
sizeof(WORD),
"compresssize");
573 AR.ComprTop = AR.CompressBuffer + AM.CompressSize;
579 AT.WorkSpace = (WORD *)Malloc1(AM.WorkSize*
sizeof(WORD),
"WorkSpace");
580 AT.WorkTop = AT.WorkSpace + AM.WorkSize;
581 AT.WorkPointer = AT.WorkSpace;
583 AT.Nest = (
NESTING)Malloc1((LONG)
sizeof(
struct NeStInG)*AM.maxFlevels,
"functionlevels");
584 AT.NestStop = AT.Nest + AM.maxFlevels;
585 AT.NestPoin = AT.Nest;
587 AT.WildMask = (WORD *)Malloc1((LONG)AM.MaxWildcards*
sizeof(WORD),
"maxwildcards");
589 LOCK(availabilitylock);
594 UNLOCK(availabilitylock);
596 AT.RepCount = (
int *)Malloc1((LONG)((AM.RepMax+3)*
sizeof(
int)),
"repeat buffers");
597 AN.RepPoint = AT.RepCount;
601 AT.RepTop = AT.RepCount + AM.RepMax;
603 AT.WildArgTaken = (WORD *)Malloc1((LONG)AC.WildcardBufferSize*
sizeof(WORD)/2
604 ,
"argument list names");
605 AT.WildcardBufferSize = AC.WildcardBufferSize;
606 AT.previousEfactor = 0;
608 AT.identity = identity;
609 AT.LoadBalancing = 0;
615 if ( AT.WorkSpace == 0 ||
619 AT.WildArgTaken == 0 )
goto OnError;
624 AT.comsym[1] = SYMBOL;
635 AT.comfun[0] = FUNHEAD+4;
636 AT.comfun[1] = FUNCTION;
637 AT.comfun[2] = FUNHEAD;
640 for ( i = 4; i <= FUNHEAD; i++ )
643 AT.comfun[FUNHEAD+1] = 1;
644 AT.comfun[FUNHEAD+2] = 1;
645 AT.comfun[FUNHEAD+3] = 3;
647 AT.comind[1] = INDEX;
653 AT.locwildvalue[0] = SUBEXPRESSION;
654 AT.locwildvalue[1] = SUBEXPSIZE;
655 for ( i = 2; i < SUBEXPSIZE; i++ ) AT.locwildvalue[i] = 0;
656 AT.mulpat[0] = TYPEMULT;
657 AT.mulpat[1] = SUBEXPSIZE+3;
659 AT.mulpat[3] = SUBEXPRESSION;
660 AT.mulpat[4] = SUBEXPSIZE;
663 for ( i = 7; i < SUBEXPSIZE+5; i++ ) AT.mulpat[i] = 0;
664 AT.proexp[0] = SUBEXPSIZE+4;
665 AT.proexp[1] = EXPRESSION;
666 AT.proexp[2] = SUBEXPSIZE;
669 for ( i = 5; i < SUBEXPSIZE+1; i++ ) AT.proexp[i] = 0;
670 AT.proexp[SUBEXPSIZE+1] = 1;
671 AT.proexp[SUBEXPSIZE+2] = 1;
672 AT.proexp[SUBEXPSIZE+3] = 3;
673 AT.proexp[SUBEXPSIZE+4] = 0;
674 AT.dummysubexp[0] = SUBEXPRESSION;
675 AT.dummysubexp[1] = SUBEXPSIZE+4;
676 for ( i = 2; i < SUBEXPSIZE; i++ ) AT.dummysubexp[i] = 0;
677 AT.dummysubexp[SUBEXPSIZE] = WILDDUMMY;
678 AT.dummysubexp[SUBEXPSIZE+1] = 4;
679 AT.dummysubexp[SUBEXPSIZE+2] = 0;
680 AT.dummysubexp[SUBEXPSIZE+3] = 0;
682 AT.MinVecArg[0] = 7+ARGHEAD;
683 AT.MinVecArg[ARGHEAD] = 7;
684 AT.MinVecArg[1+ARGHEAD] = INDEX;
685 AT.MinVecArg[2+ARGHEAD] = 3;
686 AT.MinVecArg[3+ARGHEAD] = 0;
687 AT.MinVecArg[4+ARGHEAD] = 1;
688 AT.MinVecArg[5+ARGHEAD] = 1;
689 AT.MinVecArg[6+ARGHEAD] = -3;
691 *t++ = 4+ARGHEAD+FUNHEAD;
692 for ( i = 1; i < ARGHEAD; i++ ) *t++ = 0;
696 for ( i = 2; i < FUNHEAD; i++ ) *t++ = 0;
697 *t++ = 1; *t++ = 1; *t++ = 3;
700 AT.sizeprimelist = 0;
702 AT.nfac = AT.nBer = 0;
707 AR.wranfnpair1 = NPAIR1;
708 AR.wranfnpair2 = NPAIR2;
711 AN.SplitScratchSize = AN.InScratch = 0;
712 AN.SplitScratch1 = 0;
713 AN.SplitScratchSize1 = AN.InScratch1 = 0;
718 if ( identity == 0 ) {
726 AT.S0 = AllocSort(AM.S0->LargeSize*
sizeof(WORD)/numberofworkers
727 ,AM.S0->SmallSize*
sizeof(WORD)/numberofworkers
728 ,AM.S0->SmallEsize*
sizeof(WORD)/numberofworkers
732 ,AM.S0->MaxFpatches/numberofworkers
733 ,AM.S0->file.POsize);
735 AR.CompressPointer = AR.CompressBuffer;
739 AT.StoreCache = AT.StoreCacheAlloc = 0;
740 if ( AM.NumStoreCaches > 0 ) {
743 size =
sizeof(
struct StOrEcAcHe)+AM.SizeStoreCache;
744 size = ((size-1)/
sizeof(size_t)+1)*
sizeof(size_t);
745 AT.StoreCacheAlloc = (
STORECACHE)Malloc1(size*AM.NumStoreCaches,
"StoreCaches");
746 sa = AT.StoreCache = AT.StoreCacheAlloc;
747 for ( i = 0; i < AM.NumStoreCaches; i++ ) {
749 if ( i == AM.NumStoreCaches-1 ) {
755 SETBASEPOSITION(sa->position,-1);
756 SETBASEPOSITION(sa->toppos,-1);
764 MLOCK(ErrorMessageLock);
765 MesPrint(
"Error initializing thread %d",identity);
766 MUNLOCK(ErrorMessageLock);
785void FinalizeOneThread(
int identity)
787 timerinfo[identity] =
TimeCPU(1);
800VOID ClearAllThreads()
804 for ( i = 1; i <= numberofworkers; i++ ) {
805 WakeupThread(i,CLEARCLOCK);
808 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
809 WakeupThread(i,CLEARCLOCK);
824VOID TerminateAllThreads()
827 for ( i = 1; i <= numberofworkers; i++ ) {
829 WakeupThread(i,TERMINATETHREAD);
832 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
833 WakeupThread(i,TERMINATETHREAD);
836 for ( i = 1; i <= numberofworkers; i++ ) {
837 pthread_join(threadpointers[i],NULL);
840 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
841 pthread_join(threadpointers[i],NULL);
875int MakeThreadBuckets(
int number,
int par)
878 LONG sizethreadbuckets;
886 sizethreadbuckets = ( AC.ThreadBucketSize + 1 ) * AM.MaxTer + 2*
sizeof(WORD);
887 if ( AC.ThreadBucketSize >= 250 ) sizethreadbuckets /= 4;
888 else if ( AC.ThreadBucketSize >= 90 ) sizethreadbuckets /= 3;
889 else if ( AC.ThreadBucketSize >= 40 ) sizethreadbuckets /= 2;
890 sizethreadbuckets /=
sizeof(WORD);
893 numthreadbuckets = 2*(number-1);
894 threadbuckets = (THREADBUCKET **)Malloc1(numthreadbuckets*
sizeof(THREADBUCKET *),
"threadbuckets");
895 freebuckets = (THREADBUCKET **)Malloc1(numthreadbuckets*
sizeof(THREADBUCKET *),
"threadbuckets");
898 if ( sizethreadbuckets <= threadbuckets[0]->threadbuffersize )
return(0);
899 for ( i = 0; i < numthreadbuckets; i++ ) {
900 thr = threadbuckets[i];
901 M_free(thr->deferbuffer,
"deferbuffer");
905 for ( i = 0; i < numthreadbuckets; i++ ) {
906 threadbuckets[i] = (THREADBUCKET *)Malloc1(
sizeof(THREADBUCKET),
"threadbuckets");
907 threadbuckets[i]->lock = dummylock;
910 for ( i = 0; i < numthreadbuckets; i++ ) {
911 thr = threadbuckets[i];
912 thr->threadbuffersize = sizethreadbuckets;
913 thr->free = BUCKETFREE;
914 thr->deferbuffer = (POSITION *)Malloc1(2*sizethreadbuckets*
sizeof(WORD)
915 +(AC.ThreadBucketSize+1)*
sizeof(POSITION),
"deferbuffer");
916 thr->threadbuffer = (WORD *)(thr->deferbuffer+AC.ThreadBucketSize+1);
917 thr->compressbuffer = (WORD *)(thr->threadbuffer+sizethreadbuckets);
918 thr->busy = BUCKETPREPARINGTERM;
919 thr->usenum = thr->totnum = 0;
920 thr->type = BUCKETDOINGTERMS;
935int GetTimerInfo(LONG** ti,LONG** sti)
940 return AM.totalnumberofthreads*2;
942 return AM.totalnumberofthreads;
955void WriteTimerInfo(LONG* ti,LONG* sti)
959 int max = AM.totalnumberofthreads*2;
961 int max = AM.totalnumberofthreads;
963 for ( i=0; i<max; ++i ) {
964 timerinfo[i] = ti[i];
965 sumtimerinfo[i] = sti[i];
982 for ( i = 1; i <= numberofworkers; i++ ) retval += timerinfo[i] + sumtimerinfo[i];
984 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ )
985 retval += timerinfo[i] + sumtimerinfo[i];
1000int UpdateOneThread(
int identity)
1002 ALLPRIVATES *B = AB[identity], *B0 = AB[0];
1003 AR.GetFile = AR0.GetFile;
1004 AR.KeptInHold = AR0.KeptInHold;
1005 AR.CurExpr = AR0.CurExpr;
1006 AR.SortType = AC.SortType;
1007 if ( AT.WildcardBufferSize < AC.WildcardBufferSize ) {
1008 M_free(AT.WildArgTaken,
"argument list names");
1009 AT.WildcardBufferSize = AC.WildcardBufferSize;
1010 AT.WildArgTaken = (WORD *)Malloc1((LONG)AC.WildcardBufferSize*
sizeof(WORD)/2
1011 ,
"argument list names");
1012 if ( AT.WildArgTaken == 0 )
return(-1);
1034int LoadOneThread(
int from,
int identity, THREADBUCKET *thr,
int par)
1037 ALLPRIVATES *B = AB[identity], *B0 = AB[from];
1039 AR.DefPosition = AR0.DefPosition;
1040 AR.NoCompress = AR0.NoCompress;
1041 AR.gzipCompress = AR0.gzipCompress;
1042 AR.BracketOn = AR0.BracketOn;
1043 AR.CurDum = AR0.CurDum;
1044 AR.DeferFlag = AR0.DeferFlag;
1046 AR.sLevel = AR0.sLevel;
1047 AR.Stage4Name = AR0.Stage4Name;
1048 AR.GetOneFile = AR0.GetOneFile;
1049 AR.PolyFun = AR0.PolyFun;
1050 AR.PolyFunInv = AR0.PolyFunInv;
1051 AR.PolyFunType = AR0.PolyFunType;
1052 AR.PolyFunExp = AR0.PolyFunExp;
1053 AR.PolyFunVar = AR0.PolyFunVar;
1054 AR.PolyFunPow = AR0.PolyFunPow;
1055 AR.Eside = AR0.Eside;
1056 AR.Cnumlhs = AR0.Cnumlhs;
1068 t1 = AR.CompressBuffer; t2 = AR0.CompressBuffer;
1069 while ( t2 < AR0.CompressPointer ) *t1++ = *t2++;
1070 AR.CompressPointer = t1;
1074 AR.CompressPointer = AR.CompressBuffer;
1076 if ( AR.DeferFlag ) {
1077 if ( AR.infile->handle < 0 ) {
1078 AR.infile->POfill = AR0.infile->POfill;
1085 AR.infile->POfull = AR.infile->POfill = AR.infile->PObuffer;
1089 AN.threadbuck = thr;
1090 AN.ninterms = thr->firstterm;
1092 else if ( par == 1 ) {
1094 t1 = thr->threadbuffer; tstop = t1 + *t1;
1095 t2 = AT.WorkPointer;
1096 while ( t1 < tstop ) *t2++ = *t1++;
1097 AN.ninterms = thr->firstterm;
1100 AN.ncmod = AC.ncmod;
1101 AT.BrackBuf = AT0.BrackBuf;
1102 AT.bracketindexflag = AT0.bracketindexflag;
1130int BalanceRunThread(PHEAD
int identity, WORD *term, WORD level)
1137 LoadOneThread(AT.identity,identity,0,2);
1143 BB->R.level = level;
1144 BB->T.TMbuff = AT.TMbuff;
1145 ti = AT.RepCount; tti = BB->T.RepCount;
1146 i = AN.RepPoint - AT.RepCount;
1147 BB->N.RepPoint = BB->T.RepCount + i;
1148 for ( ; i >= 0; i-- ) tti[i] = ti[i];
1150 t = term; i = *term;
1151 tt = BB->T.WorkSpace;
1153 BB->T.WorkPointer = tt;
1155 WakeupThread(identity,HIGHERLEVELGENERATION);
1168void SetWorkerFiles()
1171 ALLPRIVATES *B, *B0 = AB[0];
1172 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
1174 AR.infile = &(AR.Fscr[0]);
1175 AR.outfile = &(AR.Fscr[1]);
1176 AR.hidefile = &(AR.Fscr[2]);
1177 AR.infile->handle = AR0.infile->handle;
1178 AR.hidefile->handle = AR0.hidefile->handle;
1179 if ( AR.infile->handle < 0 ) {
1180 AR.infile->PObuffer = AR0.infile->PObuffer;
1181 AR.infile->POstop = AR0.infile->POstop;
1182 AR.infile->POfill = AR0.infile->POfill;
1183 AR.infile->POfull = AR0.infile->POfull;
1184 AR.infile->POsize = AR0.infile->POsize;
1185 AR.InInBuf = AR0.InInBuf;
1186 AR.infile->POposition = AR0.infile->POposition;
1187 AR.infile->filesize = AR0.infile->filesize;
1190 AR.infile->PObuffer = AR.infile->wPObuffer;
1191 AR.infile->POstop = AR.infile->wPOstop;
1192 AR.infile->POfill = AR.infile->wPOfill;
1193 AR.infile->POfull = AR.infile->wPOfull;
1194 AR.infile->POsize = AR.infile->wPOsize;
1196 PUTZERO(AR.infile->POposition);
1204 AR.outfile->PObuffer = AR.outfile->wPObuffer;
1205 AR.outfile->POstop = AR.outfile->wPOstop;
1206 AR.outfile->POfill = AR.outfile->wPOfill;
1207 AR.outfile->POfull = AR.outfile->wPOfull;
1208 AR.outfile->POsize = AR.outfile->wPOsize;
1209 PUTZERO(AR.outfile->POposition);
1211 if ( AR.hidefile->handle < 0 ) {
1212 AR.hidefile->PObuffer = AR0.hidefile->PObuffer;
1213 AR.hidefile->POstop = AR0.hidefile->POstop;
1214 AR.hidefile->POfill = AR0.hidefile->POfill;
1215 AR.hidefile->POfull = AR0.hidefile->POfull;
1216 AR.hidefile->POsize = AR0.hidefile->POsize;
1217 AR.InHiBuf = AR0.InHiBuf;
1218 AR.hidefile->POposition = AR0.hidefile->POposition;
1219 AR.hidefile->filesize = AR0.hidefile->filesize;
1222 AR.hidefile->PObuffer = AR.hidefile->wPObuffer;
1223 AR.hidefile->POstop = AR.hidefile->wPOstop;
1224 AR.hidefile->POfill = AR.hidefile->wPOfill;
1225 AR.hidefile->POfull = AR.hidefile->wPOfull;
1226 AR.hidefile->POsize = AR.hidefile->wPOsize;
1228 PUTZERO(AR.hidefile->POposition);
1231 if ( AR0.StoreData.dirtyflag ) {
1232 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
1234 AR.StoreData = AR0.StoreData;
1250void *RunThread(
void *dummy)
1252 WORD *term, *ttin, *tt, *ttco, *oldwork;
1253 int identity, wakeupsignal, identityretv, i, tobereleased, errorcode;
1259 identity = SetIdentity(&identityretv);
1260 threadpointers[identity] = pthread_self();
1261 B = InitializeOneThread(identity);
1262 while ( ( wakeupsignal = ThreadWait(identity) ) > 0 ) {
1263 switch ( wakeupsignal ) {
1267 case STARTNEWEXPRESSION:
1272 if ( UpdateOneThread(identity) ) {
1273 MLOCK(ErrorMessageLock);
1274 MesPrint(
"Update error in starting expression in thread %d in module %d",identity,AC.CModule);
1275 MUNLOCK(ErrorMessageLock);
1278 AR.DeferFlag = AC.ComDefer;
1279 AR.sLevel = AS.sLevel;
1280 AR.MaxDum = AM.IndDum;
1281 AR.expchanged = AB[0]->R.expchanged;
1282 AR.expflags = AB[0]->R.expflags;
1283 AR.PolyFun = AB[0]->R.PolyFun;
1284 AR.PolyFunInv = AB[0]->R.PolyFunInv;
1285 AR.PolyFunType = AB[0]->R.PolyFunType;
1286 AR.PolyFunExp = AB[0]->R.PolyFunExp;
1287 AR.PolyFunVar = AB[0]->R.PolyFunVar;
1288 AR.PolyFunPow = AB[0]->R.PolyFunPow;
1298 case LOWESTLEVELGENERATION:
1300 if ( AC.InnerTest ) {
1301 if ( StrCmp(AC.TestValue,(UBYTE *)INNERTEST) == 0 ) {
1302 MesPrint(
"Testing(Worker%d): value = %s",AT.identity,AC.TestValue);
1306 e = Expressions + AR.CurExpr;
1307 thr = AN.threadbuck;
1308 ppdef = thr->deferbuffer;
1309 ttin = thr->threadbuffer;
1310 ttco = thr->compressbuffer;
1311 term = AT.WorkPointer;
1314 AN.inputnumber = thr->firstterm;
1315 AN.ninterms = thr->firstterm;
1318 tt = term; i = *ttin;
1320 AT.WorkPointer = tt;
1321 if ( AR.DeferFlag ) {
1322 tt = AR.CompressBuffer; i = *ttco;
1324 AR.CompressPointer = tt;
1325 AR.DefPosition = ppdef[0]; ppdef++;
1327 if ( thr->free == BUCKETTERMINATED ) {
1335 if ( thr->usenum == thr->totnum ) {
1336 thr->free = BUCKETCOMINGFREE;
1339 thr->free = BUCKETRELEASED;
1349 thr->busy = BUCKETDOINGTERM;
1357 AN.RepPoint = AT.RepCount + 1;
1359 if ( ( e->vflags & ISFACTORIZED ) != 0 && term[1] == HAAKJE ) {
1363 if ( AR.DeferFlag ) {
1364 AR.CurDum = AN.IndDum = Expressions[AR.CurExpr].numdummies + AM.IndDum;
1367 AN.IndDum = AM.IndDum;
1368 AR.CurDum = ReNumber(BHEAD term);
1370 if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
1372 if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1373 else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1375 else if ( AC.PolyRatFunChanged ) PolyFunDirty(BHEAD term);
1376 if ( ( AP.PreDebug & THREADSDEBUG ) != 0 ) {
1377 MLOCK(ErrorMessageLock);
1378 MesPrint(
"Thread %w executing term:");
1379 PrintTerm(term,
"LLG");
1380 MUNLOCK(ErrorMessageLock);
1382 if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
1383 && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1384 PolyFunClean(BHEAD term);
1388 MLOCK(ErrorMessageLock);
1389 MesPrint(
"Error in processing one term in thread %d in module %d",identity,AC.CModule);
1390 MUNLOCK(ErrorMessageLock);
1397 thr->busy = BUCKETPREPARINGTERM;
1405 if ( thr->free == BUCKETTERMINATED ) {
1406 if ( thr->usenum == thr->totnum ) {
1407 thr->free = BUCKETCOMINGFREE;
1410 thr->free = BUCKETRELEASED;
1414 if ( tobereleased )
goto bucketstolen;
1416 thr->free = BUCKETCOMINGFREE;
1420 thr->busy = BUCKETTOBERELEASED;
1427 AT.WorkPointer = term;
1435 LOCK(AT.SB.MasterBlockLock[1]);
1438 case FINISHEXPRESSION:
1446 LOCK(AT.SB.MasterBlockLock[1]);
1447 ThreadClaimedBlock(identity);
1453 case FINISHEXPRESSION2:
1458 if ( AC.ThreadSortFileSynch ) {
1459 if ( AT.S0->file.handle >= 0 ) {
1460 SynchFile(AT.S0->file.handle);
1463 AT.SB.FillBlock = 1;
1464 AT.SB.MasterFill[1] = AT.SB.MasterStart[1];
1465 errorcode =
EndSort(BHEAD AT.S0->sBuffer,0);
1466 UNLOCK(AT.SB.MasterBlockLock[AT.SB.FillBlock]);
1469 MLOCK(ErrorMessageLock);
1470 MesPrint(
"Error terminating sort in thread %d in module %d",identity,AC.CModule);
1471 MUNLOCK(ErrorMessageLock);
1479 case CLEANUPEXPRESSION:
1483 if ( AR.outfile->handle >= 0 ) {
1484 CloseFile(AR.outfile->handle);
1485 AR.outfile->handle = -1;
1486 remove(AR.outfile->name);
1487 AR.outfile->POfill = AR.outfile->POfull = AR.outfile->PObuffer;
1488 PUTZERO(AR.outfile->POposition);
1489 PUTZERO(AR.outfile->filesize);
1492 AR.outfile->POfill = AR.outfile->POfull = AR.outfile->PObuffer;
1493 PUTZERO(AR.outfile->POposition);
1494 PUTZERO(AR.outfile->filesize);
1497 CBUF *C = cbuf+AT.ebufnum;
1499 if ( C->numrhs > 0 || C->numlhs > 0 ) {
1501 w = C->
rhs; ii = C->numrhs;
1502 do { *w++ = 0; }
while ( --ii > 0 );
1505 w = C->
lhs; ii = C->numlhs;
1506 do { *w++ = 0; }
while ( --ii > 0 );
1508 C->numlhs = C->numrhs = 0;
1509 ClearTree(AT.ebufnum);
1518 case HIGHERLEVELGENERATION:
1523 term = AT.WorkSpace; AT.WorkPointer = term + *term;
1526 MLOCK(ErrorMessageLock);
1527 MesPrint(
"Error in load balancing one term at level %d in thread %d in module %d",AR.level,AT.identity,AC.CModule);
1528 MUNLOCK(ErrorMessageLock);
1531 AT.WorkPointer = term;
1537 case STARTNEWMODULE:
1547 case TERMINATETHREAD:
1565 case DOONEEXPRESSION: {
1567 POSITION position, outposition;
1570 WORD oldBracketOn = AR.BracketOn;
1571 WORD *oldBrackBuf = AT.BrackBuf;
1572 WORD oldbracketindexflag = AT.bracketindexflag;
1573 WORD fromspectator = 0;
1574 e = Expressions + AR.exprtodo;
1577 AR.SortType = AC.SortType;
1579 if ( ( e->vflags & ISFACTORIZED ) != 0 ) {
1581 AT.BrackBuf = AM.BracketFactors;
1582 AT.bracketindexflag = 1;
1585 position = AS.OldOnFile[i];
1586 if ( e->status == HIDDENLEXPRESSION || e->status == HIDDENGEXPRESSION ) {
1587 AR.GetFile = 2; fi = AR.hidefile;
1590 AR.GetFile = 0; fi = AR.infile;
1598 SetScratch(fi,&position);
1599 term = oldwork = AT.WorkPointer;
1600 AR.CompressPointer = AR.CompressBuffer;
1601 AR.CompressPointer[0] = 0;
1603 if ( GetTerm(BHEAD term) <= 0 ) {
1604 MLOCK(ErrorMessageLock);
1605 MesPrint(
"Expression %d has problems in scratchfile (t)",i);
1606 MUNLOCK(ErrorMessageLock);
1609 if ( AT.bracketindexflag > 0 ) OpenBracketIndex(i);
1611 if ( term[5] < 0 ) {
1612 fromspectator = -term[5];
1613 PUTZERO(AM.SpectatorFiles[fromspectator-1].readpos);
1614 term[5] = AC.cbufnum;
1616 PUTZERO(outposition);
1618 fout->POfill = fout->POfull = fout->PObuffer;
1619 fout->POposition = outposition;
1620 if ( fout->
handle >= 0 ) {
1621 fout->POposition = outposition;
1633 if (
PutOut(BHEAD term,&outposition,fout,0) < 0 )
goto ProcErr;
1635 AR.DeferFlag = AC.ComDefer;
1637 AR.sLevel = AB[0]->R.sLevel;
1638 term = AT.WorkPointer;
1640 AR.MaxDum = AM.IndDum;
1642 if ( fromspectator ) {
1643 while ( GetFromSpectator(term,fromspectator-1) ) {
1644 AT.WorkPointer = term + *term;
1645 AN.RepPoint = AT.RepCount + 1;
1646 AN.IndDum = AM.IndDum;
1647 AR.CurDum = ReNumber(BHEAD term);
1648 if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
1650 if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1651 else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1653 else if ( AC.PolyRatFunChanged ) PolyFunDirty(BHEAD term);
1654 if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
1655 && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1656 PolyFunClean(BHEAD term);
1664 while ( GetTerm(BHEAD term) ) {
1665 SeekScratch(fi,&position);
1666 AN.ninterms++; dd = AN.deferskipped;
1667 if ( ( e->vflags & ISFACTORIZED ) != 0 && term[1] == HAAKJE ) {
1671 if ( AC.CollectFun && *term <= (AM.MaxTer/(2*(LONG)
sizeof(WORD))) ) {
1672 if ( GetMoreTerms(term) < 0 ) {
1675 SeekScratch(fi,&position);
1677 AT.WorkPointer = term + *term;
1678 AN.RepPoint = AT.RepCount + 1;
1679 if ( AR.DeferFlag ) {
1680 AR.CurDum = AN.IndDum = Expressions[AR.exprtodo].numdummies;
1683 AN.IndDum = AM.IndDum;
1684 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);
1701 SetScratch(fi,&position);
1702 if ( fi == AR.hidefile ) {
1703 AR.InHiBuf = (fi->POfull-fi->PObuffer)
1704 -DIFBASE(position,fi->POposition)/
sizeof(WORD);
1707 AR.InInBuf = (fi->POfull-fi->PObuffer)
1708 -DIFBASE(position,fi->POposition)/
sizeof(WORD);
1713 if (
EndSort(BHEAD AT.S0->sBuffer,0) < 0 )
goto ProcErr;
1714 e->numdummies = AR.MaxDum - AM.IndDum;
1715 AR.BracketOn = oldBracketOn;
1716 AT.BrackBuf = oldBrackBuf;
1717 if ( ( e->vflags & TOBEFACTORED ) != 0 )
1719 else if ( ( ( e->vflags & TOBEUNFACTORED ) != 0 )
1720 && ( ( e->vflags & ISFACTORIZED ) != 0 ) )
1722 if ( AT.S0->TermsLeft ) e->vflags &= ~ISZERO;
1723 else e->vflags |= ISZERO;
1724 if ( AR.expchanged == 0 ) e->vflags |= ISUNMODIFIED;
1725 if ( AT.S0->TermsLeft ) AR.expflags |= ISZERO;
1726 if ( AR.expchanged ) AR.expflags |= ISUNMODIFIED;
1728 AT.bracketindexflag = oldbracketindexflag;
1733 SeekScratch(fout,&outposition);
1734 LOCK(AS.outputslock);
1735 oldoutfile = AB[0]->R.outfile;
1736 if ( e->status == INTOHIDELEXPRESSION || e->status == INTOHIDEGEXPRESSION ) {
1737 AB[0]->R.outfile = AB[0]->R.hidefile;
1739 SeekScratch(AB[0]->R.outfile,&position);
1740 e->onfile = position;
1741 if ( CopyExpression(fout,AB[0]->R.outfile) < 0 ) {
1742 AB[0]->R.outfile = oldoutfile;
1743 UNLOCK(AS.outputslock);
1744 MLOCK(ErrorMessageLock);
1745 MesPrint(
"Error copying output of 'InParallel' expression to master. Thread: %d",identity);
1746 MUNLOCK(ErrorMessageLock);
1749 AB[0]->R.outfile = oldoutfile;
1750 AB[0]->R.hidefile->POfull = AB[0]->R.hidefile->POfill;
1751 AB[0]->R.expflags = AR.expflags;
1752 UNLOCK(AS.outputslock);
1754 if ( fout->
handle >= 0 ) {
1758 PUTZERO(fout->POposition);
1759 PUTZERO(fout->filesize);
1760 fout->POfill = fout->POfull = fout->PObuffer;
1764 AT.WorkPointer = oldwork;
1787 POSITION stoppos,where;
1788 e = Expressions + AR.CurExpr;
1789 binfo = e->bracketinfo;
1790 thr = AN.threadbuck;
1792 if ( AR.GetFile == 2 ) fi = AR.hidefile;
1793 else fi = AR.infile;
1795 ADD2POS(where,AS.OldOnFile[AR.CurExpr]);
1796 SetScratch(fi,&(where));
1797 stoppos = binfo->
indexbuffer[thr->lastbracket].next;
1798 ADD2POS(stoppos,AS.OldOnFile[AR.CurExpr]);
1799 AN.ninterms = thr->firstterm;
1804 ttco = AR.CompressBuffer;
1808 AR.CompressPointer = ttco;
1809 term = AT.WorkPointer;
1810 while ( GetTerm(BHEAD term) ) {
1811 SeekScratch(fi,&where);
1812 AT.WorkPointer = term + *term;
1813 AN.IndDum = AM.IndDum;
1814 AR.CurDum = ReNumber(BHEAD term);
1815 if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
1817 if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1818 else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1820 else if ( AC.PolyRatFunChanged ) PolyFunDirty(BHEAD term);
1821 if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
1822 && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1823 PolyFunClean(BHEAD term);
1825 if ( ( AP.PreDebug & THREADSDEBUG ) != 0 ) {
1826 MLOCK(ErrorMessageLock);
1827 MesPrint(
"Thread %w executing term:");
1828 PrintTerm(term,
"DoBrackets");
1829 MUNLOCK(ErrorMessageLock);
1831 AT.WorkPointer = term + *term;
1834 MLOCK(ErrorMessageLock);
1835 MesPrint(
"Error in processing one term in thread %d in module %d",identity,AC.CModule);
1836 MUNLOCK(ErrorMessageLock);
1840 SetScratch(fi,&(where));
1841 if ( ISGEPOS(where,stoppos) )
break;
1843 AT.WorkPointer = term;
1844 thr->free = BUCKETCOMINGFREE;
1855 sumtimerinfo[identity] +=
TimeCPU(1);
1856 timerinfo[identity] =
TimeCPU(0);
1863 case MCTSEXPANDTREE:
1864 AT.optimtimes = AB[0]->T.optimtimes;
1865 find_Horner_MCTS_expand_tree();
1871 case OPTIMIZEEXPRESSION:
1878 MLOCK(ErrorMessageLock);
1879 MesPrint(
"Illegal wakeup signal %d for thread %d",wakeupsignal,identity);
1880 MUNLOCK(ErrorMessageLock);
1886 timerinfo[identity] =
TimeCPU(1);
1892 FinalizeOneThread(identity);
1912void *RunSortBot(
void *dummy)
1914 int identity, wakeupsignal, identityretv;
1915 ALLPRIVATES *B, *BB;
1917 identity = SetIdentity(&identityretv);
1918 threadpointers[identity] = pthread_self();
1919 B = InitializeOneThread(identity);
1920 while ( ( wakeupsignal = SortBotWait(identity) ) > 0 ) {
1921 switch ( wakeupsignal ) {
1926 AR.CurExpr = AB[0]->R.CurExpr;
1927 AR.PolyFun = AB[0]->R.PolyFun;
1928 AR.PolyFunInv = AB[0]->R.PolyFunInv;
1929 AR.PolyFunType = AB[0]->R.PolyFunType;
1930 AR.PolyFunExp = AB[0]->R.PolyFunExp;
1931 AR.PolyFunVar = AB[0]->R.PolyFunVar;
1932 AR.PolyFunPow = AB[0]->R.PolyFunPow;
1933 AR.SortType = AC.SortType;
1934 if ( AR.PolyFun == 0 ) { AT.SS->PolyFlag = 0; }
1935 else if ( AR.PolyFunType == 1 ) { AT.SS->PolyFlag = 1; }
1936 else if ( AR.PolyFunType == 2 ) {
1937 if ( AR.PolyFunExp == 2
1938 || AR.PolyFunExp == 3 ) AT.SS->PolyFlag = 1;
1939 else AT.SS->PolyFlag = 2;
1941 AT.SS->PolyWise = 0;
1942 AN.ncmod = AC.ncmod;
1943 LOCK(AT.SB.MasterBlockLock[1]);
1944 BB = AB[AT.SortBotIn1];
1945 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
1946 BB = AB[AT.SortBotIn2];
1947 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
1948 AT.SB.FillBlock = 1;
1949 AT.SB.MasterFill[1] = AT.SB.MasterStart[1];
1950 SETBASEPOSITION(AN.theposition,0);
1963 case TERMINATETHREAD:
1973 sumtimerinfo[identity] +=
TimeCPU(1);
1974 timerinfo[identity] =
TimeCPU(0);
1981 MLOCK(ErrorMessageLock);
1982 MesPrint(
"Illegal wakeup signal %d for thread %d",wakeupsignal,identity);
1983 MUNLOCK(ErrorMessageLock);
1992 FinalizeOneThread(identity);
2013void IAmAvailable(
int identity)
2016 LOCK(availabilitylock);
2017 top = topofavailables;
2018 listofavailables[topofavailables++] = identity;
2020 UNLOCK(availabilitylock);
2021 LOCK(wakeupmasterlock);
2022 wakeupmaster = identity;
2023 pthread_cond_signal(&wakeupmasterconditions);
2024 UNLOCK(wakeupmasterlock);
2027 UNLOCK(availabilitylock);
2043int GetAvailableThread()
2046 LOCK(availabilitylock);
2047 if ( topofavailables > 0 ) retval = listofavailables[--topofavailables];
2048 UNLOCK(availabilitylock);
2049 if ( retval >= 0 ) {
2054 LOCK(wakeuplocks[retval]);
2055 UNLOCK(wakeuplocks[retval]);
2071int ConditionalGetAvailableThread()
2074 if ( topofavailables > 0 ) {
2075 LOCK(availabilitylock);
2076 if ( topofavailables > 0 ) {
2077 retval = listofavailables[--topofavailables];
2079 UNLOCK(availabilitylock);
2080 if ( retval >= 0 ) {
2085 LOCK(wakeuplocks[retval]);
2086 UNLOCK(wakeuplocks[retval]);
2105int GetThread(
int identity)
2108 LOCK(availabilitylock);
2109 for ( j = 0; j < topofavailables; j++ ) {
2110 if ( identity == listofavailables[j] )
break;
2112 if ( j < topofavailables ) {
2114 for ( ; j < topofavailables; j++ ) {
2115 listofavailables[j] = listofavailables[j+1];
2119 UNLOCK(availabilitylock);
2136int ThreadWait(
int identity)
2139 LOCK(wakeuplocks[identity]);
2140 LOCK(availabilitylock);
2141 top = topofavailables;
2142 for ( j = topofavailables; j > 0; j-- )
2143 listofavailables[j] = listofavailables[j-1];
2144 listofavailables[0] = identity;
2146 if ( top == 0 || topofavailables == numberofworkers ) {
2147 UNLOCK(availabilitylock);
2148 LOCK(wakeupmasterlock);
2149 wakeupmaster = identity;
2150 pthread_cond_signal(&wakeupmasterconditions);
2151 UNLOCK(wakeupmasterlock);
2154 UNLOCK(availabilitylock);
2156 while ( wakeup[identity] == 0 ) {
2157 pthread_cond_wait(&(wakeupconditions[identity]),&(wakeuplocks[identity]));
2159 retval = wakeup[identity];
2160 wakeup[identity] = 0;
2161 UNLOCK(wakeuplocks[identity]);
2180int SortBotWait(
int identity)
2183 LOCK(wakeuplocks[identity]);
2184 LOCK(availabilitylock);
2185 topsortbotavailables++;
2186 if ( topsortbotavailables >= numberofsortbots ) {
2187 UNLOCK(availabilitylock);
2188 LOCK(wakeupsortbotlock);
2189 wakeupmaster = identity;
2190 pthread_cond_signal(&wakeupsortbotconditions);
2191 UNLOCK(wakeupsortbotlock);
2194 UNLOCK(availabilitylock);
2196 while ( wakeup[identity] == 0 ) {
2197 pthread_cond_wait(&(wakeupconditions[identity]),&(wakeuplocks[identity]));
2199 retval = wakeup[identity];
2200 wakeup[identity] = 0;
2201 UNLOCK(wakeuplocks[identity]);
2221int ThreadClaimedBlock(
int identity)
2223 LOCK(availabilitylock);
2225 if ( numberclaimed >= numberofworkers ) {
2226 UNLOCK(availabilitylock);
2227 LOCK(wakeupmasterlock);
2228 wakeupmaster = identity;
2229 pthread_cond_signal(&wakeupmasterconditions);
2230 UNLOCK(wakeupmasterlock);
2233 UNLOCK(availabilitylock);
2252 LOCK(wakeupmasterlock);
2253 while ( wakeupmaster == 0 ) {
2254 pthread_cond_wait(&wakeupmasterconditions,&wakeupmasterlock);
2256 retval = wakeupmaster;
2258 UNLOCK(wakeupmasterlock);
2272int MasterWaitThread(
int identity)
2275 LOCK(wakeupmasterthreadlocks[identity]);
2276 while ( wakeupmasterthread[identity] == 0 ) {
2277 pthread_cond_wait(&(wakeupmasterthreadconditions[identity])
2278 ,&(wakeupmasterthreadlocks[identity]));
2280 retval = wakeupmasterthread[identity];
2281 wakeupmasterthread[identity] = 0;
2282 UNLOCK(wakeupmasterthreadlocks[identity]);
2298 LOCK(wakeupmasterlock);
2299 while ( topofavailables < numberofworkers ) {
2300 pthread_cond_wait(&wakeupmasterconditions,&wakeupmasterlock);
2302 UNLOCK(wakeupmasterlock);
2318void MasterWaitAllSortBots()
2320 LOCK(wakeupsortbotlock);
2321 while ( topsortbotavailables < numberofsortbots ) {
2322 pthread_cond_wait(&wakeupsortbotconditions,&wakeupsortbotlock);
2324 UNLOCK(wakeupsortbotlock);
2340void MasterWaitAllBlocks()
2342 LOCK(wakeupmasterlock);
2343 while ( numberclaimed < numberofworkers ) {
2344 pthread_cond_wait(&wakeupmasterconditions,&wakeupmasterlock);
2346 UNLOCK(wakeupmasterlock);
2362void WakeupThread(
int identity,
int signalnumber)
2364 if ( signalnumber == 0 ) {
2365 MLOCK(ErrorMessageLock);
2366 MesPrint(
"Illegal wakeup signal for thread %d",identity);
2367 MUNLOCK(ErrorMessageLock);
2370 LOCK(wakeuplocks[identity]);
2371 wakeup[identity] = signalnumber;
2372 pthread_cond_signal(&(wakeupconditions[identity]));
2373 UNLOCK(wakeuplocks[identity]);
2388void WakeupMasterFromThread(
int identity,
int signalnumber)
2390 if ( signalnumber == 0 ) {
2391 MLOCK(ErrorMessageLock);
2392 MesPrint(
"Illegal wakeup signal for master %d",identity);
2393 MUNLOCK(ErrorMessageLock);
2396 LOCK(wakeupmasterthreadlocks[identity]);
2397 wakeupmasterthread[identity] = signalnumber;
2398 pthread_cond_signal(&(wakeupmasterthreadconditions[identity]));
2399 UNLOCK(wakeupmasterthreadlocks[identity]);
2411int SendOneBucket(
int type)
2413 ALLPRIVATES *B0 = AB[0];
2414 THREADBUCKET *thr = 0;
2416 for ( j = 0; j < numthreadbuckets; j++ ) {
2417 if ( threadbuckets[j]->free == BUCKETFILLED ) {
2418 thr = threadbuckets[j];
2419 for ( k = j+1; k < numthreadbuckets; k++ )
2420 threadbuckets[k-1] = threadbuckets[k];
2421 threadbuckets[numthreadbuckets-1] = thr;
2426 while ( (
id = GetAvailableThread() ) < 0 ) { MasterWait(); }
2430 LoadOneThread(0,
id,thr,0);
2431 thr->busy = BUCKETASSIGNED;
2432 thr->free = BUCKETINUSE;
2433 numberoffullbuckets--;
2441 WakeupThread(
id,type);
2469int InParallelProcessor()
2472 int i, id, retval = 0, num = 0;
2474 if ( numberofworkers >= 2 ) {
2476 for ( i = 0; i < NumExpressions; i++ ) {
2478 if ( e->partodo <= 0 )
continue;
2479 if ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION
2480 || e->status == UNHIDELEXPRESSION || e->status == UNHIDEGEXPRESSION
2481 || e->status == INTOHIDELEXPRESSION || e->status == INTOHIDEGEXPRESSION ) {
2487 if ( e->counter == 0 ) {
2494 while ( (
id = GetAvailableThread() ) < 0 ) { MasterWait(); }
2495 LoadOneThread(0,
id,0,-1);
2496 AB[id]->R.exprtodo = i;
2497 WakeupThread(
id,DOONEEXPRESSION);
2503 if ( num > 0 ) MasterWaitAll();
2505 if ( AC.CollectFun ) AR.DeferFlag = 0;
2508 for ( i = 0; i < NumExpressions; i++ ) {
2509 Expressions[i].partodo = 0;
2543int ThreadsProcessor(EXPRESSIONS e, WORD LastExpression, WORD fromspectator)
2545 ALLPRIVATES *B0 = AB[0], *B = B0;
2546 int id, oldgzipCompress, endofinput = 0, j, still, k, defcount = 0, bra = 0, first = 1;
2547 LONG dd = 0, ddd, thrbufsiz, thrbufsiz0, thrbufsiz2, numbucket = 0, numpasses;
2549 WORD *oldworkpointer = AT0.WorkPointer, *tt, *ttco = 0, *t1 = 0, ter, *tstop = 0, *t2;
2550 THREADBUCKET *thr = 0;
2552 GETTERM GetTermP = &GetTerm;
2553 POSITION eonfile = AS.OldOnFile[e-Expressions];
2554 numberoffullbuckets = 0;
2560 AM.tracebackflag = 1;
2562 AS.sLevel = AR0.sLevel;
2563 LOCK(availabilitylock);
2564 topofavailables = 0;
2565 for (
id = 1;
id <= numberofworkers;
id++ ) {
2566 WakeupThread(
id,STARTNEWEXPRESSION);
2568 UNLOCK(availabilitylock);
2574 if ( AC.numpfirstnum > 0 ) {
2575 for ( j = 0; j < AC.numpfirstnum; j++ ) {
2576 AC.inputnumbers[j] = -1;
2588 thrbufsiz2 = thrbufsiz = AC.ThreadBucketSize-1;
2589 if ( ( e->counter / ( numberofworkers * 5 ) ) < thrbufsiz ) {
2590 thrbufsiz = e->counter / ( numberofworkers * 5 ) - 1;
2591 if ( thrbufsiz < 0 ) thrbufsiz = 0;
2593 thrbufsiz0 = thrbufsiz;
2595 thrbufsiz = thrbufsiz0 / (2 << numpasses);
2599 for ( j = 0; j < numthreadbuckets; j++ )
2600 threadbuckets[j]->free = BUCKETFREE;
2601 thr = threadbuckets[0];
2610 if ( e->bracketinfo && AC.CollectFun == 0 && AR0.DeferFlag == 0 ) {
2615 for ( n = 0; n < e->bracketinfo->indexfill; n++ ) {
2616 num = TreatIndexEntry(B0,n);
2624 for ( j = 0; j < numthreadbuckets; j++ ) {
2625 switch ( threadbuckets[j]->free ) {
2627 thr = threadbuckets[j];
2629 case BUCKETCOMINGFREE:
2630 thr = threadbuckets[j];
2631 thr->free = BUCKETFREE;
2632 for ( k = j+1; k < numthreadbuckets; k++ )
2633 threadbuckets[k-1] = threadbuckets[k];
2634 threadbuckets[numthreadbuckets-1] = thr;
2642 if ( j < numthreadbuckets ) {
2646 thr->firstbracket = n;
2647 thr->lastbracket = n + num - 1;
2648 thr->type = BUCKETDOINGBRACKET;
2649 thr->free = BUCKETFILLED;
2650 thr->firstterm = AN0.ninterms;
2651 for ( j = n; j < n+num; j++ ) {
2652 AN0.ninterms += e->bracketinfo->
indexbuffer[j].termsinbracket;
2655 numberoffullbuckets++;
2656 if ( topofavailables > 0 ) {
2657 SendOneBucket(DOBRACKETS);
2666 while ( topofavailables <= 0 ) {
2669 SendOneBucket(DOBRACKETS);
2678 switch ( e->status ) {
2679 case UNHIDELEXPRESSION:
2680 case UNHIDEGEXPRESSION:
2681 case DROPHLEXPRESSION:
2682 case DROPHGEXPRESSION:
2683 case HIDDENLEXPRESSION:
2684 case HIDDENGEXPRESSION:
2685 curfile = AR0.hidefile;
2688 curfile = AR0.infile;
2691 SetScratch(curfile,&eonfile);
2692 GetTerm(B0,AT0.WorkPointer);
2696 GetTermP = &GetTerm2;
2701 for ( j = 0; j < numthreadbuckets; j++ ) {
2702 switch ( threadbuckets[j]->free ) {
2704 thr = threadbuckets[j];
2706 case BUCKETCOMINGFREE:
2707 thr = threadbuckets[j];
2708 thr->free = BUCKETFREE;
2709 for ( k = j+1; k < numthreadbuckets; k++ )
2710 threadbuckets[k-1] = threadbuckets[k];
2711 threadbuckets[numthreadbuckets-1] = thr;
2718 while ( topofavailables <= 0 ) {
2721 while ( topofavailables > 0 && numberoffullbuckets > 0 ) {
2722 SendOneBucket(DOBRACKETS);
2726 while ( numberoffullbuckets > 0 ) {
2727 while ( topofavailables <= 0 ) {
2730 while ( topofavailables > 0 && numberoffullbuckets > 0 ) {
2731 SendOneBucket(DOBRACKETS);
2740 AN0.lastinindex = -1;
2751 if ( fromspectator ) {
2752 ter = GetFromSpectator(thr->threadbuffer,fromspectator-1);
2753 if ( ter == 0 ) fromspectator = 0;
2756 ter = GetTermP(B0,thr->threadbuffer);
2758 if ( ter < 0 )
break;
2759 if ( ter == 0 ) { endofinput = 1;
goto Finalize; }
2760 dd = AN0.deferskipped;
2761 if ( AR0.DeferFlag ) {
2763 thr->deferbuffer[defcount++] = AR0.DefPosition;
2764 ttco = thr->compressbuffer; t1 = AR0.CompressBuffer; j = *t1;
2767 else if ( first && ( AC.CollectFun == 0 ) ) {
2769 t1 = tstop = thr->threadbuffer;
2770 tstop += *tstop; tstop -= ABS(tstop[-1]);
2772 while ( t1 < tstop ) {
2773 if ( t1[0] == HAAKJE ) { bra = 1;
break; }
2776 t1 = thr->threadbuffer;
2781 if ( AC.CollectFun && *(thr->threadbuffer) < (AM.MaxTer/((LONG)
sizeof(WORD))-10) ) {
2782 if ( ( dd = GetMoreTerms(thr->threadbuffer) ) < 0 ) {
2789 if ( topofavailables > 0 && numberoffullbuckets > 0 ) SendOneBucket(LOWESTLEVELGENERATION);
2793 tt = thr->threadbuffer; tt += *tt;
2800 if ( numpasses > 0 ) {
2802 if ( numbucket >= numberofworkers ) {
2805 if ( numpasses == 0 ) thrbufsiz = thrbufsiz0;
2806 else thrbufsiz = thrbufsiz0 / (2 << numpasses);
2808 thrbufsiz2 = thrbufsiz + thrbufsiz/5;
2813 while ( ( dd < thrbufsiz ) &&
2814 ( tt - thr->threadbuffer ) < ( thr->threadbuffersize - AM.MaxTer/((LONG)
sizeof(WORD)) - 2 ) ) {
2818 if ( topofavailables > 0 && numberoffullbuckets > 0 ) SendOneBucket(LOWESTLEVELGENERATION);
2822 if ( GetTermP(B0,tt) == 0 ) { endofinput = 1;
break; }
2825 dd += AN0.deferskipped;
2826 if ( AR0.DeferFlag ) {
2827 thr->deferbuffer[defcount++] = AR0.DefPosition;
2828 t1 = AR0.CompressBuffer; j = *t1;
2831 if ( AC.CollectFun && *tt < (AM.MaxTer/((LONG)
sizeof(WORD))-10) ) {
2832 if ( ( ddd = GetMoreTerms(tt) ) < 0 ) {
2847 tstop = t1 + *t1; tstop -= ABS(tstop[-1]);
2849 while ( t2 < tstop ) {
2850 if ( t2[0] == HAAKJE ) {
break; }
2853 if ( t2[0] == HAAKJE ) {
2854 t2 += t2[1]; num = t2 - t1;
2855 while ( ( dd < thrbufsiz2 ) &&
2856 ( tt - thr->threadbuffer ) < ( thr->threadbuffersize - AM.MaxTer - 2 ) ) {
2860 if ( topofavailables > 0 && numberoffullbuckets > 0 ) SendOneBucket(LOWESTLEVELGENERATION);
2864 if ( GetTermP(B0,tt) == 0 ) { endofinput = 1;
break; }
2868 tstop = tt + *tt; tstop -= ABS(tstop[-1]);
2869 if ( tstop-tt < num ) {
2873 for ( i = 1; i < num; i++ ) {
2874 if ( t1[i] != tt[i] )
break;
2890 thr->firstterm = AN0.ninterms;
2893 thr->free = BUCKETFILLED;
2894 thr->type = BUCKETDOINGTERMS;
2895 numberoffullbuckets++;
2896 if ( topofavailables <= 0 && endofinput == 0 ) {
2910 for ( j = 0; j < numthreadbuckets; j++ ) {
2911 switch ( threadbuckets[j]->free ) {
2913 thr = threadbuckets[j];
2914 if ( !endofinput )
goto NextBucket;
2920 thr->free = BUCKETATEND;
2922 case BUCKETCOMINGFREE:
2923 thr = threadbuckets[j];
2924 thr->free = BUCKETFREE;
2930 for ( k = j+1; k < numthreadbuckets; k++ )
2931 threadbuckets[k-1] = threadbuckets[k];
2932 threadbuckets[numthreadbuckets-1] = thr;
2948 for ( j = 0; j < numthreadbuckets; j++ ) {
2949 if ( threadbuckets[j]->free == BUCKETFILLED ) {
2950 thr = threadbuckets[j];
2951 for ( k = j+1; k < numthreadbuckets; k++ )
2952 threadbuckets[k-1] = threadbuckets[k];
2953 threadbuckets[numthreadbuckets-1] = thr;
2963 while ( (
id = GetAvailableThread() ) < 0 ) { MasterWait(); }
2967 LoadOneThread(0,
id,thr,0);
2969 thr->busy = BUCKETASSIGNED;
2971 thr->free = BUCKETINUSE;
2972 numberoffullbuckets--;
2980 WakeupThread(
id,LOWESTLEVELGENERATION);
2985 if ( topofavailables > 0 ) {
2986 for ( j = 0; j < numthreadbuckets; j++ ) {
2987 if ( threadbuckets[j]->free == BUCKETFILLED ) {
2988 thr = threadbuckets[j];
2989 for ( k = j+1; k < numthreadbuckets; k++ )
2990 threadbuckets[k-1] = threadbuckets[k];
2991 threadbuckets[numthreadbuckets-1] = thr;
3000 for ( j = 0; j < numthreadbuckets; j++ ) {
3001 switch ( threadbuckets[j]->free ) {
3003 thr = threadbuckets[j];
3004 if ( !endofinput )
goto NextBucket;
3005 thr->free = BUCKETATEND;
3007 case BUCKETCOMINGFREE:
3008 thr = threadbuckets[j];
3010 thr->free = BUCKETATEND;
3013 thr->free = BUCKETFREE;
3014 for ( k = j+1; k < numthreadbuckets; k++ )
3015 threadbuckets[k-1] = threadbuckets[k];
3016 threadbuckets[numthreadbuckets-1] = thr;
3024 if ( j >= numthreadbuckets )
break;
3034 for ( j = 0; j < numthreadbuckets; j++ ) {
3035 switch ( threadbuckets[j]->free ) {
3037 thr = threadbuckets[j];
3038 if ( !endofinput )
goto NextBucket;
3039 thr->free = BUCKETATEND;
3041 case BUCKETCOMINGFREE:
3042 thr = threadbuckets[j];
3043 if ( endofinput ) thr->free = BUCKETATEND;
3045 thr->free = BUCKETFREE;
3046 for ( k = j+1; k < numthreadbuckets; k++ )
3047 threadbuckets[k-1] = threadbuckets[k];
3048 threadbuckets[numthreadbuckets-1] = thr;
3053 if ( still < 0 ) still = j;
3066 thr = threadbuckets[still];
3067 for ( k = still+1; k < numthreadbuckets; k++ )
3068 threadbuckets[k-1] = threadbuckets[k];
3069 threadbuckets[numthreadbuckets-1] = thr;
3082 if ( AC.ThreadBalancing ) {
3083 for (
id = 1;
id <= numberofworkers;
id++ ) {
3084 AB[id]->T.LoadBalancing = 1;
3086 if ( LoadReadjusted() )
goto Finalize;
3087 for (
id = 1;
id <= numberofworkers;
id++ ) {
3088 AB[id]->T.LoadBalancing = 0;
3091 if ( AC.ThreadBalancing ) {
3116 if ( LastExpression ) {
3118 if ( AR0.infile->handle >= 0 ) {
3119 CloseFile(AR0.infile->handle);
3120 AR0.infile->handle = -1;
3121 remove(AR0.infile->name);
3122 PUTZERO(AR0.infile->POposition);
3123 AR0.infile->POfill = AR0.infile->POfull = AR0.infile->PObuffer;
3135 oldgzipCompress = AR0.gzipCompress;
3136 AR0.gzipCompress = 0;
3137 if ( AR0.outtohide ) AR0.outfile = AR0.hidefile;
3138 if ( MasterMerge() < 0 ) {
3139 if ( AR0.outtohide ) AR0.outfile = oldoutfile;
3140 AR0.gzipCompress = oldgzipCompress;
3143 if ( AR0.outtohide ) AR0.outfile = oldoutfile;
3144 AR0.gzipCompress = oldgzipCompress;
3152 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
3153 if ( GetThread(
id) > 0 ) WakeupThread(
id,CLEANUPEXPRESSION);
3156 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
3157 if ( AB[
id]->R.MaxDum - AM.IndDum > e->numdummies )
3158 e->numdummies = AB[id]->R.MaxDum - AM.IndDum;
3159 AR0.expchanged |= AB[id]->R.expchanged;
3165 AT0.WorkPointer = oldworkpointer;
3195 ALLPRIVATES *B0 = AB[0];
3196 THREADBUCKET *thr = 0, *thrtogo = 0;
3197 int numtogo, numfree, numbusy, n, nperbucket, extra, i, j, u, bus;
3199 WORD *t1, *c1, *t2, *c2, *t3;
3204 while ( topofavailables <= 0 ) MasterWait();
3213 for ( j = 0; j < numthreadbuckets; j++ ) {
3214 thr = threadbuckets[j];
3215 if ( thr->free == BUCKETFREE || thr->free == BUCKETATEND
3216 || thr->free == BUCKETCOMINGFREE ) {
3217 freebuckets[numfree++] = thr;
3219 else if ( thr->type != BUCKETDOINGTERMS ) {}
3220 else if ( thr->totnum > 1 ) {
3224 if ( thr->free == BUCKETINUSE ) {
3225 n = thr->totnum-thr->usenum;
3226 if ( bus == BUCKETASSIGNED ) numbusy++;
3227 else if ( ( bus != BUCKETASSIGNED )
3228 && ( n > numtogo ) ) {
3233 else if ( bus == BUCKETTOBERELEASED
3234 && thr->free == BUCKETRELEASED ) {
3235 freebuckets[numfree++] = thr;
3236 thr->free = BUCKETATEND;
3238 thr->busy = BUCKETPREPARINGTERM;
3243 if ( numfree == 0 )
return(0);
3244 if ( numtogo > 0 ) {
3251 if ( thr->totnum-thr->usenum < numtogo )
goto restart;
3261 if ( thr->busy != BUCKETDOINGTERM ) {
3265 if ( thr->totnum-thr->usenum < numtogo ) {
3269 thr->free = BUCKETTERMINATED;
3276 if ( thr->usenum == thr->totnum ) {
3281 thr->free = BUCKETATEND;
3288 if ( numbusy > 0 )
return(1);
3300 numinput = thr->firstterm + thr->usenum;
3301 nperbucket = numtogo / numfree;
3302 extra = numtogo - nperbucket*numfree;
3303 if ( AR0.DeferFlag ) {
3304 t1 = thr->threadbuffer; c1 = thr->compressbuffer; u = thr->usenum;
3305 for ( n = 0; n < thr->usenum; n++ ) { t1 += *t1; c1 += *c1; }
3308 for ( i = 0; i < extra; i++ ) {
3309 thrtogo = freebuckets[i];
3310 t2 = thrtogo->threadbuffer;
3311 c2 = thrtogo->compressbuffer;
3312 thrtogo->free = BUCKETFILLED;
3313 thrtogo->type = BUCKETDOINGTERMS;
3314 thrtogo->totnum = nperbucket+1;
3315 thrtogo->ddterms = 0;
3316 thrtogo->usenum = 0;
3317 thrtogo->busy = BUCKETASSIGNED;
3318 thrtogo->firstterm = numinput;
3319 numinput += nperbucket+1;
3320 for ( n = 0; n <= nperbucket; n++ ) {
3321 j = *t1; NCOPY(t2,t1,j);
3322 j = *c1; NCOPY(c2,c1,j);
3323 thrtogo->deferbuffer[n] = thr->deferbuffer[u++];
3328 if ( nperbucket > 0 ) {
3329 for ( i = extra; i < numfree; i++ ) {
3330 thrtogo = freebuckets[i];
3331 t2 = thrtogo->threadbuffer;
3332 c2 = thrtogo->compressbuffer;
3333 thrtogo->free = BUCKETFILLED;
3334 thrtogo->type = BUCKETDOINGTERMS;
3335 thrtogo->totnum = nperbucket;
3336 thrtogo->ddterms = 0;
3337 thrtogo->usenum = 0;
3338 thrtogo->busy = BUCKETASSIGNED;
3339 thrtogo->firstterm = numinput;
3340 numinput += nperbucket;
3341 for ( n = 0; n < nperbucket; n++ ) {
3342 j = *t1; NCOPY(t2,t1,j);
3343 j = *c1; NCOPY(c2,c1,j);
3344 thrtogo->deferbuffer[n] = thr->deferbuffer[u++];
3351 t1 = thr->threadbuffer;
3352 for ( n = 0; n < thr->usenum; n++ ) { t1 += *t1; }
3355 for ( i = 0; i < extra; i++ ) {
3356 thrtogo = freebuckets[i];
3357 t2 = thrtogo->threadbuffer;
3358 thrtogo->free = BUCKETFILLED;
3359 thrtogo->type = BUCKETDOINGTERMS;
3360 thrtogo->totnum = nperbucket+1;
3361 thrtogo->ddterms = 0;
3362 thrtogo->usenum = 0;
3363 thrtogo->busy = BUCKETASSIGNED;
3364 thrtogo->firstterm = numinput;
3365 numinput += nperbucket+1;
3366 for ( n = 0; n <= nperbucket; n++ ) {
3367 j = *t1; NCOPY(t2,t1,j);
3372 if ( nperbucket > 0 ) {
3373 for ( i = extra; i < numfree; i++ ) {
3374 thrtogo = freebuckets[i];
3375 t2 = thrtogo->threadbuffer;
3376 thrtogo->free = BUCKETFILLED;
3377 thrtogo->type = BUCKETDOINGTERMS;
3378 thrtogo->totnum = nperbucket;
3379 thrtogo->ddterms = 0;
3380 thrtogo->usenum = 0;
3381 thrtogo->busy = BUCKETASSIGNED;
3382 thrtogo->firstterm = numinput;
3383 numinput += nperbucket;
3384 for ( n = 0; n < nperbucket; n++ ) {
3385 j = *t1; NCOPY(t2,t1,j);
3392 if ( thr->free == BUCKETRELEASED && thr->busy == BUCKETTOBERELEASED ) {
3393 thr->free = BUCKETATEND; thr->busy = BUCKETPREPARINGTERM;
3461int PutToMaster(PHEAD WORD *term)
3463 int i,j,nexti,ret = 0;
3464 WORD *t, *fill, *top, zero = 0;
3469 t = term; ret = j = *term;
3470 if ( j == 0 ) { j = 1; }
3472 i = AT.SB.FillBlock;
3473 fill = AT.SB.MasterFill[i];
3474 top = AT.SB.MasterStop[i];
3476 while ( j > 0 && fill < top ) {
3477 *fill++ = *t++; j--;
3487 if ( nexti > AT.SB.MasterNumBlocks ) {
3490 LOCK(AT.SB.MasterBlockLock[nexti]);
3491 UNLOCK(AT.SB.MasterBlockLock[i]);
3492 AT.SB.MasterFill[i] = AT.SB.MasterStart[i];
3493 AT.SB.FillBlock = i = nexti;
3494 fill = AT.SB.MasterStart[i];
3495 top = AT.SB.MasterStop[i];
3498 AT.SB.MasterFill[i] = fill;
3518SortBotOut(PHEAD WORD *term)
3522 if ( AT.identity != 0 )
return(PutToMaster(BHEAD term));
3525 if (
FlushOut(&SortBotPosition,AR.outfile,1) )
return(-1);
3526 ADDPOS(AT.SS->SizeInFile[0],1);
3531 if ( ( im =
PutOut(BHEAD term,&SortBotPosition,AR.outfile,1) ) < 0 ) {
3532 MLOCK(ErrorMessageLock);
3533 MesPrint(
"Called from MasterMerge/SortBotOut");
3534 MUNLOCK(ErrorMessageLock);
3537 ADDPOS(AT.SS->SizeInFile[0],im);
3567 ALLPRIVATES *B0 = AB[0], *B = 0;
3569 WORD **poin, **poin2, ul, k, i, im, *m1, j;
3570 WORD lpat, mpat, level, l1, l2, r1, r2, r3, c;
3571 WORD *m2, *m3, r31, r33, ki, *rr;
3576 if ( numberofworkers > 2 )
return(SortBotMasterMerge());
3579 if ( AR0.PolyFun == 0 ) { S->PolyFlag = 0; }
3580 else if ( AR0.PolyFunType == 1 ) { S->PolyFlag = 1; }
3581 else if ( AR0.PolyFunType == 2 ) {
3582 if ( AR0.PolyFunExp == 2
3583 || AR0.PolyFunExp == 3 ) S->PolyFlag = 1;
3584 else S->PolyFlag = 2;
3587 coef = AN0.SoScratC;
3588 poin = S->poina; poin2 = S->poin2a;
3589 rr = AR0.CompressPointer;
3594 S->inNum = numberofthreads;
3599 S->lPatch = S->inNum - 1;
3609 for ( i = 1; i <= S->lPatch; i++ ) {
3611 LOCK(AT.SB.MasterBlockLock[0]);
3612 LOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
3620 for ( i = 0; i < S->lPatch; i++ ) {
3622 WakeupThread(i+1,FINISHEXPRESSION);
3627 if ( fout->
handle >= 0 ) {
3629 SeekFile(fout->
handle,&position,SEEK_END);
3630 ADDPOS(position,((fout->POfill-fout->PObuffer)*
sizeof(WORD)));
3633 SETBASEPOSITION(position,(fout->POfill-fout->PObuffer)*
sizeof(WORD));
3638 MasterWaitAllBlocks();
3646 for ( i = 1; i <= S->lPatch; i++ ) {
3648 LOCK(AT.SB.MasterBlockLock[1]);
3649 AT.SB.MasterBlock = 1;
3657 do { lpat <<= 1; }
while ( lpat < S->lPatch );
3658 mpat = ( lpat >> 1 ) - 1;
3659 k = lpat - S->lPatch;
3664 for ( i = 1; i < lpat; i++ ) { S->tree[i] = -1; }
3665 for ( i = 1; i <= k; i++ ) {
3667 poin[im] = AB[i]->T.SB.MasterStart[AB[i]->T.SB.MasterBlock];
3668 poin2[im] = poin[im] + *(poin[im]);
3671 S->tree[mpat+i] = 0;
3672 poin[im-1] = poin2[im-1] = 0;
3674 for ( i = (k*2)+1; i <= lpat; i++ ) {
3677 poin[i] = AB[i-k]->T.SB.MasterStart[AB[i-k]->T.SB.MasterBlock];
3678 poin2[i] = poin[i] + *(poin[i]);
3699 if ( !*(poin[k]) ) {
3700 do {
if ( !( i >>= 1 ) )
goto EndOfMerge; }
while ( !S->tree[i] );
3701 if ( S->tree[i] == -1 ) {
3714 if ( S->tree[i] > 0 ) {
3718 if ( ( c = CompareTerms(poin[S->tree[i]],poin[k],(WORD)0) ) > 0 ) {
3722 S->used[level] = S->tree[i];
3732 l1 = *( m1 = poin[S->tree[i]] );
3733 l2 = *( m2 = poin[k] );
3734 if ( S->PolyWise ) {
3739 if ( S->PolyFlag == 2 ) {
3741 if ( *tt1 + w[1] - m1[1] > AM.MaxTer/((LONG)
sizeof(WORD)) ) {
3742 MLOCK(ErrorMessageLock);
3743 MesPrint(
"Term too complex in PolyRatFun addition. MaxTermSize of %10l is too small",AM.MaxTer);
3744 MUNLOCK(ErrorMessageLock);
3747 AT0.WorkPointer = w;
3748 if ( w[FUNHEAD] == -SNUMBER && w[FUNHEAD+1] == 0 && w[1] > FUNHEAD ) {
3753 w = AT0.WorkPointer;
3754 if ( w + m1[1] + m2[1] > AT0.WorkTop ) {
3755 MLOCK(ErrorMessageLock);
3756 MesPrint(
"MasterMerge: A WorkSpace of %10l is too small",AM.WorkSize);
3757 MUNLOCK(ErrorMessageLock);
3764 || ( w[FUNHEAD] == -SNUMBER && w[FUNHEAD+1] == 0 ) )
3766 if ( r1 == m1[1] ) {
3769 else if ( r1 < m1[1] ) {
3773 while ( --r1 >= 0 ) *--m1 = *--m2;
3776 while ( --r1 >= 0 ) *--m1 = *--m2;
3778 poin[S->tree[i]] = m1;
3786 poin[S->tree[i]] = m2;
3793 r1 = *( m1 += l1 - 1 );
3795 r1 = ( ( r1 > 0 ) ? (r1-1) : (r1+1) ) >> 1;
3796 r2 = *( m2 += l2 - 1 );
3798 r2 = ( ( r2 > 0 ) ? (r2-1) : (r2+1) ) >> 1;
3800 if ( AddRat(B0,(UWORD *)m1,r1,(UWORD *)m2,r2,coef,&r3) ) {
3801 MLOCK(ErrorMessageLock);
3802 MesCall(
"MasterMerge");
3803 MUNLOCK(ErrorMessageLock);
3807 if ( AN.ncmod != 0 ) {
3808 if ( ( AC.modmode & POSNEG ) != 0 ) {
3811 else if ( BigLong(coef,r3,(UWORD *)AC.cmod,ABS(AN.ncmod)) >= 0 ) {
3813 SubPLon(coef,r3,(UWORD *)AC.cmod,ABS(AN.ncmod),coef,&r3);
3815 for ( ii = 1; ii < r3; ii++ ) coef[r3+ii] = 0;
3819 r33 = ( r3 > 0 ) ? ( r3 + 1 ) : ( r3 - 1 );
3820 if ( r3 < 0 ) r3 = -r3;
3821 if ( r1 < 0 ) r1 = -r1;
3826 ul = S->used[level] = S->tree[i];
3832 poin[ul] = poin2[ul];
3834 if ( (poin[ul] + im + COMPINC) >=
3835 AB[ki+1]->T.SB.MasterStop[AB[ki+1]->T.SB.MasterBlock]
3842 i = AT.SB.MasterBlock;
3844 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
3847 UNLOCK(AT.SB.MasterBlockLock[i-1]);
3849 if ( i == AT.SB.MasterNumBlocks ) {
3854 to = AT.SB.MasterStart[1];
3855 from = AT.SB.MasterStop[i];
3856 while ( from > poin[ul] ) *--to = *--from;
3861 LOCK(AT.SB.MasterBlockLock[i]);
3862 AT.SB.MasterBlock = i;
3863 poin2[ul] = poin[ul] + im;
3868 S->used[++level] = k;
3874 else if ( r31 < 0 ) {
3883 if( (poin[S->tree[i]]+l1+r31) >= poin2[S->tree[i]] ) {
3889 if ( (l1 + r31)*((LONG)
sizeof(WORD)) >= AM.MaxTer ) {
3890 MLOCK(ErrorMessageLock);
3891 MesPrint(
"MasterMerge: Coefficient overflow during sort");
3892 MUNLOCK(ErrorMessageLock);
3895 m2 = poin[S->tree[i]];
3896 m3 = ( poin[S->tree[i]] -= r31 );
3897 do { *m3++ = *m2++; }
while ( m2 < m1 );
3901 *(poin[S->tree[i]]) += r31;
3903 m2 = (WORD *)coef; im = r3;
3915 if ( (poin[k] + im + COMPINC) >=
3916 AB[ki+1]->T.SB.MasterStop[AB[ki+1]->T.SB.MasterBlock]
3923 i = AT.SB.MasterBlock;
3925 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
3928 UNLOCK(AT.SB.MasterBlockLock[i-1]);
3930 if ( i == AT.SB.MasterNumBlocks ) {
3935 to = AT.SB.MasterStart[1];
3936 from = AT.SB.MasterStop[i];
3937 while ( from > poin[k] ) *--to = *--from;
3942 LOCK(AT.SB.MasterBlockLock[i]);
3943 AT.SB.MasterBlock = i;
3944 poin2[k] = poin[k] + im;
3952 else if ( S->tree[i] < 0 ) {
3963 if ( ( im =
PutOut(B0,poin[k],&position,fout,1) ) < 0 ) {
3964 MLOCK(ErrorMessageLock);
3965 MesPrint(
"Called from MasterMerge with k = %d (stream %d)",k,S->ktoi[k]);
3966 MUNLOCK(ErrorMessageLock);
3969 ADDPOS(S->SizeInFile[0],im);
3972 if (
FlushOut(&position,fout,1) )
goto ReturnError;
3973 ADDPOS(S->SizeInFile[0],1);
3977 position = S->SizeInFile[0];
3978 MULPOS(position,
sizeof(WORD));
3980 for ( j = 1; j <= numberofworkers; j++ ) {
3981 S->GenTerms += AB[j]->T.SS->GenTerms;
3984 Expressions[AR0.CurExpr].counter = S->TermsLeft;
3985 Expressions[AR0.CurExpr].size = position;
3989 for ( i = 1; i <= S->lPatch; i++ ) {
3991 UNLOCK(AT.SB.MasterBlockLock[0]);
3992 if ( AT.SB.MasterBlock == 1 ) {
3993 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
3996 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterBlock-1]);
3998 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterBlock]);
4003 for ( i = 1; i <= S->lPatch; i++ ) {
4005 UNLOCK(AT.SB.MasterBlockLock[0]);
4006 if ( AT.SB.MasterBlock == 1 ) {
4007 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
4010 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterBlock-1]);
4012 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterBlock]);
4040int SortBotMasterMerge()
4043 ALLPRIVATES *B = AB[0], *BB;
4056 topsortbotavailables = 0;
4057 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
4058 WakeupThread(i,INISORTBOT);
4064 AR.CompressPointer[0] = 0;
4066 BB = AB[AT.SortBotIn1];
4067 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
4068 BB = AB[AT.SortBotIn2];
4069 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
4071 MasterWaitAllSortBots();
4076 for ( i = 1; i <= numberofworkers; i++ ) {
4078 WakeupThread(i,FINISHEXPRESSION);
4083 if ( fout->
handle >= 0 ) {
4084 PUTZERO(SortBotPosition);
4085 SeekFile(fout->
handle,&SortBotPosition,SEEK_END);
4086 ADDPOS(SortBotPosition,((fout->POfill-fout->PObuffer)*
sizeof(WORD)));
4089 SETBASEPOSITION(SortBotPosition,(fout->POfill-fout->PObuffer)*
sizeof(WORD));
4091 MasterWaitAllBlocks();
4097 topsortbotavailables = 0;
4098 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
4099 WakeupThread(i,RUNSORTBOT);
4101 if ( SortBotMerge(BHEAD0) ) {
4102 MLOCK(ErrorMessageLock);
4103 MesPrint(
"Called from SortBotMasterMerge");
4104 MUNLOCK(ErrorMessageLock);
4111 if ( S->file.
handle >= 0 )
4118 position = S->SizeInFile[0];
4119 MULPOS(position,
sizeof(WORD));
4121 for ( j = 1; j <= numberofworkers; j++ ) {
4122 S->GenTerms += AB[j]->T.SS->GenTerms;
4124 S->TermsLeft = numberofterms;
4126 Expressions[AR.CurExpr].counter = S->TermsLeft;
4127 Expressions[AR.CurExpr].size = position;
4136 MasterWaitAllSortBots();
4155int SortBotMerge(PHEAD0)
4158 ALLPRIVATES *Bin1 = AB[AT.SortBotIn1],*Bin2 = AB[AT.SortBotIn2];
4159 WORD *term1, *term2, *next, *wp;
4162 WORD l1, l2, *m1, *m2, *w, r1, r2, r3, r33, r31, *tt1, ii;
4163 WORD *to, *from, im, c;
4172 if ( AT.identity == 0 ) {
4173 wp = AT.WorkPointer;
4176 wp = AT.WorkPointer = AT.WorkSpace;
4183 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4184 LOCK(Bin2->T.SB.MasterBlockLock[blin2]);
4186 term1 = Bin1->T.SB.MasterStart[blin1];
4187 term2 = Bin2->T.SB.MasterStart[blin2];
4188 AT.SB.FillBlock = 1;
4192 while ( *term1 && *term2 ) {
4193 if ( ( c = CompareTerms(term1,term2,(WORD)0) ) > 0 ) {
4197 if ( SortBotOut(BHEAD term1) < 0 ) {
4198 MLOCK(ErrorMessageLock);
4199 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4200 MUNLOCK(ErrorMessageLock);
4206 if ( next >= Bin1->T.SB.MasterStop[blin1] || ( *next &&
4207 next+*next+COMPINC > Bin1->T.SB.MasterStop[blin1] ) ) {
4209 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4212 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4214 if ( blin1 == Bin1->T.SB.MasterNumBlocks ) {
4218 to = Bin1->T.SB.MasterStart[1];
4219 from = Bin1->T.SB.MasterStop[Bin1->T.SB.MasterNumBlocks];
4220 while ( from > next ) *--to = *--from;
4227 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4228 Bin1->T.SB.MasterBlock = blin1;
4239 if ( SortBotOut(BHEAD term2) < 0 ) {
4240 MLOCK(ErrorMessageLock);
4241 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4242 MUNLOCK(ErrorMessageLock);
4248 if ( next >= Bin2->T.SB.MasterStop[blin2] || ( *next
4249 && next+*next+COMPINC > Bin2->T.SB.MasterStop[blin2] ) ) {
4251 UNLOCK(Bin2->T.SB.MasterBlockLock[Bin2->T.SB.MasterNumBlocks]);
4254 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2-1]);
4256 if ( blin2 == Bin2->T.SB.MasterNumBlocks ) {
4260 to = Bin2->T.SB.MasterStart[1];
4261 from = Bin2->T.SB.MasterStop[Bin2->T.SB.MasterNumBlocks];
4262 while ( from > next ) *--to = *--from;
4269 LOCK(Bin2->T.SB.MasterBlockLock[blin2]);
4270 Bin2->T.SB.MasterBlock = blin2;
4281 l1 = *( m1 = term1 );
4282 l2 = *( m2 = term2 );
4283 if ( S->PolyWise ) {
4287 if ( S->PolyFlag == 2 ) {
4288 AT.WorkPointer = wp;
4290 if ( *tt1 + w[1] - m1[1] > AM.MaxTer/((LONG)
sizeof(WORD)) ) {
4291 MLOCK(ErrorMessageLock);
4292 MesPrint(
"Term too complex in PolyRatFun addition. MaxTermSize of %10l is too small",AM.MaxTer);
4293 MUNLOCK(ErrorMessageLock);
4296 AT.WorkPointer = wp;
4297 if ( w[FUNHEAD] == -SNUMBER && w[FUNHEAD+1] == 0 && w[1] > FUNHEAD ) {
4303 if ( w + m1[1] + m2[1] > AT.WorkTop ) {
4304 MLOCK(ErrorMessageLock);
4305 MesPrint(
"SortBotMerge(%d): A Maxtermsize of %10l is too small",
4306 AT.identity,AM.MaxTer/
sizeof(WORD));
4307 MesPrint(
"m1[1] = %d, m2[1] = %d, Space = %l",m1[1],m2[1],(LONG)(AT.WorkTop-wp));
4308 PrintTerm(term1,
"term1");
4309 PrintTerm(term2,
"term2");
4310 MesPrint(
"PolyWise = %d",S->PolyWise);
4311 MUNLOCK(ErrorMessageLock);
4318 || ( w[FUNHEAD] == -SNUMBER && w[FUNHEAD+1] == 0 ) )
4320 if ( r1 == m1[1] ) {
4323 else if ( r1 < m1[1] ) {
4327 while ( --r1 >= 0 ) *--m1 = *--m2;
4330 while ( --r1 >= 0 ) *--m1 = *--m2;
4347 r1 = *( m1 += l1 - 1 );
4349 r1 = ( ( r1 > 0 ) ? (r1-1) : (r1+1) ) >> 1;
4350 r2 = *( m2 += l2 - 1 );
4352 r2 = ( ( r2 > 0 ) ? (r2-1) : (r2+1) ) >> 1;
4354 if ( AddRat(BHEAD (UWORD *)m1,r1,(UWORD *)m2,r2,coef,&r3) ) {
4355 MLOCK(ErrorMessageLock);
4356 MesCall(
"SortBotMerge");
4357 MUNLOCK(ErrorMessageLock);
4361 if ( AN.ncmod != 0 ) {
4362 if ( ( AC.modmode & POSNEG ) != 0 ) {
4365 else if ( BigLong(coef,r3,(UWORD *)AC.cmod,ABS(AN.ncmod)) >= 0 ) {
4366 SubPLon(coef,r3,(UWORD *)AC.cmod,ABS(AN.ncmod),coef,&r3);
4368 for ( ii = 1; ii < r3; ii++ ) coef[r3+ii] = 0;
4371 if ( !r3 ) {
goto cancelled; }
4373 r33 = ( r3 > 0 ) ? ( r3 + 1 ) : ( r3 - 1 );
4374 if ( r3 < 0 ) r3 = -r3;
4375 if ( r1 < 0 ) r1 = -r1;
4379 m2 = (WORD *)coef; im = r3;
4392 to = wp; from = term1;
4393 while ( from < m1 ) *to++ = *from++;
4394 from = (WORD *)coef; im = r3;
4398 if ( SortBotOut(BHEAD wp) < 0 ) {
4399 MLOCK(ErrorMessageLock);
4400 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4401 MUNLOCK(ErrorMessageLock);
4408 if ( SortBotOut(BHEAD term1) < 0 ) {
4409 MLOCK(ErrorMessageLock);
4410 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4411 MUNLOCK(ErrorMessageLock);
4418 if ( next >= Bin1->T.SB.MasterStop[blin1] || ( *next &&
4419 next+*next+COMPINC > Bin1->T.SB.MasterStop[blin1] ) ) {
4421 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4424 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4426 if ( blin1 == Bin1->T.SB.MasterNumBlocks ) {
4430 to = Bin1->T.SB.MasterStart[1];
4431 from = Bin1->T.SB.MasterStop[Bin1->T.SB.MasterNumBlocks];
4432 while ( from > next ) *--to = *--from;
4439 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4440 Bin1->T.SB.MasterBlock = blin1;
4457 if ( SortBotOut(BHEAD term1) < 0 ) {
4458 MLOCK(ErrorMessageLock);
4459 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4460 MUNLOCK(ErrorMessageLock);
4466 if ( next >= Bin1->T.SB.MasterStop[blin1] || ( *next &&
4467 next+*next+COMPINC > Bin1->T.SB.MasterStop[blin1] ) ) {
4469 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4472 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4474 if ( blin1 == Bin1->T.SB.MasterNumBlocks ) {
4478 to = Bin1->T.SB.MasterStart[1];
4479 from = Bin1->T.SB.MasterStop[Bin1->T.SB.MasterNumBlocks];
4480 while ( from > next ) *--to = *--from;
4487 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4488 Bin1->T.SB.MasterBlock = blin1;
4496 else if ( *term2 ) {
4501 if ( SortBotOut(BHEAD term2) < 0 ) {
4502 MLOCK(ErrorMessageLock);
4503 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4504 MUNLOCK(ErrorMessageLock);
4510 if ( next >= Bin2->T.SB.MasterStop[blin2] || ( *next
4511 && next+*next+COMPINC > Bin2->T.SB.MasterStop[blin2] ) ) {
4513 UNLOCK(Bin2->T.SB.MasterBlockLock[Bin2->T.SB.MasterNumBlocks]);
4516 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2-1]);
4518 if ( blin2 == Bin2->T.SB.MasterNumBlocks ) {
4522 to = Bin2->T.SB.MasterStart[1];
4523 from = Bin2->T.SB.MasterStop[Bin2->T.SB.MasterNumBlocks];
4524 while ( from > next ) *--to = *--from;
4531 LOCK(Bin2->T.SB.MasterBlockLock[blin2]);
4532 Bin2->T.SB.MasterBlock = blin2;
4540 SortBotOut(BHEAD 0);
4545 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4547 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4550 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4552 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2]);
4554 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2-1]);
4557 UNLOCK(Bin2->T.SB.MasterBlockLock[Bin2->T.SB.MasterNumBlocks]);
4559 if ( AT.identity > 0 ) {
4560 UNLOCK(AT.SB.MasterBlockLock[AT.SB.FillBlock]);
4575static int SortBlocksInitialized = 0;
4583int IniSortBlocks(
int numworkers)
4587 LONG totalsize, workersize, blocksize, numberofterms;
4589 int numberofblocks = NUMBEROFBLOCKSINSORT, numparts;
4592 if ( SortBlocksInitialized )
return(0);
4593 SortBlocksInitialized = 1;
4594 if ( numworkers == 0 )
return(0);
4597 if ( numworkers > 2 ) {
4598 numparts = 2*numworkers - 2;
4599 numberofblocks = numberofblocks/2;
4602 numparts = numworkers;
4605 numparts = numworkers;
4608 totalsize = S->LargeSize + S->SmallEsize;
4609 workersize = totalsize / numparts;
4610 maxter = AM.MaxTer/
sizeof(WORD);
4611 blocksize = ( workersize - maxter )/numberofblocks;
4612 numberofterms = blocksize / maxter;
4613 if ( numberofterms < MINIMUMNUMBEROFTERMS ) {
4617 MesPrint(
"We have a problem with the size of the blocks in IniSortBlocks");
4626 if ( w == 0 ) w = S->sBuffer;
4627 for (
id = 1;
id <= numparts;
id++ ) {
4629 AT.SB.MasterBlockLock = (pthread_mutex_t *)Malloc1(
4630 sizeof(pthread_mutex_t)*(numberofblocks+1),
"MasterBlockLock");
4631 AT.SB.MasterStart = (WORD **)Malloc1(
sizeof(WORD *)*(numberofblocks+1)*3,
"MasterBlock");
4632 AT.SB.MasterFill = AT.SB.MasterStart + (numberofblocks+1);
4633 AT.SB.MasterStop = AT.SB.MasterFill + (numberofblocks+1);
4634 AT.SB.MasterNumBlocks = numberofblocks;
4635 AT.SB.MasterBlock = 0;
4636 AT.SB.FillBlock = 0;
4637 AT.SB.MasterFill[0] = AT.SB.MasterStart[0] = w;
4639 AT.SB.MasterStop[0] = w;
4640 AT.SB.MasterBlockLock[0] = dummylock;
4641 for ( j = 1; j <= numberofblocks; j++ ) {
4642 AT.SB.MasterFill[j] = AT.SB.MasterStart[j] = w;
4644 AT.SB.MasterStop[j] = w;
4645 AT.SB.MasterBlockLock[j] = dummylock;
4648 if ( w > S->sTop2 ) {
4649 MesPrint(
"Counting problem in IniSortBlocks");
4667void DefineSortBotTree()
4671 if ( numberofworkers <= 2 )
return;
4672 n = numberofworkers*2-2;
4673 for ( i = numberofworkers+1, from = 1; i <= n; i++ ) {
4675 AT.SortBotIn1 = from++;
4676 AT.SortBotIn2 = from++;
4679 AT.SortBotIn1 = from++;
4680 AT.SortBotIn2 = from++;
4695WORD GetTerm2(PHEAD WORD *term)
4697 WORD *ttco, *tt, retval;
4700 EXPRESSIONS e = AN.expr;
4701 BRACKETINFO *b = e->bracketinfo;
4703 POSITION where, eonfile = AS.OldOnFile[e-Expressions], bstart, bnext;
4707 switch ( e->status ) {
4708 case UNHIDELEXPRESSION:
4709 case UNHIDEGEXPRESSION:
4710 case DROPHLEXPRESSION:
4711 case DROPHGEXPRESSION:
4712 case HIDDENLEXPRESSION:
4713 case HIDDENGEXPRESSION:
4720 if ( AR.KeptInHold ) {
4721 retval = GetTerm(BHEAD term);
4724 SeekScratch(fi,&where);
4725 if ( AN.lastinindex < 0 ) {
4729 if ( ( n = TreatIndexEntry(BHEAD 0) ) <= 0 ) {
4731 where = bi[n].start;
4732 ADD2POS(where,eonfile);
4733 SetScratch(fi,&where);
4737 ttco = AR.CompressBuffer;
4741 AR.CompressPointer = ttco;
4742 retval = GetTerm(BHEAD term);
4745 else AN.lastinindex = n-1;
4752 bstart = bi[n].start;
4753 ADD2POS(bstart,eonfile);
4755 ADD2POS(bnext,eonfile);
4756 if ( ISLESSPOS(bstart,where) && ISLESSPOS(where,bnext) ) {
4757 retval = GetTerm(BHEAD term);
4760 for ( n++ ; n < b->indexfill; n++ ) {
4761 i = TreatIndexEntry(BHEAD n);
4766 ttco = AR.CompressBuffer;
4770 AR.CompressPointer = ttco;
4772 where = bi[n].start;
4773 ADD2POS(where,eonfile);
4774 SetScratch(fi,&(where));
4775 retval = GetTerm(BHEAD term);
4795int TreatIndexEntry(PHEAD LONG n)
4797 BRACKETINFO *b = AN.expr->bracketinfo;
4798 LONG numbra = b->indexfill - 1, i;
4801 POSITION pos1, average;
4806 if ( ( numbra - n ) <= numberofworkers )
return(0);
4812 DIFPOS(pos1,bi[numbra].next,bi[n].next);
4813 BASEPOSITION(average) = DIVPOS(pos1,(3*numberofworkers));
4814 DIFPOS(pos1,bi[n].next,bi[n].start);
4815 if ( ISLESSPOS(average,pos1) )
return(0);
4820 totterms = bi->termsinbracket;
4821 if ( totterms > 2*AC.ThreadBucketSize )
return(1);
4822 for ( i = 1; i < numbra-n; i++ ) {
4823 DIFPOS(pos1,bi[n+i].next,bi[n].start);
4824 if ( ISLESSPOS(average,pos1) )
return(i);
4825 totterms += bi->termsinbracket;
4826 if ( totterms > 2*AC.ThreadBucketSize )
return(i+1);
4839void SetHideFiles() {
4841 ALLPRIVATES *B, *B0 = AB[0];
4842 for ( i = 1; i <= numberofworkers; i++ ) {
4844 AR.hidefile->handle = AR0.hidefile->handle;
4845 if ( AR.hidefile->handle < 0 ) {
4846 AR.hidefile->PObuffer = AR0.hidefile->PObuffer;
4847 AR.hidefile->POstop = AR0.hidefile->POstop;
4848 AR.hidefile->POfill = AR0.hidefile->POfill;
4849 AR.hidefile->POfull = AR0.hidefile->POfull;
4850 AR.hidefile->POsize = AR0.hidefile->POsize;
4851 AR.hidefile->POposition = AR0.hidefile->POposition;
4852 AR.hidefile->filesize = AR0.hidefile->filesize;
4855 AR.hidefile->PObuffer = AR.hidefile->wPObuffer;
4856 AR.hidefile->POstop = AR.hidefile->wPOstop;
4857 AR.hidefile->POfill = AR.hidefile->wPOfill;
4858 AR.hidefile->POfull = AR.hidefile->wPOfull;
4859 AR.hidefile->POsize = AR.hidefile->wPOsize;
4860 PUTZERO(AR.hidefile->POposition);
4873 for ( i = 0; i < AM.totalnumberofthreads; i++ ) {
4887 for ( j = 0; j < AM.totalnumberofthreads; j++ ) {
4889 AN.ncmod = AC.ncmod;
4890 if ( AN.cmod != 0 ) M_free(AN.cmod,
"AN.cmod");
4892 AN.cmod = (UWORD *)Malloc1(
sizeof(WORD)*n,
"AN.cmod");
4893 for ( i = 0; i < n; i++ ) AN.cmod[i] = AC.cmod[i];
4906 for ( j = 0; j < AM.totalnumberofthreads; j++ ) {
4908 if ( AN.cmod != 0 ) M_free(AN.cmod,
"AN.cmod");
4918void find_Horner_MCTS_expand_tree_threaded() {
4920 while ((
id = GetAvailableThread() ) < 0)
4922 WakeupThread(
id,MCTSEXPANDTREE);
4930extern void optimize_expression_given_Horner_threaded() {
4932 while ((
id = GetAvailableThread() ) < 0)
4934 WakeupThread(
id,OPTIMIZEEXPRESSION);
WORD * poly_ratfun_add(PHEAD WORD *, WORD *)
int poly_unfactorize_expression(EXPRESSIONS)
VOID WriteStats(POSITION *, WORD)
WORD PutOut(PHEAD WORD *, POSITION *, FILEHANDLE *, WORD)
LONG EndSort(PHEAD WORD *, int)
WORD Generator(PHEAD WORD *, WORD)
WORD StoreTerm(PHEAD WORD *)
int poly_factorize_expression(EXPRESSIONS)
VOID AddArgs(PHEAD WORD *, WORD *, WORD *)
int NormalModulus(UWORD *, WORD *)
WORD FlushOut(POSITION *, FILEHANDLE *, int)
WORD Compare1(WORD *, WORD *, WORD)
void optimize_expression_given_Horner()
BRACKETINDEX * indexbuffer
struct StOrEcAcHe * STORECACHE