3 #include "multicoreruntime.h"
4 #include "runtime_arch.h"
5 #include "GenericHashtable.h"
7 // data structures for task invocation
8 struct genhashtable * activetasks;
9 struct taskparamdescriptor * currtpd;
11 // specific functions used inside critical sections
12 void enqueueObject_I(void * ptr, struct parameterwrapper ** queues, int length);
13 int enqueuetasks_I(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr, int * enterflags, int numenterflags);
15 inline void initruntimedata() {
16 // initialize the arrays
17 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
18 // startup core to initialize corestatus[]
19 for(i = 0; i < NUMCORES; ++i) {
21 numsendobjs[i] = 0; // assume all variables are local variables! MAY BE WRONG!!!
22 numreceiveobjs[i] = 0;
24 // initialize the profile data arrays
30 gcnumreceiveobjs[i] = 0;
36 } // for(i = 0; i < NUMCORES; ++i)
46 self_numreceiveobjs = 0;
48 for(i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
53 msglength = BAMBOO_MSG_BUF_LENGTH;
54 for(i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
64 bamboo_cur_msp = NULL;
70 gcphase = FINISHPHASE;
71 gcself_numsendobjs = 0;
72 gcself_numreceiveobjs = 0;
76 pointertbl = allocateRuntimeHash(20);
81 // create the lock table, lockresult table and obj queue
83 locktable.bucket = (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
84 /* Set allocation blocks*/
85 locktable.listhead=NULL;
86 locktable.listtail=NULL;
88 locktable.numelements = 0;
93 lockRedirectTbl = allocateRuntimeHash(20);
94 objRedirectLockTbl = allocateRuntimeHash(20);
100 objqueue.tail = NULL;
104 //isInterrupt = true;
107 taskInfoOverflow = false;
108 /*interruptInfoIndex = 0;
109 interruptInfoOverflow = false;*/
113 inline void disruntimedata() {
115 freeRuntimeHash(pointertbl);
117 freeRuntimeHash(lockRedirectTbl);
118 freeRuntimeHash(objRedirectLockTbl);
119 RUNFREE(locktable.bucket);
121 genfreehashtable(activetasks);
125 bool checkObjQueue(void * sendStall) {
126 int tocontinue = false;
127 struct transObjInfo * objInfo = NULL;
130 #ifdef ACCURATEPROFILE
132 bool isChecking = false;
133 if(!isEmpty(&objqueue)) {
134 profileTaskStart("objqueue checking");
139 while(!isEmpty(&objqueue)) {
141 BAMBOO_START_CRITICAL_SECTION_OBJ_QUEUE();
143 BAMBOO_DEBUGPRINT(0xf001);
146 //isInterrupt = false;
149 BAMBOO_DEBUGPRINT(0xeee1);
151 (*((bool *)sendStall)) = false;
153 objInfo = (struct transObjInfo *)getItem(&objqueue);
154 obj = objInfo->objptr;
156 BAMBOO_DEBUGPRINT_REG((int)obj);
158 // grab lock and flush the obj
162 BAMBOO_WAITING_FOR_LOCK();
166 BAMBOO_DEBUGPRINT_REG(grount);
181 BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
182 BAMBOO_CACHE_FLUSH_RANGE((int)obj, classsize[((struct ___Object___ *)obj)->type]);
184 // enqueue the object
185 for(k = 0; k < objInfo->length; ++k) {
186 int taskindex = objInfo->queues[2 * k];
187 int paramindex = objInfo->queues[2 * k + 1];
188 struct parameterwrapper ** queues = &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
190 BAMBOO_DEBUGPRINT_REG(taskindex);
191 BAMBOO_DEBUGPRINT_REG(paramindex);
192 struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
193 tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n", BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj, (long)obj, tmpptr->flag);
195 enqueueObject_I(obj, queues, 1);
197 BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
200 releasewritelock_I(obj);
201 RUNFREE(objInfo->queues);
205 // put it at the end of the queue if no update version in the queue
206 struct QueueItem * qitem = getHead(&objqueue);
207 struct QueueItem * prev = NULL;
208 while(qitem != NULL) {
209 struct transObjInfo * tmpinfo = (struct transObjInfo *)(qitem->objectptr);
210 if(tmpinfo->objptr == obj) {
211 // the same object in the queue, which should be enqueued
212 // recently. Current one is outdate, do not re-enqueue it
213 RUNFREE(objInfo->queues);
218 } // if(tmpinfo->objptr == obj)
219 qitem = getNextQueueItem(prev);
220 } // while(qitem != NULL)
221 // try to execute active tasks already enqueued first
222 addNewItem_I(&objqueue, objInfo);
224 //isInterrupt = true;
227 BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE();
229 BAMBOO_DEBUGPRINT(0xf000);
233 BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE();
235 BAMBOO_DEBUGPRINT(0xf000);
237 } // while(!isEmpty(&objqueue))
239 #ifdef ACCURATEPROFILE
247 BAMBOO_DEBUGPRINT(0xee02);
252 void checkCoreStatue() {
253 bool allStall = false;
257 (waitconfirm && (numconfirm == 0))) {
259 BAMBOO_DEBUGPRINT(0xee04);
260 BAMBOO_DEBUGPRINT_REG(waitconfirm);
262 BAMBOO_START_CRITICAL_SECTION_STATUS();
264 BAMBOO_DEBUGPRINT(0xf001);
266 corestatus[BAMBOO_NUM_OF_CORE] = 0;
267 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
268 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
269 // check the status of all cores
272 BAMBOO_DEBUGPRINT_REG(NUMCORES);
274 for(i = 0; i < NUMCORES; ++i) {
276 BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
278 if(corestatus[i] != 0) {
282 } // for(i = 0; i < NUMCORES; ++i)
284 // check if the sum of send objs and receive obj are the same
285 // yes->check if the info is the latest; no->go on executing
287 for(i = 0; i < NUMCORES; ++i) {
288 sumsendobj += numsendobjs[i];
290 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
292 } // for(i = 0; i < NUMCORES; ++i)
293 for(i = 0; i < NUMCORES; ++i) {
294 sumsendobj -= numreceiveobjs[i];
296 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
298 } // for(i = 0; i < NUMCORES; ++i)
299 if(0 == sumsendobj) {
301 // the first time found all cores stall
302 // send out status confirm msg to all other cores
303 // reset the corestatus array too
305 BAMBOO_DEBUGPRINT(0xee05);
307 corestatus[BAMBOO_NUM_OF_CORE] = 1;
308 for(i = 1; i < NUMCORES; ++i) {
310 // send status confirm msg to core i
311 send_msg_1(i, STATUSCONFIRM);
312 } // for(i = 1; i < NUMCORES; ++i)
314 numconfirm = NUMCORES - 1;
316 // all the core status info are the latest
317 // terminate; for profiling mode, send request to all
318 // other cores to pour out profiling data
320 BAMBOO_DEBUGPRINT(0xee06);
324 totalexetime = BAMBOO_GET_EXE_TIME();
326 BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME());
327 BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
328 BAMBOO_DEBUGPRINT(0xbbbbbbbb);
330 // profile mode, send msgs to other cores to request pouring
331 // out progiling data
333 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
335 BAMBOO_DEBUGPRINT(0xf000);
337 for(i = 1; i < NUMCORES; ++i) {
338 // send profile request msg to core i
339 send_msg_2(i, PROFILEOUTPUT, totalexetime);
340 } // for(i = 1; i < NUMCORES; ++i)
341 // pour profiling data on startup core
344 BAMBOO_START_CRITICAL_SECTION_STATUS();
346 BAMBOO_DEBUGPRINT(0xf001);
348 profilestatus[BAMBOO_NUM_OF_CORE] = 0;
349 // check the status of all cores
352 BAMBOO_DEBUGPRINT_REG(NUMCORES);
354 for(i = 0; i < NUMCORES; ++i) {
356 BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
358 if(profilestatus[i] != 0) {
362 } // for(i = 0; i < NUMCORES; ++i)
365 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
367 BAMBOO_DEBUGPRINT(0xf000);
377 terminate(); // All done.
378 } // if(!waitconfirm)
380 // still some objects on the fly on the network
381 // reset the waitconfirm and numconfirm
383 BAMBOO_DEBUGPRINT(0xee07);
387 } // if(0 == sumsendobj)
389 // not all cores are stall, keep on waiting
391 BAMBOO_DEBUGPRINT(0xee08);
396 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
398 BAMBOO_DEBUGPRINT(0xf000);
400 } // if((!waitconfirm) ||
403 // main function for each core
404 inline void run(void * arg) {
408 bool sendStall = false;
410 bool tocontinue = false;
412 corenum = BAMBOO_GET_NUM_OF_CORE();
414 BAMBOO_DEBUGPRINT(0xeeee);
415 BAMBOO_DEBUGPRINT_REG(corenum);
416 BAMBOO_DEBUGPRINT(STARTUPCORE);
419 // initialize runtime data structures
422 // other architecture related initialization
426 initializeexithandler();
428 // main process of the execution module
429 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
430 // non-executing cores, only processing communications
433 BAMBOO_DEBUGPRINT(0xee01);
434 BAMBOO_DEBUGPRINT_REG(taskInfoIndex);
435 BAMBOO_DEBUGPRINT_REG(taskInfoOverflow);
436 profileTaskStart("msg handling");
440 //isInterrupt = false;
444 /* Create queue of active tasks */
445 activetasks=genallocatehashtable((unsigned int(*) (void *)) &hashCodetpd,
446 (int(*) (void *,void *)) &comparetpd);
448 /* Process task information */
451 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
452 /* Create startup object */
453 createstartupobject(argc, argv);
457 BAMBOO_DEBUGPRINT(0xee00);
462 // check if need to do GC
466 // check if there are new active tasks can be executed
470 while(receiveObject() != -1) {
475 BAMBOO_DEBUGPRINT(0xee01);
478 // check if there are some pending objects, if yes, enqueue them and executetasks again
479 tocontinue = checkObjQueue();
483 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
486 BAMBOO_DEBUGPRINT(0xee03);
494 BAMBOO_DEBUGPRINT(0xee09);
500 // wait for some time
503 BAMBOO_DEBUGPRINT(0xee0a);
509 // send StallMsg to startup core
511 BAMBOO_DEBUGPRINT(0xee0b);
514 send_msg_4(STARTUPCORE, 1, BAMBOO_NUM_OF_CORE, self_numsendobjs, self_numreceiveobjs);
526 BAMBOO_DEBUGPRINT(0xee0c);
529 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
532 } // if(BAMBOO_NUM_OF_CORE > NUMCORES - 1)
536 void createstartupobject(int argc, char ** argv) {
539 /* Allocate startup object */
541 struct ___StartupObject___ *startupobject=(struct ___StartupObject___*) allocate_new(NULL, STARTUPTYPE);
542 struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);
544 struct ___StartupObject___ *startupobject=(struct ___StartupObject___*) allocate_new(STARTUPTYPE);
545 struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);
547 /* Build array of strings */
548 startupobject->___parameters___=stringarray;
549 for(i=1; i<argc; i++) {
550 int length=strlen(argv[i]);
552 struct ___String___ *newstring=NewString(NULL, argv[i],length);
554 struct ___String___ *newstring=NewString(argv[i],length);
556 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=newstring;
559 startupobject->version = 0;
560 startupobject->lock = NULL;
562 /* Set initialized flag for startup object */
563 flagorandinit(startupobject,1,0xFFFFFFFF);
564 enqueueObject(startupobject, NULL, 0);
566 BAMBOO_CACHE_FLUSH_ALL();
570 int hashCodetpd(struct taskparamdescriptor *ftd) {
571 int hash=(int)ftd->task;
573 for(i=0; i<ftd->numParameters; i++) {
574 hash^=(int)ftd->parameterArray[i];
579 int comparetpd(struct taskparamdescriptor *ftd1, struct taskparamdescriptor *ftd2) {
581 if (ftd1->task!=ftd2->task)
583 for(i=0; i<ftd1->numParameters; i++)
584 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
589 /* This function sets a tag. */
591 void tagset(void *ptr, struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
593 void tagset(struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
595 struct ArrayObject * ao=NULL;
596 struct ___Object___ * tagptr=obj->___tags___;
598 obj->___tags___=(struct ___Object___ *)tagd;
600 /* Have to check if it is already set */
601 if (tagptr->type==TAGTYPE) {
602 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
607 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
608 struct ArrayObject * ao=allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
609 obj=(struct ___Object___ *)ptrarray[2];
610 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
611 td=(struct ___TagDescriptor___ *) obj->___tags___;
613 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
616 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
617 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
618 obj->___tags___=(struct ___Object___ *) ao;
619 ao->___cachedCode___=2;
623 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
624 for(i=0; i<ao->___cachedCode___; i++) {
625 struct ___TagDescriptor___ * td=ARRAYGET(ao, struct ___TagDescriptor___*, i);
630 if (ao->___cachedCode___<ao->___length___) {
631 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
632 ao->___cachedCode___++;
635 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
636 struct ArrayObject * aonew=allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
637 obj=(struct ___Object___ *)ptrarray[2];
638 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
639 ao=(struct ArrayObject *)obj->___tags___;
641 struct ArrayObject * aonew=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
644 aonew->___cachedCode___=ao->___length___+1;
645 for(i=0; i<ao->___length___; i++) {
646 ARRAYSET(aonew, struct ___TagDescriptor___*, i, ARRAYGET(ao, struct ___TagDescriptor___*, i));
648 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
654 struct ___Object___ * tagset=tagd->flagptr;
657 } else if (tagset->type!=OBJECTARRAYTYPE) {
659 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
660 struct ArrayObject * ao=allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
661 obj=(struct ___Object___ *)ptrarray[2];
662 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
664 struct ArrayObject * ao=allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
666 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
667 ARRAYSET(ao, struct ___Object___ *, 1, obj);
668 ao->___cachedCode___=2;
669 tagd->flagptr=(struct ___Object___ *)ao;
671 struct ArrayObject *ao=(struct ArrayObject *) tagset;
672 if (ao->___cachedCode___<ao->___length___) {
673 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
677 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
678 struct ArrayObject * aonew=allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
679 obj=(struct ___Object___ *)ptrarray[2];
680 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
681 ao=(struct ArrayObject *)tagd->flagptr;
683 struct ArrayObject * aonew=allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
685 aonew->___cachedCode___=ao->___cachedCode___+1;
686 for(i=0; i<ao->___length___; i++) {
687 ARRAYSET(aonew, struct ___Object___*, i, ARRAYGET(ao, struct ___Object___*, i));
689 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
690 tagd->flagptr=(struct ___Object___ *) aonew;
696 /* This function clears a tag. */
698 void tagclear(void *ptr, struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
700 void tagclear(struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
702 /* We'll assume that tag is alway there.
703 Need to statically check for this of course. */
704 struct ___Object___ * tagptr=obj->___tags___;
706 if (tagptr->type==TAGTYPE) {
707 if ((struct ___TagDescriptor___ *)tagptr==tagd)
708 obj->___tags___=NULL;
711 printf("ERROR 1 in tagclear\n");
716 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
718 for(i=0; i<ao->___cachedCode___; i++) {
719 struct ___TagDescriptor___ * td=ARRAYGET(ao, struct ___TagDescriptor___ *, i);
721 ao->___cachedCode___--;
722 if (i<ao->___cachedCode___)
723 ARRAYSET(ao, struct ___TagDescriptor___ *, i, ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
724 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
725 if (ao->___cachedCode___==0)
726 obj->___tags___=NULL;
731 printf("ERROR 2 in tagclear\n");
736 struct ___Object___ *tagset=tagd->flagptr;
737 if (tagset->type!=OBJECTARRAYTYPE) {
742 printf("ERROR 3 in tagclear\n");
747 struct ArrayObject *ao=(struct ArrayObject *) tagset;
749 for(i=0; i<ao->___cachedCode___; i++) {
750 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
752 ao->___cachedCode___--;
753 if (i<ao->___cachedCode___)
754 ARRAYSET(ao, struct ___Object___ *, i, ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
755 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
756 if (ao->___cachedCode___==0)
762 printf("ERROR 4 in tagclear\n");
770 /* This function allocates a new tag. */
772 struct ___TagDescriptor___ * allocate_tag(void *ptr, int index) {
773 struct ___TagDescriptor___ * v=(struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr, classsize[TAGTYPE]);
775 struct ___TagDescriptor___ * allocate_tag(int index) {
776 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
778 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
786 /* This function updates the flag for object ptr. It or's the flag
787 with the or mask and and's it with the andmask. */
789 void flagbody(struct ___Object___ *ptr, int flag, struct parameterwrapper ** queues, int length, bool isnew);
791 int flagcomp(const int *val1, const int *val2) {
792 return (*val1)-(*val2);
795 void flagorand(void * ptr, int ormask, int andmask, struct parameterwrapper ** queues, int length) {
797 int oldflag=((int *)ptr)[1];
798 int flag=ormask|oldflag;
800 flagbody(ptr, flag, queues, length, false);
804 bool intflagorand(void * ptr, int ormask, int andmask) {
806 int oldflag=((int *)ptr)[1];
807 int flag=ormask|oldflag;
809 if (flag==oldflag) /* Don't do anything */
812 flagbody(ptr, flag, NULL, 0, false);
818 void flagorandinit(void * ptr, int ormask, int andmask) {
819 int oldflag=((int *)ptr)[1];
820 int flag=ormask|oldflag;
822 flagbody(ptr,flag,NULL,0,true);
825 void flagbody(struct ___Object___ *ptr, int flag, struct parameterwrapper ** vqueues, int vlength, bool isnew) {
826 struct parameterwrapper * flagptr = NULL;
828 struct parameterwrapper ** queues = vqueues;
829 int length = vlength;
832 int * enterflags = NULL;
833 if((!isnew) && (queues == NULL)) {
834 if(BAMBOO_NUM_OF_CORE < NUMCORES) {
835 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
836 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
843 /*Remove object from all queues */
844 for(i = 0; i < length; ++i) {
846 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next, (int *) &enterflags, &UNUSED, &UNUSED2);
847 ObjectHashremove(flagptr->objectset, (int)ptr);
848 if (enterflags!=NULL)
853 void enqueueObject(void * vptr, struct parameterwrapper ** vqueues, int vlength) {
854 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
857 //struct QueueItem *tmpptr;
858 struct parameterwrapper * parameter=NULL;
861 struct parameterwrapper * prevptr=NULL;
862 struct ___Object___ *tagptr=NULL;
863 struct parameterwrapper ** queues = vqueues;
864 int length = vlength;
865 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
869 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
870 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
872 tagptr=ptr->___tags___;
874 /* Outer loop iterates through all parameter queues an object of
875 this type could be in. */
876 for(j = 0; j < length; ++j) {
877 parameter = queues[j];
879 if (parameter->numbertags>0) {
881 goto nextloop; //that means the object has no tag but that param needs tag
882 else if(tagptr->type==TAGTYPE) { //one tag
883 //struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
884 for(i=0; i<parameter->numbertags; i++) {
885 //slotid is parameter->tagarray[2*i];
886 int tagid=parameter->tagarray[2*i+1];
887 if (tagid!=tagptr->flag)
888 goto nextloop; /*We don't have this tag */
890 } else { //multiple tags
891 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
892 for(i=0; i<parameter->numbertags; i++) {
893 //slotid is parameter->tagarray[2*i];
894 int tagid=parameter->tagarray[2*i+1];
896 for(j=0; j<ao->___cachedCode___; j++) {
897 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
908 for(i=0; i<parameter->numberofterms; i++) {
909 int andmask=parameter->intarray[i*2];
910 int checkmask=parameter->intarray[i*2+1];
911 if ((ptr->flag&andmask)==checkmask) {
912 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
923 void enqueueObject_I(void * vptr, struct parameterwrapper ** vqueues, int vlength) {
924 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
927 //struct QueueItem *tmpptr;
928 struct parameterwrapper * parameter=NULL;
931 struct parameterwrapper * prevptr=NULL;
932 struct ___Object___ *tagptr=NULL;
933 struct parameterwrapper ** queues = vqueues;
934 int length = vlength;
935 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
939 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
940 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
942 tagptr=ptr->___tags___;
944 /* Outer loop iterates through all parameter queues an object of
945 this type could be in. */
946 for(j = 0; j < length; ++j) {
947 parameter = queues[j];
949 if (parameter->numbertags>0) {
951 goto nextloop; //that means the object has no tag but that param needs tag
952 else if(tagptr->type==TAGTYPE) { //one tag
953 //struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
954 for(i=0; i<parameter->numbertags; i++) {
955 //slotid is parameter->tagarray[2*i];
956 int tagid=parameter->tagarray[2*i+1];
957 if (tagid!=tagptr->flag)
958 goto nextloop; /*We don't have this tag */
960 } else { //multiple tags
961 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
962 for(i=0; i<parameter->numbertags; i++) {
963 //slotid is parameter->tagarray[2*i];
964 int tagid=parameter->tagarray[2*i+1];
966 for(j=0; j<ao->___cachedCode___; j++) {
967 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
978 for(i=0; i<parameter->numberofterms; i++) {
979 int andmask=parameter->intarray[i*2];
980 int checkmask=parameter->intarray[i*2+1];
981 if ((ptr->flag&andmask)==checkmask) {
982 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
994 int * getAliasLock(void ** ptrs, int length, struct RuntimeHash * tbl) {
996 return (int*)(RUNMALLOC(sizeof(int)));
1001 bool redirect = false;
1002 int redirectlock = 0;
1003 for(; i < length; i++) {
1004 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1007 if(ptr->lock == NULL) {
1010 lock = (int)(ptr->lock);
1013 if(lock != redirectlock) {
1014 RuntimeHashadd(tbl, lock, redirectlock);
1017 if(RuntimeHashcontainskey(tbl, lock)) {
1018 // already redirected
1020 RuntimeHashget(tbl, lock, &redirectlock);
1021 for(; j < locklen; j++) {
1022 if(locks[j] != redirectlock) {
1023 RuntimeHashadd(tbl, locks[j], redirectlock);
1028 for(j = 0; j < locklen; j++) {
1029 if(locks[j] == lock) {
1032 } else if(locks[j] > lock) {
1039 locks[h] = locks[h-1];
1048 return (int *)redirectlock;
1050 return (int *)(locks[0]);
1055 void addAliasLock(void * ptr, int lock) {
1056 struct ___Object___ * obj = (struct ___Object___ *)ptr;
1057 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1058 // originally no alias lock associated or have a different alias lock
1059 // flush it as the new one
1060 obj->lock = (int *)lock;
1065 inline void setTaskExitIndex(int index) {
1066 taskInfoArray[taskInfoIndex]->exitIndex = index;
1069 inline void addNewObjInfo(void * nobj) {
1070 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1071 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1073 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1077 // receive object transferred from other cores
1078 // or the terminate message from other cores
1079 // Should be invoked in critical sections!!
1080 // NOTICE: following format is for threadsimulate version only
1081 // RAW version please see previous description
1082 // format: type + object
1083 // type: -1--stall msg
1085 // return value: 0--received an object
1086 // 1--received nothing
1087 // 2--received a Stall Msg
1088 // 3--received a lock Msg
1089 // RAW version: -1 -- received nothing
1090 // otherwise -- received msg type
1091 int receiveObject() {
1095 if(receiveMsg() == -1) {
1099 if(msgdataindex == msglength) {
1100 // received a whole msg
1102 int data1; // will receive at least 2 words including type
1107 // receive a object transfer msg
1108 struct transObjInfo * transObj = RUNMALLOC_I(sizeof(struct transObjInfo));
1112 BAMBOO_DEBUGPRINT(0xe880);
1115 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1117 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1119 BAMBOO_EXIT(0xa005);
1121 // store the object and its corresponding queue info, enqueue it later
1122 transObj->objptr = (void *)msgdata[2]; // data1 is now size of the msg
1123 transObj->length = (msglength - 3) / 2;
1124 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
1125 for(k = 0; k < transObj->length; ++k) {
1126 transObj->queues[2*k] = msgdata[3+2*k];
1129 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
1132 transObj->queues[2*k+1] = msgdata[3+2*k+1];
1135 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
1139 // check if there is an existing duplicate item
1141 struct QueueItem * qitem = getHead(&objqueue);
1142 struct QueueItem * prev = NULL;
1143 while(qitem != NULL) {
1144 struct transObjInfo * tmpinfo =
1145 (struct transObjInfo *)(qitem->objectptr);
1146 if(tmpinfo->objptr == transObj->objptr) {
1147 // the same object, remove outdate one
1148 removeItem(&objqueue, qitem);
1154 qitem = getHead(&objqueue);
1156 qitem = getNextQueueItem(prev);
1159 addNewItem_I(&objqueue, (void *)transObj);
1161 ++(self_numreceiveobjs);
1166 // receive a stall msg
1167 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1168 // non startup core can not receive stall msg
1170 BAMBOO_DEBUGPRINT_REG(data1);
1172 BAMBOO_EXIT(0xa006);
1174 if(data1 < NUMCORES) {
1177 BAMBOO_DEBUGPRINT(0xe881);
1180 corestatus[data1] = 0;
1181 numsendobjs[data1] = msgdata[2];
1182 numreceiveobjs[data1] = msgdata[3];
1187 // GC version have no lock msgs
1188 #ifndef MULTICORE_GC
1190 // receive lock request msg, handle it right now
1191 // check to see if there is a lock exist for the required obj
1192 // data1 -> lock type
1193 int data2 = msgdata[2]; // obj pointer
1194 int data3 = msgdata[3]; // lock
1195 int data4 = msgdata[4]; // request core
1196 deny = processlockrequest(data1, data3, data2, data4, data4, true); // -1: redirected, 0: approved, 1: denied
1198 // this lock request is redirected
1201 // send response msg
1202 // for 32 bit machine, the size is always 4 words
1203 int tmp = deny==1?LOCKDENY:LOCKGROUNT;
1205 cache_msg_4(data4, tmp, data1, data2, data3);
1207 send_msg_4(data4, tmp, data1, data2, data3);
1214 // receive lock grount msg
1215 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1217 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1219 BAMBOO_EXIT(0xa007);
1221 if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1224 BAMBOO_DEBUGPRINT(0xe882);
1233 // conflicts on lockresults
1235 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1237 BAMBOO_EXIT(0xa008);
1243 // receive lock deny msg
1244 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1246 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1248 BAMBOO_EXIT(0xa009);
1250 if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1253 BAMBOO_DEBUGPRINT(0xe883);
1262 // conflicts on lockresults
1264 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1266 BAMBOO_EXIT(0xa00a);
1272 // receive lock release msg
1273 processlockrelease(data1, msgdata[2], 0, false);
1279 case PROFILEOUTPUT: {
1280 // receive an output profile data request msg
1281 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
1282 // startup core can not receive profile output finish msg
1283 BAMBOO_EXIT(0xa00c);
1287 BAMBOO_DEBUGPRINT(0xe885);
1291 totalexetime = data1;
1292 outputProfileData();
1294 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1296 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1301 case PROFILEFINISH: {
1302 // receive a profile output finish msg
1303 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1304 // non startup core can not receive profile output finish msg
1306 BAMBOO_DEBUGPRINT_REG(data1);
1308 BAMBOO_EXIT(0xa00d);
1312 BAMBOO_DEBUGPRINT(0xe886);
1315 profilestatus[data1] = 0;
1320 // GC version has no lock msgs
1321 #ifndef MULTICORE_GC
1322 case REDIRECTLOCK: {
1323 // receive a redirect lock request msg, handle it right now
1324 // check to see if there is a lock exist for the required obj
1325 // data1 -> lock type
1326 int data2 = msgdata[2]; // obj pointer
1327 int data3 = msgdata[3]; // redirect lock
1328 int data4 = msgdata[4]; // root request core
1329 int data5 = msgdata[5]; // request core
1330 deny = processlockrequest(data1, data3, data2, data5, data4, true);
1332 // this lock request is redirected
1335 // send response msg
1336 // for 32 bit machine, the size is always 4 words
1338 cache_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
1339 data1, data2, data3);
1341 send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
1342 data1, data2, data3);
1348 case REDIRECTGROUNT: {
1349 // receive a lock grant msg with redirect info
1350 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1352 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1354 BAMBOO_EXIT(0xa00e);
1356 if(lockobj == msgdata[2]) {
1359 BAMBOO_DEBUGPRINT(0xe891);
1364 RuntimeHashadd_I(objRedirectLockTbl, lockobj, msgdata[3]);
1369 // conflicts on lockresults
1371 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1373 BAMBOO_EXIT(0xa00f);
1378 case REDIRECTDENY: {
1379 // receive a lock deny msg with redirect info
1380 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1382 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1384 BAMBOO_EXIT(0xa010);
1386 if(lockobj == msgdata[2]) {
1389 BAMBOO_DEBUGPRINT(0xe892);
1398 // conflicts on lockresults
1400 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1402 BAMBOO_EXIT(0xa011);
1407 case REDIRECTRELEASE: {
1408 // receive a lock release msg with redirect info
1409 processlockrelease(data1, msgdata[2], msgdata[3], true);
1414 case STATUSCONFIRM: {
1415 // receive a status confirm info
1416 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
1417 || (BAMBOO_NUM_OF_CORE > NUMCORES - 1)) {
1418 // wrong core to receive such msg
1419 BAMBOO_EXIT(0xa013);
1421 // send response msg
1424 BAMBOO_DEBUGPRINT(0xe887);
1428 cache_msg_5(STARTUPCORE, STATUSREPORT,
1429 busystatus?1:0, BAMBOO_NUM_OF_CORE,
1430 self_numsendobjs, self_numreceiveobjs);
1432 send_msg_5(STARTUPCORE, STATUSREPORT,
1433 busystatus?1:0, BAMBOO_NUM_OF_CORE,
1434 self_numsendobjs, self_numreceiveobjs);
1440 case STATUSREPORT: {
1441 // receive a status confirm info
1442 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1443 // wrong core to receive such msg
1445 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1447 BAMBOO_EXIT(0xa014);
1451 BAMBOO_DEBUGPRINT(0xe888);
1457 corestatus[msgdata[2]] = msgdata[1];
1458 numsendobjs[data1] = msgdata[2];
1459 numreceiveobjs[data1] = msgdata[3];
1465 // receive a terminate msg
1468 BAMBOO_DEBUGPRINT(0xe889);
1477 // receive a shared memory request msg
1478 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1479 // wrong core to receive such msg
1481 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1483 BAMBOO_EXIT(0xa015);
1487 BAMBOO_DEBUGPRINT(0xe88a);
1492 // is currently doing gc, dump this msg
1496 void * mem = mspace_calloc(bamboo_free_msp, 1, msgdata[1]);
1498 // no enough shared global memory
1503 BAMBOO_DEBUGPRINT(0xa016);
1504 BAMBOO_EXIT(0xa016);
1507 // send the start_va to request core
1509 cache_msg_3(msgdata[2], MEMRESPONSE, mem, msgdata[1]);
1511 send_msg_3( msgdata[2], MEMRESPONSE, mem, msgdata[1]);
1518 // receive a shared memory response msg
1521 BAMBOO_DEBUGPRINT(0xe88b);
1526 // is currently doing gc, dump this msg
1530 if(msgdata[2] == 0) {
1531 bamboo_smem_size = 0;
1532 bamboo_cur_msp = NULL;
1534 // fill header to store the size of this mem block
1535 (*((int*)msgdata[1])) = msgdata[2];
1536 bamboo_smem_size = msgdata[2] - BAMBOO_CACHE_LINE_SIZE;
1537 bamboo_cur_msp = create_mspace_with_base((void*)(msgdata[1]+BAMBOO_CACHE_LINE_SIZE),
1538 msgdata[2] - BAMBOO_CACHE_LINE_SIZE,
1548 // receive a start GC msg
1551 BAMBOO_DEBUGPRINT(0xe88c);
1556 gcphase = MARKPHASE;
1558 // is waiting for response of mem request
1559 // let it return NULL and start gc
1560 bamboo_smem_size = 0;
1561 bamboo_cur_msp = NULL;
1567 case GCSTARTCOMPACT: {
1568 // a compact phase start msg
1569 if(cinstruction == NULL) {
1571 (struct compactInstr *)RUNMALLOC(sizeof(struct compactInstr));
1573 // clean up out of date info
1574 cinstruction->movenum = 0;
1576 cinstruction->loads = msgdata[2];
1578 // have objs to move etc.
1580 // process objs to move
1581 cinstruction->movenum = msgdata[startindex++];
1582 cinstruction->ismove = msgdata[startindex++];
1583 for(i = 0; i < cinstruction->movenum; i++) {
1584 cinstruction->size2move[i] = msgdata[startindex++];
1585 cinstruction->dsts[i] = msgdata[startindex++];
1586 cinstruction->moveflag[i] = 0;
1587 cinstruction->startaddrs[i] = 0;
1588 cinstruction->endaddrs[i] = 0;
1591 /*// process large objs
1592 num = msgdata[startindex++];
1593 for(i = 0; i < num; i++) {
1594 struct largeObjItem * loi =
1595 (struct largeObjItem *)RUNMALLOC(sizeof(struct largeObjItem ));
1596 loi->orig = msgdata[startindex++];
1597 loi->length = msgdata[startindex++];
1598 loi->dst = msgdata[startindex++];
1601 cinstruction->largeobjs->next = loi;
1603 cinstruction->largeobjs = loi;
1606 gcphase = COMPACTPHASE;
1610 case GCSTARTFLUSH: {
1611 // received a flush phase start msg
1612 gcphase = FLUSHPHASE;
1616 case GCFINISHMARK: {
1617 // received a mark phase finish msg
1618 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1619 // non startup core can not receive this msg
1621 BAMBOO_DEBUGPRINT_REG(data1);
1623 BAMBOO_EXIT(0xb006);
1625 if(data1 < NUMCORES) {
1626 gccorestatus[data1] = 0;
1627 gcnumsendobjs[data1] = gcmsgdata[2];
1628 gcnumreceiveobjs[data1] = gcmsgdata[3];
1633 case GCFINISHCOMPACT: {
1634 // received a compact phase finish msg
1635 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1636 // non startup core can not receive this msg
1639 BAMBOO_DEBUGPRINT_REG(data1);
1641 BAMBOO_EXIT(0xb006);
1643 if(data1 < NUMCORES) {
1644 gccorestatus[data1] = 0;
1645 gcloads[data1] = msgdata[2];
1650 case GCFINISHFLUSH: {
1651 // received a flush phase finish msg
1652 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1653 // non startup core can not receive this msg
1656 BAMBOO_DEBUGPRINT_REG(data1);
1658 BAMBOO_EXIT(0xb006);
1660 if(data1 < NUMCORES) {
1661 gccorestatus[data1] = 0;
1667 // received a GC finish msg
1668 gcphase = FINISHPHASE;
1672 case GCMARKCONFIRM: {
1673 // received a marked phase finish confirm request msg
1674 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
1675 || (BAMBOO_NUM_OF_CORE > NUMCORES - 1)) {
1676 // wrong core to receive such msg
1677 BAMBOO_EXIT(0xa013);
1679 // send response msg
1681 cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
1682 gcbusystatus, gcself_numsendobjs, gcself_numreceiveobjs);
1684 send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
1685 gcbusystatus, gcself_numsendobjs, gcself_numreceiveobjs);
1691 case GCMARKREPORT: {
1692 // received a marked phase finish confirm response msg
1693 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1694 // wrong core to receive such msg
1696 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1698 BAMBOO_EXIT(0xb014);
1703 gccorestatus[data1] = gcmsgdata[2];
1704 gcnumsendobjs[data1] = gcmsgdata[3];
1705 gcnumreceiveobjs[data1] = gcmsgdata[4];
1711 // received a markedObj msg
1713 gcself_numreceiveobjs++;
1714 gcbusystatus = true;
1719 // received a start moving objs msg
1720 if(cinstruction == NULL) {
1721 // something is wrong
1722 BAMBOO_EXIT(0xa023);
1724 for(i = 0; i < cinstruction->movenum; i++) {
1725 if(cinstruction->dsts[i] == data1) {
1726 // set the flag to indicate the core is ready to accept objs
1727 cinstruction->moveflag[i] = 1;
1728 cinstruction->startaddrs[i] = msgdata[2];
1729 cinstruction->endaddrs[i] = msgdata[3];
1736 case GCMAPREQUEST: {
1737 // received a mapping info request msg
1738 void * dstptr = NULL;
1739 RuntimeHashget(pointertbl, data1, &dstptr);
1740 if(NULL == dstptr) {
1741 // no such pointer in this core, something is wrong
1742 BAMBOO_EXIT(0xb008);
1744 // send back the mapping info
1746 cache_msg_3(msgdata[2], GCMAPINFO, data1, (int)dstptr);
1748 send_msg_3(msgdata[2], GCMAPINFO,data1, (int)dstptr);
1755 // received a mapping info response msg
1756 if(data1 != obj2map) {
1757 // obj not matched, something is wrong
1758 BAMBOO_EXIT(0xb009);
1760 mappedobj = msgdata[2];
1761 RuntimeHashadd(pointertbl, obj2map, mappedobj);
1767 case GCLOBJREQUEST: {
1768 // received a large objs info request msg
1769 transferMarkResults();
1774 // received a large objs info response msg
1784 for(msgdataindex--; msgdataindex > 0; --msgdataindex) {
1785 msgdata[msgdataindex] = -1;
1791 BAMBOO_DEBUGPRINT(0xe88d);
1795 if(BAMBOO_MSG_AVAIL() != 0) {
1808 BAMBOO_DEBUGPRINT(0xe88e);
1812 /* if(isInterrupt) {
1821 ent enqueuetasks(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr, int * enterflags, int numenterflags) {
1822 void * taskpointerarray[MAXTASKPARAMS];
1824 //int numparams=parameter->task->numParameters;
1825 int numiterators=parameter->task->numTotal-1;
1828 struct taskdescriptor * task=parameter->task;
1830 //this add the object to parameterwrapper
1831 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags, numenterflags, enterflags==NULL);
1833 /* Add enqueued object to parameter vector */
1834 taskpointerarray[parameter->slot]=ptr;
1836 /* Reset iterators */
1837 for(j=0; j<numiterators; j++) {
1838 toiReset(¶meter->iterators[j]);
1841 /* Find initial state */
1842 for(j=0; j<numiterators; j++) {
1844 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
1845 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
1847 /* Need to backtrack */
1848 toiReset(¶meter->iterators[j]);
1852 /* Nothing to enqueue */
1858 /* Enqueue current state */
1860 struct taskparamdescriptor *tpd=RUNMALLOC(sizeof(struct taskparamdescriptor));
1862 tpd->numParameters=numiterators+1;
1863 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
1865 for(j=0; j<=numiterators; j++) {
1866 tpd->parameterArray[j]=taskpointerarray[j]; //store the actual parameters
1869 if ((/*!gencontains(failedtasks, tpd)&&*/ !gencontains(activetasks,tpd))) {
1870 genputtable(activetasks, tpd, tpd);
1872 RUNFREE(tpd->parameterArray);
1876 /* This loop iterates to the next parameter combination */
1877 if (numiterators==0)
1880 for(j=numiterators-1; j<numiterators; j++) {
1882 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
1883 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
1885 /* Need to backtrack */
1886 toiReset(¶meter->iterators[j]);
1890 /* Nothing more to enqueue */
1898 int enqueuetasks_I(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr, int * enterflags, int numenterflags) {
1899 void * taskpointerarray[MAXTASKPARAMS];
1901 //int numparams=parameter->task->numParameters;
1902 int numiterators=parameter->task->numTotal-1;
1907 struct taskdescriptor * task=parameter->task;
1909 //this add the object to parameterwrapper
1910 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags, numenterflags, enterflags==NULL);
1912 /* Add enqueued object to parameter vector */
1913 taskpointerarray[parameter->slot]=ptr;
1915 /* Reset iterators */
1916 for(j=0; j<numiterators; j++) {
1917 toiReset(¶meter->iterators[j]);
1920 /* Find initial state */
1921 for(j=0; j<numiterators; j++) {
1923 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
1924 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
1926 /* Need to backtrack */
1927 toiReset(¶meter->iterators[j]);
1931 /* Nothing to enqueue */
1937 /* Enqueue current state */
1939 struct taskparamdescriptor *tpd=RUNMALLOC_I(sizeof(struct taskparamdescriptor));
1941 tpd->numParameters=numiterators+1;
1942 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
1944 for(j=0; j<=numiterators; j++) {
1945 tpd->parameterArray[j]=taskpointerarray[j]; //store the actual parameters
1948 if ((/*!gencontains(failedtasks, tpd)&&*/ !gencontains(activetasks,tpd))) {
1949 genputtable_I(activetasks, tpd, tpd);
1951 RUNFREE(tpd->parameterArray);
1955 /* This loop iterates to the next parameter combination */
1956 if (numiterators==0)
1959 for(j=numiterators-1; j<numiterators; j++) {
1961 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
1962 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
1964 /* Need to backtrack */
1965 toiReset(¶meter->iterators[j]);
1969 /* Nothing more to enqueue */
1977 /* Handler for signals. The signals catch null pointer errors and
1978 arithmatic errors. */
1980 void myhandler(int sig, siginfo_t *info, void *uap) {
1983 printf("sig=%d\n",sig);
1986 sigemptyset(&toclear);
1987 sigaddset(&toclear, sig);
1988 sigprocmask(SIG_UNBLOCK, &toclear,NULL);
1989 longjmp(error_handler,1);
1996 struct RuntimeHash *fdtoobject;
1998 void addreadfd(int fd) {
2001 FD_SET(fd, &readfds);
2004 void removereadfd(int fd) {
2005 FD_CLR(fd, &readfds);
2006 if (maxreadfd==(fd+1)) {
2008 while(maxreadfd>0&&!FD_ISSET(maxreadfd-1, &readfds))
2020 int containstag(struct ___Object___ *ptr, struct ___TagDescriptor___ *tag);
2022 void executetasks() {
2023 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
2026 struct ___Object___ * tmpparam = NULL;
2027 struct parameterdescriptor * pd=NULL;
2028 struct parameterwrapper *pw=NULL;
2033 struct LockValue locks[MAXTASKPARAMS];
2041 while(hashsize(activetasks)>0) {
2046 BAMBOO_DEBUGPRINT(0xe990);
2049 /* See if there are any active tasks */
2050 if (hashsize(activetasks)>0) {
2053 #ifdef ACCURATEPROFILE
2054 profileTaskStart("tpd checking");
2058 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
2059 genfreekey(activetasks, currtpd);
2061 numparams=currtpd->task->numParameters;
2062 numtotal=currtpd->task->numTotal;
2064 // clear the lockRedirectTbl (TODO, this table should be empty after all locks are released)
2066 for(j = 0; j < MAXTASKPARAMS; j++) {
2067 locks[j].redirectlock = 0;
2070 // get all required locks
2072 // check which locks are needed
2073 for(i = 0; i < numparams; i++) {
2074 void * param = currtpd->parameterArray[i];
2078 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
2080 taskpointerarray[i+OFFSET]=param;
2083 if(((struct ___Object___ *)param)->lock == NULL) {
2084 tmplock = (int)param;
2086 tmplock = (int)(((struct ___Object___ *)param)->lock);
2088 // insert into the locks array
2089 for(j = 0; j < locklen; j++) {
2090 if(locks[j].value == tmplock) {
2093 } else if(locks[j].value > tmplock) {
2100 locks[h].redirectlock = locks[h-1].redirectlock;
2101 locks[h].value = locks[h-1].value;
2103 locks[j].value = tmplock;
2104 locks[j].redirectlock = (int)param;
2107 } // line 2713: for(i = 0; i < numparams; i++)
2108 // grab these required locks
2110 BAMBOO_DEBUGPRINT(0xe991);
2112 for(i = 0; i < locklen; i++) {
2113 int * lock = (int *)(locks[i].redirectlock);
2115 // require locks for this parameter if it is not a startup object
2117 BAMBOO_DEBUGPRINT_REG((int)lock);
2118 BAMBOO_DEBUGPRINT_REG((int)(locks[i].value));
2121 BAMBOO_START_CRITICAL_SECTION();
2123 BAMBOO_DEBUGPRINT(0xf001);
2126 //isInterrupt = false;
2129 BAMBOO_WAITING_FOR_LOCK();
2133 while(BAMBOO_WAITING_FOR_LOCK() != -1) {
2137 grount = lockresult;
2147 //isInterrupt = true;
2149 BAMBOO_CLOSE_CRITICAL_SECTION();
2151 BAMBOO_DEBUGPRINT(0xf000);
2157 BAMBOO_DEBUGPRINT(0xe992);
2159 // can not get the lock, try later
2160 // releas all grabbed locks for previous parameters
2161 for(j = 0; j < i; ++j) {
2162 lock = (int*)(locks[j].redirectlock);
2163 releasewritelock(lock);
2165 genputtable(activetasks, currtpd, currtpd);
2166 if(hashsize(activetasks) == 1) {
2167 // only one task right now, wait a little while before next try
2173 #ifdef ACCURATEPROFILE
2174 // fail, set the end of the checkTaskInfo
2179 } // line 2794: if(grount == 0)
2180 } // line 2752: for(i = 0; i < locklen; i++)
2183 BAMBOO_DEBUGPRINT(0xe993);
2185 /* Make sure that the parameters are still in the queues */
2186 for(i=0; i<numparams; i++) {
2187 void * parameter=currtpd->parameterArray[i];
2191 BAMBOO_CACHE_FLUSH_RANGE((int)parameter, classsize[((struct ___Object___ *)parameter)->type]);
2193 tmpparam = (struct ___Object___ *)parameter;
2194 pd=currtpd->task->descriptorarray[i];
2195 pw=(struct parameterwrapper *) pd->queue;
2196 /* Check that object is still in queue */
2198 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
2200 BAMBOO_DEBUGPRINT(0xe994);
2202 // release grabbed locks
2203 for(j = 0; j < locklen; ++j) {
2204 int * lock = (int *)(locks[j].redirectlock);
2205 releasewritelock(lock);
2207 RUNFREE(currtpd->parameterArray);
2212 /* Check if the object's flags still meets requirements */
2216 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
2217 andmask=pw->intarray[tmpi*2];
2218 checkmask=pw->intarray[tmpi*2+1];
2219 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
2225 // flags are never suitable
2226 // remove this obj from the queue
2228 int UNUSED, UNUSED2;
2231 BAMBOO_DEBUGPRINT(0xe995);
2233 ObjectHashget(pw->objectset, (int) parameter, (int *) &next, (int *) &enterflags, &UNUSED, &UNUSED2);
2234 ObjectHashremove(pw->objectset, (int)parameter);
2235 if (enterflags!=NULL)
2236 RUNFREE(enterflags);
2237 // release grabbed locks
2238 for(j = 0; j < locklen; ++j) {
2239 int * lock = (int *)(locks[j].redirectlock);
2240 releasewritelock(lock);
2242 RUNFREE(currtpd->parameterArray);
2245 #ifdef ACCURATEPROFILE
2246 // fail, set the end of the checkTaskInfo
2251 } // line 2878: if (!ismet)
2255 /* Check that object still has necessary tags */
2256 for(j=0; j<pd->numbertags; j++) {
2257 int slotid=pd->tagarray[2*j]+numparams;
2258 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
2259 if (!containstag(parameter, tagd)) {
2261 BAMBOO_DEBUGPRINT(0xe996);
2264 // release grabbed locks
2266 for(tmpj = 0; tmpj < locklen; ++tmpj) {
2267 int * lock = (int *)(locks[tmpj].redirectlock);
2268 releasewritelock(lock);
2271 RUNFREE(currtpd->parameterArray);
2274 } // line2911: if (!containstag(parameter, tagd))
2275 } // line 2808: for(j=0; j<pd->numbertags; j++)
2277 taskpointerarray[i+OFFSET]=parameter;
2278 } // line 2824: for(i=0; i<numparams; i++)
2280 for(; i<numtotal; i++) {
2281 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
2285 /* Actually call task */
2287 ((int *)taskpointerarray)[0]=currtpd->numParameters;
2288 taskpointerarray[1]=NULL;
2292 #ifdef ACCURATEPROFILE
2293 // check finish, set the end of the checkTaskInfo
2296 profileTaskStart(currtpd->task->name);
2301 printf("ENTER %s count=%d\n",currtpd->task->name, (instaccum-instructioncount));
2303 ((void(*) (void **))currtpd->task->taskptr)(taskpointerarray);
2305 printf("EXIT %s count=%d\n",currtpd->task->name, (instaccum-instructioncount));
2309 BAMBOO_DEBUGPRINT(0xe997);
2311 ((void(*) (void **))currtpd->task->taskptr)(taskpointerarray);
2312 } // line 2990: if(debugtask)
2314 #ifdef ACCURATEPROFILE
2315 // task finish, set the end of the checkTaskInfo
2317 // new a PostTaskInfo for the post-task execution
2318 profileTaskStart("post task execution");
2322 BAMBOO_DEBUGPRINT(0xe998);
2323 BAMBOO_DEBUGPRINT_REG(islock);
2328 BAMBOO_DEBUGPRINT(0xe999);
2330 for(i = 0; i < locklen; ++i) {
2331 void * ptr = (void *)(locks[i].redirectlock);
2332 int * lock = (int *)(locks[i].value);
2334 BAMBOO_DEBUGPRINT_REG((int)ptr);
2335 BAMBOO_DEBUGPRINT_REG((int)lock);
2337 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
2339 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
2340 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
2341 releasewritelock_r(lock, (int *)redirectlock);
2343 releasewritelock(ptr);
2346 } // line 3015: if(islock)
2349 // post task execution finish, set the end of the postTaskInfo
2353 // Free up task parameter descriptor
2354 RUNFREE(currtpd->parameterArray);
2357 BAMBOO_DEBUGPRINT(0xe99a);
2360 } // if (hashsize(activetasks)>0)
2361 } // while(hashsize(activetasks)>0)
2363 BAMBOO_DEBUGPRINT(0xe99b);
2367 /* This function processes an objects tags */
2368 void processtags(struct parameterdescriptor *pd, int index, struct parameterwrapper *parameter, int * iteratorcount, int *statusarray, int numparams) {
2371 for(i=0; i<pd->numbertags; i++) {
2372 int slotid=pd->tagarray[2*i];
2373 int tagid=pd->tagarray[2*i+1];
2375 if (statusarray[slotid+numparams]==0) {
2376 parameter->iterators[*iteratorcount].istag=1;
2377 parameter->iterators[*iteratorcount].tagid=tagid;
2378 parameter->iterators[*iteratorcount].slot=slotid+numparams;
2379 parameter->iterators[*iteratorcount].tagobjectslot=index;
2380 statusarray[slotid+numparams]=1;
2387 void processobject(struct parameterwrapper *parameter, int index, struct parameterdescriptor *pd, int *iteratorcount, int * statusarray, int numparams) {
2390 struct ObjectHash * objectset=((struct parameterwrapper *)pd->queue)->objectset;
2392 parameter->iterators[*iteratorcount].istag=0;
2393 parameter->iterators[*iteratorcount].slot=index;
2394 parameter->iterators[*iteratorcount].objectset=objectset;
2395 statusarray[index]=1;
2397 for(i=0; i<pd->numbertags; i++) {
2398 int slotid=pd->tagarray[2*i];
2399 //int tagid=pd->tagarray[2*i+1];
2400 if (statusarray[slotid+numparams]!=0) {
2401 /* This tag has already been enqueued, use it to narrow search */
2402 parameter->iterators[*iteratorcount].tagbindings[tagcount]=slotid+numparams;
2406 parameter->iterators[*iteratorcount].numtags=tagcount;
2411 /* This function builds the iterators for a task & parameter */
2413 void builditerators(struct taskdescriptor * task, int index, struct parameterwrapper * parameter) {
2414 int statusarray[MAXTASKPARAMS];
2416 int numparams=task->numParameters;
2417 int iteratorcount=0;
2418 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
2420 statusarray[index]=1; /* Initial parameter */
2421 /* Process tags for initial iterator */
2423 processtags(task->descriptorarray[index], index, parameter, &iteratorcount, statusarray, numparams);
2427 /* Check for objects with existing tags */
2428 for(i=0; i<numparams; i++) {
2429 if (statusarray[i]==0) {
2430 struct parameterdescriptor *pd=task->descriptorarray[i];
2432 for(j=0; j<pd->numbertags; j++) {
2433 int slotid=pd->tagarray[2*j];
2434 if(statusarray[slotid+numparams]!=0) {
2435 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
2436 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
2443 /* Next do objects w/ unbound tags*/
2445 for(i=0; i<numparams; i++) {
2446 if (statusarray[i]==0) {
2447 struct parameterdescriptor *pd=task->descriptorarray[i];
2448 if (pd->numbertags>0) {
2449 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
2450 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
2456 /* Nothing with a tag enqueued */
2458 for(i=0; i<numparams; i++) {
2459 if (statusarray[i]==0) {
2460 struct parameterdescriptor *pd=task->descriptorarray[i];
2461 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
2462 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
2475 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
2478 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
2479 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
2481 printf("%s\n", task->name);
2483 for(j=0; j<task->numParameters; j++) {
2484 struct parameterdescriptor *param=task->descriptorarray[j];
2485 struct parameterwrapper *parameter=param->queue;
2486 struct ObjectHash * set=parameter->objectset;
2487 struct ObjectIterator objit;
2489 printf(" Parameter %d\n", j);
2491 ObjectHashiterator(set, &objit);
2492 while(ObjhasNext(&objit)) {
2493 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
2494 struct ___Object___ * tagptr=obj->___tags___;
2495 int nonfailed=Objdata4(&objit);
2496 int numflags=Objdata3(&objit);
2497 int flags=Objdata2(&objit);
2500 printf(" Contains %lx\n", obj);
2501 printf(" flag=%d\n", obj->flag);
2504 } else if (tagptr->type==TAGTYPE) {
2506 printf(" tag=%lx\n",tagptr);
2512 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
2513 for(; tagindex<ao->___cachedCode___; tagindex++) {
2515 printf(" tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*, tagindex));
2527 /* This function processes the task information to create queues for
2528 each parameter type. */
2530 void processtasks() {
2532 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
2535 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
2536 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
2539 /* Build objectsets */
2540 for(j=0; j<task->numParameters; j++) {
2541 struct parameterdescriptor *param=task->descriptorarray[j];
2542 struct parameterwrapper *parameter=param->queue;
2543 parameter->objectset=allocateObjectHash(10);
2544 parameter->task=task;
2547 /* Build iterators for parameters */
2548 for(j=0; j<task->numParameters; j++) {
2549 struct parameterdescriptor *param=task->descriptorarray[j];
2550 struct parameterwrapper *parameter=param->queue;
2551 builditerators(task, j, parameter);
2556 void toiReset(struct tagobjectiterator * it) {
2559 } else if (it->numtags>0) {
2562 ObjectHashiterator(it->objectset, &it->it);
2566 int toiHasNext(struct tagobjectiterator *it, void ** objectarray OPTARG(int * failed)) {
2569 /* Get object with tags */
2570 struct ___Object___ *obj=objectarray[it->tagobjectslot];
2571 struct ___Object___ *tagptr=obj->___tags___;
2572 if (tagptr->type==TAGTYPE) {
2573 if ((it->tagobjindex==0)&& /* First object */
2574 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
2579 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
2580 int tagindex=it->tagobjindex;
2581 for(; tagindex<ao->___cachedCode___; tagindex++) {
2582 struct ___TagDescriptor___ *td=ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
2583 if (td->flag==it->tagid) {
2584 it->tagobjindex=tagindex; /* Found right type of tag */
2590 } else if (it->numtags>0) {
2591 /* Use tags to locate appropriate objects */
2592 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
2593 struct ___Object___ *objptr=tag->flagptr;
2595 if (objptr->type!=OBJECTARRAYTYPE) {
2596 if (it->tagobjindex>0)
2598 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
2600 for(i=1; i<it->numtags; i++) {
2601 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
2602 if (!containstag(objptr,tag2))
2607 struct ArrayObject *ao=(struct ArrayObject *) objptr;
2610 for(tagindex=it->tagobjindex; tagindex<ao->___cachedCode___; tagindex++) {
2611 struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
2612 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
2614 for(i=1; i<it->numtags; i++) {
2615 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
2616 if (!containstag(objptr,tag2))
2619 it->tagobjindex=tagindex;
2624 it->tagobjindex=tagindex;
2628 return ObjhasNext(&it->it);
2632 int containstag(struct ___Object___ *ptr, struct ___TagDescriptor___ *tag) {
2634 struct ___Object___ * objptr=tag->flagptr;
2635 if (objptr->type==OBJECTARRAYTYPE) {
2636 struct ArrayObject *ao=(struct ArrayObject *)objptr;
2637 for(j=0; j<ao->___cachedCode___; j++) {
2638 if (ptr==ARRAYGET(ao, struct ___Object___*, j))
2646 void toiNext(struct tagobjectiterator *it, void ** objectarray OPTARG(int * failed)) {
2647 /* hasNext has all of the intelligence */
2650 /* Get object with tags */
2651 struct ___Object___ *obj=objectarray[it->tagobjectslot];
2652 struct ___Object___ *tagptr=obj->___tags___;
2653 if (tagptr->type==TAGTYPE) {
2655 objectarray[it->slot]=tagptr;
2657 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
2658 objectarray[it->slot]=ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
2660 } else if (it->numtags>0) {
2661 /* Use tags to locate appropriate objects */
2662 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
2663 struct ___Object___ *objptr=tag->flagptr;
2664 if (objptr->type!=OBJECTARRAYTYPE) {
2666 objectarray[it->slot]=objptr;
2668 struct ArrayObject *ao=(struct ArrayObject *) objptr;
2669 objectarray[it->slot]=ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
2672 /* Iterate object */
2673 objectarray[it->slot]=(void *)Objkey(&it->it);