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.
440 // still some objects on the fly on the network
441 // reset the waitconfirm and numconfirm
443 BAMBOO_DEBUGPRINT(0xee07);
449 // not all cores are stall, keep on waiting
451 BAMBOO_DEBUGPRINT(0xee08);
456 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
458 BAMBOO_DEBUGPRINT(0xf000);
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);
502 } // right-bracket for if-else of line 220
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
1082 * ObjMsg: 0 + size of msg + obj's address + (task index + param index)+
1083 * StallMsg: 1 + corenum + sendobjs + receiveobjs (size is always 4 * sizeof(int))
1084 * LockMsg: 2 + lock type + obj pointer + lock + request core (size is always 5 * sizeof(int))
1085 * 3/4/5 + lock type + obj pointer + lock (size is always 4 * sizeof(int))
1086 * 8 + lock type + obj pointer + redirect lock + root request core + request core (size is always 6 * sizeof(int))
1087 * 9/a + lock type + obj pointer + redirect lock (size is always 4 * sizeof(int))
1088 * b + lock type + lock + redirect lock (size is always 4 * sizeof(int))
1089 * lock type: 0 -- read; 1 -- write
1090 * ProfileMsg: 6 + totalexetime (size is always 2 * sizeof(int))
1091 * 7 + corenum (size is always 2 * sizeof(int))
1092 * StatusMsg: c (size is always 1 * sizeof(int))
1093 * d + status + corenum (size is always 3 * sizeof(int))
1094 * status: 0 -- stall; 1 -- busy
1098 // output the profiling data
1099 void outputProfileData() {
1106 int totaltasktime = 0;
1107 int preprocessingtime = 0;
1108 int objqueuecheckingtime = 0;
1109 int postprocessingtime = 0;
1110 //int interruptiontime = 0;
1112 int averagetasktime = 0;
1115 for(i = 0; i < 50; i++) {
1119 calCoords(corenum, &self_y, &self_x);
1120 c_y = (char)self_y + '0';
1121 c_x = (char)self_x + '0';
1122 strcat(fn, "profile_");
1128 if((fp = fopen(fn, "w+")) == NULL) {
1129 fprintf(stderr, "fopen error\n");
1133 fprintf(fp, "Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
1134 // output task related info
1135 for(i = 0; i < taskInfoIndex; i++) {
1136 TaskInfo* tmpTInfo = taskInfoArray[i];
1137 int duration = tmpTInfo->endTime - tmpTInfo->startTime;
1138 fprintf(fp, "%s, %d, %d, %d, %d", tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime, duration, tmpTInfo->exitIndex);
1139 // summarize new obj info
1140 if(tmpTInfo->newObjs != NULL) {
1141 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
1142 struct RuntimeIterator * iter = NULL;
1143 while(0 == isEmpty(tmpTInfo->newObjs)) {
1144 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
1145 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
1147 RuntimeHashget(nobjtbl, (int)objtype, &num);
1148 RuntimeHashremovekey(nobjtbl, (int)objtype);
1150 RuntimeHashadd(nobjtbl, (int)objtype, num);
1152 RuntimeHashadd(nobjtbl, (int)objtype, 1);
1154 //fprintf(stderr, "new obj!\n");
1157 // output all new obj info
1158 iter = RuntimeHashcreateiterator(nobjtbl);
1159 while(RunhasNext(iter)) {
1160 char * objtype = (char *)Runkey(iter);
1161 int num = Runnext(iter);
1162 fprintf(fp, ", %s, %d", objtype, num);
1166 if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
1167 preprocessingtime += duration;
1168 } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
1169 postprocessingtime += duration;
1170 } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
1171 objqueuecheckingtime += duration;
1173 totaltasktime += duration;
1174 averagetasktime += duration;
1179 if(taskInfoOverflow) {
1180 fprintf(stderr, "Caution: task info overflow!\n");
1183 other = totalexetime - totaltasktime - preprocessingtime - postprocessingtime;
1184 averagetasktime /= tasknum;
1186 fprintf(fp, "\nTotal time: %d\n", totalexetime);
1187 fprintf(fp, "Total task execution time: %d (%f%%)\n", totaltasktime, ((double)totaltasktime/(double)totalexetime)*100);
1188 fprintf(fp, "Total objqueue checking time: %d (%f%%)\n", objqueuecheckingtime, ((double)objqueuecheckingtime/(double)totalexetime)*100);
1189 fprintf(fp, "Total pre-processing time: %d (%f%%)\n", preprocessingtime, ((double)preprocessingtime/(double)totalexetime)*100);
1190 fprintf(fp, "Total post-processing time: %d (%f%%)\n", postprocessingtime, ((double)postprocessingtime/(double)totalexetime)*100);
1191 fprintf(fp, "Other time: %d (%f%%)\n", other, ((double)other/(double)totalexetime)*100);
1193 fprintf(fp, "\nAverage task execution time: %d\n", averagetasktime);
1200 BAMBOO_DEBUGPRINT(0xdddd);
1201 // output task related info
1202 for(i= 0; i < taskInfoIndex; i++) {
1203 TaskInfo* tmpTInfo = taskInfoArray[i];
1204 char* tmpName = tmpTInfo->taskName;
1205 int nameLen = strlen(tmpName);
1206 BAMBOO_DEBUGPRINT(0xddda);
1207 for(j = 0; j < nameLen; j++) {
1208 BAMBOO_DEBUGPRINT_REG(tmpName[j]);
1210 BAMBOO_DEBUGPRINT(0xdddb);
1211 BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
1212 BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
1213 BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
1214 if(tmpTInfo->newObjs != NULL) {
1215 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
1216 struct RuntimeIterator * iter = NULL;
1217 while(0 == isEmpty(tmpTInfo->newObjs)) {
1218 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
1219 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
1221 RuntimeHashget(nobjtbl, (int)objtype, &num);
1222 RuntimeHashremovekey(nobjtbl, (int)objtype);
1224 RuntimeHashadd(nobjtbl, (int)objtype, num);
1226 RuntimeHashadd(nobjtbl, (int)objtype, 1);
1230 // ouput all new obj info
1231 iter = RuntimeHashcreateiterator(nobjtbl);
1232 while(RunhasNext(iter)) {
1233 char * objtype = (char *)Runkey(iter);
1234 int num = Runnext(iter);
1235 int nameLen = strlen(objtype);
1236 BAMBOO_DEBUGPRINT(0xddda);
1237 for(j = 0; j < nameLen; j++) {
1238 BAMBOO_DEBUGPRINT_REG(objtype[j]);
1240 BAMBOO_DEBUGPRINT(0xdddb);
1241 BAMBOO_DEBUGPRINT_REG(num);
1244 BAMBOO_DEBUGPRINT(0xdddc);
1247 if(taskInfoOverflow) {
1248 BAMBOO_DEBUGPRINT(0xefee);
1251 // output interrupt related info
1252 /*for(i = 0; i < interruptInfoIndex; i++) {
1253 InterruptInfo* tmpIInfo = interruptInfoArray[i];
1254 BAMBOO_DEBUGPRINT(0xddde);
1255 BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
1256 BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
1257 BAMBOO_DEBUGPRINT(0xdddf);
1260 if(interruptInfoOverflow) {
1261 BAMBOO_DEBUGPRINT(0xefef);
1264 BAMBOO_DEBUGPRINT(0xeeee);
1268 inline void setTaskExitIndex(int index) {
1269 taskInfoArray[taskInfoIndex]->exitIndex = index;
1272 inline void addNewObjInfo(void * nobj) {
1273 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1274 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1276 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1280 /* this function is to process lock requests.
1281 * can only be invoked in receiveObject() */
1282 // if return -1: the lock request is redirected
1283 // 0: the lock request is approved
1284 // 1: the lock request is denied
1285 int processlockrequest(int locktype, int lock, int obj, int requestcore, int rootrequestcore, bool cache);
1287 // receive object transferred from other cores
1288 // or the terminate message from other cores
1289 // Should be invoked in critical sections!!
1290 // NOTICE: following format is for threadsimulate version only
1291 // RAW version please see previous description
1292 // format: type + object
1293 // type: -1--stall msg
1295 // return value: 0--received an object
1296 // 1--received nothing
1297 // 2--received a Stall Msg
1298 // 3--received a lock Msg
1299 // RAW version: -1 -- received nothing
1300 // otherwise -- received msg type
1301 int receiveObject() {
1303 //int targetcore = 0;
1306 if(receiveMsg() == -1) {
1310 if(msgdataindex == msglength) {
1311 // received a whole msg
1312 int type, data1; // will receive at least 2 words including type
1317 // receive a object transfer msg
1318 struct transObjInfo * transObj = RUNMALLOC_I(sizeof(struct transObjInfo));
1321 BAMBOO_DEBUGPRINT(0xe880);
1323 if(corenum > NUMCORES - 1) {
1324 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1325 BAMBOO_EXIT(0xa005);
1326 } /*else if((corenum == STARTUPCORE) && waitconfirm) {
1327 waitconfirm = false;
1330 // store the object and its corresponding queue info, enqueue it later
1331 transObj->objptr = (void *)msgdata[2]; // data1 is now size of the msg
1332 transObj->length = (msglength - 3) / 2;
1333 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
1334 for(k = 0; k < transObj->length; ++k) {
1335 transObj->queues[2*k] = msgdata[3+2*k];
1337 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
1339 transObj->queues[2*k+1] = msgdata[3+2*k+1];
1341 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
1344 // check if there is an existing duplicate item
1346 struct QueueItem * qitem = getTail(&objqueue);
1347 struct QueueItem * prev = NULL;
1348 while(qitem != NULL) {
1349 struct transObjInfo * tmpinfo = (struct transObjInfo *)(qitem->objectptr);
1350 if(tmpinfo->objptr == transObj->objptr) {
1351 // the same object, remove outdate one
1352 removeItem(&objqueue, qitem);
1357 qitem = getTail(&objqueue);
1359 qitem = getNextQueueItem(prev);
1362 addNewItem_I(&objqueue, (void *)transObj);
1364 ++(self_numreceiveobjs);
1369 // receive a stall msg
1370 if(corenum != STARTUPCORE) {
1371 // non startup core can not receive stall msg
1373 BAMBOO_DEBUGPRINT_REG(data1);
1374 BAMBOO_EXIT(0xa006);
1375 } /*else if(waitconfirm) {
1376 waitconfirm = false;
1379 if(data1 < NUMCORES) {
1381 BAMBOO_DEBUGPRINT(0xe881);
1383 corestatus[data1] = 0;
1384 numsendobjs[data1] = msgdata[2];
1385 numreceiveobjs[data1] = msgdata[3];
1391 // receive lock request msg, handle it right now
1392 // check to see if there is a lock exist in locktbl for the required obj
1393 // data1 -> lock type
1394 int data2 = msgdata[2]; // obj pointer
1395 int data3 = msgdata[3]; // lock
1396 int data4 = msgdata[4]; // request core
1397 deny = processlockrequest(data1, data3, data2, data4, data4, true); // -1: redirected, 0: approved, 1: denied
1399 // this lock request is redirected
1402 // send response msg
1403 // for 32 bit machine, the size is always 4 words
1404 int tmp = deny==1?4:3;
1406 cache_msg_4(data4, tmp, data1, data2, data3);
1408 send_msg_4(data4, tmp, data1, data2, data3);
1415 // receive lock grount msg
1416 if(corenum > NUMCORES - 1) {
1417 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1418 BAMBOO_EXIT(0xa007);
1419 } /*else if((corenum == STARTUPCORE) && waitconfirm) {
1420 waitconfirm = false;
1423 if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1425 BAMBOO_DEBUGPRINT(0xe882);
1433 // conflicts on lockresults
1434 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1435 BAMBOO_EXIT(0xa008);
1441 // receive lock grount/deny msg
1442 if(corenum > NUMCORES - 1) {
1443 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1444 BAMBOO_EXIT(0xa009);
1445 } /*else if((corenum == STARTUPCORE) && waitconfirm) {
1446 waitconfirm = false;
1449 if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1451 BAMBOO_DEBUGPRINT(0xe883);
1459 // conflicts on lockresults
1460 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1461 BAMBOO_EXIT(0xa00a);
1467 // receive lock release msg
1468 /*if((corenum == STARTUPCORE) && waitconfirm) {
1469 waitconfirm = false;
1472 if(!RuntimeHashcontainskey(locktbl, msgdata[3])) {
1473 // no locks for this object, something is wrong
1474 BAMBOO_DEBUGPRINT_REG(msgdata[3]);
1475 BAMBOO_EXIT(0xa00b);
1478 struct LockValue * lockvalue = NULL;
1479 RuntimeHashget(locktbl, msgdata[3], &rwlock_obj);
1480 lockvalue = (struct LockValue*)(rwlock_obj);
1482 BAMBOO_DEBUGPRINT(0xe884);
1483 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1491 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1499 // receive an output profile data request msg
1500 if(corenum == STARTUPCORE) {
1501 // startup core can not receive profile output finish msg
1502 BAMBOO_EXIT(0xa00c);
1505 BAMBOO_DEBUGPRINT(0xe885);
1508 totalexetime = data1;
1509 outputProfileData();
1511 cache_msg_2(STARTUPCORE, 7, corenum);
1513 send_msg_2(STARTUPCORE, 7, corenum);
1519 // receive a profile output finish msg
1520 if(corenum != STARTUPCORE) {
1521 // non startup core can not receive profile output finish msg
1522 BAMBOO_DEBUGPRINT_REG(data1);
1523 BAMBOO_EXIT(0xa00d);
1526 BAMBOO_DEBUGPRINT(0xe886);
1528 profilestatus[data1] = 0;
1534 // receive a redirect lock request msg, handle it right now
1535 // check to see if there is a lock exist in locktbl for the required obj
1536 // data1 -> lock type
1537 int data2 = msgdata[2]; // obj pointer
1538 int data3 = msgdata[3]; // redirect lock
1539 int data4 = msgdata[4]; // root request core
1540 int data5 = msgdata[5]; // request core
1541 deny = processlockrequest(data1, data3, data2, data5, data4, true);
1543 // this lock request is redirected
1546 // send response msg
1547 // for 32 bit machine, the size is always 4 words
1549 cache_msg_4(data4, deny==1?0xa:9, data1, data2, data3);
1551 send_msg_4(data4, deny==1?0xa:9, data1, data2, data3);
1558 // receive a lock grant msg with redirect info
1559 if(corenum > NUMCORES - 1) {
1560 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1561 BAMBOO_EXIT(0xa00e);
1562 }/* else if((corenum == STARTUPCORE) && waitconfirm) {
1563 waitconfirm = false;
1566 if(lockobj == msgdata[2]) {
1568 BAMBOO_DEBUGPRINT(0xe891);
1572 RuntimeHashadd_I(objRedirectLockTbl, lockobj, msgdata[3]);
1577 // conflicts on lockresults
1578 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1579 BAMBOO_EXIT(0xa00f);
1585 // receive a lock deny msg with redirect info
1586 if(corenum > NUMCORES - 1) {
1587 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1588 BAMBOO_EXIT(0xa010);
1589 }/* else if((corenum == STARTUPCORE) && waitconfirm) {
1590 waitconfirm = false;
1593 if(lockobj == msgdata[2]) {
1595 BAMBOO_DEBUGPRINT(0xe892);
1599 //RuntimeHashadd_I(objRedirectLockTbl, lockobj, msgdata[3]);
1604 // conflicts on lockresults
1605 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1606 BAMBOO_EXIT(0xa011);
1612 // receive a lock release msg with redirect info
1613 /*if((corenum == STARTUPCORE) && waitconfirm) {
1614 waitconfirm = false;
1617 if(!RuntimeHashcontainskey(locktbl, msgdata[2])) {
1618 // no locks for this object, something is wrong
1619 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1620 BAMBOO_EXIT(0xa012);
1623 struct LockValue * lockvalue = NULL;
1624 RuntimeHashget(locktbl, msgdata[2], &rwlock_obj);
1625 lockvalue = (struct LockValue*)(rwlock_obj);
1627 BAMBOO_DEBUGPRINT(0xe893);
1628 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1636 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1638 lockvalue->redirectlock = msgdata[3];
1644 // receive a status confirm info
1645 if((corenum == STARTUPCORE) || (corenum > NUMCORES - 1)) {
1646 // wrong core to receive such msg
1647 BAMBOO_EXIT(0xa013);
1649 // send response msg
1651 BAMBOO_DEBUGPRINT(0xe887);
1654 cache_msg_3(STARTUPCORE, 0xd, busystatus?1:0, corenum);
1656 send_msg_3(STARTUPCORE, 0xd, busystatus?1:0, corenum);
1663 // receive a status confirm info
1664 if(corenum != STARTUPCORE) {
1665 // wrong core to receive such msg
1666 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1667 BAMBOO_EXIT(0xa014);
1670 BAMBOO_DEBUGPRINT(0xe888);
1675 corestatus[msgdata[2]] = msgdata[1];
1683 for(msgdataindex--; msgdataindex > 0; --msgdataindex) {
1684 msgdata[msgdataindex] = -1;
1689 BAMBOO_DEBUGPRINT(0xe889);
1692 if(BAMBOO_MSG_AVAIL() != 0) {
1704 BAMBOO_DEBUGPRINT(0xe895);
1707 /* if(isInterrupt) {
1715 /* this function is to process lock requests.
1716 * can only be invoked in receiveObject() */
1717 // if return -1: the lock request is redirected
1718 // 0: the lock request is approved
1719 // 1: the lock request is denied
1720 int processlockrequest(int locktype, int lock, int obj, int requestcore, int rootrequestcore, bool cache) {
1722 if( ((lock >> 5) % BAMBOO_TOTALCORE) != corenum ) {
1723 // the lock should not be on this core
1724 BAMBOO_DEBUGPRINT_REG(requestcore);
1725 BAMBOO_EXIT(0xa015);
1727 /*if((corenum == STARTUPCORE) && waitconfirm) {
1728 waitconfirm = false;
1731 if(!RuntimeHashcontainskey(locktbl, lock)) {
1732 // no locks for this object
1733 // first time to operate on this shared object
1734 // create a lock for it
1735 // the lock is an integer: 0 -- stall, >0 -- read lock, -1 -- write lock
1736 struct LockValue * lockvalue = (struct LockValue *)(RUNMALLOC_I(sizeof(struct LockValue)));
1737 lockvalue->redirectlock = 0;
1739 BAMBOO_DEBUGPRINT(0xe110);
1742 lockvalue->value = 1;
1744 lockvalue->value = -1;
1746 RuntimeHashadd_I(locktbl, lock, (int)lockvalue);
1749 struct LockValue * lockvalue = NULL;
1751 BAMBOO_DEBUGPRINT(0xe111);
1753 RuntimeHashget(locktbl, lock, &rwlock_obj);
1754 lockvalue = (struct LockValue *)(rwlock_obj);
1756 BAMBOO_DEBUGPRINT_REG(lockvalue->redirectlock);
1758 if(lockvalue->redirectlock != 0) {
1759 // this lock is redirected
1761 BAMBOO_DEBUGPRINT(0xe112);
1764 getreadlock_I_r((void *)obj, (void *)lockvalue->redirectlock, rootrequestcore, cache);
1766 getwritelock_I_r((void *)obj, (void *)lockvalue->redirectlock, rootrequestcore, cache);
1768 return -1; // redirected
1771 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1773 if(0 == lockvalue->value) {
1775 lockvalue->value = 1;
1777 lockvalue->value = -1;
1779 } else if((lockvalue->value > 0) && (locktype == 0)) {
1780 // read lock request and there are only read locks
1786 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1793 bool getreadlock(void * ptr) {
1796 if(((struct ___Object___ *)ptr)->lock == NULL) {
1797 lock2require = lockobj;
1799 lock2require = (int)(((struct ___Object___ *)ptr)->lock);
1801 targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
1808 if(targetcore == corenum) {
1809 // reside on this core
1811 BAMBOO_START_CRITICAL_SECTION_LOCK();
1813 BAMBOO_DEBUGPRINT(0xf001);
1815 deny = processlockrequest(0, lock2require, (int)ptr, corenum, corenum, false);
1816 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
1818 BAMBOO_DEBUGPRINT(0xf000);
1824 if(lockobj == (int)ptr) {
1835 // conflicts on lockresults
1836 BAMBOO_EXIT(0xa016);
1841 // send lock request msg
1842 // for 32 bit machine, the size is always 5 words
1843 send_msg_5(targetcore, 2, 0, (int)ptr, lock2require, corenum);
1848 void releasereadlock(void * ptr) {
1851 if(((struct ___Object___ *)ptr)->lock == NULL) {
1852 reallock = (int)ptr;
1854 reallock = (int)(((struct ___Object___ *)ptr)->lock);
1856 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
1858 if(targetcore == corenum) {
1859 BAMBOO_START_CRITICAL_SECTION_LOCK();
1861 BAMBOO_DEBUGPRINT(0xf001);
1863 // reside on this core
1864 if(!RuntimeHashcontainskey(locktbl, reallock)) {
1865 // no locks for this object, something is wrong
1866 BAMBOO_EXIT(0xa017);
1869 struct LockValue * lockvalue = NULL;
1870 RuntimeHashget(locktbl, reallock, &rwlock_obj);
1871 lockvalue = (struct LockValue *)rwlock_obj;
1874 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
1876 BAMBOO_DEBUGPRINT(0xf000);
1880 // send lock release msg
1881 // for 32 bit machine, the size is always 4 words
1882 send_msg_4(targetcore, 5, 0, (int)ptr, reallock);
1886 // redirected lock request
1887 bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
1890 if(core == corenum) {
1892 lock2require = (int)redirectlock;
1899 targetcore = ((int)redirectlock >> 5) % BAMBOO_TOTALCORE;
1901 if(targetcore == corenum) {
1902 // reside on this core
1903 int deny = processlockrequest(0, (int)redirectlock, (int)ptr, corenum, core, cache);
1908 if(core == corenum) {
1909 if(lockobj == (int)ptr) {
1914 RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
1921 // conflicts on lockresults
1922 BAMBOO_EXIT(0xa018);
1926 // send lock grant/deny request to the root requiring core
1927 // check if there is still some msg on sending
1928 if((!cache) || (cache && !isMsgSending)) {
1929 send_msg_4(core, deny==1?0xa:9, 0, (int)ptr, (int)redirectlock);
1931 cache_msg_4(core, deny==1?0xa:9, 0, (int)ptr, (int)redirectlock);
1936 // redirect the lock request
1937 // for 32 bit machine, the size is always 6 words
1938 if((!cache) || (cache && !isMsgSending)) {
1939 send_msg_6(targetcore, 8, 0, (int)ptr, lock2require, core, corenum);
1941 cache_msg_6(targetcore, 8, 0, (int)ptr, lock2require, core, corenum);
1948 bool getwritelock(void * ptr) {
1951 // for 32 bit machine, the size is always 5 words
1955 if(((struct ___Object___ *)ptr)->lock == NULL) {
1956 lock2require = lockobj;
1958 lock2require = (int)(((struct ___Object___ *)ptr)->lock);
1960 targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
1968 BAMBOO_DEBUGPRINT(0xe551);
1969 BAMBOO_DEBUGPRINT_REG(lockobj);
1970 BAMBOO_DEBUGPRINT_REG(lock2require);
1971 BAMBOO_DEBUGPRINT_REG(targetcore);
1974 if(targetcore == corenum) {
1975 // reside on this core
1977 BAMBOO_START_CRITICAL_SECTION_LOCK();
1979 BAMBOO_DEBUGPRINT(0xf001);
1981 deny = processlockrequest(1, lock2require, (int)ptr, corenum, corenum, false);
1982 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
1984 BAMBOO_DEBUGPRINT(0xf000);
1987 BAMBOO_DEBUGPRINT(0xe555);
1988 BAMBOO_DEBUGPRINT_REG(lockresult);
1994 if(lockobj == (int)ptr) {
2005 // conflicts on lockresults
2006 BAMBOO_EXIT(0xa019);
2011 // send lock request msg
2012 // for 32 bit machine, the size is always 5 words
2013 send_msg_5(targetcore, 2, 1, (int)ptr, lock2require, corenum);
2018 void releasewritelock(void * ptr) {
2021 if(((struct ___Object___ *)ptr)->lock == NULL) {
2022 reallock = (int)ptr;
2024 reallock = (int)(((struct ___Object___ *)ptr)->lock);
2026 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2029 BAMBOO_DEBUGPRINT(0xe661);
2030 BAMBOO_DEBUGPRINT_REG((int)ptr);
2031 BAMBOO_DEBUGPRINT_REG(reallock);
2032 BAMBOO_DEBUGPRINT_REG(targetcore);
2035 if(targetcore == corenum) {
2036 BAMBOO_START_CRITICAL_SECTION_LOCK();
2038 BAMBOO_DEBUGPRINT(0xf001);
2040 // reside on this core
2041 if(!RuntimeHashcontainskey(locktbl, reallock)) {
2042 // no locks for this object, something is wrong
2043 BAMBOO_EXIT(0xa01a);
2046 struct LockValue * lockvalue = NULL;
2047 RuntimeHashget(locktbl, reallock, &rwlock_obj);
2048 lockvalue = (struct LockValue *)rwlock_obj;
2051 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
2053 BAMBOO_DEBUGPRINT(0xf000);
2057 // send lock release msg
2058 // for 32 bit machine, the size is always 4 words
2059 send_msg_4(targetcore, 5, 1, (int)ptr, reallock);
2063 void releasewritelock_r(void * lock, void * redirectlock) {
2065 int reallock = (int)lock;
2066 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2069 BAMBOO_DEBUGPRINT(0xe671);
2070 BAMBOO_DEBUGPRINT_REG((int)lock);
2071 BAMBOO_DEBUGPRINT_REG(reallock);
2072 BAMBOO_DEBUGPRINT_REG(targetcore);
2075 if(targetcore == corenum) {
2076 BAMBOO_START_CRITICAL_SECTION_LOCK();
2078 BAMBOO_DEBUGPRINT(0xf001);
2080 // reside on this core
2081 if(!RuntimeHashcontainskey(locktbl, reallock)) {
2082 // no locks for this object, something is wrong
2083 BAMBOO_EXIT(0xa01b);
2086 struct LockValue * lockvalue = NULL;
2088 BAMBOO_DEBUGPRINT(0xe672);
2090 RuntimeHashget(locktbl, reallock, &rwlock_obj);
2091 lockvalue = (struct LockValue *)rwlock_obj;
2093 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2096 lockvalue->redirectlock = (int)redirectlock;
2098 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2101 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
2103 BAMBOO_DEBUGPRINT(0xf000);
2107 // send lock release with redirect info msg
2108 // for 32 bit machine, the size is always 4 words
2109 send_msg_4(targetcore, 0xb, 1, (int)lock, (int)redirectlock);
2113 bool getwritelock_I(void * ptr) {
2116 if(((struct ___Object___ *)ptr)->lock == NULL) {
2117 lock2require = lockobj;
2119 lock2require = (int)(((struct ___Object___ *)ptr)->lock);
2121 targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
2129 BAMBOO_DEBUGPRINT(0xe561);
2130 BAMBOO_DEBUGPRINT_REG(lockobj);
2131 BAMBOO_DEBUGPRINT_REG(lock2require);
2132 BAMBOO_DEBUGPRINT_REG(targetcore);
2135 if(targetcore == corenum) {
2136 // reside on this core
2137 int deny = processlockrequest(1, (int)lock2require, (int)ptr, corenum, corenum, false);
2142 if(lockobj == (int)ptr) {
2146 BAMBOO_DEBUGPRINT(0);
2151 BAMBOO_DEBUGPRINT(1);
2159 // conflicts on lockresults
2160 BAMBOO_EXIT(0xa01c);
2165 // send lock request msg
2166 // for 32 bit machine, the size is always 5 words
2167 send_msg_5(targetcore, 2, 1, (int)ptr, lock2require, corenum);
2172 // redirected lock request
2173 bool getwritelock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
2176 if(core == corenum) {
2178 lock2require = (int)redirectlock;
2185 targetcore = ((int)redirectlock >> 5) % BAMBOO_TOTALCORE;
2188 BAMBOO_DEBUGPRINT(0xe571);
2189 BAMBOO_DEBUGPRINT_REG((int)ptr);
2190 BAMBOO_DEBUGPRINT_REG((int)redirectlock);
2191 BAMBOO_DEBUGPRINT_REG(core);
2192 BAMBOO_DEBUGPRINT_REG((int)cache);
2193 BAMBOO_DEBUGPRINT_REG(targetcore);
2197 if(targetcore == corenum) {
2198 // reside on this core
2199 int deny = processlockrequest(1, (int)redirectlock, (int)ptr, corenum, core, cache);
2204 if(core == corenum) {
2205 if(lockobj == (int)ptr) {
2210 RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
2217 // conflicts on lockresults
2218 BAMBOO_EXIT(0xa01d);
2222 // send lock grant/deny request to the root requiring core
2223 // check if there is still some msg on sending
2224 if((!cache) || (cache && !isMsgSending)) {
2225 send_msg_4(core, deny==1?0xa:9, 1, (int)ptr, (int)redirectlock);
2227 cache_msg_4(core, deny==1?0xa:9, 1, (int)ptr, (int)redirectlock);
2232 // redirect the lock request
2233 // for 32 bit machine, the size is always 6 words
2234 if((!cache) || (cache && !isMsgSending)) {
2235 send_msg_6(targetcore, 8, 1, (int)ptr, (int)redirectlock, core, corenum);
2237 cache_msg_6(targetcore, 8, 1, (int)ptr, (int)redirectlock, core, corenum);
2243 void releasewritelock_I(void * ptr) {
2246 if(((struct ___Object___ *)ptr)->lock == NULL) {
2247 reallock = (int)ptr;
2249 reallock = (int)(((struct ___Object___ *)ptr)->lock);
2251 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2254 BAMBOO_DEBUGPRINT(0xe681);
2255 BAMBOO_DEBUGPRINT_REG((int)ptr);
2256 BAMBOO_DEBUGPRINT_REG(reallock);
2257 BAMBOO_DEBUGPRINT_REG(targetcore);
2260 if(targetcore == corenum) {
2261 // reside on this core
2262 if(!RuntimeHashcontainskey(locktbl, reallock)) {
2263 // no locks for this object, something is wrong
2264 BAMBOO_EXIT(0xa01e);
2267 struct LockValue * lockvalue = NULL;
2268 RuntimeHashget(locktbl, reallock, &rwlock_obj);
2269 lockvalue = (struct LockValue *)rwlock_obj;
2274 // send lock release msg
2275 // for 32 bit machine, the size is always 4 words
2276 send_msg_4(targetcore, 5, 1, (int)ptr, reallock);
2280 void releasewritelock_I_r(void * lock, void * redirectlock) {
2282 int reallock = (int)lock;
2283 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2286 BAMBOO_DEBUGPRINT(0xe691);
2287 BAMBOO_DEBUGPRINT_REG((int)lock);
2288 BAMBOO_DEBUGPRINT_REG(reallock);
2289 BAMBOO_DEBUGPRINT_REG(targetcore);
2292 if(targetcore == corenum) {
2293 // reside on this core
2294 if(!RuntimeHashcontainskey(locktbl, reallock)) {
2295 // no locks for this object, something is wrong
2296 BAMBOO_EXIT(0xa01f);
2299 struct LockValue * lockvalue = NULL;
2301 BAMBOO_DEBUGPRINT(0xe692);
2303 RuntimeHashget(locktbl, reallock, &rwlock_obj);
2304 lockvalue = (struct LockValue *)rwlock_obj;
2306 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2309 lockvalue->redirectlock = (int)redirectlock;
2311 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2316 // send lock release msg
2317 // for 32 bit machine, the size is always 4 words
2318 send_msg_4(targetcore, 0xb, 1, (int)lock, (int)redirectlock);
2322 int enqueuetasks(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr, int * enterflags, int numenterflags) {
2323 void * taskpointerarray[MAXTASKPARAMS];
2325 //int numparams=parameter->task->numParameters;
2326 int numiterators=parameter->task->numTotal-1;
2331 struct taskdescriptor * task=parameter->task;
2333 //this add the object to parameterwrapper
2334 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags, numenterflags, enterflags==NULL);
2336 /* Add enqueued object to parameter vector */
2337 taskpointerarray[parameter->slot]=ptr;
2339 /* Reset iterators */
2340 for(j=0; j<numiterators; j++) {
2341 toiReset(¶meter->iterators[j]);
2344 /* Find initial state */
2345 for(j=0; j<numiterators; j++) {
2347 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2348 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2350 /* Need to backtrack */
2351 toiReset(¶meter->iterators[j]);
2355 /* Nothing to enqueue */
2361 /* Enqueue current state */
2363 struct taskparamdescriptor *tpd=RUNMALLOC(sizeof(struct taskparamdescriptor));
2365 tpd->numParameters=numiterators+1;
2366 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
2368 for(j=0; j<=numiterators; j++) {
2369 tpd->parameterArray[j]=taskpointerarray[j]; //store the actual parameters
2372 if ((/*!gencontains(failedtasks, tpd)&&*/ !gencontains(activetasks,tpd))) {
2373 genputtable(activetasks, tpd, tpd);
2375 RUNFREE(tpd->parameterArray);
2379 /* This loop iterates to the next parameter combination */
2380 if (numiterators==0)
2383 for(j=numiterators-1; j<numiterators; j++) {
2385 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2386 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2388 /* Need to backtrack */
2389 toiReset(¶meter->iterators[j]);
2393 /* Nothing more to enqueue */
2401 int enqueuetasks_I(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr, int * enterflags, int numenterflags) {
2402 void * taskpointerarray[MAXTASKPARAMS];
2404 //int numparams=parameter->task->numParameters;
2405 int numiterators=parameter->task->numTotal-1;
2410 struct taskdescriptor * task=parameter->task;
2412 //this add the object to parameterwrapper
2413 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags, numenterflags, enterflags==NULL);
2415 /* Add enqueued object to parameter vector */
2416 taskpointerarray[parameter->slot]=ptr;
2418 /* Reset iterators */
2419 for(j=0; j<numiterators; j++) {
2420 toiReset(¶meter->iterators[j]);
2423 /* Find initial state */
2424 for(j=0; j<numiterators; j++) {
2426 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2427 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2429 /* Need to backtrack */
2430 toiReset(¶meter->iterators[j]);
2434 /* Nothing to enqueue */
2440 /* Enqueue current state */
2442 struct taskparamdescriptor *tpd=RUNMALLOC_I(sizeof(struct taskparamdescriptor));
2444 tpd->numParameters=numiterators+1;
2445 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
2447 for(j=0; j<=numiterators; j++) {
2448 tpd->parameterArray[j]=taskpointerarray[j]; //store the actual parameters
2451 if ((/*!gencontains(failedtasks, tpd)&&*/ !gencontains(activetasks,tpd))) {
2452 genputtable_I(activetasks, tpd, tpd);
2454 RUNFREE(tpd->parameterArray);
2458 /* This loop iterates to the next parameter combination */
2459 if (numiterators==0)
2462 for(j=numiterators-1; j<numiterators; j++) {
2464 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2465 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2467 /* Need to backtrack */
2468 toiReset(¶meter->iterators[j]);
2472 /* Nothing more to enqueue */
2480 /* Handler for signals. The signals catch null pointer errors and
2481 arithmatic errors. */
2483 void myhandler(int sig, siginfo_t *info, void *uap) {
2486 printf("sig=%d\n",sig);
2489 sigemptyset(&toclear);
2490 sigaddset(&toclear, sig);
2491 sigprocmask(SIG_UNBLOCK, &toclear,NULL);
2492 longjmp(error_handler,1);
2499 struct RuntimeHash *fdtoobject;
2501 void addreadfd(int fd) {
2504 FD_SET(fd, &readfds);
2507 void removereadfd(int fd) {
2508 FD_CLR(fd, &readfds);
2509 if (maxreadfd==(fd+1)) {
2511 while(maxreadfd>0&&!FD_ISSET(maxreadfd-1, &readfds))
2523 int containstag(struct ___Object___ *ptr, struct ___TagDescriptor___ *tag);
2525 void executetasks() {
2526 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
2529 struct ___Object___ * tmpparam = NULL;
2530 struct parameterdescriptor * pd=NULL;
2531 struct parameterwrapper *pw=NULL;
2536 struct LockValue * locks[MAXTASKPARAMS];
2542 for(j = 0; j < MAXTASKPARAMS; j++) {
2543 locks[j] = (struct LockValue *)(RUNMALLOC(sizeof(struct LockValue)));
2544 locks[j]->redirectlock = 0;
2545 locks[j]->value = 0;
2549 /* Set up signal handlers */
2550 struct sigaction sig;
2551 sig.sa_sigaction=&myhandler;
2552 sig.sa_flags=SA_SIGINFO;
2553 sigemptyset(&sig.sa_mask);
2555 /* Catch bus errors, segmentation faults, and floating point exceptions*/
2556 sigaction(SIGBUS,&sig,0);
2557 sigaction(SIGSEGV,&sig,0);
2558 sigaction(SIGFPE,&sig,0);
2559 sigaction(SIGPIPE,&sig,0);
2560 #endif // #if 0: non-multicore
2570 fdtoobject=allocateRuntimeHash(100);
2574 /* Map first block of memory to protected, anonymous page */
2575 mmap(0, 0x1000, 0, MAP_SHARED|MAP_FIXED|MAP_ANON, -1, 0);
2580 while(hashsize(activetasks)>0) {
2582 while((hashsize(activetasks)>0)||(maxreadfd>0)) {
2586 BAMBOO_DEBUGPRINT(0xe990);
2589 /* Check if any filedescriptors have IO pending */
2592 struct timeval timeout={0,0};
2596 numselect=select(maxreadfd, &tmpreadfds, NULL, NULL, &timeout);
2598 /* Process ready fd's */
2600 for(fd=0; fd<maxreadfd; fd++) {
2601 if (FD_ISSET(fd, &tmpreadfds)) {
2602 /* Set ready flag on object */
2604 // printf("Setting fd %d\n",fd);
2605 if (RuntimeHashget(fdtoobject, fd,(int *) &objptr)) {
2606 if(intflagorand(objptr,1,0xFFFFFFFF)) { /* Set the first flag to 1 */
2607 enqueueObject(objptr, NULL, 0);
2616 /* See if there are any active tasks */
2617 if (hashsize(activetasks)>0) {
2620 profileTaskStart("tpd checking");
2623 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
2624 genfreekey(activetasks, currtpd);
2626 numparams=currtpd->task->numParameters;
2627 numtotal=currtpd->task->numTotal;
2629 // clear the lockRedirectTbl (TODO, this table should be empty after all locks are released)
2630 // get all required locks
2632 // check which locks are needed
2633 for(i = 0; i < numparams; i++) {
2634 void * param = currtpd->parameterArray[i];
2638 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
2640 taskpointerarray[i+OFFSET]=param;
2643 if(((struct ___Object___ *)param)->lock == NULL) {
2644 tmplock = (int)param;
2646 tmplock = (int)(((struct ___Object___ *)param)->lock);
2648 // insert into the locks array
2649 for(j = 0; j < locklen; j++) {
2650 if(locks[j]->value == tmplock) {
2653 } else if(locks[j]->value > tmplock) {
2660 locks[h]->redirectlock = locks[h-1]->redirectlock;
2661 locks[h]->value = locks[h-1]->value;
2663 locks[j]->value = tmplock;
2664 locks[j]->redirectlock = (int)param;
2668 // grab these required locks
2670 BAMBOO_DEBUGPRINT(0xe991);
2672 for(i = 0; i < locklen; i++) {
2673 int * lock = (int *)(locks[i]->redirectlock);
2675 // require locks for this parameter if it is not a startup object
2677 BAMBOO_DEBUGPRINT_REG((int)lock);
2678 BAMBOO_DEBUGPRINT_REG((int)(locks[i]->value));
2681 BAMBOO_START_CRITICAL_SECTION();
2683 BAMBOO_DEBUGPRINT(0xf001);
2686 //isInterrupt = false;
2689 BAMBOO_WAITING_FOR_LOCK();
2693 while(BAMBOO_WAITING_FOR_LOCK() != -1) {
2697 grount = lockresult;
2707 //isInterrupt = true;
2709 BAMBOO_CLOSE_CRITICAL_SECTION();
2711 BAMBOO_DEBUGPRINT(0xf000);
2717 BAMBOO_DEBUGPRINT(0xe992);
2719 // can not get the lock, try later
2720 // releas all grabbed locks for previous parameters
2721 for(j = 0; j < i; ++j) {
2722 lock = (int*)(locks[j]->redirectlock);
2723 releasewritelock(lock);
2725 genputtable(activetasks, currtpd, currtpd);
2726 if(hashsize(activetasks) == 1) {
2727 // only one task right now, wait a little while before next try
2733 // fail, set the end of the checkTaskInfo
2741 BAMBOO_DEBUGPRINT(0xe993);
2743 /* Make sure that the parameters are still in the queues */
2744 for(i=0; i<numparams; i++) {
2745 void * parameter=currtpd->parameterArray[i];
2749 BAMBOO_CACHE_FLUSH_RANGE((int)parameter, classsize[((struct ___Object___ *)parameter)->type]);
2751 BAMBOO_START_CRITICAL_SECTION_LOCK();
2753 BAMBOO_DEBUGPRINT(0xf001);
2755 if(RuntimeHashcontainskey(objRedirectLockTbl, (int)parameter)) {
2756 int redirectlock_r = 0;
2757 RuntimeHashget(objRedirectLockTbl, (int)parameter, &redirectlock_r);
2758 ((struct ___Object___ *)parameter)->lock = redirectlock_r;
2759 RuntimeHashremovekey(objRedirectLockTbl, (int)parameter);
2761 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
2763 BAMBOO_DEBUGPRINT(0xf000);
2767 tmpparam = (struct ___Object___ *)parameter;
2768 pd=currtpd->task->descriptorarray[i];
2769 pw=(struct parameterwrapper *) pd->queue;
2770 /* Check that object is still in queue */
2772 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
2774 BAMBOO_DEBUGPRINT(0xe994);
2776 // release grabbed locks
2777 for(j = 0; j < locklen; ++j) {
2778 int * lock = (int *)(locks[j]->redirectlock);
2779 releasewritelock(lock);
2781 RUNFREE(currtpd->parameterArray);
2786 /* Check if the object's flags still meets requirements */
2790 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
2791 andmask=pw->intarray[tmpi*2];
2792 checkmask=pw->intarray[tmpi*2+1];
2793 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
2799 // flags are never suitable
2800 // remove this obj from the queue
2802 int UNUSED, UNUSED2;
2805 BAMBOO_DEBUGPRINT(0xe995);
2807 ObjectHashget(pw->objectset, (int) parameter, (int *) &next, (int *) &enterflags, &UNUSED, &UNUSED2);
2808 ObjectHashremove(pw->objectset, (int)parameter);
2809 if (enterflags!=NULL)
2810 RUNFREE(enterflags);
2811 // release grabbed locks
2812 for(j = 0; j < locklen; ++j) {
2813 int * lock = (int *)(locks[j]->redirectlock);
2814 releasewritelock(lock);
2816 RUNFREE(currtpd->parameterArray);
2819 // fail, set the end of the checkTaskInfo
2827 /* Check that object still has necessary tags */
2828 for(j=0; j<pd->numbertags; j++) {
2829 int slotid=pd->tagarray[2*j]+numparams;
2830 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
2831 if (!containstag(parameter, tagd)) {
2833 BAMBOO_DEBUGPRINT(0xe996);
2836 // release grabbed locks
2838 for(tmpj = 0; tmpj < locklen; ++tmpj) {
2839 int * lock = (int *)(locks[tmpj]->redirectlock);
2840 releasewritelock(lock);
2843 RUNFREE(currtpd->parameterArray);
2849 taskpointerarray[i+OFFSET]=parameter;
2852 for(; i<numtotal; i++) {
2853 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
2859 /* Checkpoint the state */
2860 forward=allocateRuntimeHash(100);
2861 reverse=allocateRuntimeHash(100);
2862 //void ** checkpoint=makecheckpoint(currtpd->task->numParameters, currtpd->parameterArray, forward, reverse);
2864 #endif // #if 0: for recovery
2866 if (x=setjmp(error_handler)) {
2871 printf("Fatal Error=%d, Recovering!\n",x);
2875 genputtable(failedtasks,currtpd,currtpd);
2876 //restorecheckpoint(currtpd->task->numParameters, currtpd->parameterArray, checkpoint, forward, reverse);
2878 freeRuntimeHash(forward);
2879 freeRuntimeHash(reverse);
2883 #endif // #if 0: for recovery
2884 BAMBOO_DEBUGPRINT_REG(x);
2885 BAMBOO_EXIT(0xa020);
2889 if (injectfailures) {
2890 if ((((double)random())/RAND_MAX)<failurechance) {
2891 printf("\nINJECTING TASK FAILURE to %s\n", currtpd->task->name);
2892 longjmp(error_handler,10);
2895 #endif // #if 0: for recovery
2896 /* Actually call task */
2899 ((int *)taskpointerarray)[0]=currtpd->numParameters;
2900 taskpointerarray[1]=NULL;
2902 #endif // #if 0: for garbage collection
2905 // check finish, set the end of the checkTaskInfo
2907 profileTaskStart(currtpd->task->name);
2912 printf("ENTER %s count=%d\n",currtpd->task->name, (instaccum-instructioncount));
2914 ((void(*) (void **))currtpd->task->taskptr)(taskpointerarray);
2916 printf("EXIT %s count=%d\n",currtpd->task->name, (instaccum-instructioncount));
2920 BAMBOO_DEBUGPRINT(0xe997);
2922 ((void(*) (void **))currtpd->task->taskptr)(taskpointerarray);
2925 // task finish, set the end of the checkTaskInfo
2927 // new a PostTaskInfo for the post-task execution
2928 profileTaskStart("post task execution");
2931 BAMBOO_DEBUGPRINT(0xe998);
2932 BAMBOO_DEBUGPRINT_REG(islock);
2937 BAMBOO_DEBUGPRINT(0xe999);
2939 for(i = 0; i < locklen; ++i) {
2940 void * ptr = (void *)(locks[i]->redirectlock);
2941 int * lock = (int *)(locks[i]->value);
2943 BAMBOO_DEBUGPRINT_REG((int)ptr);
2944 BAMBOO_DEBUGPRINT_REG((int)lock);
2946 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
2948 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
2949 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
2950 releasewritelock_r(lock, (int *)redirectlock);
2952 releasewritelock(ptr);
2958 // post task execution finish, set the end of the postTaskInfo
2963 freeRuntimeHash(forward);
2964 freeRuntimeHash(reverse);
2967 // Free up task parameter descriptor
2968 RUNFREE(currtpd->parameterArray);
2975 BAMBOO_DEBUGPRINT(0xe99a);
2984 BAMBOO_DEBUGPRINT(0xe99b);
2988 /* This function processes an objects tags */
2989 void processtags(struct parameterdescriptor *pd, int index, struct parameterwrapper *parameter, int * iteratorcount, int *statusarray, int numparams) {
2992 for(i=0; i<pd->numbertags; i++) {
2993 int slotid=pd->tagarray[2*i];
2994 int tagid=pd->tagarray[2*i+1];
2996 if (statusarray[slotid+numparams]==0) {
2997 parameter->iterators[*iteratorcount].istag=1;
2998 parameter->iterators[*iteratorcount].tagid=tagid;
2999 parameter->iterators[*iteratorcount].slot=slotid+numparams;
3000 parameter->iterators[*iteratorcount].tagobjectslot=index;
3001 statusarray[slotid+numparams]=1;
3008 void processobject(struct parameterwrapper *parameter, int index, struct parameterdescriptor *pd, int *iteratorcount, int * statusarray, int numparams) {
3011 struct ObjectHash * objectset=((struct parameterwrapper *)pd->queue)->objectset;
3013 parameter->iterators[*iteratorcount].istag=0;
3014 parameter->iterators[*iteratorcount].slot=index;
3015 parameter->iterators[*iteratorcount].objectset=objectset;
3016 statusarray[index]=1;
3018 for(i=0; i<pd->numbertags; i++) {
3019 int slotid=pd->tagarray[2*i];
3020 //int tagid=pd->tagarray[2*i+1];
3021 if (statusarray[slotid+numparams]!=0) {
3022 /* This tag has already been enqueued, use it to narrow search */
3023 parameter->iterators[*iteratorcount].tagbindings[tagcount]=slotid+numparams;
3027 parameter->iterators[*iteratorcount].numtags=tagcount;
3032 /* This function builds the iterators for a task & parameter */
3034 void builditerators(struct taskdescriptor * task, int index, struct parameterwrapper * parameter) {
3035 int statusarray[MAXTASKPARAMS];
3037 int numparams=task->numParameters;
3038 int iteratorcount=0;
3039 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
3041 statusarray[index]=1; /* Initial parameter */
3042 /* Process tags for initial iterator */
3044 processtags(task->descriptorarray[index], index, parameter, &iteratorcount, statusarray, numparams);
3048 /* Check for objects with existing tags */
3049 for(i=0; i<numparams; i++) {
3050 if (statusarray[i]==0) {
3051 struct parameterdescriptor *pd=task->descriptorarray[i];
3053 for(j=0; j<pd->numbertags; j++) {
3054 int slotid=pd->tagarray[2*j];
3055 if(statusarray[slotid+numparams]!=0) {
3056 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3057 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3064 /* Next do objects w/ unbound tags*/
3066 for(i=0; i<numparams; i++) {
3067 if (statusarray[i]==0) {
3068 struct parameterdescriptor *pd=task->descriptorarray[i];
3069 if (pd->numbertags>0) {
3070 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3071 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3077 /* Nothing with a tag enqueued */
3079 for(i=0; i<numparams; i++) {
3080 if (statusarray[i]==0) {
3081 struct parameterdescriptor *pd=task->descriptorarray[i];
3082 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3083 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3096 if(corenum > NUMCORES - 1) {
3099 for(i=0; i<numtasks[corenum]; i++) {
3100 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3102 printf("%s\n", task->name);
3104 for(j=0; j<task->numParameters; j++) {
3105 struct parameterdescriptor *param=task->descriptorarray[j];
3106 struct parameterwrapper *parameter=param->queue;
3107 struct ObjectHash * set=parameter->objectset;
3108 struct ObjectIterator objit;
3110 printf(" Parameter %d\n", j);
3112 ObjectHashiterator(set, &objit);
3113 while(ObjhasNext(&objit)) {
3114 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
3115 struct ___Object___ * tagptr=obj->___tags___;
3116 int nonfailed=Objdata4(&objit);
3117 int numflags=Objdata3(&objit);
3118 int flags=Objdata2(&objit);
3121 printf(" Contains %lx\n", obj);
3122 printf(" flag=%d\n", obj->flag);
3125 } else if (tagptr->type==TAGTYPE) {
3127 printf(" tag=%lx\n",tagptr);
3133 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
3134 for(; tagindex<ao->___cachedCode___; tagindex++) {
3136 printf(" tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*, tagindex));
3148 /* This function processes the task information to create queues for
3149 each parameter type. */
3151 void processtasks() {
3153 if(corenum > NUMCORES - 1) {
3156 for(i=0; i<numtasks[corenum]; i++) {
3157 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3160 /* Build objectsets */
3161 for(j=0; j<task->numParameters; j++) {
3162 struct parameterdescriptor *param=task->descriptorarray[j];
3163 struct parameterwrapper *parameter=param->queue;
3164 parameter->objectset=allocateObjectHash(10);
3165 parameter->task=task;
3168 /* Build iterators for parameters */
3169 for(j=0; j<task->numParameters; j++) {
3170 struct parameterdescriptor *param=task->descriptorarray[j];
3171 struct parameterwrapper *parameter=param->queue;
3172 builditerators(task, j, parameter);
3177 void toiReset(struct tagobjectiterator * it) {
3180 } else if (it->numtags>0) {
3183 ObjectHashiterator(it->objectset, &it->it);
3187 int toiHasNext(struct tagobjectiterator *it, void ** objectarray OPTARG(int * failed)) {
3190 /* Get object with tags */
3191 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3192 struct ___Object___ *tagptr=obj->___tags___;
3193 if (tagptr->type==TAGTYPE) {
3194 if ((it->tagobjindex==0)&& /* First object */
3195 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
3200 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3201 int tagindex=it->tagobjindex;
3202 for(; tagindex<ao->___cachedCode___; tagindex++) {
3203 struct ___TagDescriptor___ *td=ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
3204 if (td->flag==it->tagid) {
3205 it->tagobjindex=tagindex; /* Found right type of tag */
3211 } else if (it->numtags>0) {
3212 /* Use tags to locate appropriate objects */
3213 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3214 struct ___Object___ *objptr=tag->flagptr;
3216 if (objptr->type!=OBJECTARRAYTYPE) {
3217 if (it->tagobjindex>0)
3219 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3221 for(i=1; i<it->numtags; i++) {
3222 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3223 if (!containstag(objptr,tag2))
3228 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3231 for(tagindex=it->tagobjindex; tagindex<ao->___cachedCode___; tagindex++) {
3232 struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
3233 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3235 for(i=1; i<it->numtags; i++) {
3236 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3237 if (!containstag(objptr,tag2))
3240 it->tagobjindex=tagindex;
3245 it->tagobjindex=tagindex;
3249 return ObjhasNext(&it->it);
3253 int containstag(struct ___Object___ *ptr, struct ___TagDescriptor___ *tag) {
3255 struct ___Object___ * objptr=tag->flagptr;
3256 if (objptr->type==OBJECTARRAYTYPE) {
3257 struct ArrayObject *ao=(struct ArrayObject *)objptr;
3258 for(j=0; j<ao->___cachedCode___; j++) {
3259 if (ptr==ARRAYGET(ao, struct ___Object___*, j))
3267 void toiNext(struct tagobjectiterator *it, void ** objectarray OPTARG(int * failed)) {
3268 /* hasNext has all of the intelligence */
3271 /* Get object with tags */
3272 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3273 struct ___Object___ *tagptr=obj->___tags___;
3274 if (tagptr->type==TAGTYPE) {
3276 objectarray[it->slot]=tagptr;
3278 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3279 objectarray[it->slot]=ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
3281 } else if (it->numtags>0) {
3282 /* Use tags to locate appropriate objects */
3283 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3284 struct ___Object___ *objptr=tag->flagptr;
3285 if (objptr->type!=OBJECTARRAYTYPE) {
3287 objectarray[it->slot]=objptr;
3289 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3290 objectarray[it->slot]=ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
3293 /* Iterate object */
3294 objectarray[it->slot]=(void *)Objkey(&it->it);