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;
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;
546 AR.FoStage4[0].POsize = ((IOsize+
sizeof(WORD)-1)/
sizeof(WORD))*
sizeof(WORD);
547 AR.FoStage4[1].POsize = ((IOsize+
sizeof(WORD)-1)/
sizeof(WORD))*
sizeof(WORD);
549 AR.hidefile = &(AR.Fscr[2]);
550 AR.StoreData.Handle = -1;
551 AR.SortType = AC.SortType;
553 AN.IndDum = AM.IndDum;
555 if ( identity > 0 ) {
556 s = (UBYTE *)(FG.fname); i = 0;
557 while ( *s ) { s++; i++; }
558 s = (UBYTE *)Malloc1(
sizeof(
char)*(i+12),
"name for Fscr[0] file");
559 sprintf((
char *)s,
"%s.%d",FG.fname,identity);
560 s[i-3] =
's'; s[i-2] =
'c'; s[i-1] =
'0';
561 AR.Fscr[0].name = (
char *)s;
562 s = (UBYTE *)(FG.fname); i = 0;
563 while ( *s ) { s++; i++; }
564 s = (UBYTE *)Malloc1(
sizeof(
char)*(i+12),
"name for Fscr[1] file");
565 sprintf((
char *)s,
"%s.%d",FG.fname,identity);
566 s[i-3] =
's'; s[i-2] =
'c'; s[i-1] =
'1';
567 AR.Fscr[1].name = (
char *)s;
570 AR.CompressBuffer = (WORD *)Malloc1((AM.CompressSize+10)*
sizeof(WORD),
"compresssize");
571 AR.ComprTop = AR.CompressBuffer + AM.CompressSize;
577 AT.WorkSpace = (WORD *)Malloc1(AM.WorkSize*
sizeof(WORD),
"WorkSpace");
578 AT.WorkTop = AT.WorkSpace + AM.WorkSize;
579 AT.WorkPointer = AT.WorkSpace;
581 AT.Nest = (
NESTING)Malloc1((LONG)
sizeof(
struct NeStInG)*AM.maxFlevels,
"functionlevels");
582 AT.NestStop = AT.Nest + AM.maxFlevels;
583 AT.NestPoin = AT.Nest;
585 AT.WildMask = (WORD *)Malloc1((LONG)AM.MaxWildcards*
sizeof(WORD),
"maxwildcards");
587 LOCK(availabilitylock);
592 UNLOCK(availabilitylock);
594 AT.RepCount = (
int *)Malloc1((LONG)((AM.RepMax+3)*
sizeof(
int)),
"repeat buffers");
595 AN.RepPoint = AT.RepCount;
599 AT.RepTop = AT.RepCount + AM.RepMax;
601 AT.WildArgTaken = (WORD *)Malloc1((LONG)AC.WildcardBufferSize*
sizeof(WORD)/2
602 ,
"argument list names");
603 AT.WildcardBufferSize = AC.WildcardBufferSize;
604 AT.previousEfactor = 0;
606 AT.identity = identity;
607 AT.LoadBalancing = 0;
613 if ( AT.WorkSpace == 0 ||
617 AT.WildArgTaken == 0 )
goto OnError;
622 AT.comsym[1] = SYMBOL;
633 AT.comfun[0] = FUNHEAD+4;
634 AT.comfun[1] = FUNCTION;
635 AT.comfun[2] = FUNHEAD;
638 for ( i = 4; i <= FUNHEAD; i++ )
641 AT.comfun[FUNHEAD+1] = 1;
642 AT.comfun[FUNHEAD+2] = 1;
643 AT.comfun[FUNHEAD+3] = 3;
645 AT.comind[1] = INDEX;
651 AT.locwildvalue[0] = SUBEXPRESSION;
652 AT.locwildvalue[1] = SUBEXPSIZE;
653 for ( i = 2; i < SUBEXPSIZE; i++ ) AT.locwildvalue[i] = 0;
654 AT.mulpat[0] = TYPEMULT;
655 AT.mulpat[1] = SUBEXPSIZE+3;
657 AT.mulpat[3] = SUBEXPRESSION;
658 AT.mulpat[4] = SUBEXPSIZE;
661 for ( i = 7; i < SUBEXPSIZE+5; i++ ) AT.mulpat[i] = 0;
662 AT.proexp[0] = SUBEXPSIZE+4;
663 AT.proexp[1] = EXPRESSION;
664 AT.proexp[2] = SUBEXPSIZE;
667 for ( i = 5; i < SUBEXPSIZE+1; i++ ) AT.proexp[i] = 0;
668 AT.proexp[SUBEXPSIZE+1] = 1;
669 AT.proexp[SUBEXPSIZE+2] = 1;
670 AT.proexp[SUBEXPSIZE+3] = 3;
671 AT.proexp[SUBEXPSIZE+4] = 0;
672 AT.dummysubexp[0] = SUBEXPRESSION;
673 AT.dummysubexp[1] = SUBEXPSIZE+4;
674 for ( i = 2; i < SUBEXPSIZE; i++ ) AT.dummysubexp[i] = 0;
675 AT.dummysubexp[SUBEXPSIZE] = WILDDUMMY;
676 AT.dummysubexp[SUBEXPSIZE+1] = 4;
677 AT.dummysubexp[SUBEXPSIZE+2] = 0;
678 AT.dummysubexp[SUBEXPSIZE+3] = 0;
680 AT.MinVecArg[0] = 7+ARGHEAD;
681 AT.MinVecArg[ARGHEAD] = 7;
682 AT.MinVecArg[1+ARGHEAD] = INDEX;
683 AT.MinVecArg[2+ARGHEAD] = 3;
684 AT.MinVecArg[3+ARGHEAD] = 0;
685 AT.MinVecArg[4+ARGHEAD] = 1;
686 AT.MinVecArg[5+ARGHEAD] = 1;
687 AT.MinVecArg[6+ARGHEAD] = -3;
689 *t++ = 4+ARGHEAD+FUNHEAD;
690 for ( i = 1; i < ARGHEAD; i++ ) *t++ = 0;
694 for ( i = 2; i < FUNHEAD; i++ ) *t++ = 0;
695 *t++ = 1; *t++ = 1; *t++ = 3;
698 AT.sizeprimelist = 0;
700 AT.nfac = AT.nBer = 0;
705 AR.wranfnpair1 = NPAIR1;
706 AR.wranfnpair2 = NPAIR2;
709 AN.SplitScratchSize = AN.InScratch = 0;
710 AN.SplitScratch1 = 0;
711 AN.SplitScratchSize1 = AN.InScratch1 = 0;
716 if ( identity == 0 ) {
724 AT.S0 = AllocSort(AM.S0->LargeSize*
sizeof(WORD)/numberofworkers
725 ,AM.S0->SmallSize*
sizeof(WORD)/numberofworkers
726 ,AM.S0->SmallEsize*
sizeof(WORD)/numberofworkers
730 ,AM.S0->MaxFpatches/numberofworkers
731 ,AM.S0->file.POsize);
733 AR.CompressPointer = AR.CompressBuffer;
737 AT.StoreCache = AT.StoreCacheAlloc = 0;
738 if ( AM.NumStoreCaches > 0 ) {
741 size =
sizeof(
struct StOrEcAcHe)+AM.SizeStoreCache;
742 size = ((size-1)/
sizeof(
size_t)+1)*
sizeof(
size_t);
743 AT.StoreCacheAlloc = (
STORECACHE)Malloc1(size*AM.NumStoreCaches,
"StoreCaches");
744 sa = AT.StoreCache = AT.StoreCacheAlloc;
745 for ( i = 0; i < AM.NumStoreCaches; i++ ) {
747 if ( i == AM.NumStoreCaches-1 ) {
753 SETBASEPOSITION(sa->position,-1);
754 SETBASEPOSITION(sa->toppos,-1);
762 MLOCK(ErrorMessageLock);
763 MesPrint(
"Error initializing thread %d",identity);
764 MUNLOCK(ErrorMessageLock);
783 void FinalizeOneThread(
int identity)
785 timerinfo[identity] =
TimeCPU(1);
798 VOID ClearAllThreads()
802 for ( i = 1; i <= numberofworkers; i++ ) {
803 WakeupThread(i,CLEARCLOCK);
806 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
807 WakeupThread(i,CLEARCLOCK);
822 VOID TerminateAllThreads()
825 for ( i = 1; i <= numberofworkers; i++ ) {
827 WakeupThread(i,TERMINATETHREAD);
830 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
831 WakeupThread(i,TERMINATETHREAD);
834 for ( i = 1; i <= numberofworkers; i++ ) {
835 pthread_join(threadpointers[i],NULL);
838 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
839 pthread_join(threadpointers[i],NULL);
873 int MakeThreadBuckets(
int number,
int par)
876 LONG sizethreadbuckets;
884 sizethreadbuckets = ( AC.ThreadBucketSize + 1 ) * AM.MaxTer + 2*
sizeof(WORD);
885 if ( AC.ThreadBucketSize >= 250 ) sizethreadbuckets /= 4;
886 else if ( AC.ThreadBucketSize >= 90 ) sizethreadbuckets /= 3;
887 else if ( AC.ThreadBucketSize >= 40 ) sizethreadbuckets /= 2;
888 sizethreadbuckets /=
sizeof(WORD);
891 numthreadbuckets = 2*(number-1);
892 threadbuckets = (THREADBUCKET **)Malloc1(numthreadbuckets*
sizeof(THREADBUCKET *),
"threadbuckets");
893 freebuckets = (THREADBUCKET **)Malloc1(numthreadbuckets*
sizeof(THREADBUCKET *),
"threadbuckets");
896 if ( sizethreadbuckets <= threadbuckets[0]->threadbuffersize )
return(0);
897 for ( i = 0; i < numthreadbuckets; i++ ) {
898 thr = threadbuckets[i];
899 M_free(thr->deferbuffer,
"deferbuffer");
903 for ( i = 0; i < numthreadbuckets; i++ ) {
904 threadbuckets[i] = (THREADBUCKET *)Malloc1(
sizeof(THREADBUCKET),
"threadbuckets");
905 threadbuckets[i]->lock = dummylock;
908 for ( i = 0; i < numthreadbuckets; i++ ) {
909 thr = threadbuckets[i];
910 thr->threadbuffersize = sizethreadbuckets;
911 thr->free = BUCKETFREE;
912 thr->deferbuffer = (
POSITION *)Malloc1(2*sizethreadbuckets*
sizeof(WORD)
913 +(AC.ThreadBucketSize+1)*
sizeof(
POSITION),
"deferbuffer");
914 thr->threadbuffer = (WORD *)(thr->deferbuffer+AC.ThreadBucketSize+1);
915 thr->compressbuffer = (WORD *)(thr->threadbuffer+sizethreadbuckets);
916 thr->busy = BUCKETPREPARINGTERM;
917 thr->usenum = thr->totnum = 0;
918 thr->type = BUCKETDOINGTERMS;
933 int GetTimerInfo(LONG** ti,LONG** sti)
938 return AM.totalnumberofthreads*2;
940 return AM.totalnumberofthreads;
953 void WriteTimerInfo(LONG* ti,LONG* sti)
957 int max = AM.totalnumberofthreads*2;
959 int max = AM.totalnumberofthreads;
961 for ( i=0; i<max; ++i ) {
962 timerinfo[i] = ti[i];
963 sumtimerinfo[i] = sti[i];
976 LONG GetWorkerTimes()
980 for ( i = 1; i <= numberofworkers; i++ ) retval += timerinfo[i] + sumtimerinfo[i];
982 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ )
983 retval += timerinfo[i] + sumtimerinfo[i];
998 int UpdateOneThread(
int identity)
1000 ALLPRIVATES *B = AB[identity], *B0 = AB[0];
1001 AR.GetFile = AR0.GetFile;
1002 AR.KeptInHold = AR0.KeptInHold;
1003 AR.CurExpr = AR0.CurExpr;
1004 AR.SortType = AC.SortType;
1005 if ( AT.WildcardBufferSize < AC.WildcardBufferSize ) {
1006 M_free(AT.WildArgTaken,
"argument list names");
1007 AT.WildcardBufferSize = AC.WildcardBufferSize;
1008 AT.WildArgTaken = (WORD *)Malloc1((LONG)AC.WildcardBufferSize*
sizeof(WORD)/2
1009 ,
"argument list names");
1010 if ( AT.WildArgTaken == 0 )
return(-1);
1032 int LoadOneThread(
int from,
int identity, THREADBUCKET *thr,
int par)
1035 ALLPRIVATES *B = AB[identity], *B0 = AB[from];
1037 AR.DefPosition = AR0.DefPosition;
1038 AR.NoCompress = AR0.NoCompress;
1039 AR.gzipCompress = AR0.gzipCompress;
1040 AR.BracketOn = AR0.BracketOn;
1041 AR.CurDum = AR0.CurDum;
1042 AR.DeferFlag = AR0.DeferFlag;
1044 AR.sLevel = AR0.sLevel;
1045 AR.Stage4Name = AR0.Stage4Name;
1046 AR.GetOneFile = AR0.GetOneFile;
1047 AR.PolyFun = AR0.PolyFun;
1048 AR.PolyFunInv = AR0.PolyFunInv;
1049 AR.PolyFunType = AR0.PolyFunType;
1050 AR.PolyFunExp = AR0.PolyFunExp;
1051 AR.PolyFunVar = AR0.PolyFunVar;
1052 AR.PolyFunPow = AR0.PolyFunPow;
1053 AR.Eside = AR0.Eside;
1054 AR.Cnumlhs = AR0.Cnumlhs;
1066 t1 = AR.CompressBuffer; t2 = AR0.CompressBuffer;
1067 while ( t2 < AR0.CompressPointer ) *t1++ = *t2++;
1068 AR.CompressPointer = t1;
1072 AR.CompressPointer = AR.CompressBuffer;
1074 if ( AR.DeferFlag ) {
1075 if ( AR.infile->handle < 0 ) {
1076 AR.infile->POfill = AR0.infile->POfill;
1083 AR.infile->POfull = AR.infile->POfill = AR.infile->PObuffer;
1087 AN.threadbuck = thr;
1088 AN.ninterms = thr->firstterm;
1090 else if ( par == 1 ) {
1092 t1 = thr->threadbuffer; tstop = t1 + *t1;
1093 t2 = AT.WorkPointer;
1094 while ( t1 < tstop ) *t2++ = *t1++;
1095 AN.ninterms = thr->firstterm;
1098 AN.ncmod = AC.ncmod;
1099 AT.BrackBuf = AT0.BrackBuf;
1100 AT.bracketindexflag = AT0.bracketindexflag;
1128 int BalanceRunThread(
PHEAD int identity, WORD *term, WORD level)
1135 LoadOneThread(AT.identity,identity,0,2);
1141 BB->R.level = level;
1142 BB->T.TMbuff = AT.TMbuff;
1143 ti = AT.RepCount; tti = BB->T.RepCount;
1144 i = AN.RepPoint - AT.RepCount;
1145 BB->N.RepPoint = BB->T.RepCount + i;
1146 for ( ; i >= 0; i-- ) tti[i] = ti[i];
1148 t = term; i = *term;
1149 tt = BB->T.WorkSpace;
1151 BB->T.WorkPointer = tt;
1153 WakeupThread(identity,HIGHERLEVELGENERATION);
1166 void SetWorkerFiles()
1169 ALLPRIVATES *B, *B0 = AB[0];
1170 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
1172 AR.infile = &(AR.Fscr[0]);
1173 AR.outfile = &(AR.Fscr[1]);
1174 AR.hidefile = &(AR.Fscr[2]);
1175 AR.infile->handle = AR0.infile->handle;
1176 AR.hidefile->handle = AR0.hidefile->handle;
1177 if ( AR.infile->handle < 0 ) {
1178 AR.infile->PObuffer = AR0.infile->PObuffer;
1179 AR.infile->POstop = AR0.infile->POstop;
1180 AR.infile->POfill = AR0.infile->POfill;
1181 AR.infile->POfull = AR0.infile->POfull;
1182 AR.infile->POsize = AR0.infile->POsize;
1183 AR.InInBuf = AR0.InInBuf;
1184 AR.infile->POposition = AR0.infile->POposition;
1185 AR.infile->filesize = AR0.infile->filesize;
1188 AR.infile->PObuffer = AR.infile->wPObuffer;
1189 AR.infile->POstop = AR.infile->wPOstop;
1190 AR.infile->POfill = AR.infile->wPOfill;
1191 AR.infile->POfull = AR.infile->wPOfull;
1192 AR.infile->POsize = AR.infile->wPOsize;
1194 PUTZERO(AR.infile->POposition);
1202 AR.outfile->PObuffer = AR.outfile->wPObuffer;
1203 AR.outfile->POstop = AR.outfile->wPOstop;
1204 AR.outfile->POfill = AR.outfile->wPOfill;
1205 AR.outfile->POfull = AR.outfile->wPOfull;
1206 AR.outfile->POsize = AR.outfile->wPOsize;
1207 PUTZERO(AR.outfile->POposition);
1209 if ( AR.hidefile->handle < 0 ) {
1210 AR.hidefile->PObuffer = AR0.hidefile->PObuffer;
1211 AR.hidefile->POstop = AR0.hidefile->POstop;
1212 AR.hidefile->POfill = AR0.hidefile->POfill;
1213 AR.hidefile->POfull = AR0.hidefile->POfull;
1214 AR.hidefile->POsize = AR0.hidefile->POsize;
1215 AR.InHiBuf = AR0.InHiBuf;
1216 AR.hidefile->POposition = AR0.hidefile->POposition;
1217 AR.hidefile->filesize = AR0.hidefile->filesize;
1220 AR.hidefile->PObuffer = AR.hidefile->wPObuffer;
1221 AR.hidefile->POstop = AR.hidefile->wPOstop;
1222 AR.hidefile->POfill = AR.hidefile->wPOfill;
1223 AR.hidefile->POfull = AR.hidefile->wPOfull;
1224 AR.hidefile->POsize = AR.hidefile->wPOsize;
1226 PUTZERO(AR.hidefile->POposition);
1229 if ( AR0.StoreData.dirtyflag ) {
1230 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
1232 AR.StoreData = AR0.StoreData;
1248 void *RunThread(
void *dummy)
1250 WORD *term, *ttin, *tt, *ttco, *oldwork;
1251 int identity, wakeupsignal, identityretv, i, tobereleased, errorcode;
1257 identity = SetIdentity(&identityretv);
1258 threadpointers[identity] = pthread_self();
1259 B = InitializeOneThread(identity);
1260 while ( ( wakeupsignal = ThreadWait(identity) ) > 0 ) {
1261 switch ( wakeupsignal ) {
1265 case STARTNEWEXPRESSION:
1270 if ( UpdateOneThread(identity) ) {
1271 MLOCK(ErrorMessageLock);
1272 MesPrint(
"Update error in starting expression in thread %d in module %d",identity,AC.CModule);
1273 MUNLOCK(ErrorMessageLock);
1276 AR.DeferFlag = AC.ComDefer;
1277 AR.sLevel = AS.sLevel;
1278 AR.MaxDum = AM.IndDum;
1279 AR.expchanged = AB[0]->R.expchanged;
1280 AR.expflags = AB[0]->R.expflags;
1281 AR.PolyFun = AB[0]->R.PolyFun;
1282 AR.PolyFunInv = AB[0]->R.PolyFunInv;
1283 AR.PolyFunType = AB[0]->R.PolyFunType;
1284 AR.PolyFunExp = AB[0]->R.PolyFunExp;
1285 AR.PolyFunVar = AB[0]->R.PolyFunVar;
1286 AR.PolyFunPow = AB[0]->R.PolyFunPow;
1296 case LOWESTLEVELGENERATION:
1298 if ( AC.InnerTest ) {
1299 if ( StrCmp(AC.TestValue,(UBYTE *)INNERTEST) == 0 ) {
1300 MesPrint(
"Testing(Worker%d): value = %s",AT.identity,AC.TestValue);
1304 e = Expressions + AR.CurExpr;
1305 thr = AN.threadbuck;
1306 ppdef = thr->deferbuffer;
1307 ttin = thr->threadbuffer;
1308 ttco = thr->compressbuffer;
1309 term = AT.WorkPointer;
1312 AN.inputnumber = thr->firstterm;
1313 AN.ninterms = thr->firstterm;
1316 tt = term; i = *ttin;
1318 AT.WorkPointer = tt;
1319 if ( AR.DeferFlag ) {
1320 tt = AR.CompressBuffer; i = *ttco;
1322 AR.CompressPointer = tt;
1323 AR.DefPosition = ppdef[0]; ppdef++;
1325 if ( thr->free == BUCKETTERMINATED ) {
1333 if ( thr->usenum == thr->totnum ) {
1334 thr->free = BUCKETCOMINGFREE;
1337 thr->free = BUCKETRELEASED;
1347 thr->busy = BUCKETDOINGTERM;
1355 AN.RepPoint = AT.RepCount + 1;
1357 if ( ( e->vflags & ISFACTORIZED ) != 0 && term[1] == HAAKJE ) {
1361 if ( AR.DeferFlag ) {
1362 AR.CurDum = AN.IndDum = Expressions[AR.CurExpr].numdummies + AM.IndDum;
1365 AN.IndDum = AM.IndDum;
1366 AR.CurDum = ReNumber(BHEAD term);
1368 if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
1370 if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1371 else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1373 else if ( AC.PolyRatFunChanged ) PolyFunDirty(BHEAD term);
1374 if ( ( AP.PreDebug & THREADSDEBUG ) != 0 ) {
1375 MLOCK(ErrorMessageLock);
1376 MesPrint(
"Thread %w executing term:");
1377 PrintTerm(term,
"LLG");
1378 MUNLOCK(ErrorMessageLock);
1380 if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
1381 && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1382 PolyFunClean(BHEAD term);
1386 MLOCK(ErrorMessageLock);
1387 MesPrint(
"Error in processing one term in thread %d in module %d",identity,AC.CModule);
1388 MUNLOCK(ErrorMessageLock);
1395 thr->busy = BUCKETPREPARINGTERM;
1403 if ( thr->free == BUCKETTERMINATED ) {
1404 if ( thr->usenum == thr->totnum ) {
1405 thr->free = BUCKETCOMINGFREE;
1408 thr->free = BUCKETRELEASED;
1412 if ( tobereleased )
goto bucketstolen;
1414 thr->free = BUCKETCOMINGFREE;
1418 thr->busy = BUCKETTOBERELEASED;
1425 AT.WorkPointer = term;
1433 LOCK(AT.SB.MasterBlockLock[1]);
1436 case FINISHEXPRESSION:
1444 LOCK(AT.SB.MasterBlockLock[1]);
1445 ThreadClaimedBlock(identity);
1450 case FINISHEXPRESSION2:
1455 if ( AC.ThreadSortFileSynch ) {
1456 if ( AT.S0->file.handle >= 0 ) {
1457 SynchFile(AT.S0->file.handle);
1460 AT.SB.FillBlock = 1;
1461 AT.SB.MasterFill[1] = AT.SB.MasterStart[1];
1462 errorcode =
EndSort(BHEAD AT.S0->sBuffer,0);
1463 UNLOCK(AT.SB.MasterBlockLock[AT.SB.FillBlock]);
1466 MLOCK(ErrorMessageLock);
1467 MesPrint(
"Error terminating sort in thread %d in module %d",identity,AC.CModule);
1468 MUNLOCK(ErrorMessageLock);
1476 case CLEANUPEXPRESSION:
1480 if ( AR.outfile->handle >= 0 ) {
1481 CloseFile(AR.outfile->handle);
1482 AR.outfile->handle = -1;
1483 remove(AR.outfile->name);
1484 AR.outfile->POfill = AR.outfile->POfull = AR.outfile->PObuffer;
1485 PUTZERO(AR.outfile->POposition);
1486 PUTZERO(AR.outfile->filesize);
1489 AR.outfile->POfill = AR.outfile->POfull = AR.outfile->PObuffer;
1490 PUTZERO(AR.outfile->POposition);
1491 PUTZERO(AR.outfile->filesize);
1494 CBUF *C = cbuf+AT.ebufnum;
1496 if ( C->numrhs > 0 || C->numlhs > 0 ) {
1498 w = C->
rhs; ii = C->numrhs;
1499 do { *w++ = 0; }
while ( --ii > 0 );
1502 w = C->
lhs; ii = C->numlhs;
1503 do { *w++ = 0; }
while ( --ii > 0 );
1505 C->numlhs = C->numrhs = 0;
1506 ClearTree(AT.ebufnum);
1515 case HIGHERLEVELGENERATION:
1520 term = AT.WorkSpace; AT.WorkPointer = term + *term;
1523 MLOCK(ErrorMessageLock);
1524 MesPrint(
"Error in load balancing one term at level %d in thread %d in module %d",AR.level,AT.identity,AC.CModule);
1525 MUNLOCK(ErrorMessageLock);
1528 AT.WorkPointer = term;
1534 case STARTNEWMODULE:
1544 case TERMINATETHREAD:
1562 case DOONEEXPRESSION: {
1567 WORD oldBracketOn = AR.BracketOn;
1568 WORD *oldBrackBuf = AT.BrackBuf;
1569 WORD oldbracketindexflag = AT.bracketindexflag;
1570 WORD fromspectator = 0;
1571 e = Expressions + AR.exprtodo;
1574 AR.SortType = AC.SortType;
1576 if ( ( e->vflags & ISFACTORIZED ) != 0 ) {
1578 AT.BrackBuf = AM.BracketFactors;
1579 AT.bracketindexflag = 1;
1582 position = AS.OldOnFile[i];
1583 if ( e->status == HIDDENLEXPRESSION || e->status == HIDDENGEXPRESSION ) {
1584 AR.GetFile = 2; fi = AR.hidefile;
1587 AR.GetFile = 0; fi = AR.infile;
1595 SetScratch(fi,&position);
1596 term = oldwork = AT.WorkPointer;
1597 AR.CompressPointer = AR.CompressBuffer;
1598 AR.CompressPointer[0] = 0;
1600 if ( GetTerm(BHEAD term) <= 0 ) {
1601 MLOCK(ErrorMessageLock);
1602 MesPrint(
"Expression %d has problems in scratchfile (t)",i);
1603 MUNLOCK(ErrorMessageLock);
1606 if ( AT.bracketindexflag > 0 ) OpenBracketIndex(i);
1608 if ( term[5] < 0 ) {
1609 fromspectator = -term[5];
1610 PUTZERO(AM.SpectatorFiles[fromspectator-1].readpos);
1611 term[5] = AC.cbufnum;
1613 PUTZERO(outposition);
1615 fout->POfill = fout->POfull = fout->PObuffer;
1616 fout->POposition = outposition;
1617 if ( fout->
handle >= 0 ) {
1618 fout->POposition = outposition;
1630 if (
PutOut(BHEAD term,&outposition,fout,0) < 0 )
goto ProcErr;
1632 AR.DeferFlag = AC.ComDefer;
1634 AR.sLevel = AB[0]->R.sLevel;
1635 term = AT.WorkPointer;
1637 AR.MaxDum = AM.IndDum;
1639 if ( fromspectator ) {
1640 while ( GetFromSpectator(term,fromspectator-1) ) {
1641 AT.WorkPointer = term + *term;
1642 AN.RepPoint = AT.RepCount + 1;
1643 AN.IndDum = AM.IndDum;
1644 AR.CurDum = ReNumber(BHEAD term);
1645 if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
1647 if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1648 else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1650 else if ( AC.PolyRatFunChanged ) PolyFunDirty(BHEAD term);
1651 if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
1652 && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1653 PolyFunClean(BHEAD term);
1661 while ( GetTerm(BHEAD term) ) {
1662 SeekScratch(fi,&position);
1663 AN.ninterms++; dd = AN.deferskipped;
1664 if ( ( e->vflags & ISFACTORIZED ) != 0 && term[1] == HAAKJE ) {
1668 if ( AC.CollectFun && *term <= (AM.MaxTer/(2*(LONG)
sizeof(WORD))) ) {
1669 if ( GetMoreTerms(term) < 0 ) {
1672 SeekScratch(fi,&position);
1674 AT.WorkPointer = term + *term;
1675 AN.RepPoint = AT.RepCount + 1;
1676 if ( AR.DeferFlag ) {
1677 AR.CurDum = AN.IndDum = Expressions[AR.exprtodo].numdummies;
1680 AN.IndDum = AM.IndDum;
1681 AR.CurDum = ReNumber(BHEAD term);
1683 if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
1685 if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1686 else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1688 else if ( AC.PolyRatFunChanged ) PolyFunDirty(BHEAD term);
1689 if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
1690 && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1691 PolyFunClean(BHEAD term);
1698 SetScratch(fi,&position);
1699 if ( fi == AR.hidefile ) {
1700 AR.InHiBuf = (fi->POfull-fi->PObuffer)
1701 -DIFBASE(position,fi->POposition)/
sizeof(WORD);
1704 AR.InInBuf = (fi->POfull-fi->PObuffer)
1705 -DIFBASE(position,fi->POposition)/
sizeof(WORD);
1710 if (
EndSort(BHEAD AT.S0->sBuffer,0) < 0 )
goto ProcErr;
1711 e->numdummies = AR.MaxDum - AM.IndDum;
1712 AR.BracketOn = oldBracketOn;
1713 AT.BrackBuf = oldBrackBuf;
1714 if ( ( e->vflags & TOBEFACTORED ) != 0 )
1715 poly_factorize_expression(e);
1716 else if ( ( ( e->vflags & TOBEUNFACTORED ) != 0 )
1717 && ( ( e->vflags & ISFACTORIZED ) != 0 ) )
1718 poly_unfactorize_expression(e);
1719 if ( AT.S0->TermsLeft ) e->vflags &= ~ISZERO;
1720 else e->vflags |= ISZERO;
1721 if ( AR.expchanged == 0 ) e->vflags |= ISUNMODIFIED;
1722 if ( AT.S0->TermsLeft ) AR.expflags |= ISZERO;
1723 if ( AR.expchanged ) AR.expflags |= ISUNMODIFIED;
1725 AT.bracketindexflag = oldbracketindexflag;
1730 SeekScratch(fout,&outposition);
1731 LOCK(AS.outputslock);
1732 oldoutfile = AB[0]->R.outfile;
1733 if ( e->status == INTOHIDELEXPRESSION || e->status == INTOHIDEGEXPRESSION ) {
1734 AB[0]->R.outfile = AB[0]->R.hidefile;
1736 SeekScratch(AB[0]->R.outfile,&position);
1737 e->onfile = position;
1738 if ( CopyExpression(fout,AB[0]->R.outfile) < 0 ) {
1739 AB[0]->R.outfile = oldoutfile;
1740 UNLOCK(AS.outputslock);
1741 MLOCK(ErrorMessageLock);
1742 MesPrint(
"Error copying output of 'InParallel' expression to master. Thread: %d",identity);
1743 MUNLOCK(ErrorMessageLock);
1746 AB[0]->R.outfile = oldoutfile;
1747 AB[0]->R.hidefile->POfull = AB[0]->R.hidefile->POfill;
1748 AB[0]->R.expflags = AR.expflags;
1749 UNLOCK(AS.outputslock);
1751 if ( fout->
handle >= 0 ) {
1755 PUTZERO(fout->POposition);
1756 PUTZERO(fout->filesize);
1757 fout->POfill = fout->POfull = fout->PObuffer;
1761 AT.WorkPointer = oldwork;
1785 e = Expressions + AR.CurExpr;
1786 binfo = e->bracketinfo;
1787 thr = AN.threadbuck;
1789 if ( AR.GetFile == 2 ) fi = AR.hidefile;
1790 else fi = AR.infile;
1792 ADD2POS(where,AS.OldOnFile[AR.CurExpr]);
1793 SetScratch(fi,&(where));
1794 stoppos = binfo->
indexbuffer[thr->lastbracket].next;
1795 ADD2POS(stoppos,AS.OldOnFile[AR.CurExpr]);
1796 AN.ninterms = thr->firstterm;
1801 ttco = AR.CompressBuffer;
1805 AR.CompressPointer = ttco;
1806 term = AT.WorkPointer;
1807 while ( GetTerm(BHEAD term) ) {
1808 SeekScratch(fi,&where);
1809 AT.WorkPointer = term + *term;
1810 AN.IndDum = AM.IndDum;
1811 AR.CurDum = ReNumber(BHEAD term);
1812 if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
1814 if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1815 else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1817 else if ( AC.PolyRatFunChanged ) PolyFunDirty(BHEAD term);
1818 if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
1819 && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1820 PolyFunClean(BHEAD term);
1822 if ( ( AP.PreDebug & THREADSDEBUG ) != 0 ) {
1823 MLOCK(ErrorMessageLock);
1824 MesPrint(
"Thread %w executing term:");
1825 PrintTerm(term,
"DoBrackets");
1826 MUNLOCK(ErrorMessageLock);
1828 AT.WorkPointer = term + *term;
1831 MLOCK(ErrorMessageLock);
1832 MesPrint(
"Error in processing one term in thread %d in module %d",identity,AC.CModule);
1833 MUNLOCK(ErrorMessageLock);
1837 SetScratch(fi,&(where));
1838 if ( ISGEPOS(where,stoppos) )
break;
1840 AT.WorkPointer = term;
1841 thr->free = BUCKETCOMINGFREE;
1852 sumtimerinfo[identity] +=
TimeCPU(1);
1853 timerinfo[identity] =
TimeCPU(0);
1860 case MCTSEXPANDTREE:
1861 AT.optimtimes = AB[0]->T.optimtimes;
1862 find_Horner_MCTS_expand_tree();
1868 case OPTIMIZEEXPRESSION:
1869 optimize_expression_given_Horner();
1875 MLOCK(ErrorMessageLock);
1876 MesPrint(
"Illegal wakeup signal %d for thread %d",wakeupsignal,identity);
1877 MUNLOCK(ErrorMessageLock);
1883 timerinfo[identity] =
TimeCPU(1);
1889 FinalizeOneThread(identity);
1909 void *RunSortBot(
void *dummy)
1911 int identity, wakeupsignal, identityretv;
1912 ALLPRIVATES *B, *BB;
1914 identity = SetIdentity(&identityretv);
1915 threadpointers[identity] = pthread_self();
1916 B = InitializeOneThread(identity);
1917 while ( ( wakeupsignal = SortBotWait(identity) ) > 0 ) {
1918 switch ( wakeupsignal ) {
1923 AR.CurExpr = AB[0]->R.CurExpr;
1924 AR.PolyFun = AB[0]->R.PolyFun;
1925 AR.PolyFunInv = AB[0]->R.PolyFunInv;
1926 AR.PolyFunType = AB[0]->R.PolyFunType;
1927 AR.PolyFunExp = AB[0]->R.PolyFunExp;
1928 AR.PolyFunVar = AB[0]->R.PolyFunVar;
1929 AR.PolyFunPow = AB[0]->R.PolyFunPow;
1930 AR.SortType = AC.SortType;
1931 if ( AR.PolyFun == 0 ) { AT.SS->PolyFlag = 0; }
1932 else if ( AR.PolyFunType == 1 ) { AT.SS->PolyFlag = 1; }
1933 else if ( AR.PolyFunType == 2 ) {
1934 if ( AR.PolyFunExp == 2
1935 || AR.PolyFunExp == 3 ) AT.SS->PolyFlag = 1;
1936 else AT.SS->PolyFlag = 2;
1938 AT.SS->PolyWise = 0;
1939 AN.ncmod = AC.ncmod;
1940 LOCK(AT.SB.MasterBlockLock[1]);
1941 BB = AB[AT.SortBotIn1];
1942 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
1943 BB = AB[AT.SortBotIn2];
1944 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
1945 AT.SB.FillBlock = 1;
1946 AT.SB.MasterFill[1] = AT.SB.MasterStart[1];
1947 SETBASEPOSITION(AN.theposition,0);
1960 case TERMINATETHREAD:
1970 sumtimerinfo[identity] +=
TimeCPU(1);
1971 timerinfo[identity] =
TimeCPU(0);
1978 MLOCK(ErrorMessageLock);
1979 MesPrint(
"Illegal wakeup signal %d for thread %d",wakeupsignal,identity);
1980 MUNLOCK(ErrorMessageLock);
1989 FinalizeOneThread(identity);
2010 void IAmAvailable(
int identity)
2013 LOCK(availabilitylock);
2014 top = topofavailables;
2015 listofavailables[topofavailables++] = identity;
2017 UNLOCK(availabilitylock);
2018 LOCK(wakeupmasterlock);
2019 wakeupmaster = identity;
2020 pthread_cond_signal(&wakeupmasterconditions);
2021 UNLOCK(wakeupmasterlock);
2024 UNLOCK(availabilitylock);
2040 int GetAvailableThread()
2043 LOCK(availabilitylock);
2044 if ( topofavailables > 0 ) retval = listofavailables[--topofavailables];
2045 UNLOCK(availabilitylock);
2046 if ( retval >= 0 ) {
2051 LOCK(wakeuplocks[retval]);
2052 UNLOCK(wakeuplocks[retval]);
2068 int ConditionalGetAvailableThread()
2071 if ( topofavailables > 0 ) {
2072 LOCK(availabilitylock);
2073 if ( topofavailables > 0 ) {
2074 retval = listofavailables[--topofavailables];
2076 UNLOCK(availabilitylock);
2077 if ( retval >= 0 ) {
2082 LOCK(wakeuplocks[retval]);
2083 UNLOCK(wakeuplocks[retval]);
2102 int GetThread(
int identity)
2105 LOCK(availabilitylock);
2106 for ( j = 0; j < topofavailables; j++ ) {
2107 if ( identity == listofavailables[j] )
break;
2109 if ( j < topofavailables ) {
2111 for ( ; j < topofavailables; j++ ) {
2112 listofavailables[j] = listofavailables[j+1];
2116 UNLOCK(availabilitylock);
2133 int ThreadWait(
int identity)
2136 LOCK(wakeuplocks[identity]);
2137 LOCK(availabilitylock);
2138 top = topofavailables;
2139 for ( j = topofavailables; j > 0; j-- )
2140 listofavailables[j] = listofavailables[j-1];
2141 listofavailables[0] = identity;
2143 if ( top == 0 || topofavailables == numberofworkers ) {
2144 UNLOCK(availabilitylock);
2145 LOCK(wakeupmasterlock);
2146 wakeupmaster = identity;
2147 pthread_cond_signal(&wakeupmasterconditions);
2148 UNLOCK(wakeupmasterlock);
2151 UNLOCK(availabilitylock);
2153 while ( wakeup[identity] == 0 ) {
2154 pthread_cond_wait(&(wakeupconditions[identity]),&(wakeuplocks[identity]));
2156 retval = wakeup[identity];
2157 wakeup[identity] = 0;
2158 UNLOCK(wakeuplocks[identity]);
2177 int SortBotWait(
int identity)
2180 LOCK(wakeuplocks[identity]);
2181 LOCK(availabilitylock);
2182 topsortbotavailables++;
2183 if ( topsortbotavailables >= numberofsortbots ) {
2184 UNLOCK(availabilitylock);
2185 LOCK(wakeupsortbotlock);
2186 wakeupmaster = identity;
2187 pthread_cond_signal(&wakeupsortbotconditions);
2188 UNLOCK(wakeupsortbotlock);
2191 UNLOCK(availabilitylock);
2193 while ( wakeup[identity] == 0 ) {
2194 pthread_cond_wait(&(wakeupconditions[identity]),&(wakeuplocks[identity]));
2196 retval = wakeup[identity];
2197 wakeup[identity] = 0;
2198 UNLOCK(wakeuplocks[identity]);
2218 int ThreadClaimedBlock(
int identity)
2220 LOCK(availabilitylock);
2222 if ( numberclaimed >= numberofworkers ) {
2223 UNLOCK(availabilitylock);
2224 LOCK(wakeupmasterlock);
2225 wakeupmaster = identity;
2226 pthread_cond_signal(&wakeupmasterconditions);
2227 UNLOCK(wakeupmasterlock);
2230 UNLOCK(availabilitylock);
2249 LOCK(wakeupmasterlock);
2250 while ( wakeupmaster == 0 ) {
2251 pthread_cond_wait(&wakeupmasterconditions,&wakeupmasterlock);
2253 retval = wakeupmaster;
2255 UNLOCK(wakeupmasterlock);
2269 int MasterWaitThread(
int identity)
2272 LOCK(wakeupmasterthreadlocks[identity]);
2273 while ( wakeupmasterthread[identity] == 0 ) {
2274 pthread_cond_wait(&(wakeupmasterthreadconditions[identity])
2275 ,&(wakeupmasterthreadlocks[identity]));
2277 retval = wakeupmasterthread[identity];
2278 wakeupmasterthread[identity] = 0;
2279 UNLOCK(wakeupmasterthreadlocks[identity]);
2293 void MasterWaitAll()
2295 LOCK(wakeupmasterlock);
2296 while ( topofavailables < numberofworkers ) {
2297 pthread_cond_wait(&wakeupmasterconditions,&wakeupmasterlock);
2299 UNLOCK(wakeupmasterlock);
2315 void MasterWaitAllSortBots()
2317 LOCK(wakeupsortbotlock);
2318 while ( topsortbotavailables < numberofsortbots ) {
2319 pthread_cond_wait(&wakeupsortbotconditions,&wakeupsortbotlock);
2321 UNLOCK(wakeupsortbotlock);
2337 void MasterWaitAllBlocks()
2339 LOCK(wakeupmasterlock);
2340 while ( numberclaimed < numberofworkers ) {
2341 pthread_cond_wait(&wakeupmasterconditions,&wakeupmasterlock);
2343 UNLOCK(wakeupmasterlock);
2359 void WakeupThread(
int identity,
int signalnumber)
2361 if ( signalnumber == 0 ) {
2362 MLOCK(ErrorMessageLock);
2363 MesPrint(
"Illegal wakeup signal for thread %d",identity);
2364 MUNLOCK(ErrorMessageLock);
2367 LOCK(wakeuplocks[identity]);
2368 wakeup[identity] = signalnumber;
2369 pthread_cond_signal(&(wakeupconditions[identity]));
2370 UNLOCK(wakeuplocks[identity]);
2385 void WakeupMasterFromThread(
int identity,
int signalnumber)
2387 if ( signalnumber == 0 ) {
2388 MLOCK(ErrorMessageLock);
2389 MesPrint(
"Illegal wakeup signal for master %d",identity);
2390 MUNLOCK(ErrorMessageLock);
2393 LOCK(wakeupmasterthreadlocks[identity]);
2394 wakeupmasterthread[identity] = signalnumber;
2395 pthread_cond_signal(&(wakeupmasterthreadconditions[identity]));
2396 UNLOCK(wakeupmasterthreadlocks[identity]);
2408 int SendOneBucket(
int type)
2410 ALLPRIVATES *B0 = AB[0];
2411 THREADBUCKET *thr = 0;
2413 for ( j = 0; j < numthreadbuckets; j++ ) {
2414 if ( threadbuckets[j]->free == BUCKETFILLED ) {
2415 thr = threadbuckets[j];
2416 for ( k = j+1; k < numthreadbuckets; k++ )
2417 threadbuckets[k-1] = threadbuckets[k];
2418 threadbuckets[numthreadbuckets-1] = thr;
2423 while ( (
id = GetAvailableThread() ) < 0 ) { MasterWait(); }
2427 LoadOneThread(0,
id,thr,0);
2428 thr->busy = BUCKETASSIGNED;
2429 thr->free = BUCKETINUSE;
2430 numberoffullbuckets--;
2438 WakeupThread(
id,type);
2466 int InParallelProcessor()
2469 int i, id, retval = 0, num = 0;
2471 if ( numberofworkers >= 2 ) {
2473 for ( i = 0; i < NumExpressions; i++ ) {
2475 if ( e->partodo <= 0 )
continue;
2476 if ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION
2477 || e->status == UNHIDELEXPRESSION || e->status == UNHIDEGEXPRESSION
2478 || e->status == INTOHIDELEXPRESSION || e->status == INTOHIDEGEXPRESSION ) {
2484 if ( e->counter == 0 ) {
2491 while ( (
id = GetAvailableThread() ) < 0 ) { MasterWait(); }
2492 LoadOneThread(0,
id,0,-1);
2493 AB[id]->R.exprtodo = i;
2494 WakeupThread(
id,DOONEEXPRESSION);
2500 if ( num > 0 ) MasterWaitAll();
2502 if ( AC.CollectFun ) AR.DeferFlag = 0;
2505 for ( i = 0; i < NumExpressions; i++ ) {
2506 Expressions[i].partodo = 0;
2540 int ThreadsProcessor(
EXPRESSIONS e, WORD LastExpression, WORD fromspectator)
2542 ALLPRIVATES *B0 = AB[0], *B = B0;
2543 int id, oldgzipCompress, endofinput = 0, j, still, k, defcount = 0, bra = 0, first = 1;
2544 LONG dd = 0, ddd, thrbufsiz, thrbufsiz0, thrbufsiz2, numbucket = 0, numpasses;
2546 WORD *oldworkpointer = AT0.WorkPointer, *tt, *ttco = 0, *t1 = 0, ter, *tstop = 0, *t2;
2547 THREADBUCKET *thr = 0;
2549 GETTERM GetTermP = &GetTerm;
2550 POSITION eonfile = AS.OldOnFile[e-Expressions];
2551 numberoffullbuckets = 0;
2557 AM.tracebackflag = 1;
2559 AS.sLevel = AR0.sLevel;
2560 LOCK(availabilitylock);
2561 topofavailables = 0;
2562 for (
id = 1;
id <= numberofworkers;
id++ ) {
2563 WakeupThread(
id,STARTNEWEXPRESSION);
2565 UNLOCK(availabilitylock);
2571 if ( AC.numpfirstnum > 0 ) {
2572 for ( j = 0; j < AC.numpfirstnum; j++ ) {
2573 AC.inputnumbers[j] = -1;
2585 thrbufsiz2 = thrbufsiz = AC.ThreadBucketSize-1;
2586 if ( ( e->counter / ( numberofworkers * 5 ) ) < thrbufsiz ) {
2587 thrbufsiz = e->counter / ( numberofworkers * 5 ) - 1;
2588 if ( thrbufsiz < 0 ) thrbufsiz = 0;
2590 thrbufsiz0 = thrbufsiz;
2592 thrbufsiz = thrbufsiz0 / (2 << numpasses);
2596 for ( j = 0; j < numthreadbuckets; j++ )
2597 threadbuckets[j]->free = BUCKETFREE;
2598 thr = threadbuckets[0];
2606 #ifdef WHOLEBRACKETS 2607 if ( e->bracketinfo && AC.CollectFun == 0 && AR0.DeferFlag == 0 ) {
2612 for ( n = 0; n < e->bracketinfo->indexfill; n++ ) {
2613 num = TreatIndexEntry(B0,n);
2621 for ( j = 0; j < numthreadbuckets; j++ ) {
2622 switch ( threadbuckets[j]->free ) {
2624 thr = threadbuckets[j];
2626 case BUCKETCOMINGFREE:
2627 thr = threadbuckets[j];
2628 thr->free = BUCKETFREE;
2629 for ( k = j+1; k < numthreadbuckets; k++ )
2630 threadbuckets[k-1] = threadbuckets[k];
2631 threadbuckets[numthreadbuckets-1] = thr;
2639 if ( j < numthreadbuckets ) {
2643 thr->firstbracket = n;
2644 thr->lastbracket = n + num - 1;
2645 thr->type = BUCKETDOINGBRACKET;
2646 thr->free = BUCKETFILLED;
2647 thr->firstterm = AN0.ninterms;
2648 for ( j = n; j < n+num; j++ ) {
2649 AN0.ninterms += e->bracketinfo->
indexbuffer[j].termsinbracket;
2652 numberoffullbuckets++;
2653 if ( topofavailables > 0 ) {
2654 SendOneBucket(DOBRACKETS);
2663 while ( topofavailables <= 0 ) {
2666 SendOneBucket(DOBRACKETS);
2675 switch ( e->status ) {
2676 case UNHIDELEXPRESSION:
2677 case UNHIDEGEXPRESSION:
2678 case DROPHLEXPRESSION:
2679 case DROPHGEXPRESSION:
2680 case HIDDENLEXPRESSION:
2681 case HIDDENGEXPRESSION:
2682 curfile = AR0.hidefile;
2685 curfile = AR0.infile;
2688 SetScratch(curfile,&eonfile);
2689 GetTerm(B0,AT0.WorkPointer);
2693 GetTermP = &GetTerm2;
2698 for ( j = 0; j < numthreadbuckets; j++ ) {
2699 switch ( threadbuckets[j]->free ) {
2701 thr = threadbuckets[j];
2703 case BUCKETCOMINGFREE:
2704 thr = threadbuckets[j];
2705 thr->free = BUCKETFREE;
2706 for ( k = j+1; k < numthreadbuckets; k++ )
2707 threadbuckets[k-1] = threadbuckets[k];
2708 threadbuckets[numthreadbuckets-1] = thr;
2715 while ( topofavailables <= 0 ) {
2718 while ( topofavailables > 0 && numberoffullbuckets > 0 ) {
2719 SendOneBucket(DOBRACKETS);
2723 while ( numberoffullbuckets > 0 ) {
2724 while ( topofavailables <= 0 ) {
2727 while ( topofavailables > 0 && numberoffullbuckets > 0 ) {
2728 SendOneBucket(DOBRACKETS);
2737 AN0.lastinindex = -1;
2748 if ( fromspectator ) {
2749 ter = GetFromSpectator(thr->threadbuffer,fromspectator-1);
2750 if ( ter == 0 ) fromspectator = 0;
2753 ter = GetTermP(B0,thr->threadbuffer);
2755 if ( ter < 0 )
break;
2756 if ( ter == 0 ) { endofinput = 1;
goto Finalize; }
2757 dd = AN0.deferskipped;
2758 if ( AR0.DeferFlag ) {
2760 thr->deferbuffer[defcount++] = AR0.DefPosition;
2761 ttco = thr->compressbuffer; t1 = AR0.CompressBuffer; j = *t1;
2764 else if ( first && ( AC.CollectFun == 0 ) ) {
2766 t1 = tstop = thr->threadbuffer;
2767 tstop += *tstop; tstop -= ABS(tstop[-1]);
2769 while ( t1 < tstop ) {
2770 if ( t1[0] == HAAKJE ) { bra = 1;
break; }
2773 t1 = thr->threadbuffer;
2778 if ( AC.CollectFun && *(thr->threadbuffer) < (AM.MaxTer/((LONG)
sizeof(WORD))-10) ) {
2779 if ( ( dd = GetMoreTerms(thr->threadbuffer) ) < 0 ) {
2786 if ( topofavailables > 0 && numberoffullbuckets > 0 ) SendOneBucket(LOWESTLEVELGENERATION);
2790 tt = thr->threadbuffer; tt += *tt;
2797 if ( numpasses > 0 ) {
2799 if ( numbucket >= numberofworkers ) {
2802 if ( numpasses == 0 ) thrbufsiz = thrbufsiz0;
2803 else thrbufsiz = thrbufsiz0 / (2 << numpasses);
2805 thrbufsiz2 = thrbufsiz + thrbufsiz/5;
2810 while ( ( dd < thrbufsiz ) &&
2811 ( tt - thr->threadbuffer ) < ( thr->threadbuffersize - AM.MaxTer/((LONG)
sizeof(WORD)) - 2 ) ) {
2815 if ( topofavailables > 0 && numberoffullbuckets > 0 ) SendOneBucket(LOWESTLEVELGENERATION);
2819 if ( GetTermP(B0,tt) == 0 ) { endofinput = 1;
break; }
2822 dd += AN0.deferskipped;
2823 if ( AR0.DeferFlag ) {
2824 thr->deferbuffer[defcount++] = AR0.DefPosition;
2825 t1 = AR0.CompressBuffer; j = *t1;
2828 if ( AC.CollectFun && *tt < (AM.MaxTer/((LONG)
sizeof(WORD))-10) ) {
2829 if ( ( ddd = GetMoreTerms(tt) ) < 0 ) {
2844 tstop = t1 + *t1; tstop -= ABS(tstop[-1]);
2846 while ( t2 < tstop ) {
2847 if ( t2[0] == HAAKJE ) {
break; }
2850 if ( t2[0] == HAAKJE ) {
2851 t2 += t2[1]; num = t2 - t1;
2852 while ( ( dd < thrbufsiz2 ) &&
2853 ( tt - thr->threadbuffer ) < ( thr->threadbuffersize - AM.MaxTer - 2 ) ) {
2857 if ( topofavailables > 0 && numberoffullbuckets > 0 ) SendOneBucket(LOWESTLEVELGENERATION);
2861 if ( GetTermP(B0,tt) == 0 ) { endofinput = 1;
break; }
2865 tstop = tt + *tt; tstop -= ABS(tstop[-1]);
2866 if ( tstop-tt < num ) {
2870 for ( i = 1; i < num; i++ ) {
2871 if ( t1[i] != tt[i] )
break;
2887 thr->firstterm = AN0.ninterms;
2890 thr->free = BUCKETFILLED;
2891 thr->type = BUCKETDOINGTERMS;
2892 numberoffullbuckets++;
2893 if ( topofavailables <= 0 && endofinput == 0 ) {
2907 for ( j = 0; j < numthreadbuckets; j++ ) {
2908 switch ( threadbuckets[j]->free ) {
2910 thr = threadbuckets[j];
2911 if ( !endofinput )
goto NextBucket;
2917 thr->free = BUCKETATEND;
2919 case BUCKETCOMINGFREE:
2920 thr = threadbuckets[j];
2921 thr->free = BUCKETFREE;
2927 for ( k = j+1; k < numthreadbuckets; k++ )
2928 threadbuckets[k-1] = threadbuckets[k];
2929 threadbuckets[numthreadbuckets-1] = thr;
2945 for ( j = 0; j < numthreadbuckets; j++ ) {
2946 if ( threadbuckets[j]->free == BUCKETFILLED ) {
2947 thr = threadbuckets[j];
2948 for ( k = j+1; k < numthreadbuckets; k++ )
2949 threadbuckets[k-1] = threadbuckets[k];
2950 threadbuckets[numthreadbuckets-1] = thr;
2960 while ( (
id = GetAvailableThread() ) < 0 ) { MasterWait(); }
2964 LoadOneThread(0,
id,thr,0);
2966 thr->busy = BUCKETASSIGNED;
2968 thr->free = BUCKETINUSE;
2969 numberoffullbuckets--;
2977 WakeupThread(
id,LOWESTLEVELGENERATION);
2982 if ( topofavailables > 0 ) {
2983 for ( j = 0; j < numthreadbuckets; j++ ) {
2984 if ( threadbuckets[j]->free == BUCKETFILLED ) {
2985 thr = threadbuckets[j];
2986 for ( k = j+1; k < numthreadbuckets; k++ )
2987 threadbuckets[k-1] = threadbuckets[k];
2988 threadbuckets[numthreadbuckets-1] = thr;
2997 for ( j = 0; j < numthreadbuckets; j++ ) {
2998 switch ( threadbuckets[j]->free ) {
3000 thr = threadbuckets[j];
3001 if ( !endofinput )
goto NextBucket;
3002 thr->free = BUCKETATEND;
3004 case BUCKETCOMINGFREE:
3005 thr = threadbuckets[j];
3007 thr->free = BUCKETATEND;
3010 thr->free = BUCKETFREE;
3011 for ( k = j+1; k < numthreadbuckets; k++ )
3012 threadbuckets[k-1] = threadbuckets[k];
3013 threadbuckets[numthreadbuckets-1] = thr;
3021 if ( j >= numthreadbuckets )
break;
3031 for ( j = 0; j < numthreadbuckets; j++ ) {
3032 switch ( threadbuckets[j]->free ) {
3034 thr = threadbuckets[j];
3035 if ( !endofinput )
goto NextBucket;
3036 thr->free = BUCKETATEND;
3038 case BUCKETCOMINGFREE:
3039 thr = threadbuckets[j];
3040 if ( endofinput ) thr->free = BUCKETATEND;
3042 thr->free = BUCKETFREE;
3043 for ( k = j+1; k < numthreadbuckets; k++ )
3044 threadbuckets[k-1] = threadbuckets[k];
3045 threadbuckets[numthreadbuckets-1] = thr;
3050 if ( still < 0 ) still = j;
3063 thr = threadbuckets[still];
3064 for ( k = still+1; k < numthreadbuckets; k++ )
3065 threadbuckets[k-1] = threadbuckets[k];
3066 threadbuckets[numthreadbuckets-1] = thr;
3079 if ( AC.ThreadBalancing ) {
3080 for (
id = 1;
id <= numberofworkers;
id++ ) {
3081 AB[id]->T.LoadBalancing = 1;
3083 if ( LoadReadjusted() )
goto Finalize;
3084 for (
id = 1;
id <= numberofworkers;
id++ ) {
3085 AB[id]->T.LoadBalancing = 0;
3088 if ( AC.ThreadBalancing ) {
3113 if ( LastExpression ) {
3115 if ( AR0.infile->handle >= 0 ) {
3116 CloseFile(AR0.infile->handle);
3117 AR0.infile->handle = -1;
3118 remove(AR0.infile->name);
3119 PUTZERO(AR0.infile->POposition);
3120 AR0.infile->POfill = AR0.infile->POfull = AR0.infile->PObuffer;
3132 oldgzipCompress = AR0.gzipCompress;
3133 AR0.gzipCompress = 0;
3134 if ( AR0.outtohide ) AR0.outfile = AR0.hidefile;
3135 if ( MasterMerge() < 0 ) {
3136 if ( AR0.outtohide ) AR0.outfile = oldoutfile;
3137 AR0.gzipCompress = oldgzipCompress;
3140 if ( AR0.outtohide ) AR0.outfile = oldoutfile;
3141 AR0.gzipCompress = oldgzipCompress;
3149 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
3150 if ( GetThread(
id) > 0 ) WakeupThread(
id,CLEANUPEXPRESSION);
3153 for (
id = 1;
id < AM.totalnumberofthreads;
id++ ) {
3154 if ( AB[
id]->R.MaxDum - AM.IndDum > e->numdummies )
3155 e->numdummies = AB[id]->R.MaxDum - AM.IndDum;
3156 AR0.expchanged |= AB[id]->R.expchanged;
3162 AT0.WorkPointer = oldworkpointer;
3190 int LoadReadjusted()
3192 ALLPRIVATES *B0 = AB[0];
3193 THREADBUCKET *thr = 0, *thrtogo = 0;
3194 int numtogo, numfree, numbusy, n, nperbucket, extra, i, j, u, bus;
3196 WORD *t1, *c1, *t2, *c2, *t3;
3201 while ( topofavailables <= 0 ) MasterWait();
3210 for ( j = 0; j < numthreadbuckets; j++ ) {
3211 thr = threadbuckets[j];
3212 if ( thr->free == BUCKETFREE || thr->free == BUCKETATEND
3213 || thr->free == BUCKETCOMINGFREE ) {
3214 freebuckets[numfree++] = thr;
3216 else if ( thr->type != BUCKETDOINGTERMS ) {}
3217 else if ( thr->totnum > 1 ) {
3221 if ( thr->free == BUCKETINUSE ) {
3222 n = thr->totnum-thr->usenum;
3223 if ( bus == BUCKETASSIGNED ) numbusy++;
3224 else if ( ( bus != BUCKETASSIGNED )
3225 && ( n > numtogo ) ) {
3230 else if ( bus == BUCKETTOBERELEASED
3231 && thr->free == BUCKETRELEASED ) {
3232 freebuckets[numfree++] = thr;
3233 thr->free = BUCKETATEND;
3235 thr->busy = BUCKETPREPARINGTERM;
3240 if ( numfree == 0 )
return(0);
3241 if ( numtogo > 0 ) {
3248 if ( thr->totnum-thr->usenum < numtogo )
goto restart;
3258 if ( thr->busy != BUCKETDOINGTERM ) {
3262 if ( thr->totnum-thr->usenum < numtogo ) {
3266 thr->free = BUCKETTERMINATED;
3273 if ( thr->usenum == thr->totnum ) {
3278 thr->free = BUCKETATEND;
3285 if ( numbusy > 0 )
return(1);
3297 numinput = thr->firstterm + thr->usenum;
3298 nperbucket = numtogo / numfree;
3299 extra = numtogo - nperbucket*numfree;
3300 if ( AR0.DeferFlag ) {
3301 t1 = thr->threadbuffer; c1 = thr->compressbuffer; u = thr->usenum;
3302 for ( n = 0; n < thr->usenum; n++ ) { t1 += *t1; c1 += *c1; }
3305 for ( i = 0; i < extra; i++ ) {
3306 thrtogo = freebuckets[i];
3307 t2 = thrtogo->threadbuffer;
3308 c2 = thrtogo->compressbuffer;
3309 thrtogo->free = BUCKETFILLED;
3310 thrtogo->type = BUCKETDOINGTERMS;
3311 thrtogo->totnum = nperbucket+1;
3312 thrtogo->ddterms = 0;
3313 thrtogo->usenum = 0;
3314 thrtogo->busy = BUCKETASSIGNED;
3315 thrtogo->firstterm = numinput;
3316 numinput += nperbucket+1;
3317 for ( n = 0; n <= nperbucket; n++ ) {
3318 j = *t1; NCOPY(t2,t1,j);
3319 j = *c1; NCOPY(c2,c1,j);
3320 thrtogo->deferbuffer[n] = thr->deferbuffer[u++];
3325 if ( nperbucket > 0 ) {
3326 for ( i = extra; i < numfree; i++ ) {
3327 thrtogo = freebuckets[i];
3328 t2 = thrtogo->threadbuffer;
3329 c2 = thrtogo->compressbuffer;
3330 thrtogo->free = BUCKETFILLED;
3331 thrtogo->type = BUCKETDOINGTERMS;
3332 thrtogo->totnum = nperbucket;
3333 thrtogo->ddterms = 0;
3334 thrtogo->usenum = 0;
3335 thrtogo->busy = BUCKETASSIGNED;
3336 thrtogo->firstterm = numinput;
3337 numinput += nperbucket;
3338 for ( n = 0; n < nperbucket; n++ ) {
3339 j = *t1; NCOPY(t2,t1,j);
3340 j = *c1; NCOPY(c2,c1,j);
3341 thrtogo->deferbuffer[n] = thr->deferbuffer[u++];
3348 t1 = thr->threadbuffer;
3349 for ( n = 0; n < thr->usenum; n++ ) { t1 += *t1; }
3352 for ( i = 0; i < extra; i++ ) {
3353 thrtogo = freebuckets[i];
3354 t2 = thrtogo->threadbuffer;
3355 thrtogo->free = BUCKETFILLED;
3356 thrtogo->type = BUCKETDOINGTERMS;
3357 thrtogo->totnum = nperbucket+1;
3358 thrtogo->ddterms = 0;
3359 thrtogo->usenum = 0;
3360 thrtogo->busy = BUCKETASSIGNED;
3361 thrtogo->firstterm = numinput;
3362 numinput += nperbucket+1;
3363 for ( n = 0; n <= nperbucket; n++ ) {
3364 j = *t1; NCOPY(t2,t1,j);
3369 if ( nperbucket > 0 ) {
3370 for ( i = extra; i < numfree; i++ ) {
3371 thrtogo = freebuckets[i];
3372 t2 = thrtogo->threadbuffer;
3373 thrtogo->free = BUCKETFILLED;
3374 thrtogo->type = BUCKETDOINGTERMS;
3375 thrtogo->totnum = nperbucket;
3376 thrtogo->ddterms = 0;
3377 thrtogo->usenum = 0;
3378 thrtogo->busy = BUCKETASSIGNED;
3379 thrtogo->firstterm = numinput;
3380 numinput += nperbucket;
3381 for ( n = 0; n < nperbucket; n++ ) {
3382 j = *t1; NCOPY(t2,t1,j);
3389 if ( thr->free == BUCKETRELEASED && thr->busy == BUCKETTOBERELEASED ) {
3390 thr->free = BUCKETATEND; thr->busy = BUCKETPREPARINGTERM;
3458 int PutToMaster(
PHEAD WORD *term)
3460 int i,j,nexti,ret = 0;
3461 WORD *t, *fill, *top, zero = 0;
3466 t = term; ret = j = *term;
3467 if ( j == 0 ) { j = 1; }
3469 i = AT.SB.FillBlock;
3470 fill = AT.SB.MasterFill[i];
3471 top = AT.SB.MasterStop[i];
3473 while ( j > 0 && fill < top ) {
3474 *fill++ = *t++; j--;
3484 if ( nexti > AT.SB.MasterNumBlocks ) {
3487 LOCK(AT.SB.MasterBlockLock[nexti]);
3488 UNLOCK(AT.SB.MasterBlockLock[i]);
3489 AT.SB.MasterFill[i] = AT.SB.MasterStart[i];
3490 AT.SB.FillBlock = i = nexti;
3491 fill = AT.SB.MasterStart[i];
3492 top = AT.SB.MasterStop[i];
3495 AT.SB.MasterFill[i] = fill;
3515 SortBotOut(
PHEAD WORD *term)
3519 if ( AT.identity != 0 )
return(PutToMaster(BHEAD term));
3522 if (
FlushOut(&SortBotPosition,AR.outfile,1) )
return(-1);
3523 ADDPOS(AT.SS->SizeInFile[0],1);
3528 if ( ( im =
PutOut(BHEAD term,&SortBotPosition,AR.outfile,1) ) < 0 ) {
3529 MLOCK(ErrorMessageLock);
3530 MesPrint(
"Called from MasterMerge/SortBotOut");
3531 MUNLOCK(ErrorMessageLock);
3534 ADDPOS(AT.SS->SizeInFile[0],im);
3564 ALLPRIVATES *B0 = AB[0], *B = 0;
3566 WORD **poin, **poin2, ul, k, i, im, *m1, j;
3567 WORD lpat, mpat, level, l1, l2, r1, r2, r3, c;
3568 WORD *m2, *m3, r31, r33, ki, *rr;
3573 if ( numberofworkers > 2 )
return(SortBotMasterMerge());
3576 if ( AR0.PolyFun == 0 ) { S->PolyFlag = 0; }
3577 else if ( AR0.PolyFunType == 1 ) { S->PolyFlag = 1; }
3578 else if ( AR0.PolyFunType == 2 ) {
3579 if ( AR0.PolyFunExp == 2
3580 || AR0.PolyFunExp == 3 ) S->PolyFlag = 1;
3581 else S->PolyFlag = 2;
3584 coef = AN0.SoScratC;
3585 poin = S->poina; poin2 = S->poin2a;
3586 rr = AR0.CompressPointer;
3591 S->inNum = numberofthreads;
3596 S->lPatch = S->inNum - 1;
3606 for ( i = 1; i <= S->lPatch; i++ ) {
3608 LOCK(AT.SB.MasterBlockLock[0]);
3609 LOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
3617 for ( i = 0; i < S->lPatch; i++ ) {
3619 WakeupThread(i+1,FINISHEXPRESSION);
3624 if ( fout->
handle >= 0 ) {
3626 SeekFile(fout->
handle,&position,SEEK_END);
3627 ADDPOS(position,((fout->POfill-fout->PObuffer)*
sizeof(WORD)));
3630 SETBASEPOSITION(position,(fout->POfill-fout->PObuffer)*
sizeof(WORD));
3635 MasterWaitAllBlocks();
3643 for ( i = 1; i <= S->lPatch; i++ ) {
3645 LOCK(AT.SB.MasterBlockLock[1]);
3646 AT.SB.MasterBlock = 1;
3654 do { lpat <<= 1; }
while ( lpat < S->lPatch );
3655 mpat = ( lpat >> 1 ) - 1;
3656 k = lpat - S->lPatch;
3661 for ( i = 1; i < lpat; i++ ) { S->tree[i] = -1; }
3662 for ( i = 1; i <= k; i++ ) {
3663 im = ( i << 1 ) - 1;
3664 poin[im] = AB[i]->T.SB.MasterStart[AB[i]->T.SB.MasterBlock];
3665 poin2[im] = poin[im] + *(poin[im]);
3668 S->tree[mpat+i] = 0;
3669 poin[im-1] = poin2[im-1] = 0;
3671 for ( i = (k<<1)+1; i <= lpat; i++ ) {
3674 poin[i] = AB[i-k]->T.SB.MasterStart[AB[i-k]->T.SB.MasterBlock];
3675 poin2[i] = poin[i] + *(poin[i]);
3696 if ( !*(poin[k]) ) {
3697 do {
if ( !( i >>= 1 ) )
goto EndOfMerge; }
while ( !S->tree[i] );
3698 if ( S->tree[i] == -1 ) {
3711 if ( S->tree[i] > 0 ) {
3712 if ( ( c = CompareTerms(B0,poin[S->tree[i]],poin[k],(WORD)0) ) > 0 ) {
3716 S->used[level] = S->tree[i];
3726 l1 = *( m1 = poin[S->tree[i]] );
3727 l2 = *( m2 = poin[k] );
3728 if ( S->PolyWise ) {
3733 if ( S->PolyFlag == 2 ) {
3734 w = poly_ratfun_add(B0,m1,m2);
3735 if ( *tt1 + w[1] - m1[1] > AM.MaxTer/((LONG)
sizeof(WORD)) ) {
3736 MLOCK(ErrorMessageLock);
3737 MesPrint(
"Term too complex in PolyRatFun addition. MaxTermSize of %10l is too small",AM.MaxTer);
3738 MUNLOCK(ErrorMessageLock);
3741 AT0.WorkPointer = w;
3742 if ( w[FUNHEAD] == -SNUMBER && w[FUNHEAD+1] == 0 && w[1] > FUNHEAD ) {
3747 w = AT0.WorkPointer;
3748 if ( w + m1[1] + m2[1] > AT0.WorkTop ) {
3749 MLOCK(ErrorMessageLock);
3750 MesPrint(
"MasterMerge: A WorkSpace of %10l is too small",AM.WorkSize);
3751 MUNLOCK(ErrorMessageLock);
3758 || ( w[FUNHEAD] == -SNUMBER && w[FUNHEAD+1] == 0 ) )
3760 if ( r1 == m1[1] ) {
3763 else if ( r1 < m1[1] ) {
3767 while ( --r1 >= 0 ) *--m1 = *--m2;
3770 while ( --r1 >= 0 ) *--m1 = *--m2;
3772 poin[S->tree[i]] = m1;
3780 poin[S->tree[i]] = m2;
3787 r1 = *( m1 += l1 - 1 );
3789 r1 = ( ( r1 > 0 ) ? (r1-1) : (r1+1) ) >> 1;
3790 r2 = *( m2 += l2 - 1 );
3792 r2 = ( ( r2 > 0 ) ? (r2-1) : (r2+1) ) >> 1;
3794 if ( AddRat(B0,(UWORD *)m1,r1,(UWORD *)m2,r2,coef,&r3) ) {
3795 MLOCK(ErrorMessageLock);
3796 MesCall(
"MasterMerge");
3797 MUNLOCK(ErrorMessageLock);
3801 if ( AN.ncmod != 0 ) {
3802 if ( ( AC.modmode & POSNEG ) != 0 ) {
3805 else if ( BigLong(coef,r3,(UWORD *)AC.cmod,ABS(AN.ncmod)) >= 0 ) {
3807 SubPLon(coef,r3,(UWORD *)AC.cmod,ABS(AN.ncmod),coef,&r3);
3809 for ( ii = 1; ii < r3; ii++ ) coef[r3+ii] = 0;
3813 r33 = ( r3 > 0 ) ? ( r3 + 1 ) : ( r3 - 1 );
3814 if ( r3 < 0 ) r3 = -r3;
3815 if ( r1 < 0 ) r1 = -r1;
3820 ul = S->used[level] = S->tree[i];
3826 poin[ul] = poin2[ul];
3828 if ( (poin[ul] + im + COMPINC) >=
3829 AB[ki+1]->T.SB.MasterStop[AB[ki+1]->T.SB.MasterBlock]
3836 i = AT.SB.MasterBlock;
3838 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
3841 UNLOCK(AT.SB.MasterBlockLock[i-1]);
3843 if ( i == AT.SB.MasterNumBlocks ) {
3848 to = AT.SB.MasterStart[1];
3849 from = AT.SB.MasterStop[i];
3850 while ( from > poin[ul] ) *--to = *--from;
3855 LOCK(AT.SB.MasterBlockLock[i]);
3856 AT.SB.MasterBlock = i;
3857 poin2[ul] = poin[ul] + im;
3862 S->used[++level] = k;
3868 else if ( r31 < 0 ) {
3877 if( (poin[S->tree[i]]+l1+r31) >= poin2[S->tree[i]] ) {
3883 if ( (l1 + r31)*((LONG)
sizeof(WORD)) >= AM.MaxTer ) {
3884 MLOCK(ErrorMessageLock);
3885 MesPrint(
"MasterMerge: Coefficient overflow during sort");
3886 MUNLOCK(ErrorMessageLock);
3889 m2 = poin[S->tree[i]];
3890 m3 = ( poin[S->tree[i]] -= r31 );
3891 do { *m3++ = *m2++; }
while ( m2 < m1 );
3895 *(poin[S->tree[i]]) += r31;
3897 m2 = (WORD *)coef; im = r3;
3909 if ( (poin[k] + im + COMPINC) >=
3910 AB[ki+1]->T.SB.MasterStop[AB[ki+1]->T.SB.MasterBlock]
3917 i = AT.SB.MasterBlock;
3919 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
3922 UNLOCK(AT.SB.MasterBlockLock[i-1]);
3924 if ( i == AT.SB.MasterNumBlocks ) {
3929 to = AT.SB.MasterStart[1];
3930 from = AT.SB.MasterStop[i];
3931 while ( from > poin[k] ) *--to = *--from;
3936 LOCK(AT.SB.MasterBlockLock[i]);
3937 AT.SB.MasterBlock = i;
3938 poin2[k] = poin[k] + im;
3946 else if ( S->tree[i] < 0 ) {
3957 if ( ( im =
PutOut(B0,poin[k],&position,fout,1) ) < 0 ) {
3958 MLOCK(ErrorMessageLock);
3959 MesPrint(
"Called from MasterMerge with k = %d (stream %d)",k,S->ktoi[k]);
3960 MUNLOCK(ErrorMessageLock);
3963 ADDPOS(S->SizeInFile[0],im);
3966 if (
FlushOut(&position,fout,1) )
goto ReturnError;
3967 ADDPOS(S->SizeInFile[0],1);
3971 position = S->SizeInFile[0];
3972 MULPOS(position,
sizeof(WORD));
3974 for ( j = 1; j <= numberofworkers; j++ ) {
3975 S->GenTerms += AB[j]->T.SS->GenTerms;
3978 Expressions[AR0.CurExpr].counter = S->TermsLeft;
3979 Expressions[AR0.CurExpr].size = position;
3983 for ( i = 1; i <= S->lPatch; i++ ) {
3985 UNLOCK(AT.SB.MasterBlockLock[0]);
3986 if ( AT.SB.MasterBlock == 1 ) {
3987 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
3990 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterBlock-1]);
3992 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterBlock]);
3997 for ( i = 1; i <= S->lPatch; i++ ) {
3999 UNLOCK(AT.SB.MasterBlockLock[0]);
4000 if ( AT.SB.MasterBlock == 1 ) {
4001 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterNumBlocks]);
4004 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterBlock-1]);
4006 UNLOCK(AT.SB.MasterBlockLock[AT.SB.MasterBlock]);
4034 int SortBotMasterMerge()
4037 ALLPRIVATES *B = AB[0], *BB;
4050 topsortbotavailables = 0;
4051 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
4052 WakeupThread(i,INISORTBOT);
4058 AR.CompressPointer[0] = 0;
4060 BB = AB[AT.SortBotIn1];
4061 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
4062 BB = AB[AT.SortBotIn2];
4063 LOCK(BB->T.SB.MasterBlockLock[BB->T.SB.MasterNumBlocks]);
4065 MasterWaitAllSortBots();
4070 for ( i = 1; i <= numberofworkers; i++ ) {
4072 WakeupThread(i,FINISHEXPRESSION);
4077 if ( fout->
handle >= 0 ) {
4078 PUTZERO(SortBotPosition);
4079 SeekFile(fout->
handle,&SortBotPosition,SEEK_END);
4080 ADDPOS(SortBotPosition,((fout->POfill-fout->PObuffer)*
sizeof(WORD)));
4083 SETBASEPOSITION(SortBotPosition,(fout->POfill-fout->PObuffer)*
sizeof(WORD));
4085 MasterWaitAllBlocks();
4091 topsortbotavailables = 0;
4092 for ( i = numberofworkers+1; i <= numberofworkers+numberofsortbots; i++ ) {
4093 WakeupThread(i,RUNSORTBOT);
4095 if ( SortBotMerge(BHEAD0) ) {
4096 MLOCK(ErrorMessageLock);
4097 MesPrint(
"Called from SortBotMasterMerge");
4098 MUNLOCK(ErrorMessageLock);
4105 if ( S->file.
handle >= 0 )
4112 position = S->SizeInFile[0];
4113 MULPOS(position,
sizeof(WORD));
4115 for ( j = 1; j <= numberofworkers; j++ ) {
4116 S->GenTerms += AB[j]->T.SS->GenTerms;
4118 S->TermsLeft = numberofterms;
4120 Expressions[AR.CurExpr].counter = S->TermsLeft;
4121 Expressions[AR.CurExpr].size = position;
4130 MasterWaitAllSortBots();
4149 int SortBotMerge(PHEAD0)
4152 ALLPRIVATES *Bin1 = AB[AT.SortBotIn1],*Bin2 = AB[AT.SortBotIn2];
4153 WORD *term1, *term2, *next, *wp;
4156 WORD l1, l2, *m1, *m2, *w, r1, r2, r3, r33, r31, *tt1, ii;
4157 WORD *to, *from, im, c;
4166 if ( AT.identity == 0 ) {
4167 wp = AT.WorkPointer;
4170 wp = AT.WorkPointer = AT.WorkSpace;
4177 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4178 LOCK(Bin2->T.SB.MasterBlockLock[blin2]);
4180 term1 = Bin1->T.SB.MasterStart[blin1];
4181 term2 = Bin2->T.SB.MasterStart[blin2];
4182 AT.SB.FillBlock = 1;
4186 while ( *term1 && *term2 ) {
4187 if ( ( c = CompareTerms(BHEAD term1,term2,(WORD)0) ) > 0 ) {
4191 if ( SortBotOut(BHEAD term1) < 0 ) {
4192 MLOCK(ErrorMessageLock);
4193 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4194 MUNLOCK(ErrorMessageLock);
4200 if ( next >= Bin1->T.SB.MasterStop[blin1] || ( *next &&
4201 next+*next+COMPINC > Bin1->T.SB.MasterStop[blin1] ) ) {
4203 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4206 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4208 if ( blin1 == Bin1->T.SB.MasterNumBlocks ) {
4212 to = Bin1->T.SB.MasterStart[1];
4213 from = Bin1->T.SB.MasterStop[Bin1->T.SB.MasterNumBlocks];
4214 while ( from > next ) *--to = *--from;
4221 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4222 Bin1->T.SB.MasterBlock = blin1;
4233 if ( SortBotOut(BHEAD term2) < 0 ) {
4234 MLOCK(ErrorMessageLock);
4235 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4236 MUNLOCK(ErrorMessageLock);
4242 if ( next >= Bin2->T.SB.MasterStop[blin2] || ( *next
4243 && next+*next+COMPINC > Bin2->T.SB.MasterStop[blin2] ) ) {
4245 UNLOCK(Bin2->T.SB.MasterBlockLock[Bin2->T.SB.MasterNumBlocks]);
4248 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2-1]);
4250 if ( blin2 == Bin2->T.SB.MasterNumBlocks ) {
4254 to = Bin2->T.SB.MasterStart[1];
4255 from = Bin2->T.SB.MasterStop[Bin2->T.SB.MasterNumBlocks];
4256 while ( from > next ) *--to = *--from;
4263 LOCK(Bin2->T.SB.MasterBlockLock[blin2]);
4264 Bin2->T.SB.MasterBlock = blin2;
4275 l1 = *( m1 = term1 );
4276 l2 = *( m2 = term2 );
4277 if ( S->PolyWise ) {
4281 if ( S->PolyFlag == 2 ) {
4282 AT.WorkPointer = wp;
4283 w = poly_ratfun_add(BHEAD m1,m2);
4284 if ( *tt1 + w[1] - m1[1] > AM.MaxTer/((LONG)
sizeof(WORD)) ) {
4285 MLOCK(ErrorMessageLock);
4286 MesPrint(
"Term too complex in PolyRatFun addition. MaxTermSize of %10l is too small",AM.MaxTer);
4287 MUNLOCK(ErrorMessageLock);
4290 AT.WorkPointer = wp;
4291 if ( w[FUNHEAD] == -SNUMBER && w[FUNHEAD+1] == 0 && w[1] > FUNHEAD ) {
4297 if ( w + m1[1] + m2[1] > AT.WorkTop ) {
4298 MLOCK(ErrorMessageLock);
4299 MesPrint(
"SortBotMerge(%d): A Maxtermsize of %10l is too small",
4300 AT.identity,AM.MaxTer/
sizeof(WORD));
4301 MesPrint(
"m1[1] = %d, m2[1] = %d, Space = %l",m1[1],m2[1],(LONG)(AT.WorkTop-wp));
4302 PrintTerm(term1,
"term1");
4303 PrintTerm(term2,
"term2");
4304 MesPrint(
"PolyWise = %d",S->PolyWise);
4305 MUNLOCK(ErrorMessageLock);
4312 || ( w[FUNHEAD] == -SNUMBER && w[FUNHEAD+1] == 0 ) )
4314 if ( r1 == m1[1] ) {
4317 else if ( r1 < m1[1] ) {
4321 while ( --r1 >= 0 ) *--m1 = *--m2;
4324 while ( --r1 >= 0 ) *--m1 = *--m2;
4341 r1 = *( m1 += l1 - 1 );
4343 r1 = ( ( r1 > 0 ) ? (r1-1) : (r1+1) ) >> 1;
4344 r2 = *( m2 += l2 - 1 );
4346 r2 = ( ( r2 > 0 ) ? (r2-1) : (r2+1) ) >> 1;
4348 if ( AddRat(BHEAD (UWORD *)m1,r1,(UWORD *)m2,r2,coef,&r3) ) {
4349 MLOCK(ErrorMessageLock);
4350 MesCall(
"SortBotMerge");
4351 MUNLOCK(ErrorMessageLock);
4355 if ( AN.ncmod != 0 ) {
4356 if ( ( AC.modmode & POSNEG ) != 0 ) {
4359 else if ( BigLong(coef,r3,(UWORD *)AC.cmod,ABS(AN.ncmod)) >= 0 ) {
4360 SubPLon(coef,r3,(UWORD *)AC.cmod,ABS(AN.ncmod),coef,&r3);
4362 for ( ii = 1; ii < r3; ii++ ) coef[r3+ii] = 0;
4365 if ( !r3 ) {
goto cancelled; }
4367 r33 = ( r3 > 0 ) ? ( r3 + 1 ) : ( r3 - 1 );
4368 if ( r3 < 0 ) r3 = -r3;
4369 if ( r1 < 0 ) r1 = -r1;
4373 m2 = (WORD *)coef; im = r3;
4386 to = wp; from = term1;
4387 while ( from < m1 ) *to++ = *from++;
4388 from = (WORD *)coef; im = r3;
4392 if ( SortBotOut(BHEAD wp) < 0 ) {
4393 MLOCK(ErrorMessageLock);
4394 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4395 MUNLOCK(ErrorMessageLock);
4402 if ( SortBotOut(BHEAD term1) < 0 ) {
4403 MLOCK(ErrorMessageLock);
4404 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4405 MUNLOCK(ErrorMessageLock);
4412 if ( next >= Bin1->T.SB.MasterStop[blin1] || ( *next &&
4413 next+*next+COMPINC > Bin1->T.SB.MasterStop[blin1] ) ) {
4415 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4418 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4420 if ( blin1 == Bin1->T.SB.MasterNumBlocks ) {
4424 to = Bin1->T.SB.MasterStart[1];
4425 from = Bin1->T.SB.MasterStop[Bin1->T.SB.MasterNumBlocks];
4426 while ( from > next ) *--to = *--from;
4433 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4434 Bin1->T.SB.MasterBlock = blin1;
4451 if ( SortBotOut(BHEAD term1) < 0 ) {
4452 MLOCK(ErrorMessageLock);
4453 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4454 MUNLOCK(ErrorMessageLock);
4460 if ( next >= Bin1->T.SB.MasterStop[blin1] || ( *next &&
4461 next+*next+COMPINC > Bin1->T.SB.MasterStop[blin1] ) ) {
4463 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4466 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4468 if ( blin1 == Bin1->T.SB.MasterNumBlocks ) {
4472 to = Bin1->T.SB.MasterStart[1];
4473 from = Bin1->T.SB.MasterStop[Bin1->T.SB.MasterNumBlocks];
4474 while ( from > next ) *--to = *--from;
4481 LOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4482 Bin1->T.SB.MasterBlock = blin1;
4490 else if ( *term2 ) {
4495 if ( SortBotOut(BHEAD term2) < 0 ) {
4496 MLOCK(ErrorMessageLock);
4497 MesPrint(
"Called from SortBotMerge with thread = %d",AT.identity);
4498 MUNLOCK(ErrorMessageLock);
4504 if ( next >= Bin2->T.SB.MasterStop[blin2] || ( *next
4505 && next+*next+COMPINC > Bin2->T.SB.MasterStop[blin2] ) ) {
4507 UNLOCK(Bin2->T.SB.MasterBlockLock[Bin2->T.SB.MasterNumBlocks]);
4510 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2-1]);
4512 if ( blin2 == Bin2->T.SB.MasterNumBlocks ) {
4516 to = Bin2->T.SB.MasterStart[1];
4517 from = Bin2->T.SB.MasterStop[Bin2->T.SB.MasterNumBlocks];
4518 while ( from > next ) *--to = *--from;
4525 LOCK(Bin2->T.SB.MasterBlockLock[blin2]);
4526 Bin2->T.SB.MasterBlock = blin2;
4534 SortBotOut(BHEAD 0);
4539 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1]);
4541 UNLOCK(Bin1->T.SB.MasterBlockLock[blin1-1]);
4544 UNLOCK(Bin1->T.SB.MasterBlockLock[Bin1->T.SB.MasterNumBlocks]);
4546 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2]);
4548 UNLOCK(Bin2->T.SB.MasterBlockLock[blin2-1]);
4551 UNLOCK(Bin2->T.SB.MasterBlockLock[Bin2->T.SB.MasterNumBlocks]);
4553 if ( AT.identity > 0 ) {
4554 UNLOCK(AT.SB.MasterBlockLock[AT.SB.FillBlock]);
4569 static int SortBlocksInitialized = 0;
4577 int IniSortBlocks(
int numworkers)
4581 LONG totalsize, workersize, blocksize, numberofterms;
4583 int numberofblocks = NUMBEROFBLOCKSINSORT, numparts;
4586 if ( SortBlocksInitialized )
return(0);
4587 SortBlocksInitialized = 1;
4588 if ( numworkers == 0 )
return(0);
4591 if ( numworkers > 2 ) {
4592 numparts = 2*numworkers - 2;
4593 numberofblocks = numberofblocks/2;
4596 numparts = numworkers;
4599 numparts = numworkers;
4602 totalsize = S->LargeSize + S->SmallEsize;
4603 workersize = totalsize / numparts;
4604 maxter = AM.MaxTer/
sizeof(WORD);
4605 blocksize = ( workersize - maxter )/numberofblocks;
4606 numberofterms = blocksize / maxter;
4607 if ( numberofterms < MINIMUMNUMBEROFTERMS ) {
4611 MesPrint(
"We have a problem with the size of the blocks in IniSortBlocks");
4620 if ( w == 0 ) w = S->sBuffer;
4621 for (
id = 1;
id <= numparts;
id++ ) {
4623 AT.SB.MasterBlockLock = (pthread_mutex_t *)Malloc1(
4624 sizeof(pthread_mutex_t)*(numberofblocks+1),
"MasterBlockLock");
4625 AT.SB.MasterStart = (WORD **)Malloc1(
sizeof(WORD *)*(numberofblocks+1)*3,
"MasterBlock");
4626 AT.SB.MasterFill = AT.SB.MasterStart + (numberofblocks+1);
4627 AT.SB.MasterStop = AT.SB.MasterFill + (numberofblocks+1);
4628 AT.SB.MasterNumBlocks = numberofblocks;
4629 AT.SB.MasterBlock = 0;
4630 AT.SB.FillBlock = 0;
4631 AT.SB.MasterFill[0] = AT.SB.MasterStart[0] = w;
4633 AT.SB.MasterStop[0] = w;
4634 AT.SB.MasterBlockLock[0] = dummylock;
4635 for ( j = 1; j <= numberofblocks; j++ ) {
4636 AT.SB.MasterFill[j] = AT.SB.MasterStart[j] = w;
4638 AT.SB.MasterStop[j] = w;
4639 AT.SB.MasterBlockLock[j] = dummylock;
4642 if ( w > S->sTop2 ) {
4643 MesPrint(
"Counting problem in IniSortBlocks");
4661 void DefineSortBotTree()
4665 if ( numberofworkers <= 2 )
return;
4666 n = numberofworkers*2-2;
4667 for ( i = numberofworkers+1, from = 1; i <= n; i++ ) {
4669 AT.SortBotIn1 = from++;
4670 AT.SortBotIn2 = from++;
4673 AT.SortBotIn1 = from++;
4674 AT.SortBotIn2 = from++;
4689 WORD GetTerm2(
PHEAD WORD *term)
4691 WORD *ttco, *tt, retval;
4697 POSITION where, eonfile = AS.OldOnFile[e-Expressions], bstart, bnext;
4701 switch ( e->status ) {
4702 case UNHIDELEXPRESSION:
4703 case UNHIDEGEXPRESSION:
4704 case DROPHLEXPRESSION:
4705 case DROPHGEXPRESSION:
4706 case HIDDENLEXPRESSION:
4707 case HIDDENGEXPRESSION:
4714 if ( AR.KeptInHold ) {
4715 retval = GetTerm(BHEAD term);
4718 SeekScratch(fi,&where);
4719 if ( AN.lastinindex < 0 ) {
4723 if ( ( n = TreatIndexEntry(BHEAD 0) ) <= 0 ) {
4725 where = bi[n].start;
4726 ADD2POS(where,eonfile);
4727 SetScratch(fi,&where);
4731 ttco = AR.CompressBuffer;
4735 AR.CompressPointer = ttco;
4736 retval = GetTerm(BHEAD term);
4739 else AN.lastinindex = n-1;
4746 bstart = bi[n].start;
4747 ADD2POS(bstart,eonfile);
4749 ADD2POS(bnext,eonfile);
4750 if ( ISLESSPOS(bstart,where) && ISLESSPOS(where,bnext) ) {
4751 retval = GetTerm(BHEAD term);
4754 for ( n++ ; n < b->indexfill; n++ ) {
4755 i = TreatIndexEntry(BHEAD n);
4760 ttco = AR.CompressBuffer;
4764 AR.CompressPointer = ttco;
4766 where = bi[n].start;
4767 ADD2POS(where,eonfile);
4768 SetScratch(fi,&(where));
4769 retval = GetTerm(BHEAD term);
4789 int TreatIndexEntry(
PHEAD LONG n)
4792 LONG numbra = b->indexfill - 1, i;
4800 if ( ( numbra - n ) <= numberofworkers )
return(0);
4806 DIFPOS(pos1,bi[numbra].next,bi[n].next);
4807 BASEPOSITION(average) = DIVPOS(pos1,(3*numberofworkers));
4808 DIFPOS(pos1,bi[n].next,bi[n].start);
4809 if ( ISLESSPOS(average,pos1) )
return(0);
4814 totterms = bi->termsinbracket;
4815 if ( totterms > 2*AC.ThreadBucketSize )
return(1);
4816 for ( i = 1; i < numbra-n; i++ ) {
4817 DIFPOS(pos1,bi[n+i].next,bi[n].start);
4818 if ( ISLESSPOS(average,pos1) )
return(i);
4819 totterms += bi->termsinbracket;
4820 if ( totterms > 2*AC.ThreadBucketSize )
return(i+1);
4833 void SetHideFiles() {
4835 ALLPRIVATES *B, *B0 = AB[0];
4836 for ( i = 1; i <= numberofworkers; i++ ) {
4838 AR.hidefile->handle = AR0.hidefile->handle;
4839 if ( AR.hidefile->handle < 0 ) {
4840 AR.hidefile->PObuffer = AR0.hidefile->PObuffer;
4841 AR.hidefile->POstop = AR0.hidefile->POstop;
4842 AR.hidefile->POfill = AR0.hidefile->POfill;
4843 AR.hidefile->POfull = AR0.hidefile->POfull;
4844 AR.hidefile->POsize = AR0.hidefile->POsize;
4845 AR.hidefile->POposition = AR0.hidefile->POposition;
4846 AR.hidefile->filesize = AR0.hidefile->filesize;
4849 AR.hidefile->PObuffer = AR.hidefile->wPObuffer;
4850 AR.hidefile->POstop = AR.hidefile->wPOstop;
4851 AR.hidefile->POfill = AR.hidefile->wPOfill;
4852 AR.hidefile->POfull = AR.hidefile->wPOfull;
4853 AR.hidefile->POsize = AR.hidefile->wPOsize;
4854 PUTZERO(AR.hidefile->POposition);
4867 for ( i = 0; i < AM.totalnumberofthreads; i++ ) {
4881 for ( j = 0; j < AM.totalnumberofthreads; j++ ) {
4883 AN.ncmod = AC.ncmod;
4884 if ( AN.cmod != 0 ) M_free(AN.cmod,
"AN.cmod");
4886 AN.cmod = (UWORD *)Malloc1(
sizeof(WORD)*n,
"AN.cmod");
4887 for ( i = 0; i < n; i++ ) AN.cmod[i] = AC.cmod[i];
4900 for ( j = 0; j < AM.totalnumberofthreads; j++ ) {
4902 if ( AN.cmod != 0 ) M_free(AN.cmod,
"AN.cmod");
4912 void find_Horner_MCTS_expand_tree_threaded() {
4914 while ((
id = GetAvailableThread() ) < 0)
4916 WakeupThread(
id,MCTSEXPANDTREE);
4924 extern void optimize_expression_given_Horner_threaded() {
4926 while ((
id = GetAvailableThread() ) < 0)
4928 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)