66 static int numberofthreads;
67 static int numberofworkers;
68 static int identityofthreads = 0;
69 static int *listofavailables;
70 static int topofavailables = 0;
71 static pthread_key_t identitykey;
72 static INILOCK(numberofthreadslock);
73 static INILOCK(availabilitylock);
74 static pthread_t *threadpointers = 0;
75 static pthread_mutex_t *wakeuplocks;
76 static pthread_mutex_t *wakeupmasterthreadlocks;
77 static pthread_cond_t *wakeupconditions;
78 static pthread_condattr_t *wakeupconditionattributes;
80 static int *wakeupmasterthread;
81 static INILOCK(wakeupmasterlock);
82 static pthread_cond_t wakeupmasterconditions = PTHREAD_COND_INITIALIZER;
83 static pthread_cond_t *wakeupmasterthreadconditions;
84 static int wakeupmaster = 0;
85 static int identityretval;
87 static LONG *timerinfo;
88 static LONG *sumtimerinfo;
89 static int numberclaimed;
91 static THREADBUCKET **threadbuckets, **freebuckets;
92 static int numthreadbuckets;
93 static int numberoffullbuckets;
98 INIRWLOCK(dummyrwlock);
99 static pthread_cond_t dummywakeupcondition = PTHREAD_COND_INITIALIZER;
103 static int numberofsortbots;
104 static INILOCK(wakeupsortbotlock);
105 static pthread_cond_t wakeupsortbotconditions = PTHREAD_COND_INITIALIZER;
106 static int topsortbotavailables = 0;
107 static LONG numberofterms;
122 pthread_key_create(&identitykey,FinishIdentity);
133 void FinishIdentity(
void *keyp)
147 int 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);
205 VOID BeginIdentities()
208 SetIdentity(&identityretval);
222 void StartHandleLock()
224 AM.handlelock = dummyrwlock;
248 int 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);
343 UBYTE *scratchname[] = { (UBYTE *)
"scratchsize",
344 (UBYTE *)
"scratchsize",
345 (UBYTE *)
"hidesize" };
372 ALLPRIVATES *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;
492 if ( identity == 0 && AN.SoScratC == 0 ) {
493 AN.SoScratC = (UWORD *)Malloc1(2*(AM.MaxTal+2)*
sizeof(UWORD),
"Scratch in SortBot");
496 AR.CurDum = AM.IndDum;
497 for ( j = 0; j < 3; j++ ) {
498 if ( identity == 0 ) {
500 ScratchSize[j] = AM.HideSize;
503 ScratchSize[j] = AM.ScratSize;
505 if ( ScratchSize[j] < 10*AM.MaxTer ) ScratchSize[j] = 10 * AM.MaxTer;
513 if ( j == 1 ) ScratchSize[j] = AM.ThreadScratOutSize;
514 else ScratchSize[j] = AM.ThreadScratSize;
515 if ( ScratchSize[j] < 4*AM.MaxTer ) ScratchSize[j] = 4 * AM.MaxTer;
518 ScratchSize[j] = ( ScratchSize[j] + 255 ) / 256;
519 ScratchSize[j] = ScratchSize[j] * 256;
520 ScratchBuf = (WORD *)Malloc1(ScratchSize[j]*
sizeof(WORD),(
char *)(scratchname[j]));
521 AR.Fscr[j].POsize = ScratchSize[j] *
sizeof(WORD);
522 AR.Fscr[j].POfull = AR.Fscr[j].POfill = AR.Fscr[j].PObuffer = ScratchBuf;
523 AR.Fscr[j].POstop = AR.Fscr[j].PObuffer + ScratchSize[j];
524 PUTZERO(AR.Fscr[j].POposition);
525 AR.Fscr[j].pthreadslock = dummylock;
526 AR.Fscr[j].wPOsize = AR.Fscr[j].POsize;
527 AR.Fscr[j].wPObuffer = AR.Fscr[j].PObuffer;
528 AR.Fscr[j].wPOfill = AR.Fscr[j].POfill;
529 AR.Fscr[j].wPOfull = AR.Fscr[j].POfull;
530 AR.Fscr[j].wPOstop = AR.Fscr[j].POstop;
534 AR.Fscr[0].handle = -1;
535 AR.Fscr[1].handle = -1;
536 AR.Fscr[2].handle = -1;
537 AR.FoStage4[0].handle = -1;
538 AR.FoStage4[1].handle = -1;
539 IOsize = AM.S0->file.POsize;
541 AR.FoStage4[0].ziosize = IOsize;
542 AR.FoStage4[1].ziosize = IOsize;
544 AR.FoStage4[0].POsize = ((IOsize+
sizeof(WORD)-1)/
sizeof(WORD))*
sizeof(WORD);
545 AR.FoStage4[1].POsize = ((IOsize+
sizeof(WORD)-1)/
sizeof(WORD))*
sizeof(WORD);
547 AR.hidefile = &(AR.Fscr[2]);
548 AR.StoreData.Handle = -1;
549 AR.SortType = AC.SortType;
551 AN.IndDum = AM.IndDum;
553 if ( identity > 0 ) {
554 s = (UBYTE *)(FG.fname); i = 0;
555 while ( *s ) { s++; i++; }
556 s = (UBYTE *)Malloc1(
sizeof(
char)*(i+12),
"name for Fscr[0] file");
557 sprintf((
char *)s,
"%s.%d",FG.fname,identity);
558 s[i-3] =
's'; s[i-2] =
'c'; s[i-1] =
'0';
559 AR.Fscr[0].name = (
char *)s;
560 s = (UBYTE *)(FG.fname); i = 0;
561 while ( *s ) { s++; i++; }
562 s = (UBYTE *)Malloc1(
sizeof(
char)*(i+12),
"name for Fscr[1] file");
563 sprintf((
char *)s,
"%s.%d",FG.fname,identity);
564 s[i-3] =
's'; s[i-2] =
'c'; s[i-1] =
'1';
565 AR.Fscr[1].name = (
char *)s;
568 AR.CompressBuffer = (WORD *)Malloc1((AM.CompressSize+10)*
sizeof(WORD),
"compresssize");
569 AR.ComprTop = AR.CompressBuffer + AM.CompressSize;
575 AT.WorkSpace = (WORD *)Malloc1(AM.WorkSize*
sizeof(WORD),
"WorkSpace");
576 AT.WorkTop = AT.WorkSpace + AM.WorkSize;
577 AT.WorkPointer = AT.WorkSpace;
579 AT.n_coef = (WORD *)Malloc1(
sizeof(WORD)*4*AM.MaxTal+2,
"maxnumbersize");
580 AT.n_llnum = AT.n_coef + 2*AM.MaxTal;
582 AT.Nest = (
NESTING)Malloc1((LONG)
sizeof(
struct NeStInG)*AM.maxFlevels,
"functionlevels");
583 AT.NestStop = AT.Nest + AM.maxFlevels;
584 AT.NestPoin = AT.Nest;
586 AT.WildMask = (WORD *)Malloc1((LONG)AM.MaxWildcards*
sizeof(WORD),
"maxwildcards");
588 LOCK(availabilitylock);
589 AT.ebufnum = inicbufs();
590 AT.fbufnum = inicbufs();
591 UNLOCK(availabilitylock);
593 AT.RepCount = (
int *)Malloc1((LONG)((AM.RepMax+3)*
sizeof(
int)),
"repeat buffers");
594 AN.RepPoint = AT.RepCount;
597 AT.RepTop = AT.RepCount + AM.RepMax;
599 AT.WildArgTaken = (WORD *)Malloc1((LONG)AC.WildcardBufferSize*
sizeof(WORD)/2
600 ,
"argument list names");
601 AT.WildcardBufferSize = AC.WildcardBufferSize;
602 AT.previousEfactor = 0;
604 AT.identity = identity;
605 AT.LoadBalancing = 0;
611 if ( AT.WorkSpace == 0 ||
616 AT.WildArgTaken == 0 )
goto OnError;
621 AT.comsym[1] = SYMBOL;
632 AT.comfun[0] = FUNHEAD+4;
633 AT.comfun[1] = FUNCTION;
634 AT.comfun[2] = FUNHEAD;
637 for ( i = 4; i <= FUNHEAD; i++ )
640 AT.comfun[FUNHEAD+1] = 1;
641 AT.comfun[FUNHEAD+2] = 1;
642 AT.comfun[FUNHEAD+3] = 3;
644 AT.comind[1] = INDEX;
650 AT.locwildvalue[0] = SUBEXPRESSION;
651 AT.locwildvalue[1] = SUBEXPSIZE;
652 for ( i = 2; i < SUBEXPSIZE; i++ ) AT.locwildvalue[i] = 0;
653 AT.mulpat[0] = TYPEMULT;
654 AT.mulpat[1] = SUBEXPSIZE+3;
656 AT.mulpat[3] = SUBEXPRESSION;
657 AT.mulpat[4] = SUBEXPSIZE;
660 for ( i = 7; i < SUBEXPSIZE+5; i++ ) AT.mulpat[i] = 0;
661 AT.proexp[0] = SUBEXPSIZE+4;
662 AT.proexp[1] = EXPRESSION;
663 AT.proexp[2] = SUBEXPSIZE;
666 for ( i = 5; i < SUBEXPSIZE+1; i++ ) AT.proexp[i] = 0;
667 AT.proexp[SUBEXPSIZE+1] = 1;
668 AT.proexp[SUBEXPSIZE+2] = 1;
669 AT.proexp[SUBEXPSIZE+3] = 3;
670 AT.proexp[SUBEXPSIZE+4] = 0;
671 AT.dummysubexp[0] = SUBEXPRESSION;
672 AT.dummysubexp[1] = SUBEXPSIZE+4;
673 for ( i = 2; i < SUBEXPSIZE; i++ ) AT.dummysubexp[i] = 0;
674 AT.dummysubexp[SUBEXPSIZE] = WILDDUMMY;
675 AT.dummysubexp[SUBEXPSIZE+1] = 4;
676 AT.dummysubexp[SUBEXPSIZE+2] = 0;
677 AT.dummysubexp[SUBEXPSIZE+3] = 0;
679 AT.MinVecArg[0] = 7+ARGHEAD;
680 AT.MinVecArg[ARGHEAD] = 7;
681 AT.MinVecArg[1+ARGHEAD] = INDEX;
682 AT.MinVecArg[2+ARGHEAD] = 3;
683 AT.MinVecArg[3+ARGHEAD] = 0;
684 AT.MinVecArg[4+ARGHEAD] = 1;
685 AT.MinVecArg[5+ARGHEAD] = 1;
686 AT.MinVecArg[6+ARGHEAD] = -3;
688 *t++ = 4+ARGHEAD+FUNHEAD;
689 for ( i = 1; i < ARGHEAD; i++ ) *t++ = 0;
693 for ( i = 2; i < FUNHEAD; i++ ) *t++ = 0;
694 *t++ = 1; *t++ = 1; *t++ = 3;
697 AT.sizeprimelist = 0;
699 AT.nfac = AT.nBer = 0;
704 AR.wranfnpair1 = NPAIR1;
705 AR.wranfnpair2 = NPAIR2;
708 AN.SplitScratchSize = AN.InScratch = 0;
709 AN.SplitScratch1 = 0;
710 AN.SplitScratchSize1 = AN.InScratch1 = 0;
715 if ( identity == 0 ) {
723 AT.S0 = AllocSort(AM.S0->LargeSize*
sizeof(WORD)/numberofworkers
724 ,AM.S0->SmallSize*
sizeof(WORD)/numberofworkers
725 ,AM.S0->SmallEsize*
sizeof(WORD)/numberofworkers
729 ,AM.S0->MaxFpatches/numberofworkers
730 ,AM.S0->file.POsize);
732 AR.CompressPointer = AR.CompressBuffer;
736 AT.StoreCache = AT.StoreCacheAlloc = 0;
737 if ( AM.NumStoreCaches > 0 ) {
740 size =
sizeof(
struct StOrEcAcHe)+AM.SizeStoreCache;
741 size = ((size-1)/
sizeof(
size_t)+1)*
sizeof(
size_t);
742 AT.StoreCacheAlloc = (
STORECACHE)Malloc1(size*AM.NumStoreCaches,
"StoreCaches");
743 sa = AT.StoreCache = AT.StoreCacheAlloc;
744 for ( i = 0; i < AM.NumStoreCaches; i++ ) {
746 if ( i == AM.NumStoreCaches-1 ) {
752 SETBASEPOSITION(sa->position,-1);
753 SETBASEPOSITION(sa->toppos,-1);
761 MLOCK(ErrorMessageLock);
762 MesPrint(
"Error initializing thread %d",identity);
763 MUNLOCK(ErrorMessageLock);
782 void FinalizeOneThread(
int identity)
784 timerinfo[identity] = TimeCPU(1);
797 VOID ClearAllThreads()
801 for ( i = 1; i <= numberofworkers; i++ ) {
802 WakeupThread(i,CLEARCLOCK);
805 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
806 WakeupThread(i,CLEARCLOCK);
821 VOID TerminateAllThreads()
824 for ( i = 1; i <= numberofworkers; i++ ) {
826 WakeupThread(i,TERMINATETHREAD);
829 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
830 WakeupThread(i,TERMINATETHREAD);
833 for ( i = 1; i <= numberofworkers; i++ ) {
834 pthread_join(threadpointers[i],NULL);
837 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
838 pthread_join(threadpointers[i],NULL);
872 int MakeThreadBuckets(
int number,
int par)
875 LONG sizethreadbuckets;
880 sizethreadbuckets = ( AC.ThreadBucketSize + 1 ) * AM.MaxTer + 2;
881 if ( AC.ThreadBucketSize >= 250 ) sizethreadbuckets /= 4;
882 else if ( AC.ThreadBucketSize >= 90 ) sizethreadbuckets /= 3;
883 else if ( AC.ThreadBucketSize >= 40 ) sizethreadbuckets /= 2;
886 numthreadbuckets = 2*(number-1);
887 threadbuckets = (THREADBUCKET **)Malloc1(numthreadbuckets*
sizeof(THREADBUCKET *),
"threadbuckets");
888 freebuckets = (THREADBUCKET **)Malloc1(numthreadbuckets*
sizeof(THREADBUCKET *),
"threadbuckets");
891 if ( sizethreadbuckets <= threadbuckets[0]->threadbuffersize )
return(0);
892 for ( i = 0; i < numthreadbuckets; i++ ) {
893 thr = threadbuckets[i];
894 M_free(thr->deferbuffer,
"deferbuffer");
898 for ( i = 0; i < numthreadbuckets; i++ ) {
899 threadbuckets[i] = (THREADBUCKET *)Malloc1(
sizeof(THREADBUCKET),
"threadbuckets");
900 threadbuckets[i]->lock = dummylock;
903 for ( i = 0; i < numthreadbuckets; i++ ) {
904 thr = threadbuckets[i];
905 thr->threadbuffersize = sizethreadbuckets;
906 thr->free = BUCKETFREE;
907 thr->deferbuffer = (
POSITION *)Malloc1(2*sizethreadbuckets*
sizeof(WORD)
908 +(AC.ThreadBucketSize+1)*
sizeof(
POSITION),
"deferbuffer");
909 thr->threadbuffer = (WORD *)(thr->deferbuffer+AC.ThreadBucketSize+1);
910 thr->compressbuffer = (WORD *)(thr->threadbuffer+sizethreadbuckets);
911 thr->busy = BUCKETPREPARINGTERM;
912 thr->usenum = thr->totnum = 0;
913 thr->type = BUCKETDOINGTERMS;
928 int GetTimerInfo(LONG** ti,LONG** sti)
933 return AM.totalnumberofthreads*2;
935 return AM.totalnumberofthreads;
948 void WriteTimerInfo(LONG* ti,LONG* sti)
952 int max = AM.totalnumberofthreads*2;
954 int max = AM.totalnumberofthreads;
956 for ( i=0; i<max; ++i ) {
957 timerinfo[i] = ti[i];
958 sumtimerinfo[i] = sti[i];
971 LONG GetWorkerTimes()
975 for ( i = 1; i <= numberofworkers; i++ ) retval += timerinfo[i] + sumtimerinfo[i];
977 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ )
978 retval += timerinfo[i] + sumtimerinfo[i];
993 int UpdateOneThread(
int identity)
995 ALLPRIVATES *B = AB[identity], *B0 = AB[0];
996 AR.GetFile = AR0.GetFile;
997 AR.KeptInHold = AR0.KeptInHold;
998 AR.CurExpr = AR0.CurExpr;
999 AR.SortType = AC.SortType;
1000 if ( AT.WildcardBufferSize < AC.WildcardBufferSize ) {
1001 M_free(AT.WildArgTaken,
"argument list names");
1002 AT.WildcardBufferSize = AC.WildcardBufferSize;
1003 AT.WildArgTaken = (WORD *)Malloc1((LONG)AC.WildcardBufferSize*
sizeof(WORD)/2
1004 ,
"argument list names");
1005 if ( AT.WildArgTaken == 0 )
return(-1);
1027 int LoadOneThread(
int from,
int identity, THREADBUCKET *thr,
int par)
1030 ALLPRIVATES *B = AB[identity], *B0 = AB[from];
1032 AR.DefPosition = AR0.DefPosition;
1033 AR.NoCompress = AR0.NoCompress;
1034 AR.gzipCompress = AR0.gzipCompress;
1035 AR.BracketOn = AR0.BracketOn;
1036 AR.CurDum = AR0.CurDum;
1037 AR.DeferFlag = AR0.DeferFlag;
1039 AR.sLevel = AR0.sLevel;
1040 AR.Stage4Name = AR0.Stage4Name;
1041 AR.GetOneFile = AR0.GetOneFile;
1042 AR.PolyFun = AR0.PolyFun;
1043 AR.PolyFunType = AR0.PolyFunType;
1044 AR.Eside = AR0.Eside;
1045 AR.Cnumlhs = AR0.Cnumlhs;
1057 t1 = AR.CompressBuffer; t2 = AR0.CompressBuffer;
1058 while ( t2 < AR0.CompressPointer ) *t1++ = *t2++;
1059 AR.CompressPointer = t1;
1063 AR.CompressPointer = AR.CompressBuffer;
1065 if ( AR.DeferFlag ) {
1066 if ( AR.infile->handle < 0 ) {
1067 AR.infile->POfill = AR0.infile->POfill;
1074 AR.infile->POfull = AR.infile->POfill = AR.infile->PObuffer;
1078 AN.threadbuck = thr;
1079 AN.ninterms = thr->firstterm;
1081 else if ( par == 1 ) {
1083 t1 = thr->threadbuffer; tstop = t1 + *t1;
1084 t2 = AT.WorkPointer;
1085 while ( t1 < tstop ) *t2++ = *t1++;
1086 AN.ninterms = thr->firstterm;
1089 AN.ncmod = AC.ncmod;
1090 AT.BrackBuf = AT0.BrackBuf;
1091 AT.bracketindexflag = AT0.bracketindexflag;
1118 int BalanceRunThread(
PHEAD int identity, WORD *term, WORD level)
1125 LoadOneThread(AT.identity,identity,0,2);
1131 BB->R.level = level;
1132 BB->T.TMbuff = AT.TMbuff;
1133 ti = AT.RepCount; tti = BB->T.RepCount;
1134 i = AN.RepPoint - AT.RepCount;
1135 BB->N.RepPoint = BB->T.RepCount + i;
1136 for ( ; i >= 0; i-- ) tti[i] = ti[i];
1138 t = term; i = *term;
1139 tt = BB->T.WorkSpace;
1141 BB->T.WorkPointer = tt;
1143 WakeupThread(identity,HIGHERLEVELGENERATION);
1156 void SetWorkerFiles()
1159 ALLPRIVATES *B, *B0 = AB[0];
1160 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
1162 AR.infile = &(AR.Fscr[0]);
1163 AR.outfile = &(AR.Fscr[1]);
1164 AR.hidefile = &(AR.Fscr[2]);
1165 AR.infile->handle = AR0.infile->handle;
1166 AR.hidefile->handle = AR0.hidefile->handle;
1167 if ( AR.infile->handle < 0 ) {
1168 AR.infile->PObuffer = AR0.infile->PObuffer;
1169 AR.infile->POstop = AR0.infile->POstop;
1170 AR.infile->POfill = AR0.infile->POfill;
1171 AR.infile->POfull = AR0.infile->POfull;
1172 AR.infile->POsize = AR0.infile->POsize;
1173 AR.InInBuf = AR0.InInBuf;
1174 AR.infile->POposition = AR0.infile->POposition;
1175 AR.infile->filesize = AR0.infile->filesize;
1178 AR.infile->PObuffer = AR.infile->wPObuffer;
1179 AR.infile->POstop = AR.infile->wPOstop;
1180 AR.infile->POfill = AR.infile->wPOfill;
1181 AR.infile->POfull = AR.infile->wPOfull;
1182 AR.infile->POsize = AR.infile->wPOsize;
1184 PUTZERO(AR.infile->POposition);
1192 AR.outfile->PObuffer = AR.outfile->wPObuffer;
1193 AR.outfile->POstop = AR.outfile->wPOstop;
1194 AR.outfile->POfill = AR.outfile->wPOfill;
1195 AR.outfile->POfull = AR.outfile->wPOfull;
1196 AR.outfile->POsize = AR.outfile->wPOsize;
1197 PUTZERO(AR.outfile->POposition);
1199 if ( AR.hidefile->handle < 0 ) {
1200 AR.hidefile->PObuffer = AR0.hidefile->PObuffer;
1201 AR.hidefile->POstop = AR0.hidefile->POstop;
1202 AR.hidefile->POfill = AR0.hidefile->POfill;
1203 AR.hidefile->POfull = AR0.hidefile->POfull;
1204 AR.hidefile->POsize = AR0.hidefile->POsize;
1205 AR.InHiBuf = AR0.InHiBuf;
1206 AR.hidefile->POposition = AR0.hidefile->POposition;
1207 AR.hidefile->filesize = AR0.hidefile->filesize;
1210 AR.hidefile->PObuffer = AR.hidefile->wPObuffer;
1211 AR.hidefile->POstop = AR.hidefile->wPOstop;
1212 AR.hidefile->POfill = AR.hidefile->wPOfill;
1213 AR.hidefile->POfull = AR.hidefile->wPOfull;
1214 AR.hidefile->POsize = AR.hidefile->wPOsize;
1216 PUTZERO(AR.hidefile->POposition);
1219 if ( AR0.StoreData.dirtyflag ) {
1220 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
1222 AR.StoreData = AR0.StoreData;
1238 void *RunThread(
void *dummy)
1240 WORD *term, *ttin, *tt, *ttco, *oldwork;
1241 int identity, wakeupsignal, identityretv, i, tobereleased, errorcode;
1247 identity = SetIdentity(&identityretv);
1248 threadpointers[identity] = pthread_self();
1249 B = InitializeOneThread(identity);
1250 while ( ( wakeupsignal = ThreadWait(identity) ) > 0 ) {
1251 switch ( wakeupsignal ) {
1255 case STARTNEWEXPRESSION:
1260 if ( UpdateOneThread(identity) ) {
1261 MLOCK(ErrorMessageLock);
1262 MesPrint(
"Update error in starting expression in thread %d in module %d",identity,AC.CModule);
1263 MUNLOCK(ErrorMessageLock);
1266 AR.DeferFlag = AC.ComDefer;
1267 AR.sLevel = AS.sLevel;
1268 AR.MaxDum = AM.IndDum;
1269 AR.expchanged = AB[0]->R.expchanged;
1270 AR.expflags = AB[0]->R.expflags;
1280 case LOWESTLEVELGENERATION:
1281 e = Expressions + AR.CurExpr;
1282 thr = AN.threadbuck;
1283 ppdef = thr->deferbuffer;
1284 ttin = thr->threadbuffer;
1285 ttco = thr->compressbuffer;
1286 term = AT.WorkPointer;
1289 AN.inputnumber = thr->firstterm;
1290 AN.ninterms = thr->firstterm;
1293 tt = term; i = *ttin;
1295 AT.WorkPointer = tt;
1296 if ( AR.DeferFlag ) {
1297 tt = AR.CompressBuffer; i = *ttco;
1299 AR.CompressPointer = tt;
1300 AR.DefPosition = ppdef[0]; ppdef++;
1302 if ( thr->free == BUCKETTERMINATED ) {
1310 if ( thr->usenum == thr->totnum ) {
1311 thr->free = BUCKETCOMINGFREE;
1314 thr->free = BUCKETRELEASED;
1324 thr->busy = BUCKETDOINGTERM;
1332 AN.RepPoint = AT.RepCount + 1;
1334 if ( ( e->vflags & ISFACTORIZED ) != 0 && term[1] == HAAKJE ) {
1338 if ( AR.DeferFlag ) {
1339 AR.CurDum = AN.IndDum = Expressions[AR.CurExpr].numdummies + AM.IndDum;
1342 AN.IndDum = AM.IndDum;
1343 AR.CurDum = ReNumber(BHEAD term);
1345 if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
1347 if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1348 else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1350 if ( ( AP.PreDebug & THREADSDEBUG ) != 0 ) {
1351 MLOCK(ErrorMessageLock);
1352 MesPrint(
"Thread %w executing term:");
1353 PrintTerm(term,
"LLG");
1354 MUNLOCK(ErrorMessageLock);
1356 if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
1357 && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1358 PolyFunClean(BHEAD term);
1362 MLOCK(ErrorMessageLock);
1363 MesPrint(
"Error in processing one term in thread %d in module %d",identity,AC.CModule);
1364 MUNLOCK(ErrorMessageLock);
1371 thr->busy = BUCKETPREPARINGTERM;
1379 if ( thr->free == BUCKETTERMINATED ) {
1380 if ( thr->usenum == thr->totnum ) {
1381 thr->free = BUCKETCOMINGFREE;
1384 thr->free = BUCKETRELEASED;
1388 if ( tobereleased )
goto bucketstolen;
1390 thr->free = BUCKETCOMINGFREE;
1394 thr->busy = BUCKETTOBERELEASED;
1401 AT.WorkPointer = term;
1409 LOCK(AT.SB.MasterBlockLock[1]);
1412 case FINISHEXPRESSION:
1420 LOCK(AT.SB.MasterBlockLock[1]);
1421 ThreadClaimedBlock(identity);
1426 case FINISHEXPRESSION2:
1431 if ( AC.ThreadSortFileSynch ) {
1432 if ( AT.S0->file.handle >= 0 ) {
1433 SynchFile(AT.S0->file.handle);
1436 AT.SB.FillBlock = 1;
1437 AT.SB.MasterFill[1] = AT.SB.MasterStart[1];
1438 errorcode =
EndSort(BHEAD AT.S0->sBuffer,0);
1439 UNLOCK(AT.SB.MasterBlockLock[AT.SB.FillBlock]);
1442 MLOCK(ErrorMessageLock);
1443 MesPrint(
"Error terminating sort in thread %d in module %d",identity,AC.CModule);
1444 MUNLOCK(ErrorMessageLock);
1452 case CLEANUPEXPRESSION:
1456 if ( AR.outfile->handle >= 0 ) {
1457 CloseFile(AR.outfile->handle);
1458 AR.outfile->handle = -1;
1459 remove(AR.outfile->name);
1460 AR.outfile->POfill = AR.outfile->POfull = AR.outfile->PObuffer;
1461 PUTZERO(AR.outfile->POposition);
1462 PUTZERO(AR.outfile->filesize);
1465 AR.outfile->POfill = AR.outfile->POfull = AR.outfile->PObuffer;
1466 PUTZERO(AR.outfile->POposition);
1467 PUTZERO(AR.outfile->filesize);
1470 CBUF *C = cbuf+AT.ebufnum;
1472 if ( C->numrhs > 0 || C->numlhs > 0 ) {
1474 w = C->
rhs; ii = C->numrhs;
1475 do { *w++ = 0; }
while ( --ii > 0 );
1478 w = C->
lhs; ii = C->numlhs;
1479 do { *w++ = 0; }
while ( --ii > 0 );
1481 C->numlhs = C->numrhs = 0;
1482 ClearTree(AT.ebufnum);
1491 case HIGHERLEVELGENERATION:
1496 term = AT.WorkSpace; AT.WorkPointer = term + *term;
1499 MLOCK(ErrorMessageLock);
1500 MesPrint(
"Error in load balancing one term at level %d in thread %d in module %d",AR.level,AT.identity,AC.CModule);
1501 MUNLOCK(ErrorMessageLock);
1504 AT.WorkPointer = term;
1510 case STARTNEWMODULE:
1520 case TERMINATETHREAD:
1538 case DOONEEXPRESSION: {
1543 WORD oldBracketOn = AR.BracketOn;
1544 WORD *oldBrackBuf = AT.BrackBuf;
1545 WORD oldbracketindexflag = AT.bracketindexflag;
1546 e = Expressions + AR.exprtodo;
1549 AR.SortType = AC.SortType;
1551 if ( ( e->vflags & ISFACTORIZED ) != 0 ) {
1553 AT.BrackBuf = AM.BracketFactors;
1554 AT.bracketindexflag = 1;
1557 position = AS.OldOnFile[i];
1558 if ( e->status == HIDDENLEXPRESSION || e->status == HIDDENGEXPRESSION ) {
1559 AR.GetFile = 2; fi = AR.hidefile;
1562 AR.GetFile = 0; fi = AR.infile;
1570 SetScratch(fi,&position);
1571 term = oldwork = AT.WorkPointer;
1572 AR.CompressPointer = AR.CompressBuffer;
1573 AR.CompressPointer[0] = 0;
1575 if ( GetTerm(BHEAD term) <= 0 ) {
1576 MLOCK(ErrorMessageLock);
1577 MesPrint(
"Expression %d has problems in scratchfile (t)",i);
1578 MUNLOCK(ErrorMessageLock);
1581 if ( AT.bracketindexflag > 0 ) OpenBracketIndex(i);
1583 PUTZERO(outposition);
1585 fout->POfill = fout->POfull = fout->PObuffer;
1586 fout->POposition = outposition;
1587 if ( fout->
handle >= 0 ) {
1588 fout->POposition = outposition;
1600 if (
PutOut(BHEAD term,&outposition,fout,0) < 0 )
goto ProcErr;
1602 AR.DeferFlag = AC.ComDefer;
1604 AR.sLevel = AB[0]->R.sLevel;
1605 term = AT.WorkPointer;
1607 AR.MaxDum = AM.IndDum;
1609 while ( GetTerm(BHEAD term) ) {
1610 SeekScratch(fi,&position);
1611 AN.ninterms++; dd = AN.deferskipped;
1612 if ( ( e->vflags & ISFACTORIZED ) != 0 && term[1] == HAAKJE ) {
1616 if ( AC.CollectFun && *term <= (AM.MaxTer/(2*(LONG)
sizeof(WORD))) ) {
1617 if ( GetMoreTerms(term) < 0 ) {
1620 SeekScratch(fi,&position);
1622 AT.WorkPointer = term + *term;
1623 AN.RepPoint = AT.RepCount + 1;
1624 if ( AR.DeferFlag ) {
1625 AR.CurDum = AN.IndDum = Expressions[AR.exprtodo].numdummies;
1628 AN.IndDum = AM.IndDum;
1629 AR.CurDum = ReNumber(BHEAD term);
1631 if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
1633 if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1634 else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1636 if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
1637 && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1638 PolyFunClean(BHEAD term);
1645 SetScratch(fi,&position);
1646 if ( fi == AR.hidefile ) {
1647 AR.InHiBuf = (fi->POfull-fi->PObuffer)
1648 -DIFBASE(position,fi->POposition)/
sizeof(WORD);
1651 AR.InInBuf = (fi->POfull-fi->PObuffer)
1652 -DIFBASE(position,fi->POposition)/
sizeof(WORD);
1656 if (
EndSort(BHEAD AT.S0->sBuffer,0) < 0 )
goto ProcErr;
1657 e->numdummies = AR.MaxDum - AM.IndDum;
1658 AR.BracketOn = oldBracketOn;
1659 AT.BrackBuf = oldBrackBuf;
1660 if ( ( e->vflags & TOBEFACTORED ) != 0 )
1661 poly_factorize_expression(e);
1662 else if ( ( ( e->vflags & TOBEUNFACTORED ) != 0 )
1663 && ( ( e->vflags & ISFACTORIZED ) != 0 ) )
1664 poly_unfactorize_expression(e);
1665 if ( AT.S0->TermsLeft ) e->vflags &= ~ISZERO;
1666 else e->vflags |= ISZERO;
1667 if ( AR.expchanged == 0 ) e->vflags |= ISUNMODIFIED;
1668 if ( AT.S0->TermsLeft ) AR.expflags |= ISZERO;
1669 if ( AR.expchanged ) AR.expflags |= ISUNMODIFIED;
1671 AT.bracketindexflag = oldbracketindexflag;
1676 SeekScratch(fout,&outposition);
1677 LOCK(AS.outputslock);
1678 oldoutfile = AB[0]->R.outfile;
1679 if ( e->status == INTOHIDELEXPRESSION || e->status == INTOHIDEGEXPRESSION ) {
1680 AB[0]->R.outfile = AB[0]->R.hidefile;
1682 SeekScratch(AB[0]->R.outfile,&position);
1683 e->onfile = position;
1684 if ( CopyExpression(fout,AB[0]->R.outfile) < 0 ) {
1685 AB[0]->R.outfile = oldoutfile;
1686 UNLOCK(AS.outputslock);
1687 MLOCK(ErrorMessageLock);
1688 MesPrint(
"Error copying output of 'InParallel' expression to master. Thread: %d",identity);
1689 MUNLOCK(ErrorMessageLock);
1692 AB[0]->R.outfile = oldoutfile;
1693 AB[0]->R.hidefile->POfull = AB[0]->R.hidefile->POfill;
1694 UNLOCK(AS.outputslock);
1696 if ( fout->
handle >= 0 ) {
1700 PUTZERO(fout->POposition);
1701 PUTZERO(fout->filesize);
1702 fout->POfill = fout->POfull = fout->PObuffer;
1706 AT.WorkPointer = oldwork;
1730 e = Expressions + AR.CurExpr;
1731 binfo = e->bracketinfo;
1732 thr = AN.threadbuck;
1734 if ( AR.GetFile == 2 ) fi = AR.hidefile;
1735 else fi = AR.infile;
1737 ADD2POS(where,AS.OldOnFile[AR.CurExpr]);
1738 SetScratch(fi,&(where));
1739 stoppos = binfo->
indexbuffer[thr->lastbracket].next;
1740 ADD2POS(stoppos,AS.OldOnFile[AR.CurExpr]);
1741 AN.ninterms = thr->firstterm;
1746 ttco = AR.CompressBuffer;
1750 AR.CompressPointer = ttco;
1751 term = AT.WorkPointer;
1752 while ( GetTerm(BHEAD term) ) {
1753 AT.WorkPointer = term + *term;
1754 AN.IndDum = AM.IndDum;
1755 AR.CurDum = ReNumber(BHEAD term);
1756 if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
1758 if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1759 else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1761 if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
1762 && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1763 PolyFunClean(BHEAD term);
1765 if ( ( AP.PreDebug & THREADSDEBUG ) != 0 ) {
1766 MLOCK(ErrorMessageLock);
1767 MesPrint(
"Thread %w executing term:");
1768 PrintTerm(term,
"DoBrackets");
1769 MUNLOCK(ErrorMessageLock);
1771 AT.WorkPointer = term + *term;
1774 MLOCK(ErrorMessageLock);
1775 MesPrint(
"Error in processing one term in thread %d in module %d",identity,AC.CModule);
1776 MUNLOCK(ErrorMessageLock);
1780 SeekScratch(fi,&where);
1781 if ( ISGEPOS(where,stoppos) )
break;
1783 AT.WorkPointer = term;
1784 thr->free = BUCKETCOMINGFREE;
1795 sumtimerinfo[identity] += TimeCPU(1);
1796 timerinfo[identity] = TimeCPU(0);
1802 case MCTSEXPANDTREE:
1803 find_Horner_MCTS_expand_tree();
1806 case OPTIMIZEEXPRESSION:
1807 optimize_expression_given_Horner();
1811 MLOCK(ErrorMessageLock);
1812 MesPrint(
"Illegal wakeup signal %d for thread %d",wakeupsignal,identity);
1813 MUNLOCK(ErrorMessageLock);
1819 timerinfo[identity] = TimeCPU(1);
1825 FinalizeOneThread(identity);
1845 void *RunSortBot(
void *dummy)
1847 int identity, wakeupsignal, identityretv;
1848 ALLPRIVATES *B, *BB;
1850 identity = SetIdentity(&identityretv);
1851 threadpointers[identity] = pthread_self();
1852 B = InitializeOneThread(identity);
1853 while ( ( wakeupsignal = SortBotWait(identity) ) > 0 ) {
1854 switch ( wakeupsignal ) {
1859 AR.CurExpr = AB[0]->R.CurExpr;
1860 AR.PolyFun = AB[0]->R.PolyFun;
1861 AR.PolyFunType = AB[0]->R.PolyFunType;
1862 AR.SortType = AC.SortType;
1863 AT.SS->PolyFlag = AR.PolyFun ? AR.PolyFunType: 0;
1864 AT.SS->PolyWise = 0;
1865 AN.ncmod = AC.ncmod;
1866 LOCK(AT.SB.MasterBlockLock[1]);
1867 BB = AB[AT.SortBotIn1];
1868 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
1869 BB = AB[AT.SortBotIn2];
1870 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
1871 AT.SB.FillBlock = 1;
1872 AT.SB.MasterFill[1] = AT.SB.MasterStart[1];
1873 SETBASEPOSITION(AN.theposition,0);
1886 case TERMINATETHREAD:
1896 sumtimerinfo[identity] += TimeCPU(1);
1897 timerinfo[identity] = TimeCPU(0);
1904 MLOCK(ErrorMessageLock);
1905 MesPrint(
"Illegal wakeup signal %d for thread %d",wakeupsignal,identity);
1906 MUNLOCK(ErrorMessageLock);
1915 FinalizeOneThread(identity);
1936 void IAmAvailable(
int identity)
1939 LOCK(availabilitylock);
1940 top = topofavailables;
1941 listofavailables[topofavailables++] = identity;
1943 UNLOCK(availabilitylock);
1944 LOCK(wakeupmasterlock);
1945 wakeupmaster = identity;
1946 pthread_cond_signal(&wakeupmasterconditions);
1947 UNLOCK(wakeupmasterlock);
1950 UNLOCK(availabilitylock);
1966 int GetAvailableThread()
1969 LOCK(availabilitylock);
1970 if ( topofavailables > 0 ) retval = listofavailables[--topofavailables];
1971 UNLOCK(availabilitylock);
1972 if ( retval >= 0 ) {
1977 LOCK(wakeuplocks[retval]);
1978 UNLOCK(wakeuplocks[retval]);
1994 int ConditionalGetAvailableThread()
1997 if ( topofavailables > 0 ) {
1998 LOCK(availabilitylock);
1999 if ( topofavailables > 0 ) {
2000 retval = listofavailables[--topofavailables];
2002 UNLOCK(availabilitylock);
2003 if ( retval >= 0 ) {
2008 LOCK(wakeuplocks[retval]);
2009 UNLOCK(wakeuplocks[retval]);
2028 int GetThread(
int identity)
2031 LOCK(availabilitylock);
2032 for ( j = 0; j < topofavailables; j++ ) {
2033 if ( identity == listofavailables[j] )
break;
2035 if ( j < topofavailables ) {
2037 for ( ; j < topofavailables; j++ ) {
2038 listofavailables[j] = listofavailables[j+1];
2042 UNLOCK(availabilitylock);
2059 int ThreadWait(
int identity)
2062 LOCK(wakeuplocks[identity]);
2063 LOCK(availabilitylock);
2064 top = topofavailables;
2065 for ( j = topofavailables; j > 0; j-- )
2066 listofavailables[j] = listofavailables[j-1];
2067 listofavailables[0] = identity;
2069 if ( top == 0 || topofavailables == numberofworkers ) {
2070 UNLOCK(availabilitylock);
2071 LOCK(wakeupmasterlock);
2072 wakeupmaster = identity;
2073 pthread_cond_signal(&wakeupmasterconditions);
2074 UNLOCK(wakeupmasterlock);
2077 UNLOCK(availabilitylock);
2079 while ( wakeup[identity] == 0 ) {
2080 pthread_cond_wait(&(wakeupconditions[identity]),&(wakeuplocks[identity]));
2082 retval = wakeup[identity];
2083 wakeup[identity] = 0;
2084 UNLOCK(wakeuplocks[identity]);
2103 int SortBotWait(
int identity)
2106 LOCK(wakeuplocks[identity]);
2107 LOCK(availabilitylock);
2108 topsortbotavailables++;
2109 if ( topsortbotavailables >= numberofsortbots ) {
2110 UNLOCK(availabilitylock);
2111 LOCK(wakeupsortbotlock);
2112 wakeupmaster = identity;
2113 pthread_cond_signal(&wakeupsortbotconditions);
2114 UNLOCK(wakeupsortbotlock);
2117 UNLOCK(availabilitylock);
2119 while ( wakeup[identity] == 0 ) {
2120 pthread_cond_wait(&(wakeupconditions[identity]),&(wakeuplocks[identity]));
2122 retval = wakeup[identity];
2123 wakeup[identity] = 0;
2124 UNLOCK(wakeuplocks[identity]);
2144 int ThreadClaimedBlock(
int identity)
2146 LOCK(availabilitylock);
2148 if ( numberclaimed >= numberofworkers ) {
2149 UNLOCK(availabilitylock);
2150 LOCK(wakeupmasterlock);
2151 wakeupmaster = identity;
2152 pthread_cond_signal(&wakeupmasterconditions);
2153 UNLOCK(wakeupmasterlock);
2156 UNLOCK(availabilitylock);
2175 LOCK(wakeupmasterlock);
2176 while ( wakeupmaster == 0 ) {
2177 pthread_cond_wait(&wakeupmasterconditions,&wakeupmasterlock);
2179 retval = wakeupmaster;
2181 UNLOCK(wakeupmasterlock);
2195 int MasterWaitThread(
int identity)
2198 LOCK(wakeupmasterthreadlocks[identity]);
2199 while ( wakeupmasterthread[identity] == 0 ) {
2200 pthread_cond_wait(&(wakeupmasterthreadconditions[identity])
2201 ,&(wakeupmasterthreadlocks[identity]));
2203 retval = wakeupmasterthread[identity];
2204 wakeupmasterthread[identity] = 0;
2205 UNLOCK(wakeupmasterthreadlocks[identity]);
2219 void MasterWaitAll()
2221 LOCK(wakeupmasterlock);
2222 while ( topofavailables < numberofworkers ) {
2223 pthread_cond_wait(&wakeupmasterconditions,&wakeupmasterlock);
2225 UNLOCK(wakeupmasterlock);
2241 void MasterWaitAllSortBots()
2243 LOCK(wakeupsortbotlock);
2244 while ( topsortbotavailables < numberofsortbots ) {
2245 pthread_cond_wait(&wakeupsortbotconditions,&wakeupsortbotlock);
2247 UNLOCK(wakeupsortbotlock);
2263 void MasterWaitAllBlocks()
2265 LOCK(wakeupmasterlock);
2266 while ( numberclaimed < numberofworkers ) {
2267 pthread_cond_wait(&wakeupmasterconditions,&wakeupmasterlock);
2269 UNLOCK(wakeupmasterlock);
2285 void WakeupThread(
int identity,
int signalnumber)
2287 if ( signalnumber == 0 ) {
2288 MLOCK(ErrorMessageLock);
2289 MesPrint(
"Illegal wakeup signal for thread %d",identity);
2290 MUNLOCK(ErrorMessageLock);
2293 LOCK(wakeuplocks[identity]);
2294 wakeup[identity] = signalnumber;
2295 pthread_cond_signal(&(wakeupconditions[identity]));
2296 UNLOCK(wakeuplocks[identity]);
2311 void WakeupMasterFromThread(
int identity,
int signalnumber)
2313 if ( signalnumber == 0 ) {
2314 MLOCK(ErrorMessageLock);
2315 MesPrint(
"Illegal wakeup signal for master %d",identity);
2316 MUNLOCK(ErrorMessageLock);
2319 LOCK(wakeupmasterthreadlocks[identity]);
2320 wakeupmasterthread[identity] = signalnumber;
2321 pthread_cond_signal(&(wakeupmasterthreadconditions[identity]));
2322 UNLOCK(wakeupmasterthreadlocks[identity]);
2334 int SendOneBucket(
int type)
2336 ALLPRIVATES *B0 = AB[0];
2337 THREADBUCKET *thr = 0;
2339 for ( j = 0; j < numthreadbuckets; j++ ) {
2340 if ( threadbuckets[j]->free == BUCKETFILLED ) {
2341 thr = threadbuckets[j];
2342 for ( k = j+1; k < numthreadbuckets; k++ )
2343 threadbuckets[k-1] = threadbuckets[k];
2344 threadbuckets[numthreadbuckets-1] = thr;
2349 while ( (
id = GetAvailableThread() ) < 0 ) { MasterWait(); }
2353 LoadOneThread(0,
id,thr,0);
2354 thr->busy = BUCKETASSIGNED;
2355 thr->free = BUCKETINUSE;
2356 numberoffullbuckets--;
2364 WakeupThread(
id,type);
2392 int InParallelProcessor()
2395 int i, id, retval = 0, num = 0;
2397 if ( numberofworkers >= 2 ) {
2399 for ( i = 0; i < NumExpressions; i++ ) {
2401 if ( e->partodo <= 0 )
continue;
2402 if ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION
2403 || e->status == UNHIDELEXPRESSION || e->status == UNHIDEGEXPRESSION
2404 || e->status == INTOHIDELEXPRESSION || e->status == INTOHIDEGEXPRESSION ) {
2410 if ( e->counter == 0 ) {
2417 while ( (
id = GetAvailableThread() ) < 0 ) { MasterWait(); }
2418 LoadOneThread(0,
id,0,-1);
2419 AB[id]->R.exprtodo = i;
2420 WakeupThread(
id,DOONEEXPRESSION);
2426 if ( num > 0 ) MasterWaitAll();
2428 if ( AC.CollectFun ) AR.DeferFlag = 0;
2431 for ( i = 0; i < NumExpressions; i++ ) {
2432 Expressions[i].partodo = 0;
2466 int ThreadsProcessor(
EXPRESSIONS e, WORD LastExpression)
2468 ALLPRIVATES *B0 = AB[0], *B = B0;
2469 int id, oldgzipCompress, endofinput = 0, j, still, k, defcount = 0, bra = 0, first = 1;
2470 LONG dd = 0, ddd, thrbufsiz, thrbufsiz0, thrbufsiz2, numbucket = 0, numpasses;
2472 WORD *oldworkpointer = AT0.WorkPointer, *tt, *ttco = 0, *t1 = 0, ter, *tstop = 0, *t2;
2473 THREADBUCKET *thr = 0;
2475 GETTERM GetTermP = &GetTerm;
2476 POSITION eonfile = AS.OldOnFile[e-Expressions];
2477 numberoffullbuckets = 0;
2483 AM.tracebackflag = 1;
2485 AS.sLevel = AR0.sLevel;
2486 LOCK(availabilitylock);
2487 topofavailables = 0;
2488 for (
id = 1;
id <= numberofworkers;
id++ ) {
2489 WakeupThread(
id,STARTNEWEXPRESSION);
2491 UNLOCK(availabilitylock);
2497 if ( AC.numpfirstnum > 0 ) {
2498 for ( j = 0; j < AC.numpfirstnum; j++ ) {
2499 AC.inputnumbers[j] = -1;
2511 thrbufsiz2 = thrbufsiz = AC.ThreadBucketSize-1;
2512 if ( ( e->counter / ( numberofworkers * 5 ) ) < thrbufsiz ) {
2513 thrbufsiz = e->counter / ( numberofworkers * 5 ) - 1;
2514 if ( thrbufsiz < 0 ) thrbufsiz = 0;
2516 thrbufsiz0 = thrbufsiz;
2518 thrbufsiz = thrbufsiz0 / (2 << numpasses);
2522 for ( j = 0; j < numthreadbuckets; j++ )
2523 threadbuckets[j]->free = BUCKETFREE;
2524 thr = threadbuckets[0];
2532 #ifdef WHOLEBRACKETS 2533 if ( e->bracketinfo && AC.CollectFun == 0 && AR0.DeferFlag == 0 ) {
2538 for ( n = 0; n < e->bracketinfo->indexfill; n++ ) {
2539 num = TreatIndexEntry(B0,n);
2547 for ( j = 0; j < numthreadbuckets; j++ ) {
2548 switch ( threadbuckets[j]->free ) {
2550 thr = threadbuckets[j];
2552 case BUCKETCOMINGFREE:
2553 thr = threadbuckets[j];
2554 thr->free = BUCKETFREE;
2555 for ( k = j+1; k < numthreadbuckets; k++ )
2556 threadbuckets[k-1] = threadbuckets[k];
2557 threadbuckets[numthreadbuckets-1] = thr;
2565 if ( j < numthreadbuckets ) {
2569 thr->firstbracket = n;
2570 thr->lastbracket = n + num - 1;
2571 thr->type = BUCKETDOINGBRACKET;
2572 thr->free = BUCKETFILLED;
2573 thr->firstterm = AN0.ninterms;
2574 for ( j = n; j < n+num; j++ ) {
2575 AN0.ninterms += e->bracketinfo->
indexbuffer[j].termsinbracket;
2578 numberoffullbuckets++;
2579 if ( topofavailables > 0 ) {
2580 SendOneBucket(DOBRACKETS);
2589 while ( topofavailables <= 0 ) {
2592 SendOneBucket(DOBRACKETS);
2601 switch ( e->status ) {
2602 case UNHIDELEXPRESSION:
2603 case UNHIDEGEXPRESSION:
2604 case DROPHLEXPRESSION:
2605 case DROPHGEXPRESSION:
2606 case HIDDENLEXPRESSION:
2607 case HIDDENGEXPRESSION:
2608 curfile = AR0.hidefile;
2611 curfile = AR0.infile;
2614 SetScratch(curfile,&eonfile);
2615 GetTerm(B0,AT0.WorkPointer);
2619 GetTermP = &GetTerm2;
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;
2641 while ( topofavailables <= 0 ) {
2644 while ( topofavailables > 0 && numberoffullbuckets > 0 ) {
2645 SendOneBucket(DOBRACKETS);
2649 while ( numberoffullbuckets > 0 ) {
2650 while ( topofavailables <= 0 ) {
2653 while ( topofavailables > 0 && numberoffullbuckets > 0 ) {
2654 SendOneBucket(DOBRACKETS);
2663 AN0.lastinindex = -1;
2673 while ( ( ter = GetTermP(B0,thr->threadbuffer) ) >= 0 ) {
2674 if ( ter == 0 ) { endofinput = 1;
goto Finalize; }
2675 dd = AN0.deferskipped;
2676 if ( AR0.DeferFlag ) {
2678 thr->deferbuffer[defcount++] = AR0.DefPosition;
2679 ttco = thr->compressbuffer; t1 = AR0.CompressBuffer; j = *t1;
2682 else if ( first && ( AC.CollectFun == 0 ) ) {
2684 t1 = tstop = thr->threadbuffer;
2685 tstop += *tstop; tstop -= ABS(tstop[-1]);
2687 while ( t1 < tstop ) {
2688 if ( t1[0] == HAAKJE ) { bra = 1;
break; }
2691 t1 = thr->threadbuffer;
2696 if ( AC.CollectFun && *(thr->threadbuffer) < (AM.MaxTer/((LONG)
sizeof(WORD))-10) ) {
2697 if ( ( dd = GetMoreTerms(thr->threadbuffer) ) < 0 ) {
2704 if ( topofavailables > 0 && numberoffullbuckets > 0 ) SendOneBucket(LOWESTLEVELGENERATION);
2708 tt = thr->threadbuffer; tt += *tt;
2715 if ( numpasses > 0 ) {
2717 if ( numbucket >= numberofworkers ) {
2720 if ( numpasses == 0 ) thrbufsiz = thrbufsiz0;
2721 else thrbufsiz = thrbufsiz0 / (2 << numpasses);
2723 thrbufsiz2 = thrbufsiz + thrbufsiz/5;
2728 while ( ( dd < thrbufsiz ) &&
2729 ( tt - thr->threadbuffer ) < ( thr->threadbuffersize - AM.MaxTer - 2 ) ) {
2733 if ( topofavailables > 0 && numberoffullbuckets > 0 ) SendOneBucket(LOWESTLEVELGENERATION);
2737 if ( GetTermP(B0,tt) == 0 ) { endofinput = 1;
break; }
2740 dd += AN0.deferskipped;
2741 if ( AR0.DeferFlag ) {
2742 thr->deferbuffer[defcount++] = AR0.DefPosition;
2743 t1 = AR0.CompressBuffer; j = *t1;
2746 if ( AC.CollectFun && *tt < (AM.MaxTer/((LONG)
sizeof(WORD))-10) ) {
2747 if ( ( ddd = GetMoreTerms(tt) ) < 0 ) {
2762 tstop = t1 + *t1; tstop -= ABS(tstop[-1]);
2764 while ( t2 < tstop ) {
2765 if ( t2[0] == HAAKJE ) {
break; }
2768 if ( t2[0] == HAAKJE ) {
2769 t2 += t2[1]; num = t2 - t1;
2770 while ( ( dd < thrbufsiz2 ) &&
2771 ( tt - thr->threadbuffer ) < ( thr->threadbuffersize - AM.MaxTer - 2 ) ) {
2775 if ( topofavailables > 0 && numberoffullbuckets > 0 ) SendOneBucket(LOWESTLEVELGENERATION);
2779 if ( GetTermP(B0,tt) == 0 ) { endofinput = 1;
break; }
2783 tstop = tt + *tt; tstop -= ABS(tstop[-1]);
2784 if ( tstop-tt < num ) {
2788 for ( i = 1; i < num; i++ ) {
2789 if ( t1[i] != tt[i] )
break;
2805 thr->firstterm = AN0.ninterms;
2808 thr->free = BUCKETFILLED;
2809 thr->type = BUCKETDOINGTERMS;
2810 numberoffullbuckets++;
2811 if ( topofavailables <= 0 && endofinput == 0 ) {
2825 for ( j = 0; j < numthreadbuckets; j++ ) {
2826 switch ( threadbuckets[j]->free ) {
2828 thr = threadbuckets[j];
2829 if ( !endofinput )
goto NextBucket;
2835 thr->free = BUCKETATEND;
2837 case BUCKETCOMINGFREE:
2838 thr = threadbuckets[j];
2839 thr->free = BUCKETFREE;
2845 for ( k = j+1; k < numthreadbuckets; k++ )
2846 threadbuckets[k-1] = threadbuckets[k];
2847 threadbuckets[numthreadbuckets-1] = thr;
2863 for ( j = 0; j < numthreadbuckets; j++ ) {
2864 if ( threadbuckets[j]->free == BUCKETFILLED ) {
2865 thr = threadbuckets[j];
2866 for ( k = j+1; k < numthreadbuckets; k++ )
2867 threadbuckets[k-1] = threadbuckets[k];
2868 threadbuckets[numthreadbuckets-1] = thr;
2878 while ( (
id = GetAvailableThread() ) < 0 ) { MasterWait(); }
2882 LoadOneThread(0,
id,thr,0);
2884 thr->busy = BUCKETASSIGNED;
2886 thr->free = BUCKETINUSE;
2887 numberoffullbuckets--;
2895 WakeupThread(
id,LOWESTLEVELGENERATION);
2900 if ( topofavailables > 0 ) {
2901 for ( j = 0; j < numthreadbuckets; j++ ) {
2902 if ( threadbuckets[j]->free == BUCKETFILLED ) {
2903 thr = threadbuckets[j];
2904 for ( k = j+1; k < numthreadbuckets; k++ )
2905 threadbuckets[k-1] = threadbuckets[k];
2906 threadbuckets[numthreadbuckets-1] = thr;
2915 for ( j = 0; j < numthreadbuckets; j++ ) {
2916 switch ( threadbuckets[j]->free ) {
2918 thr = threadbuckets[j];
2919 if ( !endofinput )
goto NextBucket;
2920 thr->free = BUCKETATEND;
2922 case BUCKETCOMINGFREE:
2923 thr = threadbuckets[j];
2925 thr->free = BUCKETATEND;
2928 thr->free = BUCKETFREE;
2929 for ( k = j+1; k < numthreadbuckets; k++ )
2930 threadbuckets[k-1] = threadbuckets[k];
2931 threadbuckets[numthreadbuckets-1] = thr;
2939 if ( j >= numthreadbuckets )
break;
2949 for ( j = 0; j < numthreadbuckets; j++ ) {
2950 switch ( threadbuckets[j]->free ) {
2952 thr = threadbuckets[j];
2953 if ( !endofinput )
goto NextBucket;
2954 thr->free = BUCKETATEND;
2956 case BUCKETCOMINGFREE:
2957 thr = threadbuckets[j];
2958 if ( endofinput ) thr->free = BUCKETATEND;
2960 thr->free = BUCKETFREE;
2961 for ( k = j+1; k < numthreadbuckets; k++ )
2962 threadbuckets[k-1] = threadbuckets[k];
2963 threadbuckets[numthreadbuckets-1] = thr;
2968 if ( still < 0 ) still = j;
2981 thr = threadbuckets[still];
2982 for ( k = still+1; k < numthreadbuckets; k++ )
2983 threadbuckets[k-1] = threadbuckets[k];
2984 threadbuckets[numthreadbuckets-1] = thr;
2997 if ( AC.ThreadBalancing ) {
2998 for (
id = 1;
id <= numberofworkers;
id++ ) {
2999 AB[id]->T.LoadBalancing = 1;
3001 if ( LoadReadjusted() )
goto Finalize;
3002 for (
id = 1;
id <= numberofworkers;
id++ ) {
3003 AB[id]->T.LoadBalancing = 0;
3006 if ( AC.ThreadBalancing ) {
3031 if ( LastExpression ) {
3033 if ( AR0.infile->handle >= 0 ) {
3034 CloseFile(AR0.infile->handle);
3035 AR0.infile->handle = -1;
3036 remove(AR0.infile->name);
3037 PUTZERO(AR0.infile->POposition);
3038 AR0.infile->POfill = AR0.infile->POfull = AR0.infile->PObuffer;
3050 oldgzipCompress = AR0.gzipCompress;
3051 AR0.gzipCompress = 0;
3052 if ( AR0.outtohide ) AR0.outfile = AR0.hidefile;
3053 if ( MasterMerge() < 0 ) {
3054 if ( AR0.outtohide ) AR0.outfile = oldoutfile;
3055 AR0.gzipCompress = oldgzipCompress;
3058 if ( AR0.outtohide ) AR0.outfile = oldoutfile;
3059 AR0.gzipCompress = oldgzipCompress;
3067 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
3068 if ( GetThread(
id) > 0 ) WakeupThread(
id,CLEANUPEXPRESSION);
3071 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
3072 if ( AB[
id]->R.MaxDum - AM.IndDum > e->numdummies )
3073 e->numdummies = AB[id]->R.MaxDum - AM.IndDum;
3074 AR0.expchanged |= AB[id]->R.expchanged;
3080 AT0.WorkPointer = oldworkpointer;
3108 int LoadReadjusted()
3110 ALLPRIVATES *B0 = AB[0];
3111 THREADBUCKET *thr = 0, *thrtogo = 0;
3112 int numtogo, numfree, numbusy, n, nperbucket, extra, i, j, u, bus;
3114 WORD *t1, *c1, *t2, *c2, *t3;
3119 while ( topofavailables <= 0 ) MasterWait();
3128 for ( j = 0; j < numthreadbuckets; j++ ) {
3129 thr = threadbuckets[j];
3130 if ( thr->free == BUCKETFREE || thr->free == BUCKETATEND
3131 || thr->free == BUCKETCOMINGFREE ) {
3132 freebuckets[numfree++] = thr;
3134 else if ( thr->type != BUCKETDOINGTERMS ) {}
3135 else if ( thr->totnum > 1 ) {
3139 if ( thr->free == BUCKETINUSE ) {
3140 n = thr->totnum-thr->usenum;
3141 if ( bus == BUCKETASSIGNED ) numbusy++;
3142 else if ( ( bus != BUCKETASSIGNED )
3143 && ( n > numtogo ) ) {
3148 else if ( bus == BUCKETTOBERELEASED
3149 && thr->free == BUCKETRELEASED ) {
3150 freebuckets[numfree++] = thr;
3151 thr->free = BUCKETATEND;
3153 thr->busy = BUCKETPREPARINGTERM;
3158 if ( numfree == 0 )
return(0);
3159 if ( numtogo > 0 ) {
3166 if ( thr->totnum-thr->usenum < numtogo )
goto restart;
3176 if ( thr->busy != BUCKETDOINGTERM ) {
3180 if ( thr->totnum-thr->usenum < numtogo ) {
3184 thr->free = BUCKETTERMINATED;
3191 if ( thr->usenum == thr->totnum ) {
3196 thr->free = BUCKETATEND;
3203 if ( numbusy > 0 )
return(1);
3215 numinput = thr->firstterm + thr->usenum;
3216 nperbucket = numtogo / numfree;
3217 extra = numtogo - nperbucket*numfree;
3218 if ( AR0.DeferFlag ) {
3219 t1 = thr->threadbuffer; c1 = thr->compressbuffer; u = thr->usenum;
3220 for ( n = 0; n < thr->usenum; n++ ) { t1 += *t1; c1 += *c1; }
3223 for ( i = 0; i < extra; i++ ) {
3224 thrtogo = freebuckets[i];
3225 t2 = thrtogo->threadbuffer;
3226 c2 = thrtogo->compressbuffer;
3227 thrtogo->free = BUCKETFILLED;
3228 thrtogo->type = BUCKETDOINGTERMS;
3229 thrtogo->totnum = nperbucket+1;
3230 thrtogo->ddterms = 0;
3231 thrtogo->usenum = 0;
3232 thrtogo->busy = BUCKETASSIGNED;
3233 thrtogo->firstterm = numinput;
3234 numinput += nperbucket+1;
3235 for ( n = 0; n <= nperbucket; n++ ) {
3236 j = *t1; NCOPY(t2,t1,j);
3237 j = *c1; NCOPY(c2,c1,j);
3238 thrtogo->deferbuffer[n] = thr->deferbuffer[u++];
3243 if ( nperbucket > 0 ) {
3244 for ( i = extra; i < numfree; i++ ) {
3245 thrtogo = freebuckets[i];
3246 t2 = thrtogo->threadbuffer;
3247 c2 = thrtogo->compressbuffer;
3248 thrtogo->free = BUCKETFILLED;
3249 thrtogo->type = BUCKETDOINGTERMS;
3250 thrtogo->totnum = nperbucket;
3251 thrtogo->ddterms = 0;
3252 thrtogo->usenum = 0;
3253 thrtogo->busy = BUCKETASSIGNED;
3254 thrtogo->firstterm = numinput;
3255 numinput += nperbucket;
3256 for ( n = 0; n < nperbucket; n++ ) {
3257 j = *t1; NCOPY(t2,t1,j);
3258 j = *c1; NCOPY(c2,c1,j);
3259 thrtogo->deferbuffer[n] = thr->deferbuffer[u++];
3266 t1 = thr->threadbuffer;
3267 for ( n = 0; n < thr->usenum; n++ ) { t1 += *t1; }
3270 for ( i = 0; i < extra; i++ ) {
3271 thrtogo = freebuckets[i];
3272 t2 = thrtogo->threadbuffer;
3273 thrtogo->free = BUCKETFILLED;
3274 thrtogo->type = BUCKETDOINGTERMS;
3275 thrtogo->totnum = nperbucket+1;
3276 thrtogo->ddterms = 0;
3277 thrtogo->usenum = 0;
3278 thrtogo->busy = BUCKETASSIGNED;
3279 thrtogo->firstterm = numinput;
3280 numinput += nperbucket+1;
3281 for ( n = 0; n <= nperbucket; n++ ) {
3282 j = *t1; NCOPY(t2,t1,j);
3287 if ( nperbucket > 0 ) {
3288 for ( i = extra; i < numfree; i++ ) {
3289 thrtogo = freebuckets[i];
3290 t2 = thrtogo->threadbuffer;
3291 thrtogo->free = BUCKETFILLED;
3292 thrtogo->type = BUCKETDOINGTERMS;
3293 thrtogo->totnum = nperbucket;
3294 thrtogo->ddterms = 0;
3295 thrtogo->usenum = 0;
3296 thrtogo->busy = BUCKETASSIGNED;
3297 thrtogo->firstterm = numinput;
3298 numinput += nperbucket;
3299 for ( n = 0; n < nperbucket; n++ ) {
3300 j = *t1; NCOPY(t2,t1,j);
3307 if ( thr->free == BUCKETRELEASED && thr->busy == BUCKETTOBERELEASED ) {
3308 thr->free = BUCKETATEND; thr->busy = BUCKETPREPARINGTERM;
3376 int PutToMaster(
PHEAD WORD *term)
3378 int i,j,nexti,ret = 0;
3379 WORD *t, *fill, *top, zero = 0;
3384 t = term; ret = j = *term;
3385 if ( j == 0 ) { j = 1; }
3387 i = AT.SB.FillBlock;
3388 fill = AT.SB.MasterFill[i];
3389 top = AT.SB.MasterStop[i];
3391 while ( j > 0 && fill < top ) {
3392 *fill++ = *t++; j--;
3402 if ( nexti > AT.SB.MasterNumBlocks ) {
3405 LOCK(AT.SB.MasterBlockLock[nexti]);
3406 UNLOCK(AT.SB.MasterBlockLock[i]);
3407 AT.SB.MasterFill[i] = AT.SB.MasterStart[i];
3408 AT.SB.FillBlock = i = nexti;
3409 fill = AT.SB.MasterStart[i];
3410 top = AT.SB.MasterStop[i];
3413 AT.SB.MasterFill[i] = fill;
3433 SortBotOut(
PHEAD WORD *term)
3437 if ( AT.identity != 0 )
return(PutToMaster(BHEAD term));
3440 if (
FlushOut(&SortBotPosition,AR.outfile,1) )
return(-1);
3441 ADDPOS(AT.SS->SizeInFile[0],1);
3446 if ( ( im =
PutOut(BHEAD term,&SortBotPosition,AR.outfile,1) ) < 0 ) {
3447 MLOCK(ErrorMessageLock);
3448 MesPrint(
"Called from MasterMerge/SortBotOut");
3449 MUNLOCK(ErrorMessageLock);
3452 ADDPOS(AT.SS->SizeInFile[0],im);
3482 ALLPRIVATES *B0 = AB[0], *B = 0;
3484 WORD **poin, **poin2, ul, k, i, im, *m1, j;
3485 WORD lpat, mpat, level, l1, l2, r1, r2, r3, c;
3486 WORD *m2, *m3, r31, r33, ki, *rr;
3491 if ( numberofworkers > 2 )
return(SortBotMasterMerge());
3494 S->PolyFlag = AR0.PolyFun ? AR0.PolyFunType: 0;
3496 coef = AN0.SoScratC;
3497 poin = S->poina; poin2 = S->poin2a;
3498 rr = AR0.CompressPointer;
3503 S->inNum = numberofthreads;
3508 S->lPatch = S->inNum - 1;
3518 for ( i = 1; i <= S->lPatch; i++ ) {
3520 LOCK(AT.SB.MasterBlockLock[0]);
3521 LOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
3529 for ( i = 0; i < S->lPatch; i++ ) {
3531 WakeupThread(i+1,FINISHEXPRESSION);
3536 if ( fout->
handle >= 0 ) {
3538 SeekFile(fout->
handle,&position,SEEK_END);
3539 ADDPOS(position,((fout->POfill-fout->PObuffer)*
sizeof(WORD)));
3542 SETBASEPOSITION(position,(fout->POfill-fout->PObuffer)*
sizeof(WORD));
3547 MasterWaitAllBlocks();
3555 for ( i = 1; i <= S->lPatch; i++ ) {
3557 LOCK(AT.SB.MasterBlockLock[1]);
3558 AT.SB.MasterBlock = 1;
3566 do { lpat <<= 1; }
while ( lpat < S->lPatch );
3567 mpat = ( lpat >> 1 ) - 1;
3568 k = lpat - S->lPatch;
3573 for ( i = 1; i < lpat; i++ ) { S->tree[i] = -1; }
3574 for ( i = 1; i <= k; i++ ) {
3575 im = ( i << 1 ) - 1;
3576 poin[im] = AB[i]->T.SB.MasterStart[AB[i]->T.SB.MasterBlock];
3577 poin2[im] = poin[im] + *(poin[im]);
3580 S->tree[mpat+i] = 0;
3581 poin[im-1] = poin2[im-1] = 0;
3583 for ( i = (k<<1)+1; i <= lpat; i++ ) {
3586 poin[i] = AB[i-k]->T.SB.MasterStart[AB[i-k]->T.SB.MasterBlock];
3587 poin2[i] = poin[i] + *(poin[i]);
3608 if ( !*(poin[k]) ) {
3609 do {
if ( !( i >>= 1 ) )
goto EndOfMerge; }
while ( !S->tree[i] );
3610 if ( S->tree[i] == -1 ) {
3623 if ( S->tree[i] > 0 ) {
3624 if ( ( c = CompareTerms(B0,poin[S->tree[i]],poin[k],(WORD)0) ) > 0 ) {
3628 S->used[level] = S->tree[i];
3638 l1 = *( m1 = poin[S->tree[i]] );
3639 l2 = *( m2 = poin[k] );
3640 if ( S->PolyWise ) {
3645 if ( S->PolyFlag == 2 ) {
3646 w = poly_ratfun_add(B0,m1,m2);
3647 if ( *tt1 + w[1] - m1[1] > AM.MaxTer/((LONG)
sizeof(WORD)) ) {
3648 MLOCK(ErrorMessageLock);
3649 MesPrint(
"Term too complex in PolyRatFun addition. MaxTermSize of %10l is too small",AM.MaxTer);
3650 MUNLOCK(ErrorMessageLock);
3653 AT0.WorkPointer = w;
3654 if ( w[FUNHEAD] == -SNUMBER && w[FUNHEAD+1] == 0 && w[1] > FUNHEAD ) {
3659 w = AT0.WorkPointer;
3660 if ( w + m1[1] + m2[1] > AT0.WorkTop ) {
3661 MLOCK(ErrorMessageLock);
3662 MesPrint(
"MasterMerge: A WorkSpace of %10l is too small",AM.WorkSize);
3663 MUNLOCK(ErrorMessageLock);
3670 || ( w[FUNHEAD] == -SNUMBER && w[FUNHEAD+1] == 0 ) )
3672 if ( r1 == m1[1] ) {
3675 else if ( r1 < m1[1] ) {
3679 while ( --r1 >= 0 ) *--m1 = *--m2;
3682 while ( --r1 >= 0 ) *--m1 = *--m2;
3684 poin[S->tree[i]] = m1;
3692 poin[S->tree[i]] = m2;
3699 r1 = *( m1 += l1 - 1 );
3701 r1 = ( ( r1 > 0 ) ? (r1-1) : (r1+1) ) >> 1;
3702 r2 = *( m2 += l2 - 1 );
3704 r2 = ( ( r2 > 0 ) ? (r2-1) : (r2+1) ) >> 1;
3706 if ( AddRat(B0,(UWORD *)m1,r1,(UWORD *)m2,r2,coef,&r3) ) {
3707 MLOCK(ErrorMessageLock);
3708 MesCall(
"MasterMerge");
3709 MUNLOCK(ErrorMessageLock);
3713 if ( AN.ncmod != 0 ) {
3714 if ( ( AC.modmode & POSNEG ) != 0 ) {
3717 else if ( BigLong(coef,r3,(UWORD *)AC.cmod,ABS(AN.ncmod)) >= 0 ) {
3719 SubPLon(coef,r3,(UWORD *)AC.cmod,ABS(AN.ncmod),coef,&r3);
3721 for ( ii = 1; ii < r3; ii++ ) coef[r3+ii] = 0;
3725 r33 = ( r3 > 0 ) ? ( r3 + 1 ) : ( r3 - 1 );
3726 if ( r3 < 0 ) r3 = -r3;
3727 if ( r1 < 0 ) r1 = -r1;
3732 ul = S->used[level] = S->tree[i];
3738 poin[ul] = poin2[ul];
3740 if ( (poin[ul] + im + COMPINC) >=
3741 AB[ki+1]->T.SB.MasterStop[AB[ki+1]->T.SB.MasterBlock]
3748 i = AT.SB.MasterBlock;
3750 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
3753 UNLOCK(AT.SB.MasterBlockLock[i-1]);
3755 if ( i == AT.SB.MasterNumBlocks ) {
3760 to = AT.SB.MasterStart[1];
3761 from = AT.SB.MasterStop[i];
3762 while ( from > poin[ul] ) *--to = *--from;
3767 LOCK(AT.SB.MasterBlockLock[i]);
3768 AT.SB.MasterBlock = i;
3769 poin2[ul] = poin[ul] + im;
3774 S->used[++level] = k;
3780 else if ( r31 < 0 ) {
3789 if( (poin[S->tree[i]]+l1+r31) >= poin2[S->tree[i]] ) {
3795 if ( (l1 + r31)*((LONG)
sizeof(WORD)) >= AM.MaxTer ) {
3796 MLOCK(ErrorMessageLock);
3797 MesPrint(
"MasterMerge: Coefficient overflow during sort");
3798 MUNLOCK(ErrorMessageLock);
3801 m2 = poin[S->tree[i]];
3802 m3 = ( poin[S->tree[i]] -= r31 );
3803 do { *m3++ = *m2++; }
while ( m2 < m1 );
3807 *(poin[S->tree[i]]) += r31;
3809 m2 = (WORD *)coef; im = r3;
3821 if ( (poin[k] + im + COMPINC) >=
3822 AB[ki+1]->T.SB.MasterStop[AB[ki+1]->T.SB.MasterBlock]
3829 i = AT.SB.MasterBlock;
3831 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
3834 UNLOCK(AT.SB.MasterBlockLock[i-1]);
3836 if ( i == AT.SB.MasterNumBlocks ) {
3841 to = AT.SB.MasterStart[1];
3842 from = AT.SB.MasterStop[i];
3843 while ( from > poin[k] ) *--to = *--from;
3848 LOCK(AT.SB.MasterBlockLock[i]);
3849 AT.SB.MasterBlock = i;
3850 poin2[k] = poin[k] + im;
3858 else if ( S->tree[i] < 0 ) {
3869 if ( ( im =
PutOut(B0,poin[k],&position,fout,1) ) < 0 ) {
3870 MLOCK(ErrorMessageLock);
3871 MesPrint(
"Called from MasterMerge with k = %d (stream %d)",k,S->ktoi[k]);
3872 MUNLOCK(ErrorMessageLock);
3875 ADDPOS(S->SizeInFile[0],im);
3878 if (
FlushOut(&position,fout,1) )
goto ReturnError;
3879 ADDPOS(S->SizeInFile[0],1);
3883 position = S->SizeInFile[0];
3884 MULPOS(position,
sizeof(WORD));
3886 for ( j = 1; j <= numberofworkers; j++ ) {
3887 S->GenTerms += AB[j]->T.SS->GenTerms;
3890 Expressions[AR0.CurExpr].counter = S->TermsLeft;
3894 for ( i = 1; i <= S->lPatch; i++ ) {
3896 UNLOCK(AT.SB.MasterBlockLock[0]);
3897 if ( AT.SB.MasterBlock == 1 ) {
3898 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
3901 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterBlock-1]);
3903 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterBlock]);
3908 for ( i = 1; i <= S->lPatch; i++ ) {
3910 UNLOCK(AT.SB.MasterBlockLock[0]);
3911 if ( AT.SB.MasterBlock == 1 ) {
3912 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
3915 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterBlock-1]);
3917 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterBlock]);
3945 int SortBotMasterMerge()
3948 ALLPRIVATES *B = AB[0], *BB;
3961 topsortbotavailables = 0;
3962 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
3963 WakeupThread(i,INISORTBOT);
3969 AR.CompressPointer[0] = 0;
3971 BB = AB[AT.SortBotIn1];
3972 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
3973 BB = AB[AT.SortBotIn2];
3974 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
3976 MasterWaitAllSortBots();
3981 for ( i = 1; i <= numberofworkers; i++ ) {
3983 WakeupThread(i,FINISHEXPRESSION);
3988 if ( fout->
handle >= 0 ) {
3989 PUTZERO(SortBotPosition);
3990 SeekFile(fout->
handle,&SortBotPosition,SEEK_END);
3991 ADDPOS(SortBotPosition,((fout->POfill-fout->PObuffer)*
sizeof(WORD)));
3994 SETBASEPOSITION(SortBotPosition,(fout->POfill-fout->PObuffer)*
sizeof(WORD));
3996 MasterWaitAllBlocks();
4002 topsortbotavailables = 0;
4003 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
4004 WakeupThread(i,RUNSORTBOT);
4006 if ( SortBotMerge(BHEAD0) ) {
4007 MLOCK(ErrorMessageLock);
4008 MesPrint(
"Called from SortBotMasterMerge");
4009 MUNLOCK(ErrorMessageLock);
4016 if ( S->file.
handle >= 0 )
4023 position = S->SizeInFile[0];
4024 MULPOS(position,
sizeof(WORD));
4026 for ( j = 1; j <= numberofworkers; j++ ) {
4027 S->GenTerms += AB[j]->T.SS->GenTerms;
4029 S->TermsLeft = numberofterms;
4031 Expressions[AR.CurExpr].counter = S->TermsLeft;
4040 MasterWaitAllSortBots();
4059 int SortBotMerge(PHEAD0)
4062 ALLPRIVATES *Bin1 = AB[AT.SortBotIn1],*Bin2 = AB[AT.SortBotIn2];
4063 WORD *term1, *term2, *next, *wp;
4066 WORD l1, l2, *m1, *m2, *w, r1, r2, r3, r33, r31, *tt1, ii;
4067 WORD *to, *from, im, c;
4076 if ( AT.identity == 0 ) {
4077 wp = AT.WorkPointer;
4080 wp = AT.WorkPointer = AT.WorkSpace;
4087 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4088 LOCK(Bin2->T.SB.MasterBlockLock[blin2]);
4090 term1 = Bin1->T.SB.MasterStart[blin1];
4091 term2 = Bin2->T.SB.MasterStart[blin2];
4092 AT.SB.FillBlock = 1;
4096 while ( *term1 && *term2 ) {
4097 if ( ( c = CompareTerms(BHEAD term1,term2,(WORD)0) ) > 0 ) {
4101 if ( SortBotOut(BHEAD term1) < 0 ) {
4102 MLOCK(ErrorMessageLock);
4103 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4104 MUNLOCK(ErrorMessageLock);
4110 if ( next >= Bin1->T.SB.MasterStop[blin1] || ( *next &&
4111 next+*next+COMPINC > Bin1->T.SB.MasterStop[blin1] ) ) {
4113 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4116 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4118 if ( blin1 == Bin1->T.SB.MasterNumBlocks ) {
4122 to = Bin1->T.SB.MasterStart[1];
4123 from = Bin1->T.SB.MasterStop[Bin1->T.SB.MasterNumBlocks];
4124 while ( from > term1 ) *--to = *--from;
4131 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4132 Bin1->T.SB.MasterBlock = blin1;
4143 if ( SortBotOut(BHEAD term2) < 0 ) {
4144 MLOCK(ErrorMessageLock);
4145 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4146 MUNLOCK(ErrorMessageLock);
4152 if ( next >= Bin2->T.SB.MasterStop[blin2] || ( *next
4153 && next+*next+COMPINC > Bin2->T.SB.MasterStop[blin2] ) ) {
4155 UNLOCK(Bin2->T.SB.MasterBlockLock[Bin2->T.SB.MasterNumBlocks]);
4158 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2-1]);
4160 if ( blin2 == Bin2->T.SB.MasterNumBlocks ) {
4164 to = Bin2->T.SB.MasterStart[1];
4165 from = Bin2->T.SB.MasterStop[Bin2->T.SB.MasterNumBlocks];
4166 while ( from > term2 ) *--to = *--from;
4173 LOCK(Bin2->T.SB.MasterBlockLock[blin2]);
4174 Bin2->T.SB.MasterBlock = blin2;
4185 l1 = *( m1 = term1 );
4186 l2 = *( m2 = term2 );
4187 if ( S->PolyWise ) {
4191 if ( S->PolyFlag == 2 ) {
4192 AT.WorkPointer = wp;
4193 w = poly_ratfun_add(BHEAD m1,m2);
4194 if ( *tt1 + w[1] - m1[1] > AM.MaxTer/((LONG)
sizeof(WORD)) ) {
4195 MLOCK(ErrorMessageLock);
4196 MesPrint(
"Term too complex in PolyRatFun addition. MaxTermSize of %10l is too small",AM.MaxTer);
4197 MUNLOCK(ErrorMessageLock);
4200 AT.WorkPointer = wp;
4201 if ( w[FUNHEAD] == -SNUMBER && w[FUNHEAD+1] == 0 && w[1] > FUNHEAD ) {
4207 if ( w + m1[1] + m2[1] > AT.WorkTop ) {
4208 MLOCK(ErrorMessageLock);
4209 MesPrint(
"SortBotMerge(%d): A Maxtermsize of %10l is too small",
4210 AT.identity,AM.MaxTer/
sizeof(WORD));
4211 MesPrint(
"m1[1] = %d, m2[1] = %d, Space = %l",m1[1],m2[1],(LONG)(AT.WorkTop-wp));
4212 PrintTerm(term1,
"term1");
4213 PrintTerm(term2,
"term2");
4214 MesPrint(
"PolyWise = %d",S->PolyWise);
4215 MUNLOCK(ErrorMessageLock);
4222 || ( w[FUNHEAD] == -SNUMBER && w[FUNHEAD+1] == 0 ) )
4224 if ( r1 == m1[1] ) {
4227 else if ( r1 < m1[1] ) {
4231 while ( --r1 >= 0 ) *--m1 = *--m2;
4234 while ( --r1 >= 0 ) *--m1 = *--m2;
4251 r1 = *( m1 += l1 - 1 );
4253 r1 = ( ( r1 > 0 ) ? (r1-1) : (r1+1) ) >> 1;
4254 r2 = *( m2 += l2 - 1 );
4256 r2 = ( ( r2 > 0 ) ? (r2-1) : (r2+1) ) >> 1;
4258 if ( AddRat(BHEAD (UWORD *)m1,r1,(UWORD *)m2,r2,coef,&r3) ) {
4259 MLOCK(ErrorMessageLock);
4260 MesCall(
"SortBotMerge");
4261 MUNLOCK(ErrorMessageLock);
4265 if ( AN.ncmod != 0 ) {
4266 if ( ( AC.modmode & POSNEG ) != 0 ) {
4269 else if ( BigLong(coef,r3,(UWORD *)AC.cmod,ABS(AN.ncmod)) >= 0 ) {
4270 SubPLon(coef,r3,(UWORD *)AC.cmod,ABS(AN.ncmod),coef,&r3);
4272 for ( ii = 1; ii < r3; ii++ ) coef[r3+ii] = 0;
4275 if ( !r3 ) {
goto cancelled; }
4277 r33 = ( r3 > 0 ) ? ( r3 + 1 ) : ( r3 - 1 );
4278 if ( r3 < 0 ) r3 = -r3;
4279 if ( r1 < 0 ) r1 = -r1;
4283 m2 = (WORD *)coef; im = r3;
4296 to = wp; from = term1;
4297 while ( from < m1 ) *to++ = *from++;
4298 from = (WORD *)coef; im = r3;
4302 if ( SortBotOut(BHEAD wp) < 0 ) {
4303 MLOCK(ErrorMessageLock);
4304 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4305 MUNLOCK(ErrorMessageLock);
4312 if ( SortBotOut(BHEAD term1) < 0 ) {
4313 MLOCK(ErrorMessageLock);
4314 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4315 MUNLOCK(ErrorMessageLock);
4322 if ( next >= Bin1->T.SB.MasterStop[blin1] || ( *next &&
4323 next+*next+COMPINC > Bin1->T.SB.MasterStop[blin1] ) ) {
4325 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4328 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4330 if ( blin1 == Bin1->T.SB.MasterNumBlocks ) {
4334 to = Bin1->T.SB.MasterStart[1];
4335 from = Bin1->T.SB.MasterStop[Bin1->T.SB.MasterNumBlocks];
4336 while ( from > term1 ) *--to = *--from;
4343 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4344 Bin1->T.SB.MasterBlock = blin1;
4361 if ( SortBotOut(BHEAD term1) < 0 ) {
4362 MLOCK(ErrorMessageLock);
4363 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4364 MUNLOCK(ErrorMessageLock);
4370 if ( next >= Bin1->T.SB.MasterStop[blin1] || ( *next &&
4371 next+*next+COMPINC > Bin1->T.SB.MasterStop[blin1] ) ) {
4373 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4376 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4378 if ( blin1 == Bin1->T.SB.MasterNumBlocks ) {
4382 to = Bin1->T.SB.MasterStart[1];
4383 from = Bin1->T.SB.MasterStop[Bin1->T.SB.MasterNumBlocks];
4384 while ( from > term1 ) *--to = *--from;
4391 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4392 Bin1->T.SB.MasterBlock = blin1;
4400 else if ( *term2 ) {
4405 if ( SortBotOut(BHEAD term2) < 0 ) {
4406 MLOCK(ErrorMessageLock);
4407 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4408 MUNLOCK(ErrorMessageLock);
4414 if ( next >= Bin2->T.SB.MasterStop[blin2] || ( *next
4415 && next+*next+COMPINC > Bin2->T.SB.MasterStop[blin2] ) ) {
4417 UNLOCK(Bin2->T.SB.MasterBlockLock[Bin2->T.SB.MasterNumBlocks]);
4420 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2-1]);
4422 if ( blin2 == Bin2->T.SB.MasterNumBlocks ) {
4426 to = Bin2->T.SB.MasterStart[1];
4427 from = Bin2->T.SB.MasterStop[Bin2->T.SB.MasterNumBlocks];
4428 while ( from > term2 ) *--to = *--from;
4435 LOCK(Bin2->T.SB.MasterBlockLock[blin2]);
4436 Bin2->T.SB.MasterBlock = blin2;
4444 SortBotOut(BHEAD 0);
4449 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4451 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4454 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4456 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2]);
4458 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2-1]);
4461 UNLOCK(Bin2->T.SB.MasterBlockLock[Bin2->T.SB.MasterNumBlocks]);
4463 if ( AT.identity > 0 ) {
4464 UNLOCK(AT.SB.MasterBlockLock[AT.SB.FillBlock]);
4479 static int SortBlocksInitialized = 0;
4487 int IniSortBlocks(
int numworkers)
4491 LONG totalsize, workersize, blocksize, numberofterms;
4493 int numberofblocks = NUMBEROFBLOCKSINSORT, numparts;
4496 if ( SortBlocksInitialized )
return(0);
4497 SortBlocksInitialized = 1;
4498 if ( numworkers == 0 )
return(0);
4501 if ( numworkers > 2 ) {
4502 numparts = 2*numworkers - 2;
4503 numberofblocks = numberofblocks/2;
4506 numparts = numworkers;
4509 numparts = numworkers;
4512 totalsize = S->LargeSize + S->SmallEsize;
4513 workersize = totalsize / numparts;
4514 maxter = AM.MaxTer/
sizeof(WORD);
4515 blocksize = ( workersize - maxter )/numberofblocks;
4516 numberofterms = blocksize / maxter;
4517 if ( numberofterms < MINIMUMNUMBEROFTERMS ) {
4521 MesPrint(
"We have a problem with the size of the blocks in IniSortBlocks");
4530 if ( w == 0 ) w = S->sBuffer;
4531 for (
id = 1;
id <= numparts;
id++ ) {
4533 AT.SB.MasterBlockLock = (pthread_mutex_t *)Malloc1(
4534 sizeof(pthread_mutex_t)*(numberofblocks+1),
"MasterBlockLock");
4535 AT.SB.MasterStart = (WORD **)Malloc1(
sizeof(WORD *)*(numberofblocks+1)*3,
"MasterBlock");
4536 AT.SB.MasterFill = AT.SB.MasterStart + (numberofblocks+1);
4537 AT.SB.MasterStop = AT.SB.MasterFill + (numberofblocks+1);
4538 AT.SB.MasterNumBlocks = numberofblocks;
4539 AT.SB.MasterBlock = 0;
4540 AT.SB.FillBlock = 0;
4541 AT.SB.MasterFill[0] = AT.SB.MasterStart[0] = w;
4543 AT.SB.MasterStop[0] = w;
4544 AT.SB.MasterBlockLock[0] = dummylock;
4545 for ( j = 1; j <= numberofblocks; j++ ) {
4546 AT.SB.MasterFill[j] = AT.SB.MasterStart[j] = w;
4548 AT.SB.MasterStop[j] = w;
4549 AT.SB.MasterBlockLock[j] = dummylock;
4552 if ( w > S->sTop2 ) {
4553 MesPrint(
"Counting problem in IniSortBlocks");
4571 void DefineSortBotTree()
4575 if ( numberofworkers <= 2 )
return;
4576 n = numberofworkers*2-2;
4577 for ( i = numberofworkers+1, from = 1; i <= n; i++ ) {
4579 AT.SortBotIn1 = from++;
4580 AT.SortBotIn2 = from++;
4583 AT.SortBotIn1 = from++;
4584 AT.SortBotIn2 = from++;
4599 WORD GetTerm2(
PHEAD WORD *term)
4601 WORD *ttco, *tt, retval;
4607 POSITION where, eonfile = AS.OldOnFile[e-Expressions], bstart, bnext;
4611 switch ( e->status ) {
4612 case UNHIDELEXPRESSION:
4613 case UNHIDEGEXPRESSION:
4614 case DROPHLEXPRESSION:
4615 case DROPHGEXPRESSION:
4616 case HIDDENLEXPRESSION:
4617 case HIDDENGEXPRESSION:
4624 if ( AR.KeptInHold ) {
4625 retval = GetTerm(BHEAD term);
4628 SeekScratch(fi,&where);
4629 if ( AN.lastinindex < 0 ) {
4633 if ( ( n = TreatIndexEntry(BHEAD 0) ) <= 0 ) {
4635 where = bi[n].start;
4636 ADD2POS(where,eonfile);
4637 SetScratch(fi,&where);
4641 ttco = AR.CompressBuffer;
4645 AR.CompressPointer = ttco;
4646 retval = GetTerm(BHEAD term);
4649 else AN.lastinindex = n-1;
4656 bstart = bi[n].start;
4657 ADD2POS(bstart,eonfile);
4659 ADD2POS(bnext,eonfile);
4660 if ( ISLESSPOS(bstart,where) && ISLESSPOS(where,bnext) ) {
4661 retval = GetTerm(BHEAD term);
4664 for ( n++ ; n < b->indexfill; n++ ) {
4665 i = TreatIndexEntry(BHEAD n);
4670 ttco = AR.CompressBuffer;
4674 AR.CompressPointer = ttco;
4676 where = bi[n].start;
4677 ADD2POS(where,eonfile);
4678 SetScratch(fi,&(where));
4679 retval = GetTerm(BHEAD term);
4699 int TreatIndexEntry(
PHEAD LONG n)
4702 LONG numbra = b->indexfill - 1, i;
4710 if ( ( numbra - n ) <= numberofworkers )
return(0);
4716 DIFPOS(pos1,bi[numbra].next,bi[n].next);
4717 BASEPOSITION(average) = DIVPOS(pos1,(3*numberofworkers));
4718 DIFPOS(pos1,bi[n].next,bi[n].start);
4719 if ( ISLESSPOS(average,pos1) )
return(0);
4724 totterms = bi->termsinbracket;
4725 if ( totterms > 2*AC.ThreadBucketSize )
return(1);
4726 for ( i = 1; i < numbra-n; i++ ) {
4727 DIFPOS(pos1,bi[n+i].next,bi[n].start);
4728 if ( ISLESSPOS(average,pos1) )
return(i);
4729 totterms += bi->termsinbracket;
4730 if ( totterms > 2*AC.ThreadBucketSize )
return(i+1);
4743 void SetHideFiles() {
4745 ALLPRIVATES *B, *B0 = AB[0];
4746 for ( i = 1; i <= numberofworkers; i++ ) {
4748 if ( AR.hidefile->handle < 0 ) {
4749 AR.hidefile->PObuffer = AR0.hidefile->PObuffer;
4750 AR.hidefile->POstop = AR0.hidefile->POstop;
4751 AR.hidefile->POfill = AR0.hidefile->POfill;
4752 AR.hidefile->POfull = AR0.hidefile->POfull;
4753 AR.hidefile->POsize = AR0.hidefile->POsize;
4754 AR.hidefile->POposition = AR0.hidefile->POposition;
4755 AR.hidefile->filesize = AR0.hidefile->filesize;
4758 AR.hidefile->PObuffer = AR.hidefile->wPObuffer;
4759 AR.hidefile->POstop = AR.hidefile->wPOstop;
4760 AR.hidefile->POfill = AR.hidefile->wPOfill;
4761 AR.hidefile->POfull = AR.hidefile->wPOfull;
4762 AR.hidefile->POsize = AR.hidefile->wPOsize;
4763 PUTZERO(AR.hidefile->POposition);
4776 for ( i = 0; i < AM.totalnumberofthreads; i++ ) {
4790 for ( j = 0; j < AM.totalnumberofthreads; j++ ) {
4792 AN.ncmod = AC.ncmod;
4793 if ( AN.cmod != 0 ) M_free(AN.cmod,
"AN.cmod");
4795 AN.cmod = (UWORD *)Malloc1(
sizeof(WORD)*n,
"AN.cmod");
4796 for ( i = 0; i < n; i++ ) AN.cmod[i] = AC.cmod[i];
4809 for ( j = 0; j < AM.totalnumberofthreads; j++ ) {
4811 if ( AN.cmod != 0 ) M_free(AN.cmod,
"AN.cmod");
4820 void find_Horner_MCTS_expand_tree_threaded() {
4822 while ((
id = GetAvailableThread() ) < 0)
4824 WakeupThread(
id,MCTSEXPANDTREE);
4827 extern void optimize_expression_given_Horner_threaded() {
4829 while ((
id = GetAvailableThread() ) < 0)
4831 WakeupThread(
id,OPTIMIZEEXPRESSION);
int NormalModulus(UWORD *, WORD *)
VOID AddArgs(PHEAD WORD *, WORD *, WORD *)
VOID WriteStats(POSITION *, WORD)
WORD StoreTerm(PHEAD WORD *)
WORD Compare1(PHEAD WORD *, WORD *, WORD)
struct StOrEcAcHe * STORECACHE
BRACKETINDEX * indexbuffer
WORD PutOut(PHEAD WORD *, POSITION *, FILEHANDLE *, WORD)
WORD Generator(PHEAD WORD *, WORD)
WORD FlushOut(POSITION *, FILEHANDLE *, int)
LONG EndSort(PHEAD WORD *, int)