3 #include "multicoreruntime.h"
4 #include "runtime_arch.h"
6 extern int injectfailures;
7 extern float failurechance;
12 void * curr_heapbase=0;
13 void * curr_heaptop=0;
17 #include "instrument.h"
19 #endif // if 0: for recovery
21 // data structures for task invocation
22 struct genhashtable * activetasks;
23 struct genhashtable * failedtasks;
24 struct taskparamdescriptor * currtpd;
26 struct RuntimeHash * forward;
27 struct RuntimeHash * reverse;
28 #endif // if 0: for recovery
31 void outputProfileData();
34 bool getreadlock(void* ptr);
35 void releasereadlock(void* ptr);
36 bool getwritelock(void* ptr);
37 void releasewritelock(void* ptr);
38 void releasewritelock_r(void * lock, void * redirectlock);
39 inline void run(void * arg);
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 //isInterrupt = false;
221 BAMBOO_DEBUGPRINT(0xeee1);
225 objitem = getTail(&objqueue);
226 objInfo = (struct transObjInfo *)objitem->objectptr;
227 obj = objInfo->objptr;
229 BAMBOO_DEBUGPRINT_REG((int)obj);
231 // grab lock and flush the obj
235 BAMBOO_WAITING_FOR_LOCK();
239 BAMBOO_DEBUGPRINT_REG(grount);
253 BAMBOO_CACHE_FLUSH_RANGE((int)obj, classsize[((struct ___Object___ *)obj)->type]);
255 // enqueue the object
256 for(k = 0; k < objInfo->length; ++k) {
257 int taskindex = objInfo->queues[2 * k];
258 int paramindex = objInfo->queues[2 * k + 1];
259 struct parameterwrapper ** queues = &(paramqueues[corenum][taskindex][paramindex]);
261 BAMBOO_DEBUGPRINT_REG(taskindex);
262 BAMBOO_DEBUGPRINT_REG(paramindex);
264 enqueueObject_I(obj, queues, 1);
266 removeItem(&objqueue, objitem);
267 releasewritelock_I(obj);
268 RUNFREE(objInfo->queues);
272 // put it at the end of the queue
273 // and try to execute active tasks already enqueued first
274 removeItem(&objqueue, objitem);
275 addNewItem_I(&objqueue, objInfo);
277 //isInterrupt = true;
279 BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE();
282 BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE();
291 BAMBOO_DEBUGPRINT(0xee02);
296 if(STARTUPCORE == corenum) {
299 BAMBOO_DEBUGPRINT(0xee03);
304 (waitconfirm && (numconfirm == 0))) {
306 BAMBOO_DEBUGPRINT(0xee04);
308 BAMBOO_START_CRITICAL_SECTION_STATUS();
309 corestatus[corenum] = 0;
310 numsendobjs[corenum] = self_numsendobjs;
311 numreceiveobjs[corenum] = self_numreceiveobjs;
312 // check the status of all cores
315 BAMBOO_DEBUGPRINT_REG(NUMCORES);
317 for(i = 0; i < NUMCORES; ++i) {
319 BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
321 if(corestatus[i] != 0) {
327 // check if the sum of send objs and receive obj are the same
328 // yes->check if the info is the latest; no->go on executing
330 for(i = 0; i < NUMCORES; ++i) {
331 sumsendobj += numsendobjs[i];
333 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
336 for(i = 0; i < NUMCORES; ++i) {
337 sumsendobj -= numreceiveobjs[i];
339 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
342 if(0 == sumsendobj) {
344 // the first time found all cores stall
345 // send out status confirm msg to all other cores
346 // reset the corestatus array too
348 BAMBOO_DEBUGPRINT(0xee05);
350 corestatus[corenum] = 1;
351 for(i = 1; i < NUMCORES; ++i) {
353 // send status confirm msg to core i
357 numconfirm = NUMCORES - 1;
359 // all the core status info are the latest
360 // terminate; for profiling mode, send request to all
361 // other cores to pour out profiling data
363 BAMBOO_DEBUGPRINT(0xee06);
367 totalexetime = BAMBOO_GET_EXE_TIME();
369 BAMBOO_DEBUGPRINT(0xbbbbbbbb);
370 BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME());
372 // profile mode, send msgs to other cores to request pouring
373 // out progiling data
375 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
376 for(i = 1; i < NUMCORES; ++i) {
377 // send profile request msg to core i
378 send_msg_2(i, 6, totalexetime);
380 // pour profiling data on startup core
383 BAMBOO_START_CRITICAL_SECTION_STATUS();
384 profilestatus[corenum] = 0;
385 // check the status of all cores
388 BAMBOO_DEBUGPRINT_REG(NUMCORES);
390 for(i = 0; i < NUMCORES; ++i) {
392 BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
394 if(profilestatus[i] != 0) {
401 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
409 terminate(); // All done.
412 // still some objects on the fly on the network
413 // reset the waitconfirm and numconfirm
415 BAMBOO_DEBUGPRINT(0xee07);
421 // not all cores are stall, keep on waiting
423 BAMBOO_DEBUGPRINT(0xee08);
428 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
433 BAMBOO_DEBUGPRINT(0xee09);
439 // wait for some time
442 BAMBOO_DEBUGPRINT(0xee0a);
448 // send StallMsg to startup core
450 BAMBOO_DEBUGPRINT(0xee0b);
453 send_msg_4(STARTUPCORE, 1, corenum, self_numsendobjs, self_numreceiveobjs);
465 BAMBOO_DEBUGPRINT(0xee0c);
471 } // right-bracket for if-else of line 220
475 void createstartupobject(int argc, char ** argv) {
478 /* Allocate startup object */
481 struct ___StartupObject___ *startupobject=(struct ___StartupObject___*) allocate_new(NULL, STARTUPTYPE);
482 struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);
484 struct ___StartupObject___ *startupobject=(struct ___StartupObject___*) allocate_new(STARTUPTYPE);
485 struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);
487 #endif // #if 0: for garbage collection
488 struct ___StartupObject___ *startupobject=(struct ___StartupObject___*) allocate_new(STARTUPTYPE);
489 struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);
490 /* Build array of strings */
491 startupobject->___parameters___=stringarray;
492 for(i=1; i<argc; i++) {
493 int length=strlen(argv[i]);
496 struct ___String___ *newstring=NewString(NULL, argv[i],length);
498 struct ___String___ *newstring=NewString(argv[i],length);
500 #endif // #if 0: for garbage collection
501 struct ___String___ *newstring=NewString(argv[i],length);
502 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=newstring;
505 startupobject->isolate = 1;
506 startupobject->version = 0;
507 startupobject->lock = NULL;
509 /* Set initialized flag for startup object */
510 flagorandinit(startupobject,1,0xFFFFFFFF);
511 enqueueObject(startupobject, NULL, 0);
513 BAMBOO_CACHE_FLUSH_ALL();
517 int hashCodetpd(struct taskparamdescriptor *ftd) {
518 int hash=(int)ftd->task;
520 for(i=0; i<ftd->numParameters; i++) {
521 hash^=(int)ftd->parameterArray[i];
526 int comparetpd(struct taskparamdescriptor *ftd1, struct taskparamdescriptor *ftd2) {
528 if (ftd1->task!=ftd2->task)
530 for(i=0; i<ftd1->numParameters; i++)
531 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
536 /* This function sets a tag. */
539 void tagset(void *ptr, struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
541 void tagset(struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
543 #endif // #if 0: for garbage collection
544 void tagset(struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
545 struct ArrayObject * ao=NULL;
546 struct ___Object___ * tagptr=obj->___tags___;
548 obj->___tags___=(struct ___Object___ *)tagd;
550 /* Have to check if it is already set */
551 if (tagptr->type==TAGTYPE) {
552 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
558 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
559 struct ArrayObject * ao=allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
560 obj=(struct ___Object___ *)ptrarray[2];
561 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
562 td=(struct ___TagDescriptor___ *) obj->___tags___;
564 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
566 #endif // #if 0: for garbage collection
567 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
569 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
570 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
571 obj->___tags___=(struct ___Object___ *) ao;
572 ao->___cachedCode___=2;
576 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
577 for(i=0; i<ao->___cachedCode___; i++) {
578 struct ___TagDescriptor___ * td=ARRAYGET(ao, struct ___TagDescriptor___*, i);
583 if (ao->___cachedCode___<ao->___length___) {
584 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
585 ao->___cachedCode___++;
589 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
590 struct ArrayObject * aonew=allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
591 obj=(struct ___Object___ *)ptrarray[2];
592 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
593 ao=(struct ArrayObject *)obj->___tags___;
595 struct ArrayObject * aonew=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
597 #endif // #if 0: for garbage collection
598 struct ArrayObject * aonew=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
600 aonew->___cachedCode___=ao->___length___+1;
601 for(i=0; i<ao->___length___; i++) {
602 ARRAYSET(aonew, struct ___TagDescriptor___*, i, ARRAYGET(ao, struct ___TagDescriptor___*, i));
604 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
610 struct ___Object___ * tagset=tagd->flagptr;
613 } else if (tagset->type!=OBJECTARRAYTYPE) {
616 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
617 struct ArrayObject * ao=allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
618 obj=(struct ___Object___ *)ptrarray[2];
619 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
621 struct ArrayObject * ao=allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
623 #endif // #if 0: for garbage collection
624 struct ArrayObject * ao=allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
625 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
626 ARRAYSET(ao, struct ___Object___ *, 1, obj);
627 ao->___cachedCode___=2;
628 tagd->flagptr=(struct ___Object___ *)ao;
630 struct ArrayObject *ao=(struct ArrayObject *) tagset;
631 if (ao->___cachedCode___<ao->___length___) {
632 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
637 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
638 struct ArrayObject * aonew=allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
639 obj=(struct ___Object___ *)ptrarray[2];
640 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
641 ao=(struct ArrayObject *)tagd->flagptr;
643 struct ArrayObject * aonew=allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
645 #endif // #if 0: for garbage collection
646 struct ArrayObject * aonew=allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
647 aonew->___cachedCode___=ao->___cachedCode___+1;
648 for(i=0; i<ao->___length___; i++) {
649 ARRAYSET(aonew, struct ___Object___*, i, ARRAYGET(ao, struct ___Object___*, i));
651 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
652 tagd->flagptr=(struct ___Object___ *) aonew;
658 /* This function clears a tag. */
661 void tagclear(void *ptr, struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
663 void tagclear(struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
665 #endif // #if 0: for garbage collection
666 void tagclear(struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) {
667 /* We'll assume that tag is alway there.
668 Need to statically check for this of course. */
669 struct ___Object___ * tagptr=obj->___tags___;
671 if (tagptr->type==TAGTYPE) {
672 if ((struct ___TagDescriptor___ *)tagptr==tagd)
673 obj->___tags___=NULL;
676 printf("ERROR 1 in tagclear\n");
681 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
683 for(i=0; i<ao->___cachedCode___; i++) {
684 struct ___TagDescriptor___ * td=ARRAYGET(ao, struct ___TagDescriptor___ *, i);
686 ao->___cachedCode___--;
687 if (i<ao->___cachedCode___)
688 ARRAYSET(ao, struct ___TagDescriptor___ *, i, ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
689 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
690 if (ao->___cachedCode___==0)
691 obj->___tags___=NULL;
696 printf("ERROR 2 in tagclear\n");
701 struct ___Object___ *tagset=tagd->flagptr;
702 if (tagset->type!=OBJECTARRAYTYPE) {
707 printf("ERROR 3 in tagclear\n");
712 struct ArrayObject *ao=(struct ArrayObject *) tagset;
714 for(i=0; i<ao->___cachedCode___; i++) {
715 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
717 ao->___cachedCode___--;
718 if (i<ao->___cachedCode___)
719 ARRAYSET(ao, struct ___Object___ *, i, ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
720 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
721 if (ao->___cachedCode___==0)
727 printf("ERROR 4 in tagclear\n");
736 /* This function allocates a new tag. */
738 struct ___TagDescriptor___ * allocate_tag(void *ptr, int index) {
739 struct ___TagDescriptor___ * v=(struct ___TagDescriptor___ *) mygcmalloc((struct garbagelist *) ptr, classsize[TAGTYPE]);
741 struct ___TagDescriptor___ * allocate_tag(int index) {
742 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
744 #endif // #if 0: for garbage collection
745 struct ___TagDescriptor___ * allocate_tag(int index) {
746 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
754 /* This function updates the flag for object ptr. It or's the flag
755 with the or mask and and's it with the andmask. */
757 void flagbody(struct ___Object___ *ptr, int flag, struct parameterwrapper ** queues, int length, bool isnew);
759 int flagcomp(const int *val1, const int *val2) {
760 return (*val1)-(*val2);
763 void flagorand(void * ptr, int ormask, int andmask, struct parameterwrapper ** queues, int length) {
765 int oldflag=((int *)ptr)[1];
766 int flag=ormask|oldflag;
768 flagbody(ptr, flag, queues, length, false);
772 bool intflagorand(void * ptr, int ormask, int andmask) {
774 int oldflag=((int *)ptr)[1];
775 int flag=ormask|oldflag;
777 if (flag==oldflag) /* Don't do anything */
780 flagbody(ptr, flag, NULL, 0, false);
786 void flagorandinit(void * ptr, int ormask, int andmask) {
787 int oldflag=((int *)ptr)[1];
788 int flag=ormask|oldflag;
790 flagbody(ptr,flag,NULL,0,true);
793 void flagbody(struct ___Object___ *ptr, int flag, struct parameterwrapper ** vqueues, int vlength, bool isnew) {
794 struct parameterwrapper * flagptr = NULL;
796 struct parameterwrapper ** queues = vqueues;
797 int length = vlength;
800 int * enterflags = NULL;
801 if((!isnew) && (queues == NULL)) {
802 if(corenum < NUMCORES) {
803 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
804 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
811 /*Remove object from all queues */
812 for(i = 0; i < length; ++i) {
814 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next, (int *) &enterflags, &UNUSED, &UNUSED2);
815 ObjectHashremove(flagptr->objectset, (int)ptr);
816 if (enterflags!=NULL)
821 void enqueueObject(void * vptr, struct parameterwrapper ** vqueues, int vlength) {
822 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
825 struct QueueItem *tmpptr;
826 struct parameterwrapper * parameter=NULL;
829 struct parameterwrapper * prevptr=NULL;
830 struct ___Object___ *tagptr=NULL;
831 struct parameterwrapper ** queues = vqueues;
832 int length = vlength;
833 if(corenum > NUMCORES - 1) {
837 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
838 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
840 tagptr=ptr->___tags___;
842 /* Outer loop iterates through all parameter queues an object of
843 this type could be in. */
844 for(j = 0; j < length; ++j) {
845 parameter = queues[j];
847 if (parameter->numbertags>0) {
849 goto nextloop; //that means the object has no tag but that param needs tag
850 else if(tagptr->type==TAGTYPE) { //one tag
851 struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
852 for(i=0; i<parameter->numbertags; i++) {
853 //slotid is parameter->tagarray[2*i];
854 int tagid=parameter->tagarray[2*i+1];
855 if (tagid!=tagptr->flag)
856 goto nextloop; /*We don't have this tag */
858 } else { //multiple tags
859 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
860 for(i=0; i<parameter->numbertags; i++) {
861 //slotid is parameter->tagarray[2*i];
862 int tagid=parameter->tagarray[2*i+1];
864 for(j=0; j<ao->___cachedCode___; j++) {
865 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
876 for(i=0; i<parameter->numberofterms; i++) {
877 int andmask=parameter->intarray[i*2];
878 int checkmask=parameter->intarray[i*2+1];
879 if ((ptr->flag&andmask)==checkmask) {
880 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
891 void enqueueObject_I(void * vptr, struct parameterwrapper ** vqueues, int vlength) {
892 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
895 struct QueueItem *tmpptr;
896 struct parameterwrapper * parameter=NULL;
899 struct parameterwrapper * prevptr=NULL;
900 struct ___Object___ *tagptr=NULL;
901 struct parameterwrapper ** queues = vqueues;
902 int length = vlength;
903 if(corenum > NUMCORES - 1) {
907 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
908 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
910 tagptr=ptr->___tags___;
912 /* Outer loop iterates through all parameter queues an object of
913 this type could be in. */
914 for(j = 0; j < length; ++j) {
915 parameter = queues[j];
917 if (parameter->numbertags>0) {
919 goto nextloop; //that means the object has no tag but that param needs tag
920 else if(tagptr->type==TAGTYPE) { //one tag
921 struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
922 for(i=0; i<parameter->numbertags; i++) {
923 //slotid is parameter->tagarray[2*i];
924 int tagid=parameter->tagarray[2*i+1];
925 if (tagid!=tagptr->flag)
926 goto nextloop; /*We don't have this tag */
928 } else { //multiple tags
929 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
930 for(i=0; i<parameter->numbertags; i++) {
931 //slotid is parameter->tagarray[2*i];
932 int tagid=parameter->tagarray[2*i+1];
934 for(j=0; j<ao->___cachedCode___; j++) {
935 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
946 for(i=0; i<parameter->numberofterms; i++) {
947 int andmask=parameter->intarray[i*2];
948 int checkmask=parameter->intarray[i*2+1];
949 if ((ptr->flag&andmask)==checkmask) {
950 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
962 int * getAliasLock(void ** ptrs, int length, struct RuntimeHash * tbl) {
964 return (int*)(RUNMALLOC(sizeof(int)));
969 bool redirect = false;
970 int redirectlock = 0;
971 for(; i < length; i++) {
972 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
975 if(ptr->lock == NULL) {
978 lock = (int)(ptr->lock);
981 if(lock != redirectlock) {
982 RuntimeHashadd(tbl, lock, redirectlock);
985 if(RuntimeHashcontainskey(tbl, lock)) {
986 // already redirected
988 RuntimeHashget(tbl, lock, &redirectlock);
989 for(; j < locklen; j++) {
990 if(locks[j] != redirectlock) {
991 RuntimeHashadd(tbl, locks[j], redirectlock);
996 for(j = 0; j < locklen; j++) {
997 if(locks[j] == lock) {
1000 } else if(locks[j] > lock) {
1007 locks[h] = locks[h-1];
1016 return (int *)redirectlock;
1018 return (int *)(locks[0]);
1023 void addAliasLock(void * ptr, int lock) {
1024 struct ___Object___ * obj = (struct ___Object___ *)ptr;
1025 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1026 // originally no alias lock associated or have a different alias lock
1027 // flush it as the new one
1028 obj->lock = (int *)lock;
1034 * type: 0 -- transfer object
1035 * 1 -- transfer stall msg
1040 * // add for profile info
1041 * 6 -- transfer profile output msg
1042 * 7 -- transfer profile output finish msg
1043 * // add for alias lock strategy
1044 * 8 -- redirect lock request
1045 * 9 -- lock grant with redirect info
1046 * a -- lock deny with redirect info
1047 * b -- lock release with redirect info
1048 * c -- status confirm request
1049 * d -- status report msg
1051 * ObjMsg: 0 + size of msg + obj's address + (task index + param index)+
1052 * StallMsg: 1 + corenum + sendobjs + receiveobjs (size is always 4 * sizeof(int))
1053 * LockMsg: 2 + lock type + obj pointer + lock + request core (size is always 5 * sizeof(int))
1054 * 3/4/5 + lock type + obj pointer + lock (size is always 4 * sizeof(int))
1055 * 8 + lock type + obj pointer + redirect lock + root request core + request core (size is always 6 * sizeof(int))
1056 * 9/a + lock type + obj pointer + redirect lock (size is always 4 * sizeof(int))
1057 * b + lock type + lock + redirect lock (size is always 4 * sizeof(int))
1058 * lock type: 0 -- read; 1 -- write
1059 * ProfileMsg: 6 + totalexetime (size is always 2 * sizeof(int))
1060 * 7 + corenum (size is always 2 * sizeof(int))
1061 * StatusMsg: c (size is always 1 * sizeof(int))
1062 * d + status + corenum (size is always 3 * sizeof(int))
1063 * status: 0 -- stall; 1 -- busy
1067 // output the profiling data
1068 void outputProfileData() {
1075 int totaltasktime = 0;
1076 int preprocessingtime = 0;
1077 int objqueuecheckingtime = 0;
1078 int postprocessingtime = 0;
1079 //int interruptiontime = 0;
1081 int averagetasktime = 0;
1084 for(i = 0; i < 50; i++) {
1088 calCoords(corenum, &self_y, &self_x);
1089 c_y = (char)self_y + '0';
1090 c_x = (char)self_x + '0';
1091 strcat(fn, "profile_");
1097 if((fp = fopen(fn, "w+")) == NULL) {
1098 fprintf(stderr, "fopen error\n");
1102 fprintf(fp, "Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
1103 // output task related info
1104 for(i = 0; i < taskInfoIndex; i++) {
1105 TaskInfo* tmpTInfo = taskInfoArray[i];
1106 int duration = tmpTInfo->endTime - tmpTInfo->startTime;
1107 fprintf(fp, "%s, %d, %d, %d, %d", tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime, duration, tmpTInfo->exitIndex);
1108 // summarize new obj info
1109 if(tmpTInfo->newObjs != NULL) {
1110 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
1111 struct RuntimeIterator * iter = NULL;
1112 while(0 == isEmpty(tmpTInfo->newObjs)) {
1113 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
1114 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
1116 RuntimeHashget(nobjtbl, (int)objtype, &num);
1117 RuntimeHashremovekey(nobjtbl, (int)objtype);
1119 RuntimeHashadd(nobjtbl, (int)objtype, num);
1121 RuntimeHashadd(nobjtbl, (int)objtype, 1);
1123 //fprintf(stderr, "new obj!\n");
1126 // output all new obj info
1127 iter = RuntimeHashcreateiterator(nobjtbl);
1128 while(RunhasNext(iter)) {
1129 char * objtype = (char *)Runkey(iter);
1130 int num = Runnext(iter);
1131 fprintf(fp, ", %s, %d", objtype, num);
1135 if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
1136 preprocessingtime += duration;
1137 } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
1138 postprocessingtime += duration;
1139 } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
1140 objqueuecheckingtime += duration;
1142 totaltasktime += duration;
1143 averagetasktime += duration;
1148 if(taskInfoOverflow) {
1149 fprintf(stderr, "Caution: task info overflow!\n");
1152 other = totalexetime - totaltasktime - preprocessingtime - postprocessingtime;
1153 averagetasktime /= tasknum;
1155 fprintf(fp, "\nTotal time: %d\n", totalexetime);
1156 fprintf(fp, "Total task execution time: %d (%f%%)\n", totaltasktime, ((double)totaltasktime/(double)totalexetime)*100);
1157 fprintf(fp, "Total objqueue checking time: %d (%f%%)\n", objqueuecheckingtime, ((double)objqueuecheckingtime/(double)totalexetime)*100);
1158 fprintf(fp, "Total pre-processing time: %d (%f%%)\n", preprocessingtime, ((double)preprocessingtime/(double)totalexetime)*100);
1159 fprintf(fp, "Total post-processing time: %d (%f%%)\n", postprocessingtime, ((double)postprocessingtime/(double)totalexetime)*100);
1160 fprintf(fp, "Other time: %d (%f%%)\n", other, ((double)other/(double)totalexetime)*100);
1162 fprintf(fp, "\nAverage task execution time: %d\n", averagetasktime);
1169 BAMBOO_DEBUGPRINT(0xdddd);
1170 // output task related info
1171 for(i= 0; i < taskInfoIndex; i++) {
1172 TaskInfo* tmpTInfo = taskInfoArray[i];
1173 char* tmpName = tmpTInfo->taskName;
1174 int nameLen = strlen(tmpName);
1175 BAMBOO_DEBUGPRINT(0xddda);
1176 for(j = 0; j < nameLen; j++) {
1177 BAMBOO_DEBUGPRINT_REG(tmpName[j]);
1179 BAMBOO_DEBUGPRINT(0xdddb);
1180 BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
1181 BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
1182 BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
1183 if(tmpTInfo->newObjs != NULL) {
1184 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
1185 struct RuntimeIterator * iter = NULL;
1186 while(0 == isEmpty(tmpTInfo->newObjs)) {
1187 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
1188 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
1190 RuntimeHashget(nobjtbl, (int)objtype, &num);
1191 RuntimeHashremovekey(nobjtbl, (int)objtype);
1193 RuntimeHashadd(nobjtbl, (int)objtype, num);
1195 RuntimeHashadd(nobjtbl, (int)objtype, 1);
1199 // ouput all new obj info
1200 iter = RuntimeHashcreateiterator(nobjtbl);
1201 while(RunhasNext(iter)) {
1202 char * objtype = (char *)Runkey(iter);
1203 int num = Runnext(iter);
1204 int nameLen = strlen(objtype);
1205 BAMBOO_DEBUGPRINT(0xddda);
1206 for(j = 0; j < nameLen; j++) {
1207 BAMBOO_DEBUGPRINT_REG(objtype[j]);
1209 BAMBOO_DEBUGPRINT(0xdddb);
1210 BAMBOO_DEBUGPRINT_REG(num);
1213 BAMBOO_DEBUGPRINT(0xdddc);
1216 if(taskInfoOverflow) {
1217 BAMBOO_DEBUGPRINT(0xefee);
1220 // output interrupt related info
1221 /*for(i = 0; i < interruptInfoIndex; i++) {
1222 InterruptInfo* tmpIInfo = interruptInfoArray[i];
1223 BAMBOO_DEBUGPRINT(0xddde);
1224 BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
1225 BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
1226 BAMBOO_DEBUGPRINT(0xdddf);
1229 if(interruptInfoOverflow) {
1230 BAMBOO_DEBUGPRINT(0xefef);
1233 BAMBOO_DEBUGPRINT(0xeeee);
1237 inline void setTaskExitIndex(int index) {
1238 taskInfoArray[taskInfoIndex]->exitIndex = index;
1241 inline void addNewObjInfo(void * nobj) {
1242 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1243 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1245 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1249 /* this function is to process lock requests.
1250 * can only be invoked in receiveObject() */
1251 // if return -1: the lock request is redirected
1252 // 0: the lock request is approved
1253 // 1: the lock request is denied
1254 int processlockrequest(int locktype, int lock, int obj, int requestcore, int rootrequestcore, bool cache);
1256 // receive object transferred from other cores
1257 // or the terminate message from other cores
1258 // Should be invoked in critical sections!!
1259 // NOTICE: following format is for threadsimulate version only
1260 // RAW version please see previous description
1261 // format: type + object
1262 // type: -1--stall msg
1264 // return value: 0--received an object
1265 // 1--received nothing
1266 // 2--received a Stall Msg
1267 // 3--received a lock Msg
1268 // RAW version: -1 -- received nothing
1269 // otherwise -- received msg type
1270 int receiveObject() {
1275 if(receiveMsg() == -1) {
1279 if(msgdataindex == msglength) {
1280 // received a whole msg
1281 int type, data1; // will receive at least 2 words including type
1286 // receive a object transfer msg
1287 struct transObjInfo * transObj = RUNMALLOC_I(sizeof(struct transObjInfo));
1290 BAMBOO_DEBUGPRINT(0xe880);
1292 if(corenum > NUMCORES - 1) {
1293 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1294 BAMBOO_EXIT(0xa005);
1295 } /*else if((corenum == STARTUPCORE) && waitconfirm) {
1296 waitconfirm = false;
1299 // store the object and its corresponding queue info, enqueue it later
1300 transObj->objptr = (void *)msgdata[2]; // data1 is now size of the msg
1301 transObj->length = (msglength - 3) / 2;
1302 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
1303 for(k = 0; k < transObj->length; ++k) {
1304 transObj->queues[2*k] = msgdata[3+2*k];
1306 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
1308 transObj->queues[2*k+1] = msgdata[3+2*k+1];
1310 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
1313 // check if there is an existing duplicate item
1315 struct QueueItem * qitem = getTail(&objqueue);
1316 struct QueueItem * prev = NULL;
1317 while(qitem != NULL) {
1318 struct transObjInfo * tmpinfo = (struct transObjInfo *)(qitem->objectptr);
1319 if(tmpinfo->objptr == transObj->objptr) {
1320 // the same object, remove outdate one
1321 removeItem(&objqueue, qitem);
1326 qitem = getTail(&objqueue);
1328 qitem = getNextQueueItem(prev);
1331 addNewItem_I(&objqueue, (void *)transObj);
1333 ++(self_numreceiveobjs);
1338 // receive a stall msg
1339 if(corenum != STARTUPCORE) {
1340 // non startup core can not receive stall msg
1342 BAMBOO_DEBUGPRINT_REG(data1);
1343 BAMBOO_EXIT(0xa006);
1344 } /*else if(waitconfirm) {
1345 waitconfirm = false;
1348 if(data1 < NUMCORES) {
1350 BAMBOO_DEBUGPRINT(0xe881);
1352 corestatus[data1] = 0;
1353 numsendobjs[data1] = msgdata[2];
1354 numreceiveobjs[data1] = msgdata[3];
1360 // receive lock request msg, handle it right now
1361 // check to see if there is a lock exist in locktbl for the required obj
1362 // data1 -> lock type
1363 int data2 = msgdata[2]; // obj pointer
1364 int data3 = msgdata[3]; // lock
1365 int data4 = msgdata[4]; // request core
1366 deny = processlockrequest(data1, data3, data2, data4, data4, true); // -1: redirected, 0: approved, 1: denied
1368 // this lock request is redirected
1371 // send response msg
1372 // for 32 bit machine, the size is always 4 words
1373 int tmp = deny==1?4:3;
1375 cache_msg_4(data4, tmp, data1, data2, data3);
1377 send_msg_4(data4, tmp, data1, data2, data3);
1384 // receive lock grount msg
1385 if(corenum > NUMCORES - 1) {
1386 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1387 BAMBOO_EXIT(0xa007);
1388 } /*else if((corenum == STARTUPCORE) && waitconfirm) {
1389 waitconfirm = false;
1392 if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1394 BAMBOO_DEBUGPRINT(0xe882);
1402 // conflicts on lockresults
1403 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1404 BAMBOO_EXIT(0xa008);
1410 // receive lock grount/deny msg
1411 if(corenum > NUMCORES - 1) {
1412 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1413 BAMBOO_EXIT(0xa009);
1414 } /*else if((corenum == STARTUPCORE) && waitconfirm) {
1415 waitconfirm = false;
1418 if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1420 BAMBOO_DEBUGPRINT(0xe883);
1428 // conflicts on lockresults
1429 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1430 BAMBOO_EXIT(0xa00a);
1436 // receive lock release msg
1437 /*if((corenum == STARTUPCORE) && waitconfirm) {
1438 waitconfirm = false;
1441 if(!RuntimeHashcontainskey(locktbl, msgdata[3])) {
1442 // no locks for this object, something is wrong
1443 BAMBOO_DEBUGPRINT_REG(msgdata[3]);
1444 BAMBOO_EXIT(0xa00b);
1447 struct LockValue * lockvalue = NULL;
1448 RuntimeHashget(locktbl, msgdata[3], &rwlock_obj);
1449 lockvalue = (struct LockValue*)(rwlock_obj);
1451 BAMBOO_DEBUGPRINT(0xe884);
1452 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1460 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1468 // receive an output profile data request msg
1469 if(corenum == STARTUPCORE) {
1470 // startup core can not receive profile output finish msg
1471 BAMBOO_EXIT(0xa00c);
1474 BAMBOO_DEBUGPRINT(0xe885);
1477 totalexetime = data1;
1478 outputProfileData();
1480 cache_msg_2(STARTUPCORE, 7, corenum);
1482 send_msg_2(STARTUPCORE, 7, corenum);
1488 // receive a profile output finish msg
1489 if(corenum != STARTUPCORE) {
1490 // non startup core can not receive profile output finish msg
1491 BAMBOO_DEBUGPRINT_REG(data1);
1492 BAMBOO_EXIT(0xa00d);
1495 BAMBOO_DEBUGPRINT(0xe886);
1497 profilestatus[data1] = 0;
1503 // receive a redirect lock request msg, handle it right now
1504 // check to see if there is a lock exist in locktbl for the required obj
1505 // data1 -> lock type
1506 int data2 = msgdata[2]; // obj pointer
1507 int data3 = msgdata[3]; // redirect lock
1508 int data4 = msgdata[4]; // root request core
1509 int data5 = msgdata[5]; // request core
1510 deny = processlockrequest(data1, data3, data2, data5, data4, true);
1512 // this lock request is redirected
1515 // send response msg
1516 // for 32 bit machine, the size is always 4 words
1518 cache_msg_4(data4, deny==1?0xa:9, data1, data2, data3);
1520 send_msg_4(data4, deny==1?0xa:9, data1, data2, data3);
1527 // receive a lock grant msg with redirect info
1528 if(corenum > NUMCORES - 1) {
1529 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1530 BAMBOO_EXIT(0xa00e);
1531 }/* else if((corenum == STARTUPCORE) && waitconfirm) {
1532 waitconfirm = false;
1535 if(lockobj == msgdata[2]) {
1537 BAMBOO_DEBUGPRINT(0xe891);
1541 RuntimeHashadd_I(objRedirectLockTbl, lockobj, msgdata[3]);
1546 // conflicts on lockresults
1547 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1548 BAMBOO_EXIT(0xa00f);
1554 // receive a lock deny msg with redirect info
1555 if(corenum > NUMCORES - 1) {
1556 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1557 BAMBOO_EXIT(0xa010);
1558 }/* else if((corenum == STARTUPCORE) && waitconfirm) {
1559 waitconfirm = false;
1562 if(lockobj == msgdata[2]) {
1564 BAMBOO_DEBUGPRINT(0xe892);
1568 //RuntimeHashadd_I(objRedirectLockTbl, lockobj, msgdata[3]);
1573 // conflicts on lockresults
1574 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1575 BAMBOO_EXIT(0xa011);
1581 // receive a lock release msg with redirect info
1582 /*if((corenum == STARTUPCORE) && waitconfirm) {
1583 waitconfirm = false;
1586 if(!RuntimeHashcontainskey(locktbl, msgdata[2])) {
1587 // no locks for this object, something is wrong
1588 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1589 BAMBOO_EXIT(0xa012);
1592 struct LockValue * lockvalue = NULL;
1593 RuntimeHashget(locktbl, msgdata[2], &rwlock_obj);
1594 lockvalue = (struct LockValue*)(rwlock_obj);
1596 BAMBOO_DEBUGPRINT(0xe893);
1597 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1605 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1607 lockvalue->redirectlock = msgdata[3];
1613 // receive a status confirm info
1614 if((corenum == STARTUPCORE) || (corenum > NUMCORES - 1)) {
1615 // wrong core to receive such msg
1616 BAMBOO_EXIT(0xa013);
1618 // send response msg
1620 BAMBOO_DEBUGPRINT(0xe887);
1623 cache_msg_3(STARTUPCORE, 0xd, busystatus?1:0, corenum);
1625 send_msg_3(STARTUPCORE, 0xd, busystatus?1:0, corenum);
1632 // receive a status confirm info
1633 if(corenum != STARTUPCORE) {
1634 // wrong core to receive such msg
1635 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1636 BAMBOO_EXIT(0xa014);
1639 BAMBOO_DEBUGPRINT(0xe888);
1644 corestatus[msgdata[2]] = msgdata[1];
1652 for(msgdataindex--; msgdataindex > 0; --msgdataindex) {
1653 msgdata[msgdataindex] = -1;
1658 BAMBOO_DEBUGPRINT(0xe889);
1661 if(BAMBOO_MSG_AVAIL() != 0) {
1673 BAMBOO_DEBUGPRINT(0xe895);
1676 /* if(isInterrupt) {
1684 /* this function is to process lock requests.
1685 * can only be invoked in receiveObject() */
1686 // if return -1: the lock request is redirected
1687 // 0: the lock request is approved
1688 // 1: the lock request is denied
1689 int processlockrequest(int locktype, int lock, int obj, int requestcore, int rootrequestcore, bool cache) {
1691 if( ((lock >> 5) % BAMBOO_TOTALCORE) != corenum ) {
1692 // the lock should not be on this core
1693 BAMBOO_DEBUGPRINT_REG(requestcore);
1694 BAMBOO_EXIT(0xa015);
1696 /*if((corenum == STARTUPCORE) && waitconfirm) {
1697 waitconfirm = false;
1700 if(!RuntimeHashcontainskey(locktbl, lock)) {
1701 // no locks for this object
1702 // first time to operate on this shared object
1703 // create a lock for it
1704 // the lock is an integer: 0 -- stall, >0 -- read lock, -1 -- write lock
1705 struct LockValue * lockvalue = (struct LockValue *)(RUNMALLOC_I(sizeof(struct LockValue)));
1706 lockvalue->redirectlock = 0;
1708 BAMBOO_DEBUGPRINT(0xe110);
1711 lockvalue->value = 1;
1713 lockvalue->value = -1;
1715 RuntimeHashadd_I(locktbl, lock, (int)lockvalue);
1718 struct LockValue * lockvalue = NULL;
1720 BAMBOO_DEBUGPRINT(0xe111);
1722 RuntimeHashget(locktbl, lock, &rwlock_obj);
1723 lockvalue = (struct LockValue *)(rwlock_obj);
1725 BAMBOO_DEBUGPRINT_REG(lockvalue->redirectlock);
1727 if(lockvalue->redirectlock != 0) {
1728 // this lock is redirected
1730 BAMBOO_DEBUGPRINT(0xe112);
1733 getreadlock_I_r((void *)obj, (void *)lockvalue->redirectlock, rootrequestcore, cache);
1735 getwritelock_I_r((void *)obj, (void *)lockvalue->redirectlock, rootrequestcore, cache);
1737 return -1; // redirected
1740 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1742 if(0 == lockvalue->value) {
1744 lockvalue->value = 1;
1746 lockvalue->value = -1;
1748 } else if((lockvalue->value > 0) && (locktype == 0)) {
1749 // read lock request and there are only read locks
1755 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1762 bool getreadlock(void * ptr) {
1765 if(((struct ___Object___ *)ptr)->lock == NULL) {
1766 lock2require = lockobj;
1768 lock2require = (int)(((struct ___Object___ *)ptr)->lock);
1770 targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
1777 if(targetcore == corenum) {
1778 // reside on this core
1780 BAMBOO_START_CRITICAL_SECTION_LOCK();
1781 deny = processlockrequest(0, lock2require, (int)ptr, corenum, corenum, false);
1782 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
1787 if(lockobj == (int)ptr) {
1798 // conflicts on lockresults
1799 BAMBOO_EXIT(0xa016);
1804 // send lock request msg
1805 // for 32 bit machine, the size is always 5 words
1806 send_msg_5(targetcore, 2, 0, (int)ptr, lock2require, corenum);
1811 void releasereadlock(void * ptr) {
1814 if(((struct ___Object___ *)ptr)->lock == NULL) {
1815 reallock = (int)ptr;
1817 reallock = (int)(((struct ___Object___ *)ptr)->lock);
1819 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
1821 if(targetcore == corenum) {
1822 BAMBOO_START_CRITICAL_SECTION_LOCK();
1823 // reside on this core
1824 if(!RuntimeHashcontainskey(locktbl, reallock)) {
1825 // no locks for this object, something is wrong
1826 BAMBOO_EXIT(0xa017);
1829 struct LockValue * lockvalue = NULL;
1830 RuntimeHashget(locktbl, reallock, &rwlock_obj);
1831 lockvalue = (struct LockValue *)rwlock_obj;
1834 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
1837 // send lock release msg
1838 // for 32 bit machine, the size is always 4 words
1839 send_msg_4(targetcore, 5, 0, (int)ptr, reallock);
1843 // redirected lock request
1844 bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
1847 if(core == corenum) {
1849 lock2require = (int)redirectlock;
1856 targetcore = ((int)redirectlock >> 5) % BAMBOO_TOTALCORE;
1858 if(targetcore == corenum) {
1859 // reside on this core
1860 int deny = processlockrequest(0, (int)redirectlock, (int)ptr, corenum, core, cache);
1865 if(core == corenum) {
1866 if(lockobj == (int)ptr) {
1871 RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
1878 // conflicts on lockresults
1879 BAMBOO_EXIT(0xa018);
1883 // send lock grant/deny request to the root requiring core
1884 // check if there is still some msg on sending
1885 if((!cache) || (cache && !isMsgSending)) {
1886 send_msg_4(core, deny==1?0xa:9, 0, (int)ptr, (int)redirectlock);
1888 cache_msg_4(core, deny==1?0xa:9, 0, (int)ptr, (int)redirectlock);
1893 // redirect the lock request
1894 // for 32 bit machine, the size is always 6 words
1895 if((!cache) || (cache && !isMsgSending)) {
1896 send_msg_6(targetcore, 8, 0, (int)ptr, lock2require, core, corenum);
1898 cache_msg_6(targetcore, 8, 0, (int)ptr, lock2require, core, corenum);
1905 bool getwritelock(void * ptr) {
1908 // for 32 bit machine, the size is always 5 words
1912 if(((struct ___Object___ *)ptr)->lock == NULL) {
1913 lock2require = lockobj;
1915 lock2require = (int)(((struct ___Object___ *)ptr)->lock);
1917 targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
1925 BAMBOO_DEBUGPRINT(0xe551);
1926 BAMBOO_DEBUGPRINT_REG(lockobj);
1927 BAMBOO_DEBUGPRINT_REG(lock2require);
1928 BAMBOO_DEBUGPRINT_REG(targetcore);
1931 if(targetcore == corenum) {
1932 // reside on this core
1934 BAMBOO_START_CRITICAL_SECTION_LOCK();
1935 deny = processlockrequest(1, lock2require, (int)ptr, corenum, corenum, false);
1936 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
1938 BAMBOO_DEBUGPRINT(0xe555);
1939 BAMBOO_DEBUGPRINT_REG(lockresult);
1945 if(lockobj == (int)ptr) {
1956 // conflicts on lockresults
1957 BAMBOO_EXIT(0xa019);
1962 // send lock request msg
1963 // for 32 bit machine, the size is always 5 words
1964 send_msg_5(targetcore, 2, 1, (int)ptr, lock2require, corenum);
1969 void releasewritelock(void * ptr) {
1972 if(((struct ___Object___ *)ptr)->lock == NULL) {
1973 reallock = (int)ptr;
1975 reallock = (int)(((struct ___Object___ *)ptr)->lock);
1977 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
1980 BAMBOO_DEBUGPRINT(0xe661);
1981 BAMBOO_DEBUGPRINT_REG((int)ptr);
1982 BAMBOO_DEBUGPRINT_REG(reallock);
1983 BAMBOO_DEBUGPRINT_REG(targetcore);
1986 if(targetcore == corenum) {
1987 BAMBOO_START_CRITICAL_SECTION_LOCK();
1988 // reside on this core
1989 if(!RuntimeHashcontainskey(locktbl, reallock)) {
1990 // no locks for this object, something is wrong
1991 BAMBOO_EXIT(0xa01a);
1994 struct LockValue * lockvalue = NULL;
1995 RuntimeHashget(locktbl, reallock, &rwlock_obj);
1996 lockvalue = (struct LockValue *)rwlock_obj;
1999 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
2002 // send lock release msg
2003 // for 32 bit machine, the size is always 4 words
2004 send_msg_4(targetcore, 5, 1, (int)ptr, reallock);
2008 void releasewritelock_r(void * lock, void * redirectlock) {
2010 int reallock = (int)lock;
2011 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2014 BAMBOO_DEBUGPRINT(0xe671);
2015 BAMBOO_DEBUGPRINT_REG((int)lock);
2016 BAMBOO_DEBUGPRINT_REG(reallock);
2017 BAMBOO_DEBUGPRINT_REG(targetcore);
2020 if(targetcore == corenum) {
2021 BAMBOO_START_CRITICAL_SECTION_LOCK();
2022 // reside on this core
2023 if(!RuntimeHashcontainskey(locktbl, reallock)) {
2024 // no locks for this object, something is wrong
2025 BAMBOO_EXIT(0xa01b);
2028 struct LockValue * lockvalue = NULL;
2030 BAMBOO_DEBUGPRINT(0xe672);
2032 RuntimeHashget(locktbl, reallock, &rwlock_obj);
2033 lockvalue = (struct LockValue *)rwlock_obj;
2035 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2038 lockvalue->redirectlock = (int)redirectlock;
2040 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2043 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
2046 // send lock release with redirect info msg
2047 // for 32 bit machine, the size is always 4 words
2048 send_msg_4(targetcore, 0xb, 1, (int)lock, (int)redirectlock);
2052 bool getwritelock_I(void * ptr) {
2055 if(((struct ___Object___ *)ptr)->lock == NULL) {
2056 lock2require = lockobj;
2058 lock2require = (int)(((struct ___Object___ *)ptr)->lock);
2060 targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
2068 BAMBOO_DEBUGPRINT(0xe561);
2069 BAMBOO_DEBUGPRINT_REG(lockobj);
2070 BAMBOO_DEBUGPRINT_REG(lock2require);
2071 BAMBOO_DEBUGPRINT_REG(targetcore);
2074 if(targetcore == corenum) {
2075 // reside on this core
2076 int deny = processlockrequest(1, (int)lock2require, (int)ptr, corenum, corenum, false);
2081 if(lockobj == (int)ptr) {
2085 BAMBOO_DEBUGPRINT(0);
2090 BAMBOO_DEBUGPRINT(1);
2098 // conflicts on lockresults
2099 BAMBOO_EXIT(0xa01c);
2104 // send lock request msg
2105 // for 32 bit machine, the size is always 5 words
2106 send_msg_5(targetcore, 2, 1, (int)ptr, lock2require, corenum);
2111 // redirected lock request
2112 bool getwritelock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
2115 if(core == corenum) {
2117 lock2require = (int)redirectlock;
2124 targetcore = ((int)redirectlock >> 5) % BAMBOO_TOTALCORE;
2127 BAMBOO_DEBUGPRINT(0xe571);
2128 BAMBOO_DEBUGPRINT_REG((int)ptr);
2129 BAMBOO_DEBUGPRINT_REG((int)redirectlock);
2130 BAMBOO_DEBUGPRINT_REG(core);
2131 BAMBOO_DEBUGPRINT_REG((int)cache);
2132 BAMBOO_DEBUGPRINT_REG(targetcore);
2136 if(targetcore == corenum) {
2137 // reside on this core
2138 int deny = processlockrequest(1, (int)redirectlock, (int)ptr, corenum, core, cache);
2143 if(core == corenum) {
2144 if(lockobj == (int)ptr) {
2149 RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
2156 // conflicts on lockresults
2157 BAMBOO_EXIT(0xa01d);
2161 // send lock grant/deny request to the root requiring core
2162 // check if there is still some msg on sending
2163 if((!cache) || (cache && !isMsgSending)) {
2164 send_msg_4(core, deny==1?0xa:9, 1, (int)ptr, (int)redirectlock);
2166 cache_msg_4(core, deny==1?0xa:9, 1, (int)ptr, (int)redirectlock);
2171 // redirect the lock request
2172 // for 32 bit machine, the size is always 6 words
2173 if((!cache) || (cache && !isMsgSending)) {
2174 send_msg_6(targetcore, 8, 1, (int)ptr, (int)redirectlock, core, corenum);
2176 cache_msg_6(targetcore, 8, 1, (int)ptr, (int)redirectlock, core, corenum);
2182 void releasewritelock_I(void * ptr) {
2185 if(((struct ___Object___ *)ptr)->lock == NULL) {
2186 reallock = (int)ptr;
2188 reallock = (int)(((struct ___Object___ *)ptr)->lock);
2190 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2193 BAMBOO_DEBUGPRINT(0xe681);
2194 BAMBOO_DEBUGPRINT_REG((int)ptr);
2195 BAMBOO_DEBUGPRINT_REG(reallock);
2196 BAMBOO_DEBUGPRINT_REG(targetcore);
2199 if(targetcore == corenum) {
2200 // reside on this core
2201 if(!RuntimeHashcontainskey(locktbl, reallock)) {
2202 // no locks for this object, something is wrong
2203 BAMBOO_EXIT(0xa01e);
2206 struct LockValue * lockvalue = NULL;
2207 RuntimeHashget(locktbl, reallock, &rwlock_obj);
2208 lockvalue = (struct LockValue *)rwlock_obj;
2213 // send lock release msg
2214 // for 32 bit machine, the size is always 4 words
2215 send_msg_4(targetcore, 5, 1, (int)ptr, reallock);
2219 void releasewritelock_I_r(void * lock, void * redirectlock) {
2221 int reallock = (int)lock;
2222 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2225 BAMBOO_DEBUGPRINT(0xe691);
2226 BAMBOO_DEBUGPRINT_REG((int)lock);
2227 BAMBOO_DEBUGPRINT_REG(reallock);
2228 BAMBOO_DEBUGPRINT_REG(targetcore);
2231 if(targetcore == corenum) {
2232 // reside on this core
2233 if(!RuntimeHashcontainskey(locktbl, reallock)) {
2234 // no locks for this object, something is wrong
2235 BAMBOO_EXIT(0xa01f);
2238 struct LockValue * lockvalue = NULL;
2240 BAMBOO_DEBUGPRINT(0xe692);
2242 RuntimeHashget(locktbl, reallock, &rwlock_obj);
2243 lockvalue = (struct LockValue *)rwlock_obj;
2245 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2248 lockvalue->redirectlock = (int)redirectlock;
2250 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2255 // send lock release msg
2256 // for 32 bit machine, the size is always 4 words
2257 send_msg_4(targetcore, 0xb, 1, (int)lock, (int)redirectlock);
2261 int enqueuetasks(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr, int * enterflags, int numenterflags) {
2262 void * taskpointerarray[MAXTASKPARAMS];
2264 int numparams=parameter->task->numParameters;
2265 int numiterators=parameter->task->numTotal-1;
2270 struct taskdescriptor * task=parameter->task;
2272 //this add the object to parameterwrapper
2273 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags, numenterflags, enterflags==NULL);
2275 /* Add enqueued object to parameter vector */
2276 taskpointerarray[parameter->slot]=ptr;
2278 /* Reset iterators */
2279 for(j=0; j<numiterators; j++) {
2280 toiReset(¶meter->iterators[j]);
2283 /* Find initial state */
2284 for(j=0; j<numiterators; j++) {
2286 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2287 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2289 /* Need to backtrack */
2290 toiReset(¶meter->iterators[j]);
2294 /* Nothing to enqueue */
2300 /* Enqueue current state */
2302 struct taskparamdescriptor *tpd=RUNMALLOC(sizeof(struct taskparamdescriptor));
2304 tpd->numParameters=numiterators+1;
2305 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
2307 for(j=0; j<=numiterators; j++) {
2308 tpd->parameterArray[j]=taskpointerarray[j]; //store the actual parameters
2311 if ((/*!gencontains(failedtasks, tpd)&&*/ !gencontains(activetasks,tpd))) {
2312 genputtable(activetasks, tpd, tpd);
2314 RUNFREE(tpd->parameterArray);
2318 /* This loop iterates to the next parameter combination */
2319 if (numiterators==0)
2322 for(j=numiterators-1; j<numiterators; j++) {
2324 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2325 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2327 /* Need to backtrack */
2328 toiReset(¶meter->iterators[j]);
2332 /* Nothing more to enqueue */
2340 int enqueuetasks_I(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr, int * enterflags, int numenterflags) {
2341 void * taskpointerarray[MAXTASKPARAMS];
2343 int numparams=parameter->task->numParameters;
2344 int numiterators=parameter->task->numTotal-1;
2349 struct taskdescriptor * task=parameter->task;
2351 //this add the object to parameterwrapper
2352 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags, numenterflags, enterflags==NULL);
2354 /* Add enqueued object to parameter vector */
2355 taskpointerarray[parameter->slot]=ptr;
2357 /* Reset iterators */
2358 for(j=0; j<numiterators; j++) {
2359 toiReset(¶meter->iterators[j]);
2362 /* Find initial state */
2363 for(j=0; j<numiterators; j++) {
2365 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2366 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2368 /* Need to backtrack */
2369 toiReset(¶meter->iterators[j]);
2373 /* Nothing to enqueue */
2379 /* Enqueue current state */
2381 struct taskparamdescriptor *tpd=RUNMALLOC_I(sizeof(struct taskparamdescriptor));
2383 tpd->numParameters=numiterators+1;
2384 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
2386 for(j=0; j<=numiterators; j++) {
2387 tpd->parameterArray[j]=taskpointerarray[j]; //store the actual parameters
2390 if ((/*!gencontains(failedtasks, tpd)&&*/ !gencontains(activetasks,tpd))) {
2391 genputtable_I(activetasks, tpd, tpd);
2393 RUNFREE(tpd->parameterArray);
2397 /* This loop iterates to the next parameter combination */
2398 if (numiterators==0)
2401 for(j=numiterators-1; j<numiterators; j++) {
2403 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2404 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2406 /* Need to backtrack */
2407 toiReset(¶meter->iterators[j]);
2411 /* Nothing more to enqueue */
2419 /* Handler for signals. The signals catch null pointer errors and
2420 arithmatic errors. */
2422 void myhandler(int sig, siginfo_t *info, void *uap) {
2425 printf("sig=%d\n",sig);
2428 sigemptyset(&toclear);
2429 sigaddset(&toclear, sig);
2430 sigprocmask(SIG_UNBLOCK, &toclear,NULL);
2431 longjmp(error_handler,1);
2437 struct RuntimeHash *fdtoobject;
2439 void addreadfd(int fd) {
2442 FD_SET(fd, &readfds);
2445 void removereadfd(int fd) {
2446 FD_CLR(fd, &readfds);
2447 if (maxreadfd==(fd+1)) {
2449 while(maxreadfd>0&&!FD_ISSET(maxreadfd-1, &readfds))
2460 void executetasks() {
2461 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
2464 struct ___Object___ * tmpparam = NULL;
2465 struct parameterdescriptor * pd=NULL;
2466 struct parameterwrapper *pw=NULL;
2471 struct LockValue * locks[MAXTASKPARAMS];
2477 for(j = 0; j < MAXTASKPARAMS; j++) {
2478 locks[j] = (struct LockValue *)(RUNMALLOC(sizeof(struct LockValue)));
2479 locks[j]->redirectlock = 0;
2480 locks[j]->value = 0;
2484 /* Set up signal handlers */
2485 struct sigaction sig;
2486 sig.sa_sigaction=&myhandler;
2487 sig.sa_flags=SA_SIGINFO;
2488 sigemptyset(&sig.sa_mask);
2490 /* Catch bus errors, segmentation faults, and floating point exceptions*/
2491 sigaction(SIGBUS,&sig,0);
2492 sigaction(SIGSEGV,&sig,0);
2493 sigaction(SIGFPE,&sig,0);
2494 sigaction(SIGPIPE,&sig,0);
2495 #endif // #if 0: non-multicore
2503 fdtoobject=allocateRuntimeHash(100);
2507 /* Map first block of memory to protected, anonymous page */
2508 mmap(0, 0x1000, 0, MAP_SHARED|MAP_FIXED|MAP_ANON, -1, 0);
2512 while((hashsize(activetasks)>0)||(maxreadfd>0)) {
2515 BAMBOO_DEBUGPRINT(0xe990);
2518 /* Check if any filedescriptors have IO pending */
2521 struct timeval timeout={0,0};
2525 numselect=select(maxreadfd, &tmpreadfds, NULL, NULL, &timeout);
2527 /* Process ready fd's */
2529 for(fd=0; fd<maxreadfd; fd++) {
2530 if (FD_ISSET(fd, &tmpreadfds)) {
2531 /* Set ready flag on object */
2533 // printf("Setting fd %d\n",fd);
2534 if (RuntimeHashget(fdtoobject, fd,(int *) &objptr)) {
2535 if(intflagorand(objptr,1,0xFFFFFFFF)) { /* Set the first flag to 1 */
2536 enqueueObject(objptr, NULL, 0);
2545 /* See if there are any active tasks */
2546 if (hashsize(activetasks)>0) {
2549 profileTaskStart("tpd checking");
2552 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
2553 genfreekey(activetasks, currtpd);
2555 numparams=currtpd->task->numParameters;
2556 numtotal=currtpd->task->numTotal;
2558 // clear the lockRedirectTbl (TODO, this table should be empty after all locks are released)
2559 // get all required locks
2561 // check which locks are needed
2562 for(i = 0; i < numparams; i++) {
2563 void * param = currtpd->parameterArray[i];
2567 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
2569 taskpointerarray[i+OFFSET]=param;
2572 if(((struct ___Object___ *)param)->lock == NULL) {
2573 tmplock = (int)param;
2575 tmplock = (int)(((struct ___Object___ *)param)->lock);
2577 // insert into the locks array
2578 for(j = 0; j < locklen; j++) {
2579 if(locks[j]->value == tmplock) {
2582 } else if(locks[j]->value > tmplock) {
2589 locks[h]->redirectlock = locks[h-1]->redirectlock;
2590 locks[h]->value = locks[h-1]->value;
2592 locks[j]->value = tmplock;
2593 locks[j]->redirectlock = (int)param;
2597 // grab these required locks
2599 BAMBOO_DEBUGPRINT(0xe991);
2601 for(i = 0; i < locklen; i++) {
2602 int * lock = (int *)(locks[i]->redirectlock);
2604 // require locks for this parameter if it is not a startup object
2606 BAMBOO_DEBUGPRINT_REG((int)lock);
2607 BAMBOO_DEBUGPRINT_REG((int)(locks[i]->value));
2610 BAMBOO_START_CRITICAL_SECTION();
2612 //isInterrupt = false;
2615 BAMBOO_WAITING_FOR_LOCK();
2619 while(BAMBOO_WAITING_FOR_LOCK() != -1) {
2623 grount = lockresult;
2633 //isInterrupt = true;
2635 BAMBOO_CLOSE_CRITICAL_SECTION();
2640 BAMBOO_DEBUGPRINT(0xe992);
2642 // can not get the lock, try later
2643 // releas all grabbed locks for previous parameters
2644 for(j = 0; j < i; ++j) {
2645 lock = (int*)(locks[j]->redirectlock);
2646 releasewritelock(lock);
2648 genputtable(activetasks, currtpd, currtpd);
2649 if(hashsize(activetasks) == 1) {
2650 // only one task right now, wait a little while before next try
2656 // fail, set the end of the checkTaskInfo
2664 BAMBOO_DEBUGPRINT(0xe993);
2666 /* Make sure that the parameters are still in the queues */
2667 for(i=0; i<numparams; i++) {
2668 void * parameter=currtpd->parameterArray[i];
2672 BAMBOO_CACHE_FLUSH_RANGE((int)parameter, classsize[((struct ___Object___ *)parameter)->type]);
2674 BAMBOO_START_CRITICAL_SECTION_LOCK();
2675 if(RuntimeHashcontainskey(objRedirectLockTbl, (int)parameter)) {
2676 int redirectlock_r = 0;
2677 RuntimeHashget(objRedirectLockTbl, (int)parameter, &redirectlock_r);
2678 ((struct ___Object___ *)parameter)->lock = redirectlock_r;
2679 RuntimeHashremovekey(objRedirectLockTbl, (int)parameter);
2681 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
2684 tmpparam = (struct ___Object___ *)parameter;
2685 pd=currtpd->task->descriptorarray[i];
2686 pw=(struct parameterwrapper *) pd->queue;
2687 /* Check that object is still in queue */
2689 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
2691 BAMBOO_DEBUGPRINT(0xe994);
2693 // release grabbed locks
2694 for(j = 0; j < locklen; ++j) {
2695 int * lock = (int *)(locks[j]->redirectlock);
2696 releasewritelock(lock);
2698 RUNFREE(currtpd->parameterArray);
2703 /* Check if the object's flags still meets requirements */
2707 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
2708 andmask=pw->intarray[tmpi*2];
2709 checkmask=pw->intarray[tmpi*2+1];
2710 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
2716 // flags are never suitable
2717 // remove this obj from the queue
2719 int UNUSED, UNUSED2;
2722 BAMBOO_DEBUGPRINT(0xe995);
2724 ObjectHashget(pw->objectset, (int) parameter, (int *) &next, (int *) &enterflags, &UNUSED, &UNUSED2);
2725 ObjectHashremove(pw->objectset, (int)parameter);
2726 if (enterflags!=NULL)
2728 // release grabbed locks
2729 for(j = 0; j < locklen; ++j) {
2730 int * lock = (int *)(locks[j]->redirectlock);
2731 releasewritelock(lock);
2733 RUNFREE(currtpd->parameterArray);
2736 // fail, set the end of the checkTaskInfo
2744 /* Check that object still has necessary tags */
2745 for(j=0; j<pd->numbertags; j++) {
2746 int slotid=pd->tagarray[2*j]+numparams;
2747 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
2748 if (!containstag(parameter, tagd)) {
2750 BAMBOO_DEBUGPRINT(0xe996);
2753 // release grabbed locks
2755 for(tmpj = 0; tmpj < locklen; ++tmpj) {
2756 int * lock = (int *)(locks[tmpj]->redirectlock);
2757 releasewritelock(lock);
2760 RUNFREE(currtpd->parameterArray);
2766 taskpointerarray[i+OFFSET]=parameter;
2769 for(; i<numtotal; i++) {
2770 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
2776 /* Checkpoint the state */
2777 forward=allocateRuntimeHash(100);
2778 reverse=allocateRuntimeHash(100);
2779 //void ** checkpoint=makecheckpoint(currtpd->task->numParameters, currtpd->parameterArray, forward, reverse);
2781 #endif // #if 0: for recovery
2782 if (x=setjmp(error_handler)) {
2787 printf("Fatal Error=%d, Recovering!\n",x);
2791 genputtable(failedtasks,currtpd,currtpd);
2792 //restorecheckpoint(currtpd->task->numParameters, currtpd->parameterArray, checkpoint, forward, reverse);
2794 freeRuntimeHash(forward);
2795 freeRuntimeHash(reverse);
2799 #endif // #if 0: for recovery
2800 BAMBOO_DEBUGPRINT_REG(x);
2801 BAMBOO_EXIT(0xa020);
2804 if (injectfailures) {
2805 if ((((double)random())/RAND_MAX)<failurechance) {
2806 printf("\nINJECTING TASK FAILURE to %s\n", currtpd->task->name);
2807 longjmp(error_handler,10);
2810 #endif // #if 0: for recovery
2811 /* Actually call task */
2814 ((int *)taskpointerarray)[0]=currtpd->numParameters;
2815 taskpointerarray[1]=NULL;
2817 #endif // #if 0: for garbage collection
2820 // check finish, set the end of the checkTaskInfo
2822 profileTaskStart(currtpd->task->name);
2827 printf("ENTER %s count=%d\n",currtpd->task->name, (instaccum-instructioncount));
2829 ((void(*) (void **))currtpd->task->taskptr)(taskpointerarray);
2831 printf("EXIT %s count=%d\n",currtpd->task->name, (instaccum-instructioncount));
2835 BAMBOO_DEBUGPRINT(0xe997);
2837 ((void(*) (void **))currtpd->task->taskptr)(taskpointerarray);
2840 // task finish, set the end of the checkTaskInfo
2842 // new a PostTaskInfo for the post-task execution
2843 profileTaskStart("post task execution");
2846 BAMBOO_DEBUGPRINT(0xe998);
2847 BAMBOO_DEBUGPRINT_REG(islock);
2852 BAMBOO_DEBUGPRINT(0xe999);
2854 for(i = 0; i < locklen; ++i) {
2855 void * ptr = (void *)(locks[i]->redirectlock);
2856 int * lock = (int *)(locks[i]->value);
2858 BAMBOO_DEBUGPRINT_REG((int)ptr);
2859 BAMBOO_DEBUGPRINT_REG((int)lock);
2861 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
2863 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
2864 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
2865 releasewritelock_r(lock, (int *)redirectlock);
2867 releasewritelock(ptr);
2873 // post task execution finish, set the end of the postTaskInfo
2878 freeRuntimeHash(forward);
2879 freeRuntimeHash(reverse);
2882 // Free up task parameter descriptor
2883 RUNFREE(currtpd->parameterArray);
2890 BAMBOO_DEBUGPRINT(0xe99a);
2897 BAMBOO_DEBUGPRINT(0xe99b);
2901 /* This function processes an objects tags */
2902 void processtags(struct parameterdescriptor *pd, int index, struct parameterwrapper *parameter, int * iteratorcount, int *statusarray, int numparams) {
2905 for(i=0; i<pd->numbertags; i++) {
2906 int slotid=pd->tagarray[2*i];
2907 int tagid=pd->tagarray[2*i+1];
2909 if (statusarray[slotid+numparams]==0) {
2910 parameter->iterators[*iteratorcount].istag=1;
2911 parameter->iterators[*iteratorcount].tagid=tagid;
2912 parameter->iterators[*iteratorcount].slot=slotid+numparams;
2913 parameter->iterators[*iteratorcount].tagobjectslot=index;
2914 statusarray[slotid+numparams]=1;
2921 void processobject(struct parameterwrapper *parameter, int index, struct parameterdescriptor *pd, int *iteratorcount, int * statusarray, int numparams) {
2924 struct ObjectHash * objectset=((struct parameterwrapper *)pd->queue)->objectset;
2926 parameter->iterators[*iteratorcount].istag=0;
2927 parameter->iterators[*iteratorcount].slot=index;
2928 parameter->iterators[*iteratorcount].objectset=objectset;
2929 statusarray[index]=1;
2931 for(i=0; i<pd->numbertags; i++) {
2932 int slotid=pd->tagarray[2*i];
2933 int tagid=pd->tagarray[2*i+1];
2934 if (statusarray[slotid+numparams]!=0) {
2935 /* This tag has already been enqueued, use it to narrow search */
2936 parameter->iterators[*iteratorcount].tagbindings[tagcount]=slotid+numparams;
2940 parameter->iterators[*iteratorcount].numtags=tagcount;
2945 /* This function builds the iterators for a task & parameter */
2947 void builditerators(struct taskdescriptor * task, int index, struct parameterwrapper * parameter) {
2948 int statusarray[MAXTASKPARAMS];
2950 int numparams=task->numParameters;
2951 int iteratorcount=0;
2952 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
2954 statusarray[index]=1; /* Initial parameter */
2955 /* Process tags for initial iterator */
2957 processtags(task->descriptorarray[index], index, parameter, &iteratorcount, statusarray, numparams);
2961 /* Check for objects with existing tags */
2962 for(i=0; i<numparams; i++) {
2963 if (statusarray[i]==0) {
2964 struct parameterdescriptor *pd=task->descriptorarray[i];
2966 for(j=0; j<pd->numbertags; j++) {
2967 int slotid=pd->tagarray[2*j];
2968 if(statusarray[slotid+numparams]!=0) {
2969 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
2970 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
2977 /* Next do objects w/ unbound tags*/
2979 for(i=0; i<numparams; i++) {
2980 if (statusarray[i]==0) {
2981 struct parameterdescriptor *pd=task->descriptorarray[i];
2982 if (pd->numbertags>0) {
2983 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
2984 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
2990 /* Nothing with a tag enqueued */
2992 for(i=0; i<numparams; i++) {
2993 if (statusarray[i]==0) {
2994 struct parameterdescriptor *pd=task->descriptorarray[i];
2995 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
2996 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3009 if(corenum > NUMCORES - 1) {
3012 for(i=0; i<numtasks[corenum]; i++) {
3013 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3015 printf("%s\n", task->name);
3017 for(j=0; j<task->numParameters; j++) {
3018 struct parameterdescriptor *param=task->descriptorarray[j];
3019 struct parameterwrapper *parameter=param->queue;
3020 struct ObjectHash * set=parameter->objectset;
3021 struct ObjectIterator objit;
3023 printf(" Parameter %d\n", j);
3025 ObjectHashiterator(set, &objit);
3026 while(ObjhasNext(&objit)) {
3027 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
3028 struct ___Object___ * tagptr=obj->___tags___;
3029 int nonfailed=Objdata4(&objit);
3030 int numflags=Objdata3(&objit);
3031 int flags=Objdata2(&objit);
3034 printf(" Contains %lx\n", obj);
3035 printf(" flag=%d\n", obj->flag);
3038 } else if (tagptr->type==TAGTYPE) {
3040 printf(" tag=%lx\n",tagptr);
3046 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
3047 for(; tagindex<ao->___cachedCode___; tagindex++) {
3049 printf(" tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*, tagindex));
3061 /* This function processes the task information to create queues for
3062 each parameter type. */
3064 void processtasks() {
3066 if(corenum > NUMCORES - 1) {
3069 for(i=0; i<numtasks[corenum]; i++) {
3070 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3073 /* Build objectsets */
3074 for(j=0; j<task->numParameters; j++) {
3075 struct parameterdescriptor *param=task->descriptorarray[j];
3076 struct parameterwrapper *parameter=param->queue;
3077 parameter->objectset=allocateObjectHash(10);
3078 parameter->task=task;
3081 /* Build iterators for parameters */
3082 for(j=0; j<task->numParameters; j++) {
3083 struct parameterdescriptor *param=task->descriptorarray[j];
3084 struct parameterwrapper *parameter=param->queue;
3085 builditerators(task, j, parameter);
3090 void toiReset(struct tagobjectiterator * it) {
3093 } else if (it->numtags>0) {
3096 ObjectHashiterator(it->objectset, &it->it);
3100 int toiHasNext(struct tagobjectiterator *it, void ** objectarray OPTARG(int * failed)) {
3103 /* Get object with tags */
3104 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3105 struct ___Object___ *tagptr=obj->___tags___;
3106 if (tagptr->type==TAGTYPE) {
3107 if ((it->tagobjindex==0)&& /* First object */
3108 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
3113 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3114 int tagindex=it->tagobjindex;
3115 for(; tagindex<ao->___cachedCode___; tagindex++) {
3116 struct ___TagDescriptor___ *td=ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
3117 if (td->flag==it->tagid) {
3118 it->tagobjindex=tagindex; /* Found right type of tag */
3124 } else if (it->numtags>0) {
3125 /* Use tags to locate appropriate objects */
3126 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3127 struct ___Object___ *objptr=tag->flagptr;
3129 if (objptr->type!=OBJECTARRAYTYPE) {
3130 if (it->tagobjindex>0)
3132 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3134 for(i=1; i<it->numtags; i++) {
3135 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3136 if (!containstag(objptr,tag2))
3141 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3144 for(tagindex=it->tagobjindex; tagindex<ao->___cachedCode___; tagindex++) {
3145 struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
3146 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3148 for(i=1; i<it->numtags; i++) {
3149 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3150 if (!containstag(objptr,tag2))
3153 it->tagobjindex=tagindex;
3158 it->tagobjindex=tagindex;
3162 return ObjhasNext(&it->it);
3166 int containstag(struct ___Object___ *ptr, struct ___TagDescriptor___ *tag) {
3168 struct ___Object___ * objptr=tag->flagptr;
3169 if (objptr->type==OBJECTARRAYTYPE) {
3170 struct ArrayObject *ao=(struct ArrayObject *)objptr;
3171 for(j=0; j<ao->___cachedCode___; j++) {
3172 if (ptr==ARRAYGET(ao, struct ___Object___*, j))
3180 void toiNext(struct tagobjectiterator *it, void ** objectarray OPTARG(int * failed)) {
3181 /* hasNext has all of the intelligence */
3184 /* Get object with tags */
3185 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3186 struct ___Object___ *tagptr=obj->___tags___;
3187 if (tagptr->type==TAGTYPE) {
3189 objectarray[it->slot]=tagptr;
3191 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3192 objectarray[it->slot]=ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
3194 } else if (it->numtags>0) {
3195 /* Use tags to locate appropriate objects */
3196 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3197 struct ___Object___ *objptr=tag->flagptr;
3198 if (objptr->type!=OBJECTARRAYTYPE) {
3200 objectarray[it->slot]=objptr;
3202 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3203 objectarray[it->slot]=ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
3206 /* Iterate object */
3207 objectarray[it->slot]=(void *)Objkey(&it->it);