3 #include "multicoreruntime.h"
4 #include "runtime_arch.h"
5 #include "GenericHashtable.h"
7 extern int injectfailures;
8 extern float failurechance;
13 void * curr_heapbase=0;
14 void * curr_heaptop=0;
18 #include "instrument.h"
20 #endif // if 0: for recovery
22 // data structures for task invocation
23 struct genhashtable * activetasks;
24 struct genhashtable * failedtasks;
25 struct taskparamdescriptor * currtpd;
27 struct RuntimeHash * forward;
28 struct RuntimeHash * reverse;
29 #endif // if 0: for recovery
32 void outputProfileData();
35 bool getreadlock(void* ptr);
36 void releasereadlock(void* ptr);
37 bool getwritelock(void* ptr);
38 void releasewritelock(void* ptr);
39 void releasewritelock_r(void * lock, void * redirectlock);
41 // specific functions used inside critical sections
42 void enqueueObject_I(void * ptr, struct parameterwrapper ** queues, int length);
43 int enqueuetasks_I(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr, int * enterflags, int numenterflags);
44 bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache);
45 bool getwritelock_I(void* ptr);
46 bool getwritelock_I_r(void* lock, void* redirectlock, int core, bool cache);
47 void releasewritelock_I(void * ptr);
49 // main function for each core
50 inline void run(void * arg) {
54 bool sendStall = false;
56 bool tocontinue = false;
57 struct QueueItem * objitem = NULL;
58 struct transObjInfo * objInfo = NULL;
63 corenum = BAMBOO_GET_NUM_OF_CORE();
65 BAMBOO_DEBUGPRINT(0xeeee);
66 BAMBOO_DEBUGPRINT_REG(corenum);
67 BAMBOO_DEBUGPRINT(STARTUPCORE);
70 // initialize the arrays
71 if(STARTUPCORE == corenum) {
72 // startup core to initialize corestatus[]
73 for(i = 0; i < NUMCORES; ++i) {
75 numsendobjs[i] = 0; // assume all variables are local variables! MAY BE WRONG!!!
76 numreceiveobjs[i] = 0;
81 // initialize the profile data arrays
82 for(i = 0; i < NUMCORES; ++i) {
89 self_numreceiveobjs = 0;
91 for(i = 0; i < 30; ++i) {
97 for(i = 0; i < 30; ++i) {
103 isMsgHanging = false;
104 isMsgSending = false;
106 // create the lock table, lockresult table and obj queue
108 locktable.bucket = (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
109 /* Set allocation blocks*/
110 locktable.listhead=NULL;
111 locktable.listtail=NULL;
113 locktable.numelements = 0;
121 objqueue.head = NULL;
122 objqueue.tail = NULL;
123 lockRedirectTbl = allocateRuntimeHash(20);
124 objRedirectLockTbl = allocateRuntimeHash(20);
128 //isInterrupt = true;
131 /*interruptInfoIndex = 0;
132 taskInfoOverflow = false;
133 interruptInfoOverflow = false;*/
136 // other architecture related initialization
143 GC_init(); // Initialize the garbage collector
149 #endif // #if 0: for recovery and garbage collection
150 initializeexithandler();
152 // main process of the execution module
153 if(corenum > NUMCORES - 1) {
154 // non-executing cores, only processing communications
158 BAMBOO_DEBUGPRINT(0xee01);
159 BAMBOO_DEBUGPRINT_REG(taskInfoIndex);
160 BAMBOO_DEBUGPRINT_REG(taskInfoOverflow);
161 profileTaskStart("msg handling");
165 //isInterrupt = false;
169 /* Create table for failed tasks */
171 failedtasks=genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
172 (int (*)(void *,void *)) &comparetpd);
173 #endif // #if 0: for recovery
175 /* Create queue of active tasks */
176 activetasks=genallocatehashtable((unsigned int(*) (void *)) &hashCodetpd,
177 (int(*) (void *,void *)) &comparetpd);
179 /* Process task information */
182 if(STARTUPCORE == corenum) {
183 /* Create startup object */
184 createstartupobject(argc, argv);
188 BAMBOO_DEBUGPRINT(0xee00);
192 // check if there are new active tasks can be executed
196 while(receiveObject() != -1) {
201 BAMBOO_DEBUGPRINT(0xee01);
204 // check if there are some pending objects, if yes, enqueue them and executetasks again
208 bool isChecking = false;
209 if(!isEmpty(&objqueue)) {
210 profileTaskStart("objqueue checking");
214 while(!isEmpty(&objqueue)) {
216 BAMBOO_START_CRITICAL_SECTION_OBJ_QUEUE();
218 BAMBOO_DEBUGPRINT(0xf001);
221 //isInterrupt = false;
224 BAMBOO_DEBUGPRINT(0xeee1);
228 objitem = getTail(&objqueue);
229 objInfo = (struct transObjInfo *)objitem->objectptr;
230 obj = objInfo->objptr;
232 BAMBOO_DEBUGPRINT_REG((int)obj);
234 // grab lock and flush the obj
238 BAMBOO_WAITING_FOR_LOCK();
242 BAMBOO_DEBUGPRINT_REG(grount);
256 BAMBOO_CACHE_FLUSH_RANGE((int)obj, classsize[((struct ___Object___ *)obj)->type]);
258 // enqueue the object
259 for(k = 0; k < objInfo->length; ++k) {
260 int taskindex = objInfo->queues[2 * k];
261 int paramindex = objInfo->queues[2 * k + 1];
262 struct parameterwrapper ** queues = &(paramqueues[corenum][taskindex][paramindex]);
264 BAMBOO_DEBUGPRINT_REG(taskindex);
265 BAMBOO_DEBUGPRINT_REG(paramindex);
266 struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
267 tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n", corenum, corenum, (int)obj, (long)obj, tmpptr->flag);
270 enqueueObject_I(obj, queues, 1);
272 BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
275 removeItem(&objqueue, objitem);
276 releasewritelock_I(obj);
277 RUNFREE(objInfo->queues);
281 // put it at the end of the queue
282 // and try to execute active tasks already enqueued first
283 removeItem(&objqueue, objitem);
284 addNewItem_I(&objqueue, objInfo);
286 //isInterrupt = true;
288 BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE();
290 BAMBOO_DEBUGPRINT(0xf000);
294 BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE();
296 BAMBOO_DEBUGPRINT(0xf000);
306 BAMBOO_DEBUGPRINT(0xee02);
311 if(STARTUPCORE == corenum) {
314 BAMBOO_DEBUGPRINT(0xee03);
319 (waitconfirm && (numconfirm == 0))) {
321 BAMBOO_DEBUGPRINT(0xee04);
322 BAMBOO_DEBUGPRINT_REG(waitconfirm);
324 BAMBOO_START_CRITICAL_SECTION_STATUS();
326 BAMBOO_DEBUGPRINT(0xf001);
328 corestatus[corenum] = 0;
329 numsendobjs[corenum] = self_numsendobjs;
330 numreceiveobjs[corenum] = self_numreceiveobjs;
331 // check the status of all cores
334 BAMBOO_DEBUGPRINT_REG(NUMCORES);
336 for(i = 0; i < NUMCORES; ++i) {
338 BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
340 if(corestatus[i] != 0) {
346 // check if the sum of send objs and receive obj are the same
347 // yes->check if the info is the latest; no->go on executing
349 for(i = 0; i < NUMCORES; ++i) {
350 sumsendobj += numsendobjs[i];
352 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
355 for(i = 0; i < NUMCORES; ++i) {
356 sumsendobj -= numreceiveobjs[i];
358 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
361 if(0 == sumsendobj) {
363 // the first time found all cores stall
364 // send out status confirm msg to all other cores
365 // reset the corestatus array too
367 BAMBOO_DEBUGPRINT(0xee05);
369 corestatus[corenum] = 1;
370 for(i = 1; i < NUMCORES; ++i) {
372 // send status confirm msg to core i
376 numconfirm = NUMCORES - 1;
378 // all the core status info are the latest
379 // terminate; for profiling mode, send request to all
380 // other cores to pour out profiling data
382 BAMBOO_DEBUGPRINT(0xee06);
386 totalexetime = BAMBOO_GET_EXE_TIME();
388 BAMBOO_DEBUGPRINT(0xbbbbbbbb);
389 BAMBOO_DEBUGPRINT((int)BAMBOO_GET_EXE_TIME());
391 // profile mode, send msgs to other cores to request pouring
392 // out progiling data
394 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
396 BAMBOO_DEBUGPRINT(0xf000);
398 for(i = 1; i < NUMCORES; ++i) {
399 // send profile request msg to core i
400 send_msg_2(i, 6, totalexetime);
402 // pour profiling data on startup core
405 BAMBOO_START_CRITICAL_SECTION_STATUS();
407 BAMBOO_DEBUGPRINT(0xf001);
409 profilestatus[corenum] = 0;
410 // check the status of all cores
413 BAMBOO_DEBUGPRINT_REG(NUMCORES);
415 for(i = 0; i < NUMCORES; ++i) {
417 BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
419 if(profilestatus[i] != 0) {
426 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
428 BAMBOO_DEBUGPRINT(0xf000);
437 terminate(); // All done.
438 } // if-else of line 364: if(!waitconfirm)
440 // still some objects on the fly on the network
441 // reset the waitconfirm and numconfirm
443 BAMBOO_DEBUGPRINT(0xee07);
447 } // if-else of line 363: if(0 == sumsendobj)
449 // not all cores are stall, keep on waiting
451 BAMBOO_DEBUGPRINT(0xee08);
455 } // if-else of line 347: if(allStall)
456 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
458 BAMBOO_DEBUGPRINT(0xf000);
460 } // if-else of line 320: if((!waitconfirm) ||
464 BAMBOO_DEBUGPRINT(0xee09);
470 // wait for some time
473 BAMBOO_DEBUGPRINT(0xee0a);
479 // send StallMsg to startup core
481 BAMBOO_DEBUGPRINT(0xee0b);
484 send_msg_4(STARTUPCORE, 1, corenum, self_numsendobjs, self_numreceiveobjs);
496 BAMBOO_DEBUGPRINT(0xee0c);
498 } // if-else of line 464: if(!sendStall)
499 } // if-else of line 313: if(STARTUPCORE == corenum)
500 } // if-else of line 311: if(!tocontinue)
501 } // line 193: while(true)
502 } // right-bracket for if-else of line 153: if(corenum > NUMCORES - 1)
506 void createstartupobject(int argc, char ** argv) {
509 /* Allocate startup object */
512 struct ___StartupObject___ *startupobject=(struct ___StartupObject___*) allocate_new(NULL, STARTUPTYPE);
513 struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);
515 struct ___StartupObject___ *startupobject=(struct ___StartupObject___*) allocate_new(STARTUPTYPE);
516 struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);
518 #endif // #if 0: for garbage collection
519 struct ___StartupObject___ *startupobject=(struct ___StartupObject___*) allocate_new(STARTUPTYPE);
520 struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);
521 /* Build array of strings */
522 startupobject->___parameters___=stringarray;
523 for(i=1; i<argc; i++) {
524 int length=strlen(argv[i]);
527 struct ___String___ *newstring=NewString(NULL, argv[i],length);
529 struct ___String___ *newstring=NewString(argv[i],length);
531 #endif // #if 0: for garbage collection
532 struct ___String___ *newstring=NewString(argv[i],length);
533 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=newstring;
536 startupobject->isolate = 1;
537 startupobject->version = 0;
538 startupobject->lock = NULL;
540 /* Set initialized flag for startup object */
541 flagorandinit(startupobject,1,0xFFFFFFFF);
542 enqueueObject(startupobject, NULL, 0);
544 BAMBOO_CACHE_FLUSH_ALL();
548 int hashCodetpd(struct taskparamdescriptor *ftd) {
549 int hash=(int)ftd->task;
551 for(i=0; i<ftd->numParameters; i++) {
552 hash^=(int)ftd->parameterArray[i];
557 int comparetpd(struct taskparamdescriptor *ftd1, struct taskparamdescriptor *ftd2) {
559 if (ftd1->task!=ftd2->task)
561 for(i=0; i<ftd1->numParameters; i++)
562 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
567 /* This function sets a tag. */
570 void tagset(void *ptr, struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
572 void tagset(struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
574 #endif // #if 0: for garbage collection
575 void tagset(struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
576 struct ArrayObject * ao=NULL;
577 struct ___Object___ * tagptr=obj->___tags___;
579 obj->___tags___=(struct ___Object___ *)tagd;
581 /* Have to check if it is already set */
582 if (tagptr->type==TAGTYPE) {
583 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
589 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
590 struct ArrayObject * ao=allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
591 obj=(struct ___Object___ *)ptrarray[2];
592 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
593 td=(struct ___TagDescriptor___ *) obj->___tags___;
595 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
597 #endif // #if 0: for garbage collection
598 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
600 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
601 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
602 obj->___tags___=(struct ___Object___ *) ao;
603 ao->___cachedCode___=2;
607 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
608 for(i=0; i<ao->___cachedCode___; i++) {
609 struct ___TagDescriptor___ * td=ARRAYGET(ao, struct ___TagDescriptor___*, i);
614 if (ao->___cachedCode___<ao->___length___) {
615 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
616 ao->___cachedCode___++;
620 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
621 struct ArrayObject * aonew=allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
622 obj=(struct ___Object___ *)ptrarray[2];
623 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
624 ao=(struct ArrayObject *)obj->___tags___;
626 struct ArrayObject * aonew=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
628 #endif // #if 0: for garbage collection
629 struct ArrayObject * aonew=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
631 aonew->___cachedCode___=ao->___length___+1;
632 for(i=0; i<ao->___length___; i++) {
633 ARRAYSET(aonew, struct ___TagDescriptor___*, i, ARRAYGET(ao, struct ___TagDescriptor___*, i));
635 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
641 struct ___Object___ * tagset=tagd->flagptr;
644 } else if (tagset->type!=OBJECTARRAYTYPE) {
647 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
648 struct ArrayObject * ao=allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
649 obj=(struct ___Object___ *)ptrarray[2];
650 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
652 struct ArrayObject * ao=allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
654 #endif // #if 0: for garbage collection
655 struct ArrayObject * ao=allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
656 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
657 ARRAYSET(ao, struct ___Object___ *, 1, obj);
658 ao->___cachedCode___=2;
659 tagd->flagptr=(struct ___Object___ *)ao;
661 struct ArrayObject *ao=(struct ArrayObject *) tagset;
662 if (ao->___cachedCode___<ao->___length___) {
663 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
668 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
669 struct ArrayObject * aonew=allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
670 obj=(struct ___Object___ *)ptrarray[2];
671 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
672 ao=(struct ArrayObject *)tagd->flagptr;
674 struct ArrayObject * aonew=allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
676 #endif // #if 0: for garbage collection
677 struct ArrayObject * aonew=allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
678 aonew->___cachedCode___=ao->___cachedCode___+1;
679 for(i=0; i<ao->___length___; i++) {
680 ARRAYSET(aonew, struct ___Object___*, i, ARRAYGET(ao, struct ___Object___*, i));
682 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
683 tagd->flagptr=(struct ___Object___ *) aonew;
689 /* This function clears a tag. */
692 void tagclear(void *ptr, struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
694 void tagclear(struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
696 #endif // #if 0: for garbage collection
697 void tagclear(struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
698 /* We'll assume that tag is alway there.
699 Need to statically check for this of course. */
700 struct ___Object___ * tagptr=obj->___tags___;
702 if (tagptr->type==TAGTYPE) {
703 if ((struct ___TagDescriptor___ *)tagptr==tagd)
704 obj->___tags___=NULL;
707 printf("ERROR 1 in tagclear\n");
712 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
714 for(i=0; i<ao->___cachedCode___; i++) {
715 struct ___TagDescriptor___ * td=ARRAYGET(ao, struct ___TagDescriptor___ *, i);
717 ao->___cachedCode___--;
718 if (i<ao->___cachedCode___)
719 ARRAYSET(ao, struct ___TagDescriptor___ *, i, ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
720 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
721 if (ao->___cachedCode___==0)
722 obj->___tags___=NULL;
727 printf("ERROR 2 in tagclear\n");
732 struct ___Object___ *tagset=tagd->flagptr;
733 if (tagset->type!=OBJECTARRAYTYPE) {
738 printf("ERROR 3 in tagclear\n");
743 struct ArrayObject *ao=(struct ArrayObject *) tagset;
745 for(i=0; i<ao->___cachedCode___; i++) {
746 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
748 ao->___cachedCode___--;
749 if (i<ao->___cachedCode___)
750 ARRAYSET(ao, struct ___Object___ *, i, ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
751 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
752 if (ao->___cachedCode___==0)
758 printf("ERROR 4 in tagclear\n");
767 /* This function allocates a new tag. */
769 struct ___TagDescriptor___ * allocate_tag(void *ptr, int index) {
770 struct ___TagDescriptor___ * v=(struct ___TagDescriptor___ *) mygcmalloc((struct garbagelist *) ptr, classsize[TAGTYPE]);
772 struct ___TagDescriptor___ * allocate_tag(int index) {
773 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
775 #endif // #if 0: for garbage collection
776 struct ___TagDescriptor___ * allocate_tag(int index) {
777 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
785 /* This function updates the flag for object ptr. It or's the flag
786 with the or mask and and's it with the andmask. */
788 void flagbody(struct ___Object___ *ptr, int flag, struct parameterwrapper ** queues, int length, bool isnew);
790 int flagcomp(const int *val1, const int *val2) {
791 return (*val1)-(*val2);
794 void flagorand(void * ptr, int ormask, int andmask, struct parameterwrapper ** queues, int length) {
796 int oldflag=((int *)ptr)[1];
797 int flag=ormask|oldflag;
799 flagbody(ptr, flag, queues, length, false);
803 bool intflagorand(void * ptr, int ormask, int andmask) {
805 int oldflag=((int *)ptr)[1];
806 int flag=ormask|oldflag;
808 if (flag==oldflag) /* Don't do anything */
811 flagbody(ptr, flag, NULL, 0, false);
817 void flagorandinit(void * ptr, int ormask, int andmask) {
818 int oldflag=((int *)ptr)[1];
819 int flag=ormask|oldflag;
821 flagbody(ptr,flag,NULL,0,true);
824 void flagbody(struct ___Object___ *ptr, int flag, struct parameterwrapper ** vqueues, int vlength, bool isnew) {
825 struct parameterwrapper * flagptr = NULL;
827 struct parameterwrapper ** queues = vqueues;
828 int length = vlength;
831 int * enterflags = NULL;
832 if((!isnew) && (queues == NULL)) {
833 if(corenum < NUMCORES) {
834 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
835 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
842 /*Remove object from all queues */
843 for(i = 0; i < length; ++i) {
845 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next, (int *) &enterflags, &UNUSED, &UNUSED2);
846 ObjectHashremove(flagptr->objectset, (int)ptr);
847 if (enterflags!=NULL)
852 void enqueueObject(void * vptr, struct parameterwrapper ** vqueues, int vlength) {
853 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
856 //struct QueueItem *tmpptr;
857 struct parameterwrapper * parameter=NULL;
860 struct parameterwrapper * prevptr=NULL;
861 struct ___Object___ *tagptr=NULL;
862 struct parameterwrapper ** queues = vqueues;
863 int length = vlength;
864 if(corenum > NUMCORES - 1) {
868 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
869 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
871 tagptr=ptr->___tags___;
873 /* Outer loop iterates through all parameter queues an object of
874 this type could be in. */
875 for(j = 0; j < length; ++j) {
876 parameter = queues[j];
878 if (parameter->numbertags>0) {
880 goto nextloop; //that means the object has no tag but that param needs tag
881 else if(tagptr->type==TAGTYPE) { //one tag
882 //struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
883 for(i=0; i<parameter->numbertags; i++) {
884 //slotid is parameter->tagarray[2*i];
885 int tagid=parameter->tagarray[2*i+1];
886 if (tagid!=tagptr->flag)
887 goto nextloop; /*We don't have this tag */
889 } else { //multiple tags
890 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
891 for(i=0; i<parameter->numbertags; i++) {
892 //slotid is parameter->tagarray[2*i];
893 int tagid=parameter->tagarray[2*i+1];
895 for(j=0; j<ao->___cachedCode___; j++) {
896 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
907 for(i=0; i<parameter->numberofterms; i++) {
908 int andmask=parameter->intarray[i*2];
909 int checkmask=parameter->intarray[i*2+1];
910 if ((ptr->flag&andmask)==checkmask) {
911 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
922 void enqueueObject_I(void * vptr, struct parameterwrapper ** vqueues, int vlength) {
923 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
926 //struct QueueItem *tmpptr;
927 struct parameterwrapper * parameter=NULL;
930 struct parameterwrapper * prevptr=NULL;
931 struct ___Object___ *tagptr=NULL;
932 struct parameterwrapper ** queues = vqueues;
933 int length = vlength;
934 if(corenum > NUMCORES - 1) {
938 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
939 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
941 tagptr=ptr->___tags___;
943 /* Outer loop iterates through all parameter queues an object of
944 this type could be in. */
945 for(j = 0; j < length; ++j) {
946 parameter = queues[j];
948 if (parameter->numbertags>0) {
950 goto nextloop; //that means the object has no tag but that param needs tag
951 else if(tagptr->type==TAGTYPE) { //one tag
952 //struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
953 for(i=0; i<parameter->numbertags; i++) {
954 //slotid is parameter->tagarray[2*i];
955 int tagid=parameter->tagarray[2*i+1];
956 if (tagid!=tagptr->flag)
957 goto nextloop; /*We don't have this tag */
959 } else { //multiple tags
960 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
961 for(i=0; i<parameter->numbertags; i++) {
962 //slotid is parameter->tagarray[2*i];
963 int tagid=parameter->tagarray[2*i+1];
965 for(j=0; j<ao->___cachedCode___; j++) {
966 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
977 for(i=0; i<parameter->numberofterms; i++) {
978 int andmask=parameter->intarray[i*2];
979 int checkmask=parameter->intarray[i*2+1];
980 if ((ptr->flag&andmask)==checkmask) {
981 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
993 int * getAliasLock(void ** ptrs, int length, struct RuntimeHash * tbl) {
995 return (int*)(RUNMALLOC(sizeof(int)));
1000 bool redirect = false;
1001 int redirectlock = 0;
1002 for(; i < length; i++) {
1003 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1006 if(ptr->lock == NULL) {
1009 lock = (int)(ptr->lock);
1012 if(lock != redirectlock) {
1013 RuntimeHashadd(tbl, lock, redirectlock);
1016 if(RuntimeHashcontainskey(tbl, lock)) {
1017 // already redirected
1019 RuntimeHashget(tbl, lock, &redirectlock);
1020 for(; j < locklen; j++) {
1021 if(locks[j] != redirectlock) {
1022 RuntimeHashadd(tbl, locks[j], redirectlock);
1027 for(j = 0; j < locklen; j++) {
1028 if(locks[j] == lock) {
1031 } else if(locks[j] > lock) {
1038 locks[h] = locks[h-1];
1047 return (int *)redirectlock;
1049 return (int *)(locks[0]);
1054 void addAliasLock(void * ptr, int lock) {
1055 struct ___Object___ * obj = (struct ___Object___ *)ptr;
1056 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1057 // originally no alias lock associated or have a different alias lock
1058 // flush it as the new one
1059 obj->lock = (int *)lock;
1065 * type: 0 -- transfer object
1066 * 1 -- transfer stall msg
1071 * // add for profile info
1072 * 6 -- transfer profile output msg
1073 * 7 -- transfer profile output finish msg
1074 * // add for alias lock strategy
1075 * 8 -- redirect lock request
1076 * 9 -- lock grant with redirect info
1077 * a -- lock deny with redirect info
1078 * b -- lock release with redirect info
1079 * c -- status confirm request
1080 * d -- status report msg
1083 * ObjMsg: 0 + size of msg + obj's address + (task index + param index)+
1084 * StallMsg: 1 + corenum + sendobjs + receiveobjs (size is always 4 * sizeof(int))
1085 * LockMsg: 2 + lock type + obj pointer + lock + request core (size is always 5 * sizeof(int))
1086 * 3/4/5 + lock type + obj pointer + lock (size is always 4 * sizeof(int))
1087 * 8 + lock type + obj pointer + redirect lock + root request core + request core (size is always 6 * sizeof(int))
1088 * 9/a + lock type + obj pointer + redirect lock (size is always 4 * sizeof(int))
1089 * b + lock type + lock + redirect lock (size is always 4 * sizeof(int))
1090 * lock type: 0 -- read; 1 -- write
1091 * ProfileMsg: 6 + totalexetime (size is always 2 * sizeof(int))
1092 * 7 + corenum (size is always 2 * sizeof(int))
1093 * StatusMsg: c (size is always 1 * sizeof(int))
1094 * d + status + corenum (size is always 3 * sizeof(int))
1095 * status: 0 -- stall; 1 -- busy
1096 * TerminateMsg: e (size is always 1 * sizeof(int)
1100 // output the profiling data
1101 void outputProfileData() {
1108 int totaltasktime = 0;
1109 int preprocessingtime = 0;
1110 int objqueuecheckingtime = 0;
1111 int postprocessingtime = 0;
1112 //int interruptiontime = 0;
1114 int averagetasktime = 0;
1117 for(i = 0; i < 50; i++) {
1121 calCoords(corenum, &self_y, &self_x);
1122 c_y = (char)self_y + '0';
1123 c_x = (char)self_x + '0';
1124 strcat(fn, "profile_");
1130 if((fp = fopen(fn, "w+")) == NULL) {
1131 fprintf(stderr, "fopen error\n");
1135 fprintf(fp, "Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
1136 // output task related info
1137 for(i = 0; i < taskInfoIndex; i++) {
1138 TaskInfo* tmpTInfo = taskInfoArray[i];
1139 int duration = tmpTInfo->endTime - tmpTInfo->startTime;
1140 fprintf(fp, "%s, %d, %d, %d, %d", tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime, duration, tmpTInfo->exitIndex);
1141 // summarize new obj info
1142 if(tmpTInfo->newObjs != NULL) {
1143 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
1144 struct RuntimeIterator * iter = NULL;
1145 while(0 == isEmpty(tmpTInfo->newObjs)) {
1146 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
1147 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
1149 RuntimeHashget(nobjtbl, (int)objtype, &num);
1150 RuntimeHashremovekey(nobjtbl, (int)objtype);
1152 RuntimeHashadd(nobjtbl, (int)objtype, num);
1154 RuntimeHashadd(nobjtbl, (int)objtype, 1);
1156 //fprintf(stderr, "new obj!\n");
1159 // output all new obj info
1160 iter = RuntimeHashcreateiterator(nobjtbl);
1161 while(RunhasNext(iter)) {
1162 char * objtype = (char *)Runkey(iter);
1163 int num = Runnext(iter);
1164 fprintf(fp, ", %s, %d", objtype, num);
1168 if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
1169 preprocessingtime += duration;
1170 } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
1171 postprocessingtime += duration;
1172 } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
1173 objqueuecheckingtime += duration;
1175 totaltasktime += duration;
1176 averagetasktime += duration;
1181 if(taskInfoOverflow) {
1182 fprintf(stderr, "Caution: task info overflow!\n");
1185 other = totalexetime - totaltasktime - preprocessingtime - postprocessingtime;
1186 averagetasktime /= tasknum;
1188 fprintf(fp, "\nTotal time: %d\n", totalexetime);
1189 fprintf(fp, "Total task execution time: %d (%f%%)\n", totaltasktime, ((double)totaltasktime/(double)totalexetime)*100);
1190 fprintf(fp, "Total objqueue checking time: %d (%f%%)\n", objqueuecheckingtime, ((double)objqueuecheckingtime/(double)totalexetime)*100);
1191 fprintf(fp, "Total pre-processing time: %d (%f%%)\n", preprocessingtime, ((double)preprocessingtime/(double)totalexetime)*100);
1192 fprintf(fp, "Total post-processing time: %d (%f%%)\n", postprocessingtime, ((double)postprocessingtime/(double)totalexetime)*100);
1193 fprintf(fp, "Other time: %d (%f%%)\n", other, ((double)other/(double)totalexetime)*100);
1195 fprintf(fp, "\nAverage task execution time: %d\n", averagetasktime);
1202 BAMBOO_DEBUGPRINT(0xdddd);
1203 // output task related info
1204 for(i= 0; i < taskInfoIndex; i++) {
1205 TaskInfo* tmpTInfo = taskInfoArray[i];
1206 char* tmpName = tmpTInfo->taskName;
1207 int nameLen = strlen(tmpName);
1208 BAMBOO_DEBUGPRINT(0xddda);
1209 for(j = 0; j < nameLen; j++) {
1210 BAMBOO_DEBUGPRINT_REG(tmpName[j]);
1212 BAMBOO_DEBUGPRINT(0xdddb);
1213 BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
1214 BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
1215 BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
1216 if(tmpTInfo->newObjs != NULL) {
1217 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
1218 struct RuntimeIterator * iter = NULL;
1219 while(0 == isEmpty(tmpTInfo->newObjs)) {
1220 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
1221 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
1223 RuntimeHashget(nobjtbl, (int)objtype, &num);
1224 RuntimeHashremovekey(nobjtbl, (int)objtype);
1226 RuntimeHashadd(nobjtbl, (int)objtype, num);
1228 RuntimeHashadd(nobjtbl, (int)objtype, 1);
1232 // ouput all new obj info
1233 iter = RuntimeHashcreateiterator(nobjtbl);
1234 while(RunhasNext(iter)) {
1235 char * objtype = (char *)Runkey(iter);
1236 int num = Runnext(iter);
1237 int nameLen = strlen(objtype);
1238 BAMBOO_DEBUGPRINT(0xddda);
1239 for(j = 0; j < nameLen; j++) {
1240 BAMBOO_DEBUGPRINT_REG(objtype[j]);
1242 BAMBOO_DEBUGPRINT(0xdddb);
1243 BAMBOO_DEBUGPRINT_REG(num);
1246 BAMBOO_DEBUGPRINT(0xdddc);
1249 if(taskInfoOverflow) {
1250 BAMBOO_DEBUGPRINT(0xefee);
1253 // output interrupt related info
1254 /*for(i = 0; i < interruptInfoIndex; i++) {
1255 InterruptInfo* tmpIInfo = interruptInfoArray[i];
1256 BAMBOO_DEBUGPRINT(0xddde);
1257 BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
1258 BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
1259 BAMBOO_DEBUGPRINT(0xdddf);
1262 if(interruptInfoOverflow) {
1263 BAMBOO_DEBUGPRINT(0xefef);
1266 BAMBOO_DEBUGPRINT(0xeeee);
1270 inline void setTaskExitIndex(int index) {
1271 taskInfoArray[taskInfoIndex]->exitIndex = index;
1274 inline void addNewObjInfo(void * nobj) {
1275 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1276 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1278 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1282 /* this function is to process lock requests.
1283 * can only be invoked in receiveObject() */
1284 // if return -1: the lock request is redirected
1285 // 0: the lock request is approved
1286 // 1: the lock request is denied
1287 int processlockrequest(int locktype, int lock, int obj, int requestcore, int rootrequestcore, bool cache);
1289 // receive object transferred from other cores
1290 // or the terminate message from other cores
1291 // Should be invoked in critical sections!!
1292 // NOTICE: following format is for threadsimulate version only
1293 // RAW version please see previous description
1294 // format: type + object
1295 // type: -1--stall msg
1297 // return value: 0--received an object
1298 // 1--received nothing
1299 // 2--received a Stall Msg
1300 // 3--received a lock Msg
1301 // RAW version: -1 -- received nothing
1302 // otherwise -- received msg type
1303 int receiveObject() {
1305 //int targetcore = 0;
1308 if(receiveMsg() == -1) {
1312 if(msgdataindex == msglength) {
1313 // received a whole msg
1314 int type, data1; // will receive at least 2 words including type
1319 // receive a object transfer msg
1320 struct transObjInfo * transObj = RUNMALLOC_I(sizeof(struct transObjInfo));
1324 BAMBOO_DEBUGPRINT(0xe880);
1327 if(corenum > NUMCORES - 1) {
1329 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1331 BAMBOO_EXIT(0xa005);
1332 } /*else if((corenum == STARTUPCORE) && waitconfirm) {
1333 waitconfirm = false;
1336 // store the object and its corresponding queue info, enqueue it later
1337 transObj->objptr = (void *)msgdata[2]; // data1 is now size of the msg
1338 transObj->length = (msglength - 3) / 2;
1339 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
1340 for(k = 0; k < transObj->length; ++k) {
1341 transObj->queues[2*k] = msgdata[3+2*k];
1344 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
1347 transObj->queues[2*k+1] = msgdata[3+2*k+1];
1350 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
1354 // check if there is an existing duplicate item
1356 struct QueueItem * qitem = getTail(&objqueue);
1357 struct QueueItem * prev = NULL;
1358 while(qitem != NULL) {
1359 struct transObjInfo * tmpinfo = (struct transObjInfo *)(qitem->objectptr);
1360 if(tmpinfo->objptr == transObj->objptr) {
1361 // the same object, remove outdate one
1362 removeItem(&objqueue, qitem);
1367 qitem = getTail(&objqueue);
1369 qitem = getNextQueueItem(prev);
1372 addNewItem_I(&objqueue, (void *)transObj);
1374 ++(self_numreceiveobjs);
1379 // receive a stall msg
1380 if(corenum != STARTUPCORE) {
1381 // non startup core can not receive stall msg
1384 BAMBOO_DEBUGPRINT_REG(data1);
1386 BAMBOO_EXIT(0xa006);
1387 } /*else if(waitconfirm) {
1388 waitconfirm = false;
1391 if(data1 < NUMCORES) {
1394 BAMBOO_DEBUGPRINT(0xe881);
1397 corestatus[data1] = 0;
1398 numsendobjs[data1] = msgdata[2];
1399 numreceiveobjs[data1] = msgdata[3];
1405 // receive lock request msg, handle it right now
1406 // check to see if there is a lock exist in locktbl for the required obj
1407 // data1 -> lock type
1408 int data2 = msgdata[2]; // obj pointer
1409 int data3 = msgdata[3]; // lock
1410 int data4 = msgdata[4]; // request core
1411 deny = processlockrequest(data1, data3, data2, data4, data4, true); // -1: redirected, 0: approved, 1: denied
1413 // this lock request is redirected
1416 // send response msg
1417 // for 32 bit machine, the size is always 4 words
1418 int tmp = deny==1?4:3;
1420 cache_msg_4(data4, tmp, data1, data2, data3);
1422 send_msg_4(data4, tmp, data1, data2, data3);
1429 // receive lock grount msg
1430 if(corenum > NUMCORES - 1) {
1432 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1434 BAMBOO_EXIT(0xa007);
1435 } /*else if((corenum == STARTUPCORE) && waitconfirm) {
1436 waitconfirm = false;
1439 if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1442 BAMBOO_DEBUGPRINT(0xe882);
1451 // conflicts on lockresults
1453 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1455 BAMBOO_EXIT(0xa008);
1461 // receive lock grount/deny msg
1462 if(corenum > NUMCORES - 1) {
1464 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1466 BAMBOO_EXIT(0xa009);
1467 } /*else if((corenum == STARTUPCORE) && waitconfirm) {
1468 waitconfirm = false;
1471 if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1474 BAMBOO_DEBUGPRINT(0xe883);
1483 // conflicts on lockresults
1485 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1487 BAMBOO_EXIT(0xa00a);
1493 // receive lock release msg
1494 /*if((corenum == STARTUPCORE) && waitconfirm) {
1495 waitconfirm = false;
1498 if(!RuntimeHashcontainskey(locktbl, msgdata[3])) {
1499 // no locks for this object, something is wrong
1501 BAMBOO_DEBUGPRINT_REG(msgdata[3]);
1503 BAMBOO_EXIT(0xa00b);
1506 struct LockValue * lockvalue = NULL;
1507 RuntimeHashget(locktbl, msgdata[3], &rwlock_obj);
1508 lockvalue = (struct LockValue*)(rwlock_obj);
1511 BAMBOO_DEBUGPRINT(0xe884);
1512 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1522 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1531 // receive an output profile data request msg
1532 if(corenum == STARTUPCORE) {
1533 // startup core can not receive profile output finish msg
1534 BAMBOO_EXIT(0xa00c);
1538 BAMBOO_DEBUGPRINT(0xe885);
1542 totalexetime = data1;
1543 outputProfileData();
1545 cache_msg_2(STARTUPCORE, 7, corenum);
1547 send_msg_2(STARTUPCORE, 7, corenum);
1553 // receive a profile output finish msg
1554 if(corenum != STARTUPCORE) {
1555 // non startup core can not receive profile output finish msg
1557 BAMBOO_DEBUGPRINT_REG(data1);
1559 BAMBOO_EXIT(0xa00d);
1563 BAMBOO_DEBUGPRINT(0xe886);
1566 profilestatus[data1] = 0;
1572 // receive a redirect lock request msg, handle it right now
1573 // check to see if there is a lock exist in locktbl for the required obj
1574 // data1 -> lock type
1575 int data2 = msgdata[2]; // obj pointer
1576 int data3 = msgdata[3]; // redirect lock
1577 int data4 = msgdata[4]; // root request core
1578 int data5 = msgdata[5]; // request core
1579 deny = processlockrequest(data1, data3, data2, data5, data4, true);
1581 // this lock request is redirected
1584 // send response msg
1585 // for 32 bit machine, the size is always 4 words
1587 cache_msg_4(data4, deny==1?0xa:9, data1, data2, data3);
1589 send_msg_4(data4, deny==1?0xa:9, data1, data2, data3);
1596 // receive a lock grant msg with redirect info
1597 if(corenum > NUMCORES - 1) {
1599 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1601 BAMBOO_EXIT(0xa00e);
1602 }/* else if((corenum == STARTUPCORE) && waitconfirm) {
1603 waitconfirm = false;
1606 if(lockobj == msgdata[2]) {
1609 BAMBOO_DEBUGPRINT(0xe891);
1614 RuntimeHashadd_I(objRedirectLockTbl, lockobj, msgdata[3]);
1619 // conflicts on lockresults
1621 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1623 BAMBOO_EXIT(0xa00f);
1629 // receive a lock deny msg with redirect info
1630 if(corenum > NUMCORES - 1) {
1632 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1634 BAMBOO_EXIT(0xa010);
1635 }/* else if((corenum == STARTUPCORE) && waitconfirm) {
1636 waitconfirm = false;
1639 if(lockobj == msgdata[2]) {
1642 BAMBOO_DEBUGPRINT(0xe892);
1647 //RuntimeHashadd_I(objRedirectLockTbl, lockobj, msgdata[3]);
1652 // conflicts on lockresults
1654 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1656 BAMBOO_EXIT(0xa011);
1662 // receive a lock release msg with redirect info
1663 /*if((corenum == STARTUPCORE) && waitconfirm) {
1664 waitconfirm = false;
1667 if(!RuntimeHashcontainskey(locktbl, msgdata[2])) {
1668 // no locks for this object, something is wrong
1670 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1672 BAMBOO_EXIT(0xa012);
1675 struct LockValue * lockvalue = NULL;
1676 RuntimeHashget(locktbl, msgdata[2], &rwlock_obj);
1677 lockvalue = (struct LockValue*)(rwlock_obj);
1680 BAMBOO_DEBUGPRINT(0xe893);
1681 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1691 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1694 lockvalue->redirectlock = msgdata[3];
1700 // receive a status confirm info
1701 if((corenum == STARTUPCORE) || (corenum > NUMCORES - 1)) {
1702 // wrong core to receive such msg
1703 BAMBOO_EXIT(0xa013);
1705 // send response msg
1708 BAMBOO_DEBUGPRINT(0xe887);
1712 cache_msg_3(STARTUPCORE, 0xd, busystatus?1:0, corenum);
1714 send_msg_3(STARTUPCORE, 0xd, busystatus?1:0, corenum);
1721 // receive a status confirm info
1722 if(corenum != STARTUPCORE) {
1723 // wrong core to receive such msg
1725 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1727 BAMBOO_EXIT(0xa014);
1731 BAMBOO_DEBUGPRINT(0xe888);
1737 corestatus[msgdata[2]] = msgdata[1];
1743 // receive a terminate msg
1746 BAMBOO_DEBUGPRINT(0xe889);
1756 for(msgdataindex--; msgdataindex > 0; --msgdataindex) {
1757 msgdata[msgdataindex] = -1;
1763 BAMBOO_DEBUGPRINT(0xe88a);
1767 if(BAMBOO_MSG_AVAIL() != 0) {
1780 BAMBOO_DEBUGPRINT(0xe88b);
1784 /* if(isInterrupt) {
1792 /* this function is to process lock requests.
1793 * can only be invoked in receiveObject() */
1794 // if return -1: the lock request is redirected
1795 // 0: the lock request is approved
1796 // 1: the lock request is denied
1797 int processlockrequest(int locktype, int lock, int obj, int requestcore, int rootrequestcore, bool cache) {
1799 if( ((lock >> 5) % BAMBOO_TOTALCORE) != corenum ) {
1800 // the lock should not be on this core
1802 BAMBOO_DEBUGPRINT_REG(requestcore);
1803 BAMBOO_DEBUGPRINT_REG(lock);
1804 BAMBOO_DEBUGPRINT_REG(corenum);
1806 BAMBOO_EXIT(0xa015);
1808 /*if((corenum == STARTUPCORE) && waitconfirm) {
1809 waitconfirm = false;
1812 if(!RuntimeHashcontainskey(locktbl, lock)) {
1813 // no locks for this object
1814 // first time to operate on this shared object
1815 // create a lock for it
1816 // the lock is an integer: 0 -- stall, >0 -- read lock, -1 -- write lock
1817 struct LockValue * lockvalue = (struct LockValue *)(RUNMALLOC_I(sizeof(struct LockValue)));
1818 lockvalue->redirectlock = 0;
1821 BAMBOO_DEBUGPRINT(0xe110);
1825 lockvalue->value = 1;
1827 lockvalue->value = -1;
1829 RuntimeHashadd_I(locktbl, lock, (int)lockvalue);
1832 struct LockValue * lockvalue = NULL;
1835 BAMBOO_DEBUGPRINT(0xe111);
1838 RuntimeHashget(locktbl, lock, &rwlock_obj);
1839 lockvalue = (struct LockValue *)(rwlock_obj);
1842 BAMBOO_DEBUGPRINT_REG(lockvalue->redirectlock);
1845 if(lockvalue->redirectlock != 0) {
1846 // this lock is redirected
1849 BAMBOO_DEBUGPRINT(0xe112);
1853 getreadlock_I_r((void *)obj, (void *)lockvalue->redirectlock, rootrequestcore, cache);
1855 getwritelock_I_r((void *)obj, (void *)lockvalue->redirectlock, rootrequestcore, cache);
1857 return -1; // redirected
1861 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1864 if(0 == lockvalue->value) {
1866 lockvalue->value = 1;
1868 lockvalue->value = -1;
1870 } else if((lockvalue->value > 0) && (locktype == 0)) {
1871 // read lock request and there are only read locks
1878 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1886 bool getreadlock(void * ptr) {
1889 if(((struct ___Object___ *)ptr)->lock == NULL) {
1890 lock2require = lockobj;
1892 lock2require = (int)(((struct ___Object___ *)ptr)->lock);
1894 targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
1901 if(targetcore == corenum) {
1902 // reside on this core
1904 BAMBOO_START_CRITICAL_SECTION_LOCK();
1906 BAMBOO_DEBUGPRINT(0xf001);
1908 deny = processlockrequest(0, lock2require, (int)ptr, corenum, corenum, false);
1909 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
1911 BAMBOO_DEBUGPRINT(0xf000);
1917 if(lockobj == (int)ptr) {
1928 // conflicts on lockresults
1929 BAMBOO_EXIT(0xa016);
1934 // send lock request msg
1935 // for 32 bit machine, the size is always 5 words
1936 send_msg_5(targetcore, 2, 0, (int)ptr, lock2require, corenum);
1941 void releasereadlock(void * ptr) {
1944 if(((struct ___Object___ *)ptr)->lock == NULL) {
1945 reallock = (int)ptr;
1947 reallock = (int)(((struct ___Object___ *)ptr)->lock);
1949 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
1951 if(targetcore == corenum) {
1952 BAMBOO_START_CRITICAL_SECTION_LOCK();
1954 BAMBOO_DEBUGPRINT(0xf001);
1956 // reside on this core
1957 if(!RuntimeHashcontainskey(locktbl, reallock)) {
1958 // no locks for this object, something is wrong
1959 BAMBOO_EXIT(0xa017);
1962 struct LockValue * lockvalue = NULL;
1963 RuntimeHashget(locktbl, reallock, &rwlock_obj);
1964 lockvalue = (struct LockValue *)rwlock_obj;
1967 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
1969 BAMBOO_DEBUGPRINT(0xf000);
1973 // send lock release msg
1974 // for 32 bit machine, the size is always 4 words
1975 send_msg_4(targetcore, 5, 0, (int)ptr, reallock);
1979 // redirected lock request
1980 bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
1983 if(core == corenum) {
1985 lock2require = (int)redirectlock;
1992 targetcore = ((int)redirectlock >> 5) % BAMBOO_TOTALCORE;
1994 if(targetcore == corenum) {
1995 // reside on this core
1996 int deny = processlockrequest(0, (int)redirectlock, (int)ptr, corenum, core, cache);
2001 if(core == corenum) {
2002 if(lockobj == (int)ptr) {
2007 RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
2014 // conflicts on lockresults
2015 BAMBOO_EXIT(0xa018);
2019 // send lock grant/deny request to the root requiring core
2020 // check if there is still some msg on sending
2021 if((!cache) || (cache && !isMsgSending)) {
2022 send_msg_4(core, deny==1?0xa:9, 0, (int)ptr, (int)redirectlock);
2024 cache_msg_4(core, deny==1?0xa:9, 0, (int)ptr, (int)redirectlock);
2029 // redirect the lock request
2030 // for 32 bit machine, the size is always 6 words
2031 if((!cache) || (cache && !isMsgSending)) {
2032 send_msg_6(targetcore, 8, 0, (int)ptr, lock2require, core, corenum);
2034 cache_msg_6(targetcore, 8, 0, (int)ptr, lock2require, core, corenum);
2041 bool getwritelock(void * ptr) {
2044 // for 32 bit machine, the size is always 5 words
2048 if(((struct ___Object___ *)ptr)->lock == NULL) {
2049 lock2require = lockobj;
2051 lock2require = (int)(((struct ___Object___ *)ptr)->lock);
2053 targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
2061 BAMBOO_DEBUGPRINT(0xe551);
2062 BAMBOO_DEBUGPRINT_REG(lockobj);
2063 BAMBOO_DEBUGPRINT_REG(lock2require);
2064 BAMBOO_DEBUGPRINT_REG(targetcore);
2067 if(targetcore == corenum) {
2068 // reside on this core
2070 BAMBOO_START_CRITICAL_SECTION_LOCK();
2072 BAMBOO_DEBUGPRINT(0xf001);
2074 deny = processlockrequest(1, lock2require, (int)ptr, corenum, corenum, false);
2075 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
2077 BAMBOO_DEBUGPRINT(0xf000);
2080 BAMBOO_DEBUGPRINT(0xe555);
2081 BAMBOO_DEBUGPRINT_REG(lockresult);
2087 if(lockobj == (int)ptr) {
2098 // conflicts on lockresults
2099 BAMBOO_EXIT(0xa019);
2104 // send lock request msg
2105 // for 32 bit machine, the size is always 5 words
2106 send_msg_5(targetcore, 2, 1, (int)ptr, lock2require, corenum);
2111 void releasewritelock(void * ptr) {
2114 if(((struct ___Object___ *)ptr)->lock == NULL) {
2115 reallock = (int)ptr;
2117 reallock = (int)(((struct ___Object___ *)ptr)->lock);
2119 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2122 BAMBOO_DEBUGPRINT(0xe661);
2123 BAMBOO_DEBUGPRINT_REG((int)ptr);
2124 BAMBOO_DEBUGPRINT_REG(reallock);
2125 BAMBOO_DEBUGPRINT_REG(targetcore);
2128 if(targetcore == corenum) {
2129 BAMBOO_START_CRITICAL_SECTION_LOCK();
2131 BAMBOO_DEBUGPRINT(0xf001);
2133 // reside on this core
2134 if(!RuntimeHashcontainskey(locktbl, reallock)) {
2135 // no locks for this object, something is wrong
2136 BAMBOO_EXIT(0xa01a);
2139 struct LockValue * lockvalue = NULL;
2140 RuntimeHashget(locktbl, reallock, &rwlock_obj);
2141 lockvalue = (struct LockValue *)rwlock_obj;
2144 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
2146 BAMBOO_DEBUGPRINT(0xf000);
2150 // send lock release msg
2151 // for 32 bit machine, the size is always 4 words
2152 send_msg_4(targetcore, 5, 1, (int)ptr, reallock);
2156 void releasewritelock_r(void * lock, void * redirectlock) {
2158 int reallock = (int)lock;
2159 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2162 BAMBOO_DEBUGPRINT(0xe671);
2163 BAMBOO_DEBUGPRINT_REG((int)lock);
2164 BAMBOO_DEBUGPRINT_REG(reallock);
2165 BAMBOO_DEBUGPRINT_REG(targetcore);
2168 if(targetcore == corenum) {
2169 BAMBOO_START_CRITICAL_SECTION_LOCK();
2171 BAMBOO_DEBUGPRINT(0xf001);
2173 // reside on this core
2174 if(!RuntimeHashcontainskey(locktbl, reallock)) {
2175 // no locks for this object, something is wrong
2176 BAMBOO_EXIT(0xa01b);
2179 struct LockValue * lockvalue = NULL;
2181 BAMBOO_DEBUGPRINT(0xe672);
2183 RuntimeHashget(locktbl, reallock, &rwlock_obj);
2184 lockvalue = (struct LockValue *)rwlock_obj;
2186 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2189 lockvalue->redirectlock = (int)redirectlock;
2191 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2194 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
2196 BAMBOO_DEBUGPRINT(0xf000);
2200 // send lock release with redirect info msg
2201 // for 32 bit machine, the size is always 4 words
2202 send_msg_4(targetcore, 0xb, 1, (int)lock, (int)redirectlock);
2206 bool getwritelock_I(void * ptr) {
2209 if(((struct ___Object___ *)ptr)->lock == NULL) {
2210 lock2require = lockobj;
2212 lock2require = (int)(((struct ___Object___ *)ptr)->lock);
2214 targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
2222 BAMBOO_DEBUGPRINT(0xe561);
2223 BAMBOO_DEBUGPRINT_REG(lockobj);
2224 BAMBOO_DEBUGPRINT_REG(lock2require);
2225 BAMBOO_DEBUGPRINT_REG(targetcore);
2228 if(targetcore == corenum) {
2229 // reside on this core
2230 int deny = processlockrequest(1, (int)lock2require, (int)ptr, corenum, corenum, false);
2235 if(lockobj == (int)ptr) {
2239 BAMBOO_DEBUGPRINT(0);
2244 BAMBOO_DEBUGPRINT(1);
2252 // conflicts on lockresults
2253 BAMBOO_EXIT(0xa01c);
2258 // send lock request msg
2259 // for 32 bit machine, the size is always 5 words
2260 send_msg_5(targetcore, 2, 1, (int)ptr, lock2require, corenum);
2265 // redirected lock request
2266 bool getwritelock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
2269 if(core == corenum) {
2271 lock2require = (int)redirectlock;
2278 targetcore = ((int)redirectlock >> 5) % BAMBOO_TOTALCORE;
2281 BAMBOO_DEBUGPRINT(0xe571);
2282 BAMBOO_DEBUGPRINT_REG((int)ptr);
2283 BAMBOO_DEBUGPRINT_REG((int)redirectlock);
2284 BAMBOO_DEBUGPRINT_REG(core);
2285 BAMBOO_DEBUGPRINT_REG((int)cache);
2286 BAMBOO_DEBUGPRINT_REG(targetcore);
2290 if(targetcore == corenum) {
2291 // reside on this core
2292 int deny = processlockrequest(1, (int)redirectlock, (int)ptr, corenum, core, cache);
2297 if(core == corenum) {
2298 if(lockobj == (int)ptr) {
2303 RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
2310 // conflicts on lockresults
2311 BAMBOO_EXIT(0xa01d);
2315 // send lock grant/deny request to the root requiring core
2316 // check if there is still some msg on sending
2317 if((!cache) || (cache && !isMsgSending)) {
2318 send_msg_4(core, deny==1?0xa:9, 1, (int)ptr, (int)redirectlock);
2320 cache_msg_4(core, deny==1?0xa:9, 1, (int)ptr, (int)redirectlock);
2325 // redirect the lock request
2326 // for 32 bit machine, the size is always 6 words
2327 if((!cache) || (cache && !isMsgSending)) {
2328 send_msg_6(targetcore, 8, 1, (int)ptr, (int)redirectlock, core, corenum);
2330 cache_msg_6(targetcore, 8, 1, (int)ptr, (int)redirectlock, core, corenum);
2336 void releasewritelock_I(void * ptr) {
2339 if(((struct ___Object___ *)ptr)->lock == NULL) {
2340 reallock = (int)ptr;
2342 reallock = (int)(((struct ___Object___ *)ptr)->lock);
2344 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2347 BAMBOO_DEBUGPRINT(0xe681);
2348 BAMBOO_DEBUGPRINT_REG((int)ptr);
2349 BAMBOO_DEBUGPRINT_REG(reallock);
2350 BAMBOO_DEBUGPRINT_REG(targetcore);
2353 if(targetcore == corenum) {
2354 // reside on this core
2355 if(!RuntimeHashcontainskey(locktbl, reallock)) {
2356 // no locks for this object, something is wrong
2357 BAMBOO_EXIT(0xa01e);
2360 struct LockValue * lockvalue = NULL;
2361 RuntimeHashget(locktbl, reallock, &rwlock_obj);
2362 lockvalue = (struct LockValue *)rwlock_obj;
2367 // send lock release msg
2368 // for 32 bit machine, the size is always 4 words
2369 send_msg_4(targetcore, 5, 1, (int)ptr, reallock);
2373 void releasewritelock_I_r(void * lock, void * redirectlock) {
2375 int reallock = (int)lock;
2376 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2379 BAMBOO_DEBUGPRINT(0xe691);
2380 BAMBOO_DEBUGPRINT_REG((int)lock);
2381 BAMBOO_DEBUGPRINT_REG(reallock);
2382 BAMBOO_DEBUGPRINT_REG(targetcore);
2385 if(targetcore == corenum) {
2386 // reside on this core
2387 if(!RuntimeHashcontainskey(locktbl, reallock)) {
2388 // no locks for this object, something is wrong
2389 BAMBOO_EXIT(0xa01f);
2392 struct LockValue * lockvalue = NULL;
2394 BAMBOO_DEBUGPRINT(0xe692);
2396 RuntimeHashget(locktbl, reallock, &rwlock_obj);
2397 lockvalue = (struct LockValue *)rwlock_obj;
2399 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2402 lockvalue->redirectlock = (int)redirectlock;
2404 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2409 // send lock release msg
2410 // for 32 bit machine, the size is always 4 words
2411 send_msg_4(targetcore, 0xb, 1, (int)lock, (int)redirectlock);
2415 int enqueuetasks(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr, int * enterflags, int numenterflags) {
2416 void * taskpointerarray[MAXTASKPARAMS];
2418 //int numparams=parameter->task->numParameters;
2419 int numiterators=parameter->task->numTotal-1;
2424 struct taskdescriptor * task=parameter->task;
2426 //this add the object to parameterwrapper
2427 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags, numenterflags, enterflags==NULL);
2429 /* Add enqueued object to parameter vector */
2430 taskpointerarray[parameter->slot]=ptr;
2432 /* Reset iterators */
2433 for(j=0; j<numiterators; j++) {
2434 toiReset(¶meter->iterators[j]);
2437 /* Find initial state */
2438 for(j=0; j<numiterators; j++) {
2440 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2441 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2443 /* Need to backtrack */
2444 toiReset(¶meter->iterators[j]);
2448 /* Nothing to enqueue */
2454 /* Enqueue current state */
2456 struct taskparamdescriptor *tpd=RUNMALLOC(sizeof(struct taskparamdescriptor));
2458 tpd->numParameters=numiterators+1;
2459 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
2461 for(j=0; j<=numiterators; j++) {
2462 tpd->parameterArray[j]=taskpointerarray[j]; //store the actual parameters
2465 if ((/*!gencontains(failedtasks, tpd)&&*/ !gencontains(activetasks,tpd))) {
2466 genputtable(activetasks, tpd, tpd);
2468 RUNFREE(tpd->parameterArray);
2472 /* This loop iterates to the next parameter combination */
2473 if (numiterators==0)
2476 for(j=numiterators-1; j<numiterators; j++) {
2478 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2479 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2481 /* Need to backtrack */
2482 toiReset(¶meter->iterators[j]);
2486 /* Nothing more to enqueue */
2494 int enqueuetasks_I(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr, int * enterflags, int numenterflags) {
2495 void * taskpointerarray[MAXTASKPARAMS];
2497 //int numparams=parameter->task->numParameters;
2498 int numiterators=parameter->task->numTotal-1;
2503 struct taskdescriptor * task=parameter->task;
2505 //this add the object to parameterwrapper
2506 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags, numenterflags, enterflags==NULL);
2508 /* Add enqueued object to parameter vector */
2509 taskpointerarray[parameter->slot]=ptr;
2511 /* Reset iterators */
2512 for(j=0; j<numiterators; j++) {
2513 toiReset(¶meter->iterators[j]);
2516 /* Find initial state */
2517 for(j=0; j<numiterators; j++) {
2519 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2520 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2522 /* Need to backtrack */
2523 toiReset(¶meter->iterators[j]);
2527 /* Nothing to enqueue */
2533 /* Enqueue current state */
2535 struct taskparamdescriptor *tpd=RUNMALLOC_I(sizeof(struct taskparamdescriptor));
2537 tpd->numParameters=numiterators+1;
2538 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
2540 for(j=0; j<=numiterators; j++) {
2541 tpd->parameterArray[j]=taskpointerarray[j]; //store the actual parameters
2544 if ((/*!gencontains(failedtasks, tpd)&&*/ !gencontains(activetasks,tpd))) {
2545 genputtable_I(activetasks, tpd, tpd);
2547 RUNFREE(tpd->parameterArray);
2551 /* This loop iterates to the next parameter combination */
2552 if (numiterators==0)
2555 for(j=numiterators-1; j<numiterators; j++) {
2557 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2558 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2560 /* Need to backtrack */
2561 toiReset(¶meter->iterators[j]);
2565 /* Nothing more to enqueue */
2573 /* Handler for signals. The signals catch null pointer errors and
2574 arithmatic errors. */
2576 void myhandler(int sig, siginfo_t *info, void *uap) {
2579 printf("sig=%d\n",sig);
2582 sigemptyset(&toclear);
2583 sigaddset(&toclear, sig);
2584 sigprocmask(SIG_UNBLOCK, &toclear,NULL);
2585 longjmp(error_handler,1);
2592 struct RuntimeHash *fdtoobject;
2594 void addreadfd(int fd) {
2597 FD_SET(fd, &readfds);
2600 void removereadfd(int fd) {
2601 FD_CLR(fd, &readfds);
2602 if (maxreadfd==(fd+1)) {
2604 while(maxreadfd>0&&!FD_ISSET(maxreadfd-1, &readfds))
2616 int containstag(struct ___Object___ *ptr, struct ___TagDescriptor___ *tag);
2618 void executetasks() {
2619 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
2622 struct ___Object___ * tmpparam = NULL;
2623 struct parameterdescriptor * pd=NULL;
2624 struct parameterwrapper *pw=NULL;
2629 struct LockValue locks[MAXTASKPARAMS];
2636 /* Set up signal handlers */
2637 struct sigaction sig;
2638 sig.sa_sigaction=&myhandler;
2639 sig.sa_flags=SA_SIGINFO;
2640 sigemptyset(&sig.sa_mask);
2642 /* Catch bus errors, segmentation faults, and floating point exceptions*/
2643 sigaction(SIGBUS,&sig,0);
2644 sigaction(SIGSEGV,&sig,0);
2645 sigaction(SIGFPE,&sig,0);
2646 sigaction(SIGPIPE,&sig,0);
2647 #endif // #if 0: non-multicore
2657 fdtoobject=allocateRuntimeHash(100);
2661 /* Map first block of memory to protected, anonymous page */
2662 mmap(0, 0x1000, 0, MAP_SHARED|MAP_FIXED|MAP_ANON, -1, 0);
2667 while(hashsize(activetasks)>0) {
2669 while((hashsize(activetasks)>0)||(maxreadfd>0)) {
2672 BAMBOO_DEBUGPRINT(0xe990);
2675 /* Check if any filedescriptors have IO pending */
2678 struct timeval timeout={0,0};
2682 numselect=select(maxreadfd, &tmpreadfds, NULL, NULL, &timeout);
2684 /* Process ready fd's */
2686 for(fd=0; fd<maxreadfd; fd++) {
2687 if (FD_ISSET(fd, &tmpreadfds)) {
2688 /* Set ready flag on object */
2690 // printf("Setting fd %d\n",fd);
2691 if (RuntimeHashget(fdtoobject, fd,(int *) &objptr)) {
2692 if(intflagorand(objptr,1,0xFFFFFFFF)) { /* Set the first flag to 1 */
2693 enqueueObject(objptr, NULL, 0);
2702 /* See if there are any active tasks */
2703 if (hashsize(activetasks)>0) {
2706 profileTaskStart("tpd checking");
2709 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
2710 genfreekey(activetasks, currtpd);
2712 numparams=currtpd->task->numParameters;
2713 numtotal=currtpd->task->numTotal;
2715 // clear the lockRedirectTbl (TODO, this table should be empty after all locks are released)
2717 for(j = 0; j < MAXTASKPARAMS; j++) {
2718 locks[j].redirectlock = 0;
2721 // get all required locks
2723 // check which locks are needed
2724 for(i = 0; i < numparams; i++) {
2725 void * param = currtpd->parameterArray[i];
2729 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
2731 taskpointerarray[i+OFFSET]=param;
2734 if(((struct ___Object___ *)param)->lock == NULL) {
2735 tmplock = (int)param;
2737 tmplock = (int)(((struct ___Object___ *)param)->lock);
2739 // insert into the locks array
2740 for(j = 0; j < locklen; j++) {
2741 if(locks[j].value == tmplock) {
2744 } else if(locks[j].value > tmplock) {
2751 locks[h].redirectlock = locks[h-1].redirectlock;
2752 locks[h].value = locks[h-1].value;
2754 locks[j].value = tmplock;
2755 locks[j].redirectlock = (int)param;
2758 } // line 2713: for(i = 0; i < numparams; i++)
2759 // grab these required locks
2761 BAMBOO_DEBUGPRINT(0xe991);
2763 for(i = 0; i < locklen; i++) {
2764 int * lock = (int *)(locks[i].redirectlock);
2766 // require locks for this parameter if it is not a startup object
2768 BAMBOO_DEBUGPRINT_REG((int)lock);
2769 BAMBOO_DEBUGPRINT_REG((int)(locks[i].value));
2772 BAMBOO_START_CRITICAL_SECTION();
2774 BAMBOO_DEBUGPRINT(0xf001);
2777 //isInterrupt = false;
2780 BAMBOO_WAITING_FOR_LOCK();
2784 while(BAMBOO_WAITING_FOR_LOCK() != -1) {
2788 grount = lockresult;
2798 //isInterrupt = true;
2800 BAMBOO_CLOSE_CRITICAL_SECTION();
2802 BAMBOO_DEBUGPRINT(0xf000);
2808 BAMBOO_DEBUGPRINT(0xe992);
2810 // can not get the lock, try later
2811 // releas all grabbed locks for previous parameters
2812 for(j = 0; j < i; ++j) {
2813 lock = (int*)(locks[j].redirectlock);
2814 releasewritelock(lock);
2816 genputtable(activetasks, currtpd, currtpd);
2817 if(hashsize(activetasks) == 1) {
2818 // only one task right now, wait a little while before next try
2824 // fail, set the end of the checkTaskInfo
2828 } // line 2794: if(grount == 0)
2829 } // line 2752: for(i = 0; i < locklen; i++)
2832 BAMBOO_DEBUGPRINT(0xe993);
2834 /* Make sure that the parameters are still in the queues */
2835 for(i=0; i<numparams; i++) {
2836 void * parameter=currtpd->parameterArray[i];
2840 BAMBOO_CACHE_FLUSH_RANGE((int)parameter, classsize[((struct ___Object___ *)parameter)->type]);
2842 BAMBOO_START_CRITICAL_SECTION_LOCK();
2844 BAMBOO_DEBUGPRINT(0xf001);
2846 if(RuntimeHashcontainskey(objRedirectLockTbl, (int)parameter)) {
2847 int redirectlock_r = 0;
2848 RuntimeHashget(objRedirectLockTbl, (int)parameter, &redirectlock_r);
2849 ((struct ___Object___ *)parameter)->lock = redirectlock_r;
2850 RuntimeHashremovekey(objRedirectLockTbl, (int)parameter);
2852 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
2854 BAMBOO_DEBUGPRINT(0xf000);
2858 tmpparam = (struct ___Object___ *)parameter;
2859 pd=currtpd->task->descriptorarray[i];
2860 pw=(struct parameterwrapper *) pd->queue;
2861 /* Check that object is still in queue */
2863 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
2865 BAMBOO_DEBUGPRINT(0xe994);
2867 // release grabbed locks
2868 for(j = 0; j < locklen; ++j) {
2869 int * lock = (int *)(locks[j].redirectlock);
2870 releasewritelock(lock);
2872 RUNFREE(currtpd->parameterArray);
2877 /* Check if the object's flags still meets requirements */
2881 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
2882 andmask=pw->intarray[tmpi*2];
2883 checkmask=pw->intarray[tmpi*2+1];
2884 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
2890 // flags are never suitable
2891 // remove this obj from the queue
2893 int UNUSED, UNUSED2;
2896 BAMBOO_DEBUGPRINT(0xe995);
2898 ObjectHashget(pw->objectset, (int) parameter, (int *) &next, (int *) &enterflags, &UNUSED, &UNUSED2);
2899 ObjectHashremove(pw->objectset, (int)parameter);
2900 if (enterflags!=NULL)
2901 RUNFREE(enterflags);
2902 // release grabbed locks
2903 for(j = 0; j < locklen; ++j) {
2904 int * lock = (int *)(locks[j].redirectlock);
2905 releasewritelock(lock);
2907 RUNFREE(currtpd->parameterArray);
2910 // fail, set the end of the checkTaskInfo
2914 } // line 2878: if (!ismet)
2918 /* Check that object still has necessary tags */
2919 for(j=0; j<pd->numbertags; j++) {
2920 int slotid=pd->tagarray[2*j]+numparams;
2921 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
2922 if (!containstag(parameter, tagd)) {
2924 BAMBOO_DEBUGPRINT(0xe996);
2927 // release grabbed locks
2929 for(tmpj = 0; tmpj < locklen; ++tmpj) {
2930 int * lock = (int *)(locks[tmpj].redirectlock);
2931 releasewritelock(lock);
2934 RUNFREE(currtpd->parameterArray);
2937 } // line2911: if (!containstag(parameter, tagd))
2938 } // line 2808: for(j=0; j<pd->numbertags; j++)
2940 taskpointerarray[i+OFFSET]=parameter;
2941 } // line 2824: for(i=0; i<numparams; i++)
2943 for(; i<numtotal; i++) {
2944 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
2950 /* Checkpoint the state */
2951 forward=allocateRuntimeHash(100);
2952 reverse=allocateRuntimeHash(100);
2953 //void ** checkpoint=makecheckpoint(currtpd->task->numParameters, currtpd->parameterArray, forward, reverse);
2955 #endif // #if 0: for recovery
2957 if (x=setjmp(error_handler)) {
2962 printf("Fatal Error=%d, Recovering!\n",x);
2966 genputtable(failedtasks,currtpd,currtpd);
2967 //restorecheckpoint(currtpd->task->numParameters, currtpd->parameterArray, checkpoint, forward, reverse);
2969 freeRuntimeHash(forward);
2970 freeRuntimeHash(reverse);
2974 #endif // #if 0: for recovery
2975 BAMBOO_DEBUGPRINT_REG(x);
2976 BAMBOO_EXIT(0xa020);
2978 #endif // #ifndef MULTICORE
2980 if (injectfailures) {
2981 if ((((double)random())/RAND_MAX)<failurechance) {
2982 printf("\nINJECTING TASK FAILURE to %s\n", currtpd->task->name);
2983 longjmp(error_handler,10);
2986 #endif // #if 0: for recovery
2987 /* Actually call task */
2990 ((int *)taskpointerarray)[0]=currtpd->numParameters;
2991 taskpointerarray[1]=NULL;
2993 #endif // #if 0: for garbage collection
2996 // check finish, set the end of the checkTaskInfo
2998 profileTaskStart(currtpd->task->name);
3003 printf("ENTER %s count=%d\n",currtpd->task->name, (instaccum-instructioncount));
3005 ((void(*) (void **))currtpd->task->taskptr)(taskpointerarray);
3007 printf("EXIT %s count=%d\n",currtpd->task->name, (instaccum-instructioncount));
3011 BAMBOO_DEBUGPRINT(0xe997);
3013 ((void(*) (void **))currtpd->task->taskptr)(taskpointerarray);
3014 } // line 2990: if(debugtask)
3016 // task finish, set the end of the checkTaskInfo
3018 // new a PostTaskInfo for the post-task execution
3019 profileTaskStart("post task execution");
3022 BAMBOO_DEBUGPRINT(0xe998);
3023 BAMBOO_DEBUGPRINT_REG(islock);
3028 BAMBOO_DEBUGPRINT(0xe999);
3030 for(i = 0; i < locklen; ++i) {
3031 void * ptr = (void *)(locks[i].redirectlock);
3032 int * lock = (int *)(locks[i].value);
3034 BAMBOO_DEBUGPRINT_REG((int)ptr);
3035 BAMBOO_DEBUGPRINT_REG((int)lock);
3037 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
3039 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
3040 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
3041 releasewritelock_r(lock, (int *)redirectlock);
3043 releasewritelock(ptr);
3046 } // line 3015: if(islock)
3049 // post task execution finish, set the end of the postTaskInfo
3054 freeRuntimeHash(forward);
3055 freeRuntimeHash(reverse);
3058 // Free up task parameter descriptor
3059 RUNFREE(currtpd->parameterArray);
3066 BAMBOO_DEBUGPRINT(0xe99a);
3069 } // line 2946: if (x=setjmp(error_handler))
3072 } // line 2697: if (hashsize(activetasks)>0)
3073 } // line 2659: while(hashsize(activetasks)>0)
3075 BAMBOO_DEBUGPRINT(0xe99b);
3079 /* This function processes an objects tags */
3080 void processtags(struct parameterdescriptor *pd, int index, struct parameterwrapper *parameter, int * iteratorcount, int *statusarray, int numparams) {
3083 for(i=0; i<pd->numbertags; i++) {
3084 int slotid=pd->tagarray[2*i];
3085 int tagid=pd->tagarray[2*i+1];
3087 if (statusarray[slotid+numparams]==0) {
3088 parameter->iterators[*iteratorcount].istag=1;
3089 parameter->iterators[*iteratorcount].tagid=tagid;
3090 parameter->iterators[*iteratorcount].slot=slotid+numparams;
3091 parameter->iterators[*iteratorcount].tagobjectslot=index;
3092 statusarray[slotid+numparams]=1;
3099 void processobject(struct parameterwrapper *parameter, int index, struct parameterdescriptor *pd, int *iteratorcount, int * statusarray, int numparams) {
3102 struct ObjectHash * objectset=((struct parameterwrapper *)pd->queue)->objectset;
3104 parameter->iterators[*iteratorcount].istag=0;
3105 parameter->iterators[*iteratorcount].slot=index;
3106 parameter->iterators[*iteratorcount].objectset=objectset;
3107 statusarray[index]=1;
3109 for(i=0; i<pd->numbertags; i++) {
3110 int slotid=pd->tagarray[2*i];
3111 //int tagid=pd->tagarray[2*i+1];
3112 if (statusarray[slotid+numparams]!=0) {
3113 /* This tag has already been enqueued, use it to narrow search */
3114 parameter->iterators[*iteratorcount].tagbindings[tagcount]=slotid+numparams;
3118 parameter->iterators[*iteratorcount].numtags=tagcount;
3123 /* This function builds the iterators for a task & parameter */
3125 void builditerators(struct taskdescriptor * task, int index, struct parameterwrapper * parameter) {
3126 int statusarray[MAXTASKPARAMS];
3128 int numparams=task->numParameters;
3129 int iteratorcount=0;
3130 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
3132 statusarray[index]=1; /* Initial parameter */
3133 /* Process tags for initial iterator */
3135 processtags(task->descriptorarray[index], index, parameter, &iteratorcount, statusarray, numparams);
3139 /* Check for objects with existing tags */
3140 for(i=0; i<numparams; i++) {
3141 if (statusarray[i]==0) {
3142 struct parameterdescriptor *pd=task->descriptorarray[i];
3144 for(j=0; j<pd->numbertags; j++) {
3145 int slotid=pd->tagarray[2*j];
3146 if(statusarray[slotid+numparams]!=0) {
3147 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3148 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3155 /* Next do objects w/ unbound tags*/
3157 for(i=0; i<numparams; i++) {
3158 if (statusarray[i]==0) {
3159 struct parameterdescriptor *pd=task->descriptorarray[i];
3160 if (pd->numbertags>0) {
3161 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3162 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3168 /* Nothing with a tag enqueued */
3170 for(i=0; i<numparams; i++) {
3171 if (statusarray[i]==0) {
3172 struct parameterdescriptor *pd=task->descriptorarray[i];
3173 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3174 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3187 if(corenum > NUMCORES - 1) {
3190 for(i=0; i<numtasks[corenum]; i++) {
3191 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3193 printf("%s\n", task->name);
3195 for(j=0; j<task->numParameters; j++) {
3196 struct parameterdescriptor *param=task->descriptorarray[j];
3197 struct parameterwrapper *parameter=param->queue;
3198 struct ObjectHash * set=parameter->objectset;
3199 struct ObjectIterator objit;
3201 printf(" Parameter %d\n", j);
3203 ObjectHashiterator(set, &objit);
3204 while(ObjhasNext(&objit)) {
3205 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
3206 struct ___Object___ * tagptr=obj->___tags___;
3207 int nonfailed=Objdata4(&objit);
3208 int numflags=Objdata3(&objit);
3209 int flags=Objdata2(&objit);
3212 printf(" Contains %lx\n", obj);
3213 printf(" flag=%d\n", obj->flag);
3216 } else if (tagptr->type==TAGTYPE) {
3218 printf(" tag=%lx\n",tagptr);
3224 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
3225 for(; tagindex<ao->___cachedCode___; tagindex++) {
3227 printf(" tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*, tagindex));
3239 /* This function processes the task information to create queues for
3240 each parameter type. */
3242 void processtasks() {
3244 if(corenum > NUMCORES - 1) {
3247 for(i=0; i<numtasks[corenum]; i++) {
3248 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3251 /* Build objectsets */
3252 for(j=0; j<task->numParameters; j++) {
3253 struct parameterdescriptor *param=task->descriptorarray[j];
3254 struct parameterwrapper *parameter=param->queue;
3255 parameter->objectset=allocateObjectHash(10);
3256 parameter->task=task;
3259 /* Build iterators for parameters */
3260 for(j=0; j<task->numParameters; j++) {
3261 struct parameterdescriptor *param=task->descriptorarray[j];
3262 struct parameterwrapper *parameter=param->queue;
3263 builditerators(task, j, parameter);
3268 void toiReset(struct tagobjectiterator * it) {
3271 } else if (it->numtags>0) {
3274 ObjectHashiterator(it->objectset, &it->it);
3278 int toiHasNext(struct tagobjectiterator *it, void ** objectarray OPTARG(int * failed)) {
3281 /* Get object with tags */
3282 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3283 struct ___Object___ *tagptr=obj->___tags___;
3284 if (tagptr->type==TAGTYPE) {
3285 if ((it->tagobjindex==0)&& /* First object */
3286 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
3291 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3292 int tagindex=it->tagobjindex;
3293 for(; tagindex<ao->___cachedCode___; tagindex++) {
3294 struct ___TagDescriptor___ *td=ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
3295 if (td->flag==it->tagid) {
3296 it->tagobjindex=tagindex; /* Found right type of tag */
3302 } else if (it->numtags>0) {
3303 /* Use tags to locate appropriate objects */
3304 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3305 struct ___Object___ *objptr=tag->flagptr;
3307 if (objptr->type!=OBJECTARRAYTYPE) {
3308 if (it->tagobjindex>0)
3310 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3312 for(i=1; i<it->numtags; i++) {
3313 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3314 if (!containstag(objptr,tag2))
3319 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3322 for(tagindex=it->tagobjindex; tagindex<ao->___cachedCode___; tagindex++) {
3323 struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
3324 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3326 for(i=1; i<it->numtags; i++) {
3327 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3328 if (!containstag(objptr,tag2))
3331 it->tagobjindex=tagindex;
3336 it->tagobjindex=tagindex;
3340 return ObjhasNext(&it->it);
3344 int containstag(struct ___Object___ *ptr, struct ___TagDescriptor___ *tag) {
3346 struct ___Object___ * objptr=tag->flagptr;
3347 if (objptr->type==OBJECTARRAYTYPE) {
3348 struct ArrayObject *ao=(struct ArrayObject *)objptr;
3349 for(j=0; j<ao->___cachedCode___; j++) {
3350 if (ptr==ARRAYGET(ao, struct ___Object___*, j))
3358 void toiNext(struct tagobjectiterator *it, void ** objectarray OPTARG(int * failed)) {
3359 /* hasNext has all of the intelligence */
3362 /* Get object with tags */
3363 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3364 struct ___Object___ *tagptr=obj->___tags___;
3365 if (tagptr->type==TAGTYPE) {
3367 objectarray[it->slot]=tagptr;
3369 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3370 objectarray[it->slot]=ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
3372 } else if (it->numtags>0) {
3373 /* Use tags to locate appropriate objects */
3374 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3375 struct ___Object___ *objptr=tag->flagptr;
3376 if (objptr->type!=OBJECTARRAYTYPE) {
3378 objectarray[it->slot]=objptr;
3380 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3381 objectarray[it->slot]=ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
3384 /* Iterate object */
3385 objectarray[it->slot]=(void *)Objkey(&it->it);