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
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));
1323 BAMBOO_DEBUGPRINT(0xe880);
1325 if(corenum > NUMCORES - 1) {
1326 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1327 BAMBOO_EXIT(0xa005);
1328 } /*else if((corenum == STARTUPCORE) && waitconfirm) {
1329 waitconfirm = false;
1332 // store the object and its corresponding queue info, enqueue it later
1333 transObj->objptr = (void *)msgdata[2]; // data1 is now size of the msg
1334 transObj->length = (msglength - 3) / 2;
1335 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
1336 for(k = 0; k < transObj->length; ++k) {
1337 transObj->queues[2*k] = msgdata[3+2*k];
1339 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
1341 transObj->queues[2*k+1] = msgdata[3+2*k+1];
1343 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
1346 // check if there is an existing duplicate item
1348 struct QueueItem * qitem = getTail(&objqueue);
1349 struct QueueItem * prev = NULL;
1350 while(qitem != NULL) {
1351 struct transObjInfo * tmpinfo = (struct transObjInfo *)(qitem->objectptr);
1352 if(tmpinfo->objptr == transObj->objptr) {
1353 // the same object, remove outdate one
1354 removeItem(&objqueue, qitem);
1359 qitem = getTail(&objqueue);
1361 qitem = getNextQueueItem(prev);
1364 addNewItem_I(&objqueue, (void *)transObj);
1366 ++(self_numreceiveobjs);
1371 // receive a stall msg
1372 if(corenum != STARTUPCORE) {
1373 // non startup core can not receive stall msg
1375 BAMBOO_DEBUGPRINT_REG(data1);
1376 BAMBOO_EXIT(0xa006);
1377 } /*else if(waitconfirm) {
1378 waitconfirm = false;
1381 if(data1 < NUMCORES) {
1383 BAMBOO_DEBUGPRINT(0xe881);
1385 corestatus[data1] = 0;
1386 numsendobjs[data1] = msgdata[2];
1387 numreceiveobjs[data1] = msgdata[3];
1393 // receive lock request msg, handle it right now
1394 // check to see if there is a lock exist in locktbl for the required obj
1395 // data1 -> lock type
1396 int data2 = msgdata[2]; // obj pointer
1397 int data3 = msgdata[3]; // lock
1398 int data4 = msgdata[4]; // request core
1399 deny = processlockrequest(data1, data3, data2, data4, data4, true); // -1: redirected, 0: approved, 1: denied
1401 // this lock request is redirected
1404 // send response msg
1405 // for 32 bit machine, the size is always 4 words
1406 int tmp = deny==1?4:3;
1408 cache_msg_4(data4, tmp, data1, data2, data3);
1410 send_msg_4(data4, tmp, data1, data2, data3);
1417 // receive lock grount msg
1418 if(corenum > NUMCORES - 1) {
1419 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1420 BAMBOO_EXIT(0xa007);
1421 } /*else if((corenum == STARTUPCORE) && waitconfirm) {
1422 waitconfirm = false;
1425 if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1427 BAMBOO_DEBUGPRINT(0xe882);
1435 // conflicts on lockresults
1436 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1437 BAMBOO_EXIT(0xa008);
1443 // receive lock grount/deny msg
1444 if(corenum > NUMCORES - 1) {
1445 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1446 BAMBOO_EXIT(0xa009);
1447 } /*else if((corenum == STARTUPCORE) && waitconfirm) {
1448 waitconfirm = false;
1451 if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1453 BAMBOO_DEBUGPRINT(0xe883);
1461 // conflicts on lockresults
1462 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1463 BAMBOO_EXIT(0xa00a);
1469 // receive lock release msg
1470 /*if((corenum == STARTUPCORE) && waitconfirm) {
1471 waitconfirm = false;
1474 if(!RuntimeHashcontainskey(locktbl, msgdata[3])) {
1475 // no locks for this object, something is wrong
1476 BAMBOO_DEBUGPRINT_REG(msgdata[3]);
1477 BAMBOO_EXIT(0xa00b);
1480 struct LockValue * lockvalue = NULL;
1481 RuntimeHashget(locktbl, msgdata[3], &rwlock_obj);
1482 lockvalue = (struct LockValue*)(rwlock_obj);
1484 BAMBOO_DEBUGPRINT(0xe884);
1485 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1493 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1501 // receive an output profile data request msg
1502 if(corenum == STARTUPCORE) {
1503 // startup core can not receive profile output finish msg
1504 BAMBOO_EXIT(0xa00c);
1507 BAMBOO_DEBUGPRINT(0xe885);
1510 totalexetime = data1;
1511 outputProfileData();
1513 cache_msg_2(STARTUPCORE, 7, corenum);
1515 send_msg_2(STARTUPCORE, 7, corenum);
1521 // receive a profile output finish msg
1522 if(corenum != STARTUPCORE) {
1523 // non startup core can not receive profile output finish msg
1524 BAMBOO_DEBUGPRINT_REG(data1);
1525 BAMBOO_EXIT(0xa00d);
1528 BAMBOO_DEBUGPRINT(0xe886);
1530 profilestatus[data1] = 0;
1536 // receive a redirect lock request msg, handle it right now
1537 // check to see if there is a lock exist in locktbl for the required obj
1538 // data1 -> lock type
1539 int data2 = msgdata[2]; // obj pointer
1540 int data3 = msgdata[3]; // redirect lock
1541 int data4 = msgdata[4]; // root request core
1542 int data5 = msgdata[5]; // request core
1543 deny = processlockrequest(data1, data3, data2, data5, data4, true);
1545 // this lock request is redirected
1548 // send response msg
1549 // for 32 bit machine, the size is always 4 words
1551 cache_msg_4(data4, deny==1?0xa:9, data1, data2, data3);
1553 send_msg_4(data4, deny==1?0xa:9, data1, data2, data3);
1560 // receive a lock grant msg with redirect info
1561 if(corenum > NUMCORES - 1) {
1562 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1563 BAMBOO_EXIT(0xa00e);
1564 }/* else if((corenum == STARTUPCORE) && waitconfirm) {
1565 waitconfirm = false;
1568 if(lockobj == msgdata[2]) {
1570 BAMBOO_DEBUGPRINT(0xe891);
1574 RuntimeHashadd_I(objRedirectLockTbl, lockobj, msgdata[3]);
1579 // conflicts on lockresults
1580 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1581 BAMBOO_EXIT(0xa00f);
1587 // receive a lock deny msg with redirect info
1588 if(corenum > NUMCORES - 1) {
1589 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1590 BAMBOO_EXIT(0xa010);
1591 }/* else if((corenum == STARTUPCORE) && waitconfirm) {
1592 waitconfirm = false;
1595 if(lockobj == msgdata[2]) {
1597 BAMBOO_DEBUGPRINT(0xe892);
1601 //RuntimeHashadd_I(objRedirectLockTbl, lockobj, msgdata[3]);
1606 // conflicts on lockresults
1607 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1608 BAMBOO_EXIT(0xa011);
1614 // receive a lock release msg with redirect info
1615 /*if((corenum == STARTUPCORE) && waitconfirm) {
1616 waitconfirm = false;
1619 if(!RuntimeHashcontainskey(locktbl, msgdata[2])) {
1620 // no locks for this object, something is wrong
1621 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1622 BAMBOO_EXIT(0xa012);
1625 struct LockValue * lockvalue = NULL;
1626 RuntimeHashget(locktbl, msgdata[2], &rwlock_obj);
1627 lockvalue = (struct LockValue*)(rwlock_obj);
1629 BAMBOO_DEBUGPRINT(0xe893);
1630 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1638 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1640 lockvalue->redirectlock = msgdata[3];
1646 // receive a status confirm info
1647 if((corenum == STARTUPCORE) || (corenum > NUMCORES - 1)) {
1648 // wrong core to receive such msg
1649 BAMBOO_EXIT(0xa013);
1651 // send response msg
1653 BAMBOO_DEBUGPRINT(0xe887);
1656 cache_msg_3(STARTUPCORE, 0xd, busystatus?1:0, corenum);
1658 send_msg_3(STARTUPCORE, 0xd, busystatus?1:0, corenum);
1665 // receive a status confirm info
1666 if(corenum != STARTUPCORE) {
1667 // wrong core to receive such msg
1668 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1669 BAMBOO_EXIT(0xa014);
1672 BAMBOO_DEBUGPRINT(0xe888);
1677 corestatus[msgdata[2]] = msgdata[1];
1683 // receive a terminate msg
1685 BAMBOO_DEBUGPRINT(0xe889);
1694 for(msgdataindex--; msgdataindex > 0; --msgdataindex) {
1695 msgdata[msgdataindex] = -1;
1700 BAMBOO_DEBUGPRINT(0xe88a);
1703 if(BAMBOO_MSG_AVAIL() != 0) {
1715 BAMBOO_DEBUGPRINT(0xe88b);
1718 /* if(isInterrupt) {
1726 /* this function is to process lock requests.
1727 * can only be invoked in receiveObject() */
1728 // if return -1: the lock request is redirected
1729 // 0: the lock request is approved
1730 // 1: the lock request is denied
1731 int processlockrequest(int locktype, int lock, int obj, int requestcore, int rootrequestcore, bool cache) {
1733 if( ((lock >> 5) % BAMBOO_TOTALCORE) != corenum ) {
1734 // the lock should not be on this core
1735 BAMBOO_DEBUGPRINT_REG(requestcore);
1736 BAMBOO_EXIT(0xa015);
1738 /*if((corenum == STARTUPCORE) && waitconfirm) {
1739 waitconfirm = false;
1742 if(!RuntimeHashcontainskey(locktbl, lock)) {
1743 // no locks for this object
1744 // first time to operate on this shared object
1745 // create a lock for it
1746 // the lock is an integer: 0 -- stall, >0 -- read lock, -1 -- write lock
1747 struct LockValue * lockvalue = (struct LockValue *)(RUNMALLOC_I(sizeof(struct LockValue)));
1748 lockvalue->redirectlock = 0;
1750 BAMBOO_DEBUGPRINT(0xe110);
1753 lockvalue->value = 1;
1755 lockvalue->value = -1;
1757 RuntimeHashadd_I(locktbl, lock, (int)lockvalue);
1760 struct LockValue * lockvalue = NULL;
1762 BAMBOO_DEBUGPRINT(0xe111);
1764 RuntimeHashget(locktbl, lock, &rwlock_obj);
1765 lockvalue = (struct LockValue *)(rwlock_obj);
1767 BAMBOO_DEBUGPRINT_REG(lockvalue->redirectlock);
1769 if(lockvalue->redirectlock != 0) {
1770 // this lock is redirected
1772 BAMBOO_DEBUGPRINT(0xe112);
1775 getreadlock_I_r((void *)obj, (void *)lockvalue->redirectlock, rootrequestcore, cache);
1777 getwritelock_I_r((void *)obj, (void *)lockvalue->redirectlock, rootrequestcore, cache);
1779 return -1; // redirected
1782 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1784 if(0 == lockvalue->value) {
1786 lockvalue->value = 1;
1788 lockvalue->value = -1;
1790 } else if((lockvalue->value > 0) && (locktype == 0)) {
1791 // read lock request and there are only read locks
1797 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1804 bool getreadlock(void * ptr) {
1807 if(((struct ___Object___ *)ptr)->lock == NULL) {
1808 lock2require = lockobj;
1810 lock2require = (int)(((struct ___Object___ *)ptr)->lock);
1812 targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
1819 if(targetcore == corenum) {
1820 // reside on this core
1822 BAMBOO_START_CRITICAL_SECTION_LOCK();
1824 BAMBOO_DEBUGPRINT(0xf001);
1826 deny = processlockrequest(0, lock2require, (int)ptr, corenum, corenum, false);
1827 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
1829 BAMBOO_DEBUGPRINT(0xf000);
1835 if(lockobj == (int)ptr) {
1846 // conflicts on lockresults
1847 BAMBOO_EXIT(0xa016);
1852 // send lock request msg
1853 // for 32 bit machine, the size is always 5 words
1854 send_msg_5(targetcore, 2, 0, (int)ptr, lock2require, corenum);
1859 void releasereadlock(void * ptr) {
1862 if(((struct ___Object___ *)ptr)->lock == NULL) {
1863 reallock = (int)ptr;
1865 reallock = (int)(((struct ___Object___ *)ptr)->lock);
1867 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
1869 if(targetcore == corenum) {
1870 BAMBOO_START_CRITICAL_SECTION_LOCK();
1872 BAMBOO_DEBUGPRINT(0xf001);
1874 // reside on this core
1875 if(!RuntimeHashcontainskey(locktbl, reallock)) {
1876 // no locks for this object, something is wrong
1877 BAMBOO_EXIT(0xa017);
1880 struct LockValue * lockvalue = NULL;
1881 RuntimeHashget(locktbl, reallock, &rwlock_obj);
1882 lockvalue = (struct LockValue *)rwlock_obj;
1885 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
1887 BAMBOO_DEBUGPRINT(0xf000);
1891 // send lock release msg
1892 // for 32 bit machine, the size is always 4 words
1893 send_msg_4(targetcore, 5, 0, (int)ptr, reallock);
1897 // redirected lock request
1898 bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
1901 if(core == corenum) {
1903 lock2require = (int)redirectlock;
1910 targetcore = ((int)redirectlock >> 5) % BAMBOO_TOTALCORE;
1912 if(targetcore == corenum) {
1913 // reside on this core
1914 int deny = processlockrequest(0, (int)redirectlock, (int)ptr, corenum, core, cache);
1919 if(core == corenum) {
1920 if(lockobj == (int)ptr) {
1925 RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
1932 // conflicts on lockresults
1933 BAMBOO_EXIT(0xa018);
1937 // send lock grant/deny request to the root requiring core
1938 // check if there is still some msg on sending
1939 if((!cache) || (cache && !isMsgSending)) {
1940 send_msg_4(core, deny==1?0xa:9, 0, (int)ptr, (int)redirectlock);
1942 cache_msg_4(core, deny==1?0xa:9, 0, (int)ptr, (int)redirectlock);
1947 // redirect the lock request
1948 // for 32 bit machine, the size is always 6 words
1949 if((!cache) || (cache && !isMsgSending)) {
1950 send_msg_6(targetcore, 8, 0, (int)ptr, lock2require, core, corenum);
1952 cache_msg_6(targetcore, 8, 0, (int)ptr, lock2require, core, corenum);
1959 bool getwritelock(void * ptr) {
1962 // for 32 bit machine, the size is always 5 words
1966 if(((struct ___Object___ *)ptr)->lock == NULL) {
1967 lock2require = lockobj;
1969 lock2require = (int)(((struct ___Object___ *)ptr)->lock);
1971 targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
1979 BAMBOO_DEBUGPRINT(0xe551);
1980 BAMBOO_DEBUGPRINT_REG(lockobj);
1981 BAMBOO_DEBUGPRINT_REG(lock2require);
1982 BAMBOO_DEBUGPRINT_REG(targetcore);
1985 if(targetcore == corenum) {
1986 // reside on this core
1988 BAMBOO_START_CRITICAL_SECTION_LOCK();
1990 BAMBOO_DEBUGPRINT(0xf001);
1992 deny = processlockrequest(1, lock2require, (int)ptr, corenum, corenum, false);
1993 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
1995 BAMBOO_DEBUGPRINT(0xf000);
1998 BAMBOO_DEBUGPRINT(0xe555);
1999 BAMBOO_DEBUGPRINT_REG(lockresult);
2005 if(lockobj == (int)ptr) {
2016 // conflicts on lockresults
2017 BAMBOO_EXIT(0xa019);
2022 // send lock request msg
2023 // for 32 bit machine, the size is always 5 words
2024 send_msg_5(targetcore, 2, 1, (int)ptr, lock2require, corenum);
2029 void releasewritelock(void * ptr) {
2032 if(((struct ___Object___ *)ptr)->lock == NULL) {
2033 reallock = (int)ptr;
2035 reallock = (int)(((struct ___Object___ *)ptr)->lock);
2037 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2040 BAMBOO_DEBUGPRINT(0xe661);
2041 BAMBOO_DEBUGPRINT_REG((int)ptr);
2042 BAMBOO_DEBUGPRINT_REG(reallock);
2043 BAMBOO_DEBUGPRINT_REG(targetcore);
2046 if(targetcore == corenum) {
2047 BAMBOO_START_CRITICAL_SECTION_LOCK();
2049 BAMBOO_DEBUGPRINT(0xf001);
2051 // reside on this core
2052 if(!RuntimeHashcontainskey(locktbl, reallock)) {
2053 // no locks for this object, something is wrong
2054 BAMBOO_EXIT(0xa01a);
2057 struct LockValue * lockvalue = NULL;
2058 RuntimeHashget(locktbl, reallock, &rwlock_obj);
2059 lockvalue = (struct LockValue *)rwlock_obj;
2062 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
2064 BAMBOO_DEBUGPRINT(0xf000);
2068 // send lock release msg
2069 // for 32 bit machine, the size is always 4 words
2070 send_msg_4(targetcore, 5, 1, (int)ptr, reallock);
2074 void releasewritelock_r(void * lock, void * redirectlock) {
2076 int reallock = (int)lock;
2077 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2080 BAMBOO_DEBUGPRINT(0xe671);
2081 BAMBOO_DEBUGPRINT_REG((int)lock);
2082 BAMBOO_DEBUGPRINT_REG(reallock);
2083 BAMBOO_DEBUGPRINT_REG(targetcore);
2086 if(targetcore == corenum) {
2087 BAMBOO_START_CRITICAL_SECTION_LOCK();
2089 BAMBOO_DEBUGPRINT(0xf001);
2091 // reside on this core
2092 if(!RuntimeHashcontainskey(locktbl, reallock)) {
2093 // no locks for this object, something is wrong
2094 BAMBOO_EXIT(0xa01b);
2097 struct LockValue * lockvalue = NULL;
2099 BAMBOO_DEBUGPRINT(0xe672);
2101 RuntimeHashget(locktbl, reallock, &rwlock_obj);
2102 lockvalue = (struct LockValue *)rwlock_obj;
2104 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2107 lockvalue->redirectlock = (int)redirectlock;
2109 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2112 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
2114 BAMBOO_DEBUGPRINT(0xf000);
2118 // send lock release with redirect info msg
2119 // for 32 bit machine, the size is always 4 words
2120 send_msg_4(targetcore, 0xb, 1, (int)lock, (int)redirectlock);
2124 bool getwritelock_I(void * ptr) {
2127 if(((struct ___Object___ *)ptr)->lock == NULL) {
2128 lock2require = lockobj;
2130 lock2require = (int)(((struct ___Object___ *)ptr)->lock);
2132 targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
2140 BAMBOO_DEBUGPRINT(0xe561);
2141 BAMBOO_DEBUGPRINT_REG(lockobj);
2142 BAMBOO_DEBUGPRINT_REG(lock2require);
2143 BAMBOO_DEBUGPRINT_REG(targetcore);
2146 if(targetcore == corenum) {
2147 // reside on this core
2148 int deny = processlockrequest(1, (int)lock2require, (int)ptr, corenum, corenum, false);
2153 if(lockobj == (int)ptr) {
2157 BAMBOO_DEBUGPRINT(0);
2162 BAMBOO_DEBUGPRINT(1);
2170 // conflicts on lockresults
2171 BAMBOO_EXIT(0xa01c);
2176 // send lock request msg
2177 // for 32 bit machine, the size is always 5 words
2178 send_msg_5(targetcore, 2, 1, (int)ptr, lock2require, corenum);
2183 // redirected lock request
2184 bool getwritelock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
2187 if(core == corenum) {
2189 lock2require = (int)redirectlock;
2196 targetcore = ((int)redirectlock >> 5) % BAMBOO_TOTALCORE;
2199 BAMBOO_DEBUGPRINT(0xe571);
2200 BAMBOO_DEBUGPRINT_REG((int)ptr);
2201 BAMBOO_DEBUGPRINT_REG((int)redirectlock);
2202 BAMBOO_DEBUGPRINT_REG(core);
2203 BAMBOO_DEBUGPRINT_REG((int)cache);
2204 BAMBOO_DEBUGPRINT_REG(targetcore);
2208 if(targetcore == corenum) {
2209 // reside on this core
2210 int deny = processlockrequest(1, (int)redirectlock, (int)ptr, corenum, core, cache);
2215 if(core == corenum) {
2216 if(lockobj == (int)ptr) {
2221 RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
2228 // conflicts on lockresults
2229 BAMBOO_EXIT(0xa01d);
2233 // send lock grant/deny request to the root requiring core
2234 // check if there is still some msg on sending
2235 if((!cache) || (cache && !isMsgSending)) {
2236 send_msg_4(core, deny==1?0xa:9, 1, (int)ptr, (int)redirectlock);
2238 cache_msg_4(core, deny==1?0xa:9, 1, (int)ptr, (int)redirectlock);
2243 // redirect the lock request
2244 // for 32 bit machine, the size is always 6 words
2245 if((!cache) || (cache && !isMsgSending)) {
2246 send_msg_6(targetcore, 8, 1, (int)ptr, (int)redirectlock, core, corenum);
2248 cache_msg_6(targetcore, 8, 1, (int)ptr, (int)redirectlock, core, corenum);
2254 void releasewritelock_I(void * ptr) {
2257 if(((struct ___Object___ *)ptr)->lock == NULL) {
2258 reallock = (int)ptr;
2260 reallock = (int)(((struct ___Object___ *)ptr)->lock);
2262 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2265 BAMBOO_DEBUGPRINT(0xe681);
2266 BAMBOO_DEBUGPRINT_REG((int)ptr);
2267 BAMBOO_DEBUGPRINT_REG(reallock);
2268 BAMBOO_DEBUGPRINT_REG(targetcore);
2271 if(targetcore == corenum) {
2272 // reside on this core
2273 if(!RuntimeHashcontainskey(locktbl, reallock)) {
2274 // no locks for this object, something is wrong
2275 BAMBOO_EXIT(0xa01e);
2278 struct LockValue * lockvalue = NULL;
2279 RuntimeHashget(locktbl, reallock, &rwlock_obj);
2280 lockvalue = (struct LockValue *)rwlock_obj;
2285 // send lock release msg
2286 // for 32 bit machine, the size is always 4 words
2287 send_msg_4(targetcore, 5, 1, (int)ptr, reallock);
2291 void releasewritelock_I_r(void * lock, void * redirectlock) {
2293 int reallock = (int)lock;
2294 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2297 BAMBOO_DEBUGPRINT(0xe691);
2298 BAMBOO_DEBUGPRINT_REG((int)lock);
2299 BAMBOO_DEBUGPRINT_REG(reallock);
2300 BAMBOO_DEBUGPRINT_REG(targetcore);
2303 if(targetcore == corenum) {
2304 // reside on this core
2305 if(!RuntimeHashcontainskey(locktbl, reallock)) {
2306 // no locks for this object, something is wrong
2307 BAMBOO_EXIT(0xa01f);
2310 struct LockValue * lockvalue = NULL;
2312 BAMBOO_DEBUGPRINT(0xe692);
2314 RuntimeHashget(locktbl, reallock, &rwlock_obj);
2315 lockvalue = (struct LockValue *)rwlock_obj;
2317 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2320 lockvalue->redirectlock = (int)redirectlock;
2322 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2327 // send lock release msg
2328 // for 32 bit machine, the size is always 4 words
2329 send_msg_4(targetcore, 0xb, 1, (int)lock, (int)redirectlock);
2333 int enqueuetasks(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr, int * enterflags, int numenterflags) {
2334 void * taskpointerarray[MAXTASKPARAMS];
2336 //int numparams=parameter->task->numParameters;
2337 int numiterators=parameter->task->numTotal-1;
2342 struct taskdescriptor * task=parameter->task;
2344 //this add the object to parameterwrapper
2345 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags, numenterflags, enterflags==NULL);
2347 /* Add enqueued object to parameter vector */
2348 taskpointerarray[parameter->slot]=ptr;
2350 /* Reset iterators */
2351 for(j=0; j<numiterators; j++) {
2352 toiReset(¶meter->iterators[j]);
2355 /* Find initial state */
2356 for(j=0; j<numiterators; j++) {
2358 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2359 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2361 /* Need to backtrack */
2362 toiReset(¶meter->iterators[j]);
2366 /* Nothing to enqueue */
2372 /* Enqueue current state */
2374 struct taskparamdescriptor *tpd=RUNMALLOC(sizeof(struct taskparamdescriptor));
2376 tpd->numParameters=numiterators+1;
2377 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
2379 for(j=0; j<=numiterators; j++) {
2380 tpd->parameterArray[j]=taskpointerarray[j]; //store the actual parameters
2383 if ((/*!gencontains(failedtasks, tpd)&&*/ !gencontains(activetasks,tpd))) {
2384 genputtable(activetasks, tpd, tpd);
2386 RUNFREE(tpd->parameterArray);
2390 /* This loop iterates to the next parameter combination */
2391 if (numiterators==0)
2394 for(j=numiterators-1; j<numiterators; j++) {
2396 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2397 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2399 /* Need to backtrack */
2400 toiReset(¶meter->iterators[j]);
2404 /* Nothing more to enqueue */
2412 int enqueuetasks_I(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr, int * enterflags, int numenterflags) {
2413 void * taskpointerarray[MAXTASKPARAMS];
2415 //int numparams=parameter->task->numParameters;
2416 int numiterators=parameter->task->numTotal-1;
2421 struct taskdescriptor * task=parameter->task;
2423 //this add the object to parameterwrapper
2424 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags, numenterflags, enterflags==NULL);
2426 /* Add enqueued object to parameter vector */
2427 taskpointerarray[parameter->slot]=ptr;
2429 /* Reset iterators */
2430 for(j=0; j<numiterators; j++) {
2431 toiReset(¶meter->iterators[j]);
2434 /* Find initial state */
2435 for(j=0; j<numiterators; j++) {
2437 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2438 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2440 /* Need to backtrack */
2441 toiReset(¶meter->iterators[j]);
2445 /* Nothing to enqueue */
2451 /* Enqueue current state */
2453 struct taskparamdescriptor *tpd=RUNMALLOC_I(sizeof(struct taskparamdescriptor));
2455 tpd->numParameters=numiterators+1;
2456 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
2458 for(j=0; j<=numiterators; j++) {
2459 tpd->parameterArray[j]=taskpointerarray[j]; //store the actual parameters
2462 if ((/*!gencontains(failedtasks, tpd)&&*/ !gencontains(activetasks,tpd))) {
2463 genputtable_I(activetasks, tpd, tpd);
2465 RUNFREE(tpd->parameterArray);
2469 /* This loop iterates to the next parameter combination */
2470 if (numiterators==0)
2473 for(j=numiterators-1; j<numiterators; j++) {
2475 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2476 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2478 /* Need to backtrack */
2479 toiReset(¶meter->iterators[j]);
2483 /* Nothing more to enqueue */
2491 /* Handler for signals. The signals catch null pointer errors and
2492 arithmatic errors. */
2494 void myhandler(int sig, siginfo_t *info, void *uap) {
2497 printf("sig=%d\n",sig);
2500 sigemptyset(&toclear);
2501 sigaddset(&toclear, sig);
2502 sigprocmask(SIG_UNBLOCK, &toclear,NULL);
2503 longjmp(error_handler,1);
2510 struct RuntimeHash *fdtoobject;
2512 void addreadfd(int fd) {
2515 FD_SET(fd, &readfds);
2518 void removereadfd(int fd) {
2519 FD_CLR(fd, &readfds);
2520 if (maxreadfd==(fd+1)) {
2522 while(maxreadfd>0&&!FD_ISSET(maxreadfd-1, &readfds))
2534 int containstag(struct ___Object___ *ptr, struct ___TagDescriptor___ *tag);
2536 void executetasks() {
2537 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
2540 struct ___Object___ * tmpparam = NULL;
2541 struct parameterdescriptor * pd=NULL;
2542 struct parameterwrapper *pw=NULL;
2547 struct LockValue * locks[MAXTASKPARAMS];
2553 for(j = 0; j < MAXTASKPARAMS; j++) {
2554 locks[j] = (struct LockValue *)(RUNMALLOC(sizeof(struct LockValue)));
2555 locks[j]->redirectlock = 0;
2556 locks[j]->value = 0;
2560 /* Set up signal handlers */
2561 struct sigaction sig;
2562 sig.sa_sigaction=&myhandler;
2563 sig.sa_flags=SA_SIGINFO;
2564 sigemptyset(&sig.sa_mask);
2566 /* Catch bus errors, segmentation faults, and floating point exceptions*/
2567 sigaction(SIGBUS,&sig,0);
2568 sigaction(SIGSEGV,&sig,0);
2569 sigaction(SIGFPE,&sig,0);
2570 sigaction(SIGPIPE,&sig,0);
2571 #endif // #if 0: non-multicore
2581 fdtoobject=allocateRuntimeHash(100);
2585 /* Map first block of memory to protected, anonymous page */
2586 mmap(0, 0x1000, 0, MAP_SHARED|MAP_FIXED|MAP_ANON, -1, 0);
2591 while(hashsize(activetasks)>0) {
2593 while((hashsize(activetasks)>0)||(maxreadfd>0)) {
2597 BAMBOO_DEBUGPRINT(0xe990);
2600 /* Check if any filedescriptors have IO pending */
2603 struct timeval timeout={0,0};
2607 numselect=select(maxreadfd, &tmpreadfds, NULL, NULL, &timeout);
2609 /* Process ready fd's */
2611 for(fd=0; fd<maxreadfd; fd++) {
2612 if (FD_ISSET(fd, &tmpreadfds)) {
2613 /* Set ready flag on object */
2615 // printf("Setting fd %d\n",fd);
2616 if (RuntimeHashget(fdtoobject, fd,(int *) &objptr)) {
2617 if(intflagorand(objptr,1,0xFFFFFFFF)) { /* Set the first flag to 1 */
2618 enqueueObject(objptr, NULL, 0);
2627 /* See if there are any active tasks */
2628 if (hashsize(activetasks)>0) {
2631 profileTaskStart("tpd checking");
2634 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
2635 genfreekey(activetasks, currtpd);
2637 numparams=currtpd->task->numParameters;
2638 numtotal=currtpd->task->numTotal;
2640 // clear the lockRedirectTbl (TODO, this table should be empty after all locks are released)
2641 // get all required locks
2643 // check which locks are needed
2644 for(i = 0; i < numparams; i++) {
2645 void * param = currtpd->parameterArray[i];
2649 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
2651 taskpointerarray[i+OFFSET]=param;
2654 if(((struct ___Object___ *)param)->lock == NULL) {
2655 tmplock = (int)param;
2657 tmplock = (int)(((struct ___Object___ *)param)->lock);
2659 // insert into the locks array
2660 for(j = 0; j < locklen; j++) {
2661 if(locks[j]->value == tmplock) {
2664 } else if(locks[j]->value > tmplock) {
2671 locks[h]->redirectlock = locks[h-1]->redirectlock;
2672 locks[h]->value = locks[h-1]->value;
2674 locks[j]->value = tmplock;
2675 locks[j]->redirectlock = (int)param;
2679 // grab these required locks
2681 BAMBOO_DEBUGPRINT(0xe991);
2683 for(i = 0; i < locklen; i++) {
2684 int * lock = (int *)(locks[i]->redirectlock);
2686 // require locks for this parameter if it is not a startup object
2688 BAMBOO_DEBUGPRINT_REG((int)lock);
2689 BAMBOO_DEBUGPRINT_REG((int)(locks[i]->value));
2692 BAMBOO_START_CRITICAL_SECTION();
2694 BAMBOO_DEBUGPRINT(0xf001);
2697 //isInterrupt = false;
2700 BAMBOO_WAITING_FOR_LOCK();
2704 while(BAMBOO_WAITING_FOR_LOCK() != -1) {
2708 grount = lockresult;
2718 //isInterrupt = true;
2720 BAMBOO_CLOSE_CRITICAL_SECTION();
2722 BAMBOO_DEBUGPRINT(0xf000);
2728 BAMBOO_DEBUGPRINT(0xe992);
2730 // can not get the lock, try later
2731 // releas all grabbed locks for previous parameters
2732 for(j = 0; j < i; ++j) {
2733 lock = (int*)(locks[j]->redirectlock);
2734 releasewritelock(lock);
2736 genputtable(activetasks, currtpd, currtpd);
2737 if(hashsize(activetasks) == 1) {
2738 // only one task right now, wait a little while before next try
2744 // fail, set the end of the checkTaskInfo
2752 BAMBOO_DEBUGPRINT(0xe993);
2754 /* Make sure that the parameters are still in the queues */
2755 for(i=0; i<numparams; i++) {
2756 void * parameter=currtpd->parameterArray[i];
2760 BAMBOO_CACHE_FLUSH_RANGE((int)parameter, classsize[((struct ___Object___ *)parameter)->type]);
2762 BAMBOO_START_CRITICAL_SECTION_LOCK();
2764 BAMBOO_DEBUGPRINT(0xf001);
2766 if(RuntimeHashcontainskey(objRedirectLockTbl, (int)parameter)) {
2767 int redirectlock_r = 0;
2768 RuntimeHashget(objRedirectLockTbl, (int)parameter, &redirectlock_r);
2769 ((struct ___Object___ *)parameter)->lock = redirectlock_r;
2770 RuntimeHashremovekey(objRedirectLockTbl, (int)parameter);
2772 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
2774 BAMBOO_DEBUGPRINT(0xf000);
2778 tmpparam = (struct ___Object___ *)parameter;
2779 pd=currtpd->task->descriptorarray[i];
2780 pw=(struct parameterwrapper *) pd->queue;
2781 /* Check that object is still in queue */
2783 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
2785 BAMBOO_DEBUGPRINT(0xe994);
2787 // release grabbed locks
2788 for(j = 0; j < locklen; ++j) {
2789 int * lock = (int *)(locks[j]->redirectlock);
2790 releasewritelock(lock);
2792 RUNFREE(currtpd->parameterArray);
2797 /* Check if the object's flags still meets requirements */
2801 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
2802 andmask=pw->intarray[tmpi*2];
2803 checkmask=pw->intarray[tmpi*2+1];
2804 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
2810 // flags are never suitable
2811 // remove this obj from the queue
2813 int UNUSED, UNUSED2;
2816 BAMBOO_DEBUGPRINT(0xe995);
2818 ObjectHashget(pw->objectset, (int) parameter, (int *) &next, (int *) &enterflags, &UNUSED, &UNUSED2);
2819 ObjectHashremove(pw->objectset, (int)parameter);
2820 if (enterflags!=NULL)
2821 RUNFREE(enterflags);
2822 // release grabbed locks
2823 for(j = 0; j < locklen; ++j) {
2824 int * lock = (int *)(locks[j]->redirectlock);
2825 releasewritelock(lock);
2827 RUNFREE(currtpd->parameterArray);
2830 // fail, set the end of the checkTaskInfo
2838 /* Check that object still has necessary tags */
2839 for(j=0; j<pd->numbertags; j++) {
2840 int slotid=pd->tagarray[2*j]+numparams;
2841 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
2842 if (!containstag(parameter, tagd)) {
2844 BAMBOO_DEBUGPRINT(0xe996);
2847 // release grabbed locks
2849 for(tmpj = 0; tmpj < locklen; ++tmpj) {
2850 int * lock = (int *)(locks[tmpj]->redirectlock);
2851 releasewritelock(lock);
2854 RUNFREE(currtpd->parameterArray);
2860 taskpointerarray[i+OFFSET]=parameter;
2863 for(; i<numtotal; i++) {
2864 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
2870 /* Checkpoint the state */
2871 forward=allocateRuntimeHash(100);
2872 reverse=allocateRuntimeHash(100);
2873 //void ** checkpoint=makecheckpoint(currtpd->task->numParameters, currtpd->parameterArray, forward, reverse);
2875 #endif // #if 0: for recovery
2877 if (x=setjmp(error_handler)) {
2882 printf("Fatal Error=%d, Recovering!\n",x);
2886 genputtable(failedtasks,currtpd,currtpd);
2887 //restorecheckpoint(currtpd->task->numParameters, currtpd->parameterArray, checkpoint, forward, reverse);
2889 freeRuntimeHash(forward);
2890 freeRuntimeHash(reverse);
2894 #endif // #if 0: for recovery
2895 BAMBOO_DEBUGPRINT_REG(x);
2896 BAMBOO_EXIT(0xa020);
2900 if (injectfailures) {
2901 if ((((double)random())/RAND_MAX)<failurechance) {
2902 printf("\nINJECTING TASK FAILURE to %s\n", currtpd->task->name);
2903 longjmp(error_handler,10);
2906 #endif // #if 0: for recovery
2907 /* Actually call task */
2910 ((int *)taskpointerarray)[0]=currtpd->numParameters;
2911 taskpointerarray[1]=NULL;
2913 #endif // #if 0: for garbage collection
2916 // check finish, set the end of the checkTaskInfo
2918 profileTaskStart(currtpd->task->name);
2923 printf("ENTER %s count=%d\n",currtpd->task->name, (instaccum-instructioncount));
2925 ((void(*) (void **))currtpd->task->taskptr)(taskpointerarray);
2927 printf("EXIT %s count=%d\n",currtpd->task->name, (instaccum-instructioncount));
2931 BAMBOO_DEBUGPRINT(0xe997);
2933 ((void(*) (void **))currtpd->task->taskptr)(taskpointerarray);
2936 // task finish, set the end of the checkTaskInfo
2938 // new a PostTaskInfo for the post-task execution
2939 profileTaskStart("post task execution");
2942 BAMBOO_DEBUGPRINT(0xe998);
2943 BAMBOO_DEBUGPRINT_REG(islock);
2948 BAMBOO_DEBUGPRINT(0xe999);
2950 for(i = 0; i < locklen; ++i) {
2951 void * ptr = (void *)(locks[i]->redirectlock);
2952 int * lock = (int *)(locks[i]->value);
2954 BAMBOO_DEBUGPRINT_REG((int)ptr);
2955 BAMBOO_DEBUGPRINT_REG((int)lock);
2957 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
2959 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
2960 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
2961 releasewritelock_r(lock, (int *)redirectlock);
2963 releasewritelock(ptr);
2969 // post task execution finish, set the end of the postTaskInfo
2974 freeRuntimeHash(forward);
2975 freeRuntimeHash(reverse);
2978 // Free up task parameter descriptor
2979 RUNFREE(currtpd->parameterArray);
2986 BAMBOO_DEBUGPRINT(0xe99a);
2995 BAMBOO_DEBUGPRINT(0xe99b);
2999 /* This function processes an objects tags */
3000 void processtags(struct parameterdescriptor *pd, int index, struct parameterwrapper *parameter, int * iteratorcount, int *statusarray, int numparams) {
3003 for(i=0; i<pd->numbertags; i++) {
3004 int slotid=pd->tagarray[2*i];
3005 int tagid=pd->tagarray[2*i+1];
3007 if (statusarray[slotid+numparams]==0) {
3008 parameter->iterators[*iteratorcount].istag=1;
3009 parameter->iterators[*iteratorcount].tagid=tagid;
3010 parameter->iterators[*iteratorcount].slot=slotid+numparams;
3011 parameter->iterators[*iteratorcount].tagobjectslot=index;
3012 statusarray[slotid+numparams]=1;
3019 void processobject(struct parameterwrapper *parameter, int index, struct parameterdescriptor *pd, int *iteratorcount, int * statusarray, int numparams) {
3022 struct ObjectHash * objectset=((struct parameterwrapper *)pd->queue)->objectset;
3024 parameter->iterators[*iteratorcount].istag=0;
3025 parameter->iterators[*iteratorcount].slot=index;
3026 parameter->iterators[*iteratorcount].objectset=objectset;
3027 statusarray[index]=1;
3029 for(i=0; i<pd->numbertags; i++) {
3030 int slotid=pd->tagarray[2*i];
3031 //int tagid=pd->tagarray[2*i+1];
3032 if (statusarray[slotid+numparams]!=0) {
3033 /* This tag has already been enqueued, use it to narrow search */
3034 parameter->iterators[*iteratorcount].tagbindings[tagcount]=slotid+numparams;
3038 parameter->iterators[*iteratorcount].numtags=tagcount;
3043 /* This function builds the iterators for a task & parameter */
3045 void builditerators(struct taskdescriptor * task, int index, struct parameterwrapper * parameter) {
3046 int statusarray[MAXTASKPARAMS];
3048 int numparams=task->numParameters;
3049 int iteratorcount=0;
3050 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
3052 statusarray[index]=1; /* Initial parameter */
3053 /* Process tags for initial iterator */
3055 processtags(task->descriptorarray[index], index, parameter, &iteratorcount, statusarray, numparams);
3059 /* Check for objects with existing tags */
3060 for(i=0; i<numparams; i++) {
3061 if (statusarray[i]==0) {
3062 struct parameterdescriptor *pd=task->descriptorarray[i];
3064 for(j=0; j<pd->numbertags; j++) {
3065 int slotid=pd->tagarray[2*j];
3066 if(statusarray[slotid+numparams]!=0) {
3067 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3068 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3075 /* Next do objects w/ unbound tags*/
3077 for(i=0; i<numparams; i++) {
3078 if (statusarray[i]==0) {
3079 struct parameterdescriptor *pd=task->descriptorarray[i];
3080 if (pd->numbertags>0) {
3081 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3082 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3088 /* Nothing with a tag enqueued */
3090 for(i=0; i<numparams; i++) {
3091 if (statusarray[i]==0) {
3092 struct parameterdescriptor *pd=task->descriptorarray[i];
3093 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3094 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3107 if(corenum > NUMCORES - 1) {
3110 for(i=0; i<numtasks[corenum]; i++) {
3111 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3113 printf("%s\n", task->name);
3115 for(j=0; j<task->numParameters; j++) {
3116 struct parameterdescriptor *param=task->descriptorarray[j];
3117 struct parameterwrapper *parameter=param->queue;
3118 struct ObjectHash * set=parameter->objectset;
3119 struct ObjectIterator objit;
3121 printf(" Parameter %d\n", j);
3123 ObjectHashiterator(set, &objit);
3124 while(ObjhasNext(&objit)) {
3125 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
3126 struct ___Object___ * tagptr=obj->___tags___;
3127 int nonfailed=Objdata4(&objit);
3128 int numflags=Objdata3(&objit);
3129 int flags=Objdata2(&objit);
3132 printf(" Contains %lx\n", obj);
3133 printf(" flag=%d\n", obj->flag);
3136 } else if (tagptr->type==TAGTYPE) {
3138 printf(" tag=%lx\n",tagptr);
3144 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
3145 for(; tagindex<ao->___cachedCode___; tagindex++) {
3147 printf(" tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*, tagindex));
3159 /* This function processes the task information to create queues for
3160 each parameter type. */
3162 void processtasks() {
3164 if(corenum > NUMCORES - 1) {
3167 for(i=0; i<numtasks[corenum]; i++) {
3168 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3171 /* Build objectsets */
3172 for(j=0; j<task->numParameters; j++) {
3173 struct parameterdescriptor *param=task->descriptorarray[j];
3174 struct parameterwrapper *parameter=param->queue;
3175 parameter->objectset=allocateObjectHash(10);
3176 parameter->task=task;
3179 /* Build iterators for parameters */
3180 for(j=0; j<task->numParameters; j++) {
3181 struct parameterdescriptor *param=task->descriptorarray[j];
3182 struct parameterwrapper *parameter=param->queue;
3183 builditerators(task, j, parameter);
3188 void toiReset(struct tagobjectiterator * it) {
3191 } else if (it->numtags>0) {
3194 ObjectHashiterator(it->objectset, &it->it);
3198 int toiHasNext(struct tagobjectiterator *it, void ** objectarray OPTARG(int * failed)) {
3201 /* Get object with tags */
3202 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3203 struct ___Object___ *tagptr=obj->___tags___;
3204 if (tagptr->type==TAGTYPE) {
3205 if ((it->tagobjindex==0)&& /* First object */
3206 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
3211 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3212 int tagindex=it->tagobjindex;
3213 for(; tagindex<ao->___cachedCode___; tagindex++) {
3214 struct ___TagDescriptor___ *td=ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
3215 if (td->flag==it->tagid) {
3216 it->tagobjindex=tagindex; /* Found right type of tag */
3222 } else if (it->numtags>0) {
3223 /* Use tags to locate appropriate objects */
3224 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3225 struct ___Object___ *objptr=tag->flagptr;
3227 if (objptr->type!=OBJECTARRAYTYPE) {
3228 if (it->tagobjindex>0)
3230 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3232 for(i=1; i<it->numtags; i++) {
3233 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3234 if (!containstag(objptr,tag2))
3239 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3242 for(tagindex=it->tagobjindex; tagindex<ao->___cachedCode___; tagindex++) {
3243 struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
3244 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3246 for(i=1; i<it->numtags; i++) {
3247 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3248 if (!containstag(objptr,tag2))
3251 it->tagobjindex=tagindex;
3256 it->tagobjindex=tagindex;
3260 return ObjhasNext(&it->it);
3264 int containstag(struct ___Object___ *ptr, struct ___TagDescriptor___ *tag) {
3266 struct ___Object___ * objptr=tag->flagptr;
3267 if (objptr->type==OBJECTARRAYTYPE) {
3268 struct ArrayObject *ao=(struct ArrayObject *)objptr;
3269 for(j=0; j<ao->___cachedCode___; j++) {
3270 if (ptr==ARRAYGET(ao, struct ___Object___*, j))
3278 void toiNext(struct tagobjectiterator *it, void ** objectarray OPTARG(int * failed)) {
3279 /* hasNext has all of the intelligence */
3282 /* Get object with tags */
3283 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3284 struct ___Object___ *tagptr=obj->___tags___;
3285 if (tagptr->type==TAGTYPE) {
3287 objectarray[it->slot]=tagptr;
3289 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3290 objectarray[it->slot]=ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
3292 } else if (it->numtags>0) {
3293 /* Use tags to locate appropriate objects */
3294 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3295 struct ___Object___ *objptr=tag->flagptr;
3296 if (objptr->type!=OBJECTARRAYTYPE) {
3298 objectarray[it->slot]=objptr;
3300 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3301 objectarray[it->slot]=ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
3304 /* Iterate object */
3305 objectarray[it->slot]=(void *)Objkey(&it->it);