3 #include "multicoreruntime.h"
4 #include "runtime_arch.h"
5 #include "GenericHashtable.h"
8 #define INLINE inline __attribute__((always_inline))
9 #endif // #ifndef INLINE
11 // data structures for task invocation
12 struct genhashtable * activetasks;
13 struct taskparamdescriptor * currtpd;
14 struct LockValue runtime_locks[MAXTASKPARAMS];
17 // specific functions used inside critical sections
18 void enqueueObject_I(void * ptr,
19 struct parameterwrapper ** queues,
21 int enqueuetasks_I(struct parameterwrapper *parameter,
22 struct parameterwrapper *prevptr,
23 struct ___Object___ *ptr,
27 INLINE void inittaskdata() {
30 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
31 // startup core to initialize corestatus[]
32 for(i = 0; i < NUMCORESACTIVE; ++i) {
34 // initialize the profile data arrays
37 } // for(i = 0; i < NUMCORESACTIVE; ++i)
38 total_num_t6 = 0; // TODO for test
40 totransobjqueue = createQueue_I();
50 taskInfoOverflow = false;
51 #ifdef PROFILE_INTERRUPT
52 interruptInfoIndex = 0;
53 interruptInfoOverflow = false;
54 #endif // PROFILE_INTERRUPT
57 for(i = 0; i < MAXTASKPARAMS; i++) {
58 runtime_locks[i].redirectlock = 0;
59 runtime_locks[i].value = 0;
64 // create the lock table, lockresult table and obj queue
67 (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
68 /* Set allocation blocks*/
69 locktable.listhead=NULL;
70 locktable.listtail=NULL;
72 locktable.numelements = 0;
77 lockRedirectTbl = allocateRuntimeHash_I(20);
78 objRedirectLockTbl = allocateRuntimeHash_I(20);
82 INLINE void distaskdata() {
83 if(activetasks != NULL) {
84 genfreehashtable(activetasks);
87 RUNFREE(currtpd->parameterArray);
92 freeRuntimeHash(lockRedirectTbl);
93 freeRuntimeHash(objRedirectLockTbl);
94 RUNFREE(locktable.bucket);
98 INLINE bool checkObjQueue() {
100 struct transObjInfo * objInfo = NULL;
104 #ifdef ACCURATEPROFILE
105 bool isChecking = false;
106 if(!isEmpty(&objqueue)) {
107 profileTaskStart("objqueue checking");
109 } // if(!isEmpty(&objqueue))
113 while(!isEmpty(&objqueue)) {
115 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
116 BAMBOO_DEBUGPRINT(0xf001);
117 BAMBOO_DEBUGPRINT(0xeee1);
119 objInfo = (struct transObjInfo *)getItem(&objqueue);
120 obj = objInfo->objptr;
121 BAMBOO_DEBUGPRINT_REG((int)obj);
122 // grab lock and flush the obj
124 struct ___Object___ * tmpobj = (struct ___Object___ *)obj;
125 while(tmpobj->lock != NULL) {
126 tmpobj = (struct ___Object___ *)(tmpobj->lock);
128 getwritelock_I(tmpobj);
130 BAMBOO_WAITING_FOR_LOCK(0);
131 } // while(!lockflag)
133 BAMBOO_DEBUGPRINT_REG(grount);
147 BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
148 BAMBOO_CACHE_FLUSH_RANGE((int)obj,
149 classsize[((struct ___Object___ *)obj)->type]);
151 // enqueue the object
152 for(k = 0; k < objInfo->length; ++k) {
153 int taskindex = objInfo->queues[2 * k];
154 int paramindex = objInfo->queues[2 * k + 1];
155 struct parameterwrapper ** queues =
156 &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
157 BAMBOO_DEBUGPRINT_REG(taskindex);
158 BAMBOO_DEBUGPRINT_REG(paramindex);
159 enqueueObject_I(obj, queues, 1);
160 BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
161 } // for(k = 0; k < objInfo->length; ++k)
162 releasewritelock_I(tmpobj);
163 RUNFREE(objInfo->queues);
167 // put it at the end of the queue if no update version in the queue
168 struct QueueItem * qitem = getHead(&objqueue);
169 struct QueueItem * prev = NULL;
170 while(qitem != NULL) {
171 struct transObjInfo * tmpinfo =
172 (struct transObjInfo *)(qitem->objectptr);
173 if(tmpinfo->objptr == obj) {
174 // the same object in the queue, which should be enqueued
175 // recently. Current one is outdate, do not re-enqueue it
176 RUNFREE(objInfo->queues);
181 } // if(tmpinfo->objptr == obj)
182 qitem = getNextQueueItem(prev);
183 } // while(qitem != NULL)
184 // try to execute active tasks already enqueued first
185 addNewItem_I(&objqueue, objInfo);
187 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
188 BAMBOO_DEBUGPRINT(0xf000);
191 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
192 BAMBOO_DEBUGPRINT(0xf000);
193 } // while(!isEmpty(&objqueue))
196 #ifdef ACCURATEPROFILE
203 BAMBOO_DEBUGPRINT(0xee02);
207 struct ___createstartupobject____I_locals {
210 struct ___StartupObject___ * ___startupobject___;
211 struct ArrayObject * ___stringarray___;
212 }; // struct ___createstartupobject____I_locals
214 void createstartupobject(int argc,
218 /* Allocate startup object */
220 struct ___createstartupobject____I_locals ___locals___ =
221 {2, NULL, NULL, NULL};
222 struct ___StartupObject___ *startupobject=
223 (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
224 ___locals___.___startupobject___ = startupobject;
225 struct ArrayObject * stringarray=
226 allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
227 ___locals___.___stringarray___ = stringarray;
229 struct ___StartupObject___ *startupobject=
230 (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
231 struct ArrayObject * stringarray=
232 allocate_newarray(STRINGARRAYTYPE, argc-1);
234 /* Build array of strings */
235 startupobject->___parameters___=stringarray;
236 for(i=1; i<argc; i++) {
237 int length=strlen(argv[i]);
239 struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
241 struct ___String___ *newstring=NewString(argv[i],length);
243 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
247 startupobject->version = 0;
248 startupobject->lock = NULL;
250 /* Set initialized flag for startup object */
251 flagorandinit(startupobject,1,0xFFFFFFFF);
252 enqueueObject(startupobject, NULL, 0);
254 BAMBOO_CACHE_FLUSH_ALL();
258 int hashCodetpd(struct taskparamdescriptor *ftd) {
259 int hash=(int)ftd->task;
261 for(i=0; i<ftd->numParameters; i++) {
262 hash^=(int)ftd->parameterArray[i];
267 int comparetpd(struct taskparamdescriptor *ftd1,
268 struct taskparamdescriptor *ftd2) {
270 if (ftd1->task!=ftd2->task)
272 for(i=0; i<ftd1->numParameters; i++)
273 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
278 /* This function sets a tag. */
280 void tagset(void *ptr,
281 struct ___Object___ * obj,
282 struct ___TagDescriptor___ * tagd) {
284 void tagset(struct ___Object___ * obj,
285 struct ___TagDescriptor___ * tagd) {
287 struct ArrayObject * ao=NULL;
288 struct ___Object___ * tagptr=obj->___tags___;
290 obj->___tags___=(struct ___Object___ *)tagd;
292 /* Have to check if it is already set */
293 if (tagptr->type==TAGTYPE) {
294 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
299 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
300 struct ArrayObject * ao=
301 allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
302 obj=(struct ___Object___ *)ptrarray[2];
303 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
304 td=(struct ___TagDescriptor___ *) obj->___tags___;
306 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
309 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
310 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
311 obj->___tags___=(struct ___Object___ *) ao;
312 ao->___cachedCode___=2;
316 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
317 for(i=0; i<ao->___cachedCode___; i++) {
318 struct ___TagDescriptor___ * td=
319 ARRAYGET(ao, struct ___TagDescriptor___*, i);
324 if (ao->___cachedCode___<ao->___length___) {
325 ARRAYSET(ao, struct ___TagDescriptor___ *,ao->___cachedCode___,tagd);
326 ao->___cachedCode___++;
329 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
330 struct ArrayObject * aonew=
331 allocate_newarray(&ptrarray,TAGARRAYTYPE,
332 TAGARRAYINTERVAL+ao->___length___);
333 obj=(struct ___Object___ *)ptrarray[2];
334 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
335 ao=(struct ArrayObject *)obj->___tags___;
337 struct ArrayObject * aonew=
338 allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
341 aonew->___cachedCode___=ao->___length___+1;
342 for(i=0; i<ao->___length___; i++) {
343 ARRAYSET(aonew, struct ___TagDescriptor___*, i,
344 ARRAYGET(ao, struct ___TagDescriptor___*, i));
346 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___,tagd);
352 struct ___Object___ * tagset=tagd->flagptr;
355 } else if (tagset->type!=OBJECTARRAYTYPE) {
357 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
358 struct ArrayObject * ao=
359 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
360 obj=(struct ___Object___ *)ptrarray[2];
361 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
363 struct ArrayObject * ao=
364 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
366 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
367 ARRAYSET(ao, struct ___Object___ *, 1, obj);
368 ao->___cachedCode___=2;
369 tagd->flagptr=(struct ___Object___ *)ao;
371 struct ArrayObject *ao=(struct ArrayObject *) tagset;
372 if (ao->___cachedCode___<ao->___length___) {
373 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
377 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
378 struct ArrayObject * aonew=
379 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
380 OBJECTARRAYINTERVAL+ao->___length___);
381 obj=(struct ___Object___ *)ptrarray[2];
382 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
383 ao=(struct ArrayObject *)tagd->flagptr;
385 struct ArrayObject * aonew=allocate_newarray(OBJECTARRAYTYPE,
386 OBJECTARRAYINTERVAL+ao->___length___);
388 aonew->___cachedCode___=ao->___cachedCode___+1;
389 for(i=0; i<ao->___length___; i++) {
390 ARRAYSET(aonew, struct ___Object___*, i,
391 ARRAYGET(ao, struct ___Object___*, i));
393 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
394 tagd->flagptr=(struct ___Object___ *) aonew;
400 /* This function clears a tag. */
402 void tagclear(void *ptr,
403 struct ___Object___ * obj,
404 struct ___TagDescriptor___ * tagd) {
406 void tagclear(struct ___Object___ * obj,
407 struct ___TagDescriptor___ * tagd) {
409 /* We'll assume that tag is alway there.
410 Need to statically check for this of course. */
411 struct ___Object___ * tagptr=obj->___tags___;
413 if (tagptr->type==TAGTYPE) {
414 if ((struct ___TagDescriptor___ *)tagptr==tagd)
415 obj->___tags___=NULL;
417 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
419 for(i=0; i<ao->___cachedCode___; i++) {
420 struct ___TagDescriptor___ * td=
421 ARRAYGET(ao, struct ___TagDescriptor___ *, i);
423 ao->___cachedCode___--;
424 if (i<ao->___cachedCode___)
425 ARRAYSET(ao, struct ___TagDescriptor___ *, i,
426 ARRAYGET(ao,struct ___TagDescriptor___*,ao->___cachedCode___));
427 ARRAYSET(ao,struct ___TagDescriptor___ *,ao->___cachedCode___, NULL);
428 if (ao->___cachedCode___==0)
429 obj->___tags___=NULL;
436 struct ___Object___ *tagset=tagd->flagptr;
437 if (tagset->type!=OBJECTARRAYTYPE) {
441 struct ArrayObject *ao=(struct ArrayObject *) tagset;
443 for(i=0; i<ao->___cachedCode___; i++) {
444 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
446 ao->___cachedCode___--;
447 if (i<ao->___cachedCode___)
448 ARRAYSET(ao, struct ___Object___ *, i,
449 ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
450 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
451 if (ao->___cachedCode___==0)
462 /* This function allocates a new tag. */
464 struct ___TagDescriptor___ * allocate_tag(void *ptr,
466 struct ___TagDescriptor___ * v=
467 (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
470 struct ___TagDescriptor___ * allocate_tag(int index) {
471 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
478 /* This function updates the flag for object ptr. It or's the flag
479 with the or mask and and's it with the andmask. */
481 void flagbody(struct ___Object___ *ptr,
483 struct parameterwrapper ** queues,
487 int flagcomp(const int *val1, const int *val2) {
488 return (*val1)-(*val2);
491 void flagorand(void * ptr,
494 struct parameterwrapper ** queues,
497 int oldflag=((int *)ptr)[1];
498 int flag=ormask|oldflag;
500 flagbody(ptr, flag, queues, length, false);
504 bool intflagorand(void * ptr,
508 int oldflag=((int *)ptr)[1];
509 int flag=ormask|oldflag;
511 if (flag==oldflag) /* Don't do anything */
514 flagbody(ptr, flag, NULL, 0, false);
520 void flagorandinit(void * ptr,
523 int oldflag=((int *)ptr)[1];
524 int flag=ormask|oldflag;
526 flagbody(ptr,flag,NULL,0,true);
529 void flagbody(struct ___Object___ *ptr,
531 struct parameterwrapper ** vqueues,
534 struct parameterwrapper * flagptr = NULL;
536 struct parameterwrapper ** queues = vqueues;
537 int length = vlength;
540 int * enterflags = NULL;
541 if((!isnew) && (queues == NULL)) {
542 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
543 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
544 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
551 /*Remove object from all queues */
552 for(i = 0; i < length; ++i) {
554 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
555 (int *) &enterflags, &UNUSED, &UNUSED2);
556 ObjectHashremove(flagptr->objectset, (int)ptr);
557 if (enterflags!=NULL)
562 void enqueueObject(void * vptr,
563 struct parameterwrapper ** vqueues,
565 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
568 struct parameterwrapper * parameter=NULL;
571 struct parameterwrapper * prevptr=NULL;
572 struct ___Object___ *tagptr=NULL;
573 struct parameterwrapper ** queues = vqueues;
574 int length = vlength;
575 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
579 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
580 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
582 tagptr=ptr->___tags___;
584 /* Outer loop iterates through all parameter queues an object of
585 this type could be in. */
586 for(j = 0; j < length; ++j) {
587 parameter = queues[j];
589 if (parameter->numbertags>0) {
591 goto nextloop; //that means the object has no tag
592 //but that param needs tag
593 else if(tagptr->type==TAGTYPE) { //one tag
594 for(i=0; i<parameter->numbertags; i++) {
595 //slotid is parameter->tagarray[2*i];
596 int tagid=parameter->tagarray[2*i+1];
597 if (tagid!=tagptr->flag)
598 goto nextloop; /*We don't have this tag */
600 } else { //multiple tags
601 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
602 for(i=0; i<parameter->numbertags; i++) {
603 //slotid is parameter->tagarray[2*i];
604 int tagid=parameter->tagarray[2*i+1];
606 for(j=0; j<ao->___cachedCode___; j++) {
607 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
618 for(i=0; i<parameter->numberofterms; i++) {
619 int andmask=parameter->intarray[i*2];
620 int checkmask=parameter->intarray[i*2+1];
621 if ((ptr->flag&andmask)==checkmask) {
622 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
633 void enqueueObject_I(void * vptr,
634 struct parameterwrapper ** vqueues,
636 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
639 struct parameterwrapper * parameter=NULL;
642 struct parameterwrapper * prevptr=NULL;
643 struct ___Object___ *tagptr=NULL;
644 struct parameterwrapper ** queues = vqueues;
645 int length = vlength;
646 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
650 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
651 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
653 tagptr=ptr->___tags___;
655 /* Outer loop iterates through all parameter queues an object of
656 this type could be in. */
657 for(j = 0; j < length; ++j) {
658 parameter = queues[j];
660 if (parameter->numbertags>0) {
662 goto nextloop; //that means the object has no tag
663 //but that param needs tag
664 else if(tagptr->type==TAGTYPE) { //one tag
665 for(i=0; i<parameter->numbertags; i++) {
666 //slotid is parameter->tagarray[2*i];
667 int tagid=parameter->tagarray[2*i+1];
668 if (tagid!=tagptr->flag)
669 goto nextloop; /*We don't have this tag */
671 } else { //multiple tags
672 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
673 for(i=0; i<parameter->numbertags; i++) {
674 //slotid is parameter->tagarray[2*i];
675 int tagid=parameter->tagarray[2*i+1];
677 for(j=0; j<ao->___cachedCode___; j++) {
678 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
689 for(i=0; i<parameter->numberofterms; i++) {
690 int andmask=parameter->intarray[i*2];
691 int checkmask=parameter->intarray[i*2+1];
692 if ((ptr->flag&andmask)==checkmask) {
693 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
705 int * getAliasLock(void ** ptrs,
707 struct RuntimeHash * tbl) {
712 // sort all the locks required by the objs in the aliased set
713 for(; i < length; i++) {
714 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
717 if(ptr->lock == NULL) {
720 lock = (int)(ptr->lock);
723 for(j = 0; j < locklen; j++) {
724 if(locks[j] == lock) {
727 } else if(locks[j] > lock) {
734 locks[h] = locks[h-1];
740 // use the smallest lock as the shared lock for the whole set
741 return (int *)(locks[0]);
743 // TODO possible bug here!!!
745 return (int*)(RUNMALLOC(sizeof(int)));
750 bool redirect = false;
751 int redirectlock = 0;
752 for(; i < length; i++) {
753 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
756 if(ptr->lock == NULL) {
759 lock = (int)(ptr->lock);
762 if(lock != redirectlock) {
763 RuntimeHashadd(tbl, lock, redirectlock);
766 if(RuntimeHashcontainskey(tbl, lock)) {
767 // already redirected
769 RuntimeHashget(tbl, lock, &redirectlock);
770 for(; j < locklen; j++) {
771 if(locks[j] != redirectlock) {
772 RuntimeHashadd(tbl, locks[j], redirectlock);
777 for(j = 0; j < locklen; j++) {
778 if(locks[j] == lock) {
781 } else if(locks[j] > lock) {
788 locks[h] = locks[h-1];
797 return (int *)redirectlock;
799 // use the first lock as the shared lock
800 for(j = 1; j < locklen; j++) {
801 if(locks[j] != locks[0]) {
802 RuntimeHashadd(tbl, locks[j], locks[0]);
805 return (int *)(locks[0]);
811 void addAliasLock(void * ptr,
813 struct ___Object___ * obj = (struct ___Object___ *)ptr;
814 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
815 // originally no alias lock associated or have a different alias lock
816 // flush it as the new one
818 while(obj->lock != NULL) {
819 // previously have alias lock, trace the 'root' obj and redirect it
820 obj = (struct ___Object___ *)(obj->lock);
823 obj->lock = (int *)lock;
828 inline void setTaskExitIndex(int index) {
829 taskInfoArray[taskInfoIndex]->exitIndex = index;
832 inline void addNewObjInfo(void * nobj) {
833 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
834 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
836 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
840 INLINE void processmsg_transobj_I() {
842 struct transObjInfo * transObj=RUNMALLOC_I(sizeof(struct transObjInfo));
845 BAMBOO_DEBUGPRINT(0xe880);
847 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
849 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
853 // store the object and its corresponding queue info, enqueue it later
854 transObj->objptr = (void *)msgdata[msgdataindex]; //[2]
856 transObj->length = (msglength - 3) / 2;
857 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
858 for(k = 0; k < transObj->length; ++k) {
859 transObj->queues[2*k] = msgdata[msgdataindex]; //[3+2*k];
861 transObj->queues[2*k+1] = msgdata[msgdataindex]; //[3+2*k+1];
864 // check if there is an existing duplicate item
866 struct QueueItem * qitem = getHead(&objqueue);
867 struct QueueItem * prev = NULL;
868 while(qitem != NULL) {
869 struct transObjInfo * tmpinfo =
870 (struct transObjInfo *)(qitem->objectptr);
871 if(tmpinfo->objptr == transObj->objptr) {
872 // the same object, remove outdate one
873 RUNFREE(tmpinfo->queues);
875 removeItem(&objqueue, qitem);
881 qitem = getHead(&objqueue);
883 qitem = getNextQueueItem(prev);
886 addNewItem_I(&objqueue, (void *)transObj);
888 ++(self_numreceiveobjs);
891 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
892 // set the gcprecheck to enable checking again
895 // send a update pregc information msg to the master core
896 if(BAMBOO_CHECK_SEND_MODE()) {
897 cache_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
898 self_numsendobjs, self_numreceiveobjs);
900 send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
901 self_numsendobjs, self_numreceiveobjs, true);
909 INLINE void processmsg_lockrequest_I() {
910 // check to see if there is a lock exist for the required obj
911 // msgdata[1] -> lock type
912 int locktype = msgdata[msgdataindex]; //[1];
914 int data2 = msgdata[msgdataindex]; // obj pointer
916 int data3 = msgdata[msgdataindex]; // lock
918 int data4 = msgdata[msgdataindex]; // request core
920 // -1: redirected, 0: approved, 1: denied
921 int deny=processlockrequest(locktype, data3, data2, data4, data4, true);
923 // this lock request is redirected
927 // for 32 bit machine, the size is always 4 words, cache the msg first
928 int tmp = deny==1 ? LOCKDENY : LOCKGROUNT;
929 if(BAMBOO_CHECK_SEND_MODE()) {
930 cache_msg_4(data4, tmp, locktype, data2, data3);
932 send_msg_4(data4, tmp, locktype, data2, data3, true);
937 INLINE void processmsg_lockgrount_I() {
939 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
941 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
945 int data2 = msgdata[msgdataindex];
947 int data3 = msgdata[msgdataindex];
949 if((lockobj == data2) && (lock2require == data3)) {
951 BAMBOO_DEBUGPRINT(0xe882);
959 // conflicts on lockresults
961 BAMBOO_DEBUGPRINT_REG(data2);
967 INLINE void processmsg_lockdeny_I() {
969 int data2 = msgdata[msgdataindex];
971 int data3 = msgdata[msgdataindex];
973 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
975 BAMBOO_DEBUGPRINT_REG(data2);
979 if((lockobj == data2) && (lock2require == data3)) {
981 BAMBOO_DEBUGPRINT(0xe883);
989 // conflicts on lockresults
991 BAMBOO_DEBUGPRINT_REG(data2);
997 INLINE void processmsg_lockrelease_I() {
998 int data1 = msgdata[msgdataindex];
1000 int data2 = msgdata[msgdataindex];
1002 int data3 = msgdata[msgdataindex];
1004 // receive lock release msg
1005 processlockrelease(data1, data2, 0, false);
1008 INLINE void processmsg_redirectlock_I() {
1009 // check to see if there is a lock exist for the required obj
1010 int data1 = msgdata[msgdataindex];
1011 MSG_INDEXINC_I(); //msgdata[1]; // lock type
1012 int data2 = msgdata[msgdataindex];
1013 MSG_INDEXINC_I(); //msgdata[2]; // obj pointer
1014 int data3 = msgdata[msgdataindex];
1015 MSG_INDEXINC_I(); //msgdata[3]; // redirect lock
1016 int data4 = msgdata[msgdataindex];
1017 MSG_INDEXINC_I(); //msgdata[4]; // root request core
1018 int data5 = msgdata[msgdataindex];
1019 MSG_INDEXINC_I(); //msgdata[5]; // request core
1020 int deny = processlockrequest(data1, data3, data2, data5, data4, true);
1022 // this lock request is redirected
1025 // send response msg
1026 // for 32 bit machine, the size is always 4 words, cache the msg first
1027 if(BAMBOO_CHECK_SEND_MODE()) {
1028 cache_msg_4(data4, deny==1 ? REDIRECTDENY : REDIRECTGROUNT,
1029 data1, data2, data3);
1031 send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
1032 data1, data2, data3, true);
1037 INLINE void processmsg_redirectgrount_I() {
1039 int data2 = msgdata[msgdataindex];
1041 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1043 BAMBOO_DEBUGPRINT_REG(data2);
1045 BAMBOO_EXIT(0xe206);
1047 if(lockobj == data2) {
1049 BAMBOO_DEBUGPRINT(0xe891);
1051 int data3 = msgdata[msgdataindex];
1055 RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
1060 // conflicts on lockresults
1062 BAMBOO_DEBUGPRINT_REG(data2);
1064 BAMBOO_EXIT(0xe207);
1068 INLINE void processmsg_redirectdeny_I() {
1070 int data2 = msgdata[msgdataindex];
1072 int data3 = msgdata[msgdataindex];
1074 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1076 BAMBOO_DEBUGPRINT_REG(data2);
1078 BAMBOO_EXIT(0xe208);
1080 if(lockobj == data2) {
1082 BAMBOO_DEBUGPRINT(0xe892);
1090 // conflicts on lockresults
1092 BAMBOO_DEBUGPRINT_REG(data2);
1094 BAMBOO_EXIT(0xe209);
1098 INLINE void processmsg_redirectrelease_I() {
1099 int data1 = msgdata[msgdataindex];
1101 int data2 = msgdata[msgdataindex];
1103 int data3 = msgdata[msgdataindex];
1105 processlockrelease(data1, data2, data3, true);
1107 #endif // #ifndef MULTICORE_GC
1110 INLINE void processmsg_profileoutput_I() {
1111 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
1112 // startup core can not receive profile output finish msg
1113 BAMBOO_EXIT(0xe20a);
1116 BAMBOO_DEBUGPRINT(0xe885);
1119 totalexetime = msgdata[msgdataindex]; //[1]
1122 BAMBOO_DEBUGPRINT_REG(dot_num);
1124 outputProfileData();
1126 // cache the msg first
1127 if(BAMBOO_CHECK_SEND_MODE()) {
1128 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1130 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE, true);
1134 INLINE void processmsg_profilefinish_I() {
1135 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1136 // non startup core can not receive profile output finish msg
1138 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex /*1*/]);
1140 BAMBOO_EXIT(0xe20b);
1143 BAMBOO_DEBUGPRINT(0xe886);
1145 int data1 = msgdata[msgdataindex];
1147 profilestatus[data1] = 0;
1149 #endif // #ifdef PROFILE
1151 int enqueuetasks(struct parameterwrapper *parameter,
1152 struct parameterwrapper *prevptr,
1153 struct ___Object___ *ptr,
1155 int numenterflags) {
1156 void * taskpointerarray[MAXTASKPARAMS];
1158 int numiterators=parameter->task->numTotal-1;
1161 struct taskdescriptor * task=parameter->task;
1163 //this add the object to parameterwrapper
1164 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
1165 numenterflags, enterflags==NULL);
1167 /* Add enqueued object to parameter vector */
1168 taskpointerarray[parameter->slot]=ptr;
1170 /* Reset iterators */
1171 for(j=0; j<numiterators; j++) {
1172 toiReset(¶meter->iterators[j]);
1175 /* Find initial state */
1176 for(j=0; j<numiterators; j++) {
1178 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
1179 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
1181 /* Need to backtrack */
1182 toiReset(¶meter->iterators[j]);
1186 /* Nothing to enqueue */
1192 /* Enqueue current state */
1194 struct taskparamdescriptor *tpd=
1195 RUNMALLOC(sizeof(struct taskparamdescriptor));
1197 tpd->numParameters=numiterators+1;
1198 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
1200 for(j=0; j<=numiterators; j++) {
1201 //store the actual parameters
1202 tpd->parameterArray[j]=taskpointerarray[j];
1205 if (!gencontains(activetasks,tpd)) {
1206 genputtable(activetasks, tpd, tpd);
1208 RUNFREE(tpd->parameterArray);
1212 /* This loop iterates to the next parameter combination */
1213 if (numiterators==0)
1216 for(j=numiterators-1; j<numiterators; j++) {
1219 ¶meter->iterators[j],taskpointerarray OPTARG(failed)))
1220 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
1222 /* Need to backtrack */
1223 toiReset(¶meter->iterators[j]);
1227 /* Nothing more to enqueue */
1235 int enqueuetasks_I(struct parameterwrapper *parameter,
1236 struct parameterwrapper *prevptr,
1237 struct ___Object___ *ptr,
1239 int numenterflags) {
1240 void * taskpointerarray[MAXTASKPARAMS];
1242 int numiterators=parameter->task->numTotal-1;
1245 struct taskdescriptor * task=parameter->task;
1247 //this add the object to parameterwrapper
1248 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
1249 numenterflags, enterflags==NULL);
1251 /* Add enqueued object to parameter vector */
1252 taskpointerarray[parameter->slot]=ptr;
1254 /* Reset iterators */
1255 for(j=0; j<numiterators; j++) {
1256 toiReset(¶meter->iterators[j]);
1259 /* Find initial state */
1260 for(j=0; j<numiterators; j++) {
1262 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
1263 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
1265 /* Need to backtrack */
1266 toiReset(¶meter->iterators[j]);
1270 /* Nothing to enqueue */
1276 /* Enqueue current state */
1278 struct taskparamdescriptor *tpd=
1279 RUNMALLOC_I(sizeof(struct taskparamdescriptor));
1281 tpd->numParameters=numiterators+1;
1282 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
1284 for(j=0; j<=numiterators; j++) {
1285 //store the actual parameters
1286 tpd->parameterArray[j]=taskpointerarray[j];
1289 if (!gencontains(activetasks,tpd)) {
1290 genputtable_I(activetasks, tpd, tpd);
1292 RUNFREE(tpd->parameterArray);
1296 /* This loop iterates to the next parameter combination */
1297 if (numiterators==0)
1300 for(j=numiterators-1; j<numiterators; j++) {
1303 ¶meter->iterators[j], taskpointerarray OPTARG(failed)))
1304 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
1306 /* Need to backtrack */
1307 toiReset(¶meter->iterators[j]);
1311 /* Nothing more to enqueue */
1325 int containstag(struct ___Object___ *ptr,
1326 struct ___TagDescriptor___ *tag);
1328 #ifndef MULTICORE_GC
1329 void releasewritelock_r(void * lock, void * redirectlock) {
1331 int reallock = (int)lock;
1332 targetcore = (reallock >> 5) % NUMCORES;
1334 BAMBOO_DEBUGPRINT(0xe671);
1335 BAMBOO_DEBUGPRINT_REG((int)lock);
1336 BAMBOO_DEBUGPRINT_REG(reallock);
1337 BAMBOO_DEBUGPRINT_REG(targetcore);
1339 if(targetcore == BAMBOO_NUM_OF_CORE) {
1340 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1341 BAMBOO_DEBUGPRINT(0xf001);
1342 // reside on this core
1343 if(!RuntimeHashcontainskey(locktbl, reallock)) {
1344 // no locks for this object, something is wrong
1345 BAMBOO_EXIT(0xe20c);
1348 struct LockValue * lockvalue = NULL;
1349 BAMBOO_DEBUGPRINT(0xe672);
1350 RuntimeHashget(locktbl, reallock, &rwlock_obj);
1351 lockvalue = (struct LockValue *)rwlock_obj;
1352 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1354 lockvalue->redirectlock = (int)redirectlock;
1355 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1357 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1358 BAMBOO_DEBUGPRINT(0xf000);
1361 // send lock release with redirect info msg
1362 // for 32 bit machine, the size is always 4 words
1363 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock,
1364 (int)redirectlock, false);
1369 void executetasks() {
1370 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
1373 struct ___Object___ * tmpparam = NULL;
1374 struct parameterdescriptor * pd=NULL;
1375 struct parameterwrapper *pw=NULL;
1385 while(hashsize(activetasks)>0) {
1387 if(gcflag) gc(NULL);
1389 BAMBOO_DEBUGPRINT(0xe990);
1391 /* See if there are any active tasks */
1394 #ifdef ACCURATEPROFILE
1395 profileTaskStart("tpd checking");
1400 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
1401 genfreekey(activetasks, currtpd);
1403 numparams=currtpd->task->numParameters;
1404 numtotal=currtpd->task->numTotal;
1406 // (TODO, this table should be empty after all locks are released)
1408 // get all required locks
1409 runtime_locklen = 0;
1410 // check which locks are needed
1411 for(i = 0; i < numparams; i++) {
1412 void * param = currtpd->parameterArray[i];
1416 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
1418 taskpointerarray[i+OFFSET]=param;
1421 /*if(((struct ___Object___ *)param)->lock == NULL) {
1422 tmplock = (int)param;
1424 struct ___Object___ * obj = (struct ___Object___ *)param;
1425 while(obj->lock != NULL) {
1426 obj = (struct ___Object___ *)(obj->lock);
1428 tmplock = (int)(obj);
1430 struct ___Object___ * obj = (struct ___Object___ *)param;
1431 while(obj->lock != NULL) {
1432 obj = (struct ___Object___ *)(obj->lock);
1434 tmplock = (int)(obj);
1435 // insert into the locks array
1436 for(j = 0; j < runtime_locklen; j++) {
1437 if(runtime_locks[j].value == tmplock) {
1440 } else if(runtime_locks[j].value > tmplock) {
1445 int h = runtime_locklen;
1447 runtime_locks[h].redirectlock = runtime_locks[h-1].redirectlock;
1448 runtime_locks[h].value = runtime_locks[h-1].value;
1450 runtime_locks[j].value = tmplock;
1451 runtime_locks[j].redirectlock = (int)param;
1454 } // line 2713: for(i = 0; i < numparams; i++)
1455 // grab these required locks
1456 BAMBOO_DEBUGPRINT(0xe991);
1458 for(i = 0; i < runtime_locklen; i++) {
1459 int * lock = (int *)(runtime_locks[i].value);//(runtime_locks[i].redirectlock);
1461 // require locks for this parameter if it is not a startup object
1462 BAMBOO_DEBUGPRINT_REG((int)lock);
1463 BAMBOO_DEBUGPRINT_REG((int)(runtime_locks[i].value));
1465 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
1466 BAMBOO_DEBUGPRINT(0xf001);
1468 BAMBOO_WAITING_FOR_LOCK(0);
1472 while(BAMBOO_WAITING_FOR_LOCK(0) != -1) {
1476 grount = lockresult;
1485 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
1486 BAMBOO_DEBUGPRINT(0xf000);
1489 BAMBOO_DEBUGPRINT(0xe992);
1490 BAMBOO_DEBUGPRINT_REG(lock);
1491 // check if has the lock already
1492 // can not get the lock, try later
1493 // release all grabbed locks for previous parameters
1494 for(j = 0; j < i; ++j) {
1495 lock = (int*)(runtime_locks[j].value/*redirectlock*/);
1496 releasewritelock(lock);
1498 genputtable(activetasks, currtpd, currtpd);
1499 if(hashsize(activetasks) == 1) {
1500 // only one task right now, wait a little while before next try
1506 #ifdef ACCURATEPROFILE
1507 // fail, set the end of the checkTaskInfo
1513 } // line 2752: for(i = 0; i < runtime_locklen; i++)
1515 BAMBOO_DEBUGPRINT(0xe993);
1516 /* Make sure that the parameters are still in the queues */
1517 for(i=0; i<numparams; i++) {
1518 void * parameter=currtpd->parameterArray[i];
1522 BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
1523 classsize[((struct ___Object___ *)parameter)->type]);
1525 tmpparam = (struct ___Object___ *)parameter;
1526 pd=currtpd->task->descriptorarray[i];
1527 pw=(struct parameterwrapper *) pd->queue;
1528 /* Check that object is still in queue */
1530 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
1531 BAMBOO_DEBUGPRINT(0xe994);
1532 BAMBOO_DEBUGPRINT_REG(parameter);
1533 // release grabbed locks
1534 for(j = 0; j < runtime_locklen; ++j) {
1535 int * lock = (int *)(runtime_locks[j].value/*redirectlock*/);
1536 releasewritelock(lock);
1538 RUNFREE(currtpd->parameterArray);
1544 /* Check if the object's flags still meets requirements */
1548 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
1549 andmask=pw->intarray[tmpi*2];
1550 checkmask=pw->intarray[tmpi*2+1];
1551 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
1557 // flags are never suitable
1558 // remove this obj from the queue
1560 int UNUSED, UNUSED2;
1562 BAMBOO_DEBUGPRINT(0xe995);
1563 BAMBOO_DEBUGPRINT_REG(parameter);
1564 ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
1565 (int *) &enterflags, &UNUSED, &UNUSED2);
1566 ObjectHashremove(pw->objectset, (int)parameter);
1567 if (enterflags!=NULL)
1568 RUNFREE(enterflags);
1569 // release grabbed locks
1570 for(j = 0; j < runtime_locklen; ++j) {
1571 int * lock = (int *)(runtime_locks[j].value/*redirectlock*/);
1572 releasewritelock(lock);
1574 RUNFREE(currtpd->parameterArray);
1578 #ifdef ACCURATEPROFILE
1579 // fail, set the end of the checkTaskInfo
1584 } // line 2878: if (!ismet)
1588 /* Check that object still has necessary tags */
1589 for(j=0; j<pd->numbertags; j++) {
1590 int slotid=pd->tagarray[2*j]+numparams;
1591 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
1592 if (!containstag(parameter, tagd)) {
1593 BAMBOO_DEBUGPRINT(0xe996);
1595 // release grabbed locks
1597 for(tmpj = 0; tmpj < runtime_locklen; ++tmpj) {
1598 int * lock = (int *)(runtime_locks[tmpj].value/*redirectlock*/);
1599 releasewritelock(lock);
1602 RUNFREE(currtpd->parameterArray);
1606 } // line2911: if (!containstag(parameter, tagd))
1607 } // line 2808: for(j=0; j<pd->numbertags; j++)
1609 taskpointerarray[i+OFFSET]=parameter;
1610 } // line 2824: for(i=0; i<numparams; i++)
1612 for(; i<numtotal; i++) {
1613 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
1618 /* Actually call task */
1620 ((int *)taskpointerarray)[0]=currtpd->numParameters;
1621 taskpointerarray[1]=NULL;
1624 #ifdef ACCURATEPROFILE
1625 // check finish, set the end of the checkTaskInfo
1628 profileTaskStart(currtpd->task->name);
1631 BAMBOO_DEBUGPRINT(0xe997);
1632 ((void (*)(void **))currtpd->task->taskptr)(taskpointerarray);
1635 #ifdef ACCURATEPROFILE
1636 // task finish, set the end of the checkTaskInfo
1638 // new a PostTaskInfo for the post-task execution
1639 profileTaskStart("post task execution");
1642 BAMBOO_DEBUGPRINT(0xe998);
1643 BAMBOO_DEBUGPRINT_REG(islock);
1646 BAMBOO_DEBUGPRINT(0xe999);
1647 for(i = runtime_locklen; i>0; i--) {
1648 void * ptr = (void *)(runtime_locks[i-1].redirectlock);
1649 int * lock = (int *)(runtime_locks[i-1].value);
1650 BAMBOO_DEBUGPRINT_REG((int)ptr);
1651 BAMBOO_DEBUGPRINT_REG((int)lock);
1652 BAMBOO_DEBUGPRINT_REG(*((int*)lock+5));
1653 #ifndef MULTICORE_GC
1655 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
1657 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
1658 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
1659 releasewritelock_r(lock, (int *)redirectlock);
1667 releasewritelock(lock); // ptr
1670 } // line 3015: if(islock)
1673 // post task execution finish, set the end of the postTaskInfo
1677 // Free up task parameter descriptor
1678 RUNFREE(currtpd->parameterArray);
1681 BAMBOO_DEBUGPRINT(0xe99a);
1683 //} // if (hashsize(activetasks)>0)
1684 } // while(hashsize(activetasks)>0)
1685 BAMBOO_DEBUGPRINT(0xe99b);
1688 /* This function processes an objects tags */
1689 void processtags(struct parameterdescriptor *pd,
1691 struct parameterwrapper *parameter,
1692 int * iteratorcount,
1697 for(i=0; i<pd->numbertags; i++) {
1698 int slotid=pd->tagarray[2*i];
1699 int tagid=pd->tagarray[2*i+1];
1701 if (statusarray[slotid+numparams]==0) {
1702 parameter->iterators[*iteratorcount].istag=1;
1703 parameter->iterators[*iteratorcount].tagid=tagid;
1704 parameter->iterators[*iteratorcount].slot=slotid+numparams;
1705 parameter->iterators[*iteratorcount].tagobjectslot=index;
1706 statusarray[slotid+numparams]=1;
1713 void processobject(struct parameterwrapper *parameter,
1715 struct parameterdescriptor *pd,
1721 struct ObjectHash * objectset=
1722 ((struct parameterwrapper *)pd->queue)->objectset;
1724 parameter->iterators[*iteratorcount].istag=0;
1725 parameter->iterators[*iteratorcount].slot=index;
1726 parameter->iterators[*iteratorcount].objectset=objectset;
1727 statusarray[index]=1;
1729 for(i=0; i<pd->numbertags; i++) {
1730 int slotid=pd->tagarray[2*i];
1731 if (statusarray[slotid+numparams]!=0) {
1732 /* This tag has already been enqueued, use it to narrow search */
1733 parameter->iterators[*iteratorcount].tagbindings[tagcount]=
1738 parameter->iterators[*iteratorcount].numtags=tagcount;
1743 /* This function builds the iterators for a task & parameter */
1745 void builditerators(struct taskdescriptor * task,
1747 struct parameterwrapper * parameter) {
1748 int statusarray[MAXTASKPARAMS];
1750 int numparams=task->numParameters;
1751 int iteratorcount=0;
1752 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
1754 statusarray[index]=1; /* Initial parameter */
1755 /* Process tags for initial iterator */
1757 processtags(task->descriptorarray[index], index, parameter,
1758 &iteratorcount, statusarray, numparams);
1762 /* Check for objects with existing tags */
1763 for(i=0; i<numparams; i++) {
1764 if (statusarray[i]==0) {
1765 struct parameterdescriptor *pd=task->descriptorarray[i];
1767 for(j=0; j<pd->numbertags; j++) {
1768 int slotid=pd->tagarray[2*j];
1769 if(statusarray[slotid+numparams]!=0) {
1770 processobject(parameter,i,pd,&iteratorcount,
1771 statusarray,numparams);
1772 processtags(pd,i,parameter,&iteratorcount,statusarray,numparams);
1779 /* Next do objects w/ unbound tags*/
1781 for(i=0; i<numparams; i++) {
1782 if (statusarray[i]==0) {
1783 struct parameterdescriptor *pd=task->descriptorarray[i];
1784 if (pd->numbertags>0) {
1785 processobject(parameter,i,pd,&iteratorcount,statusarray,numparams);
1786 processtags(pd,i,parameter,&iteratorcount,statusarray,numparams);
1792 /* Nothing with a tag enqueued */
1794 for(i=0; i<numparams; i++) {
1795 if (statusarray[i]==0) {
1796 struct parameterdescriptor *pd=task->descriptorarray[i];
1797 processobject(parameter,i,pd,&iteratorcount,statusarray,numparams);
1798 processtags(pd,i,parameter,&iteratorcount,statusarray,numparams);
1811 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1814 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
1815 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
1817 printf("%s\n", task->name);
1819 for(j=0; j<task->numParameters; j++) {
1820 struct parameterdescriptor *param=task->descriptorarray[j];
1821 struct parameterwrapper *parameter=param->queue;
1822 struct ObjectHash * set=parameter->objectset;
1823 struct ObjectIterator objit;
1825 printf(" Parameter %d\n", j);
1827 ObjectHashiterator(set, &objit);
1828 while(ObjhasNext(&objit)) {
1829 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
1830 struct ___Object___ * tagptr=obj->___tags___;
1831 int nonfailed=Objdata4(&objit);
1832 int numflags=Objdata3(&objit);
1833 int flags=Objdata2(&objit);
1836 printf(" Contains %lx\n", obj);
1837 printf(" flag=%d\n", obj->flag);
1840 } else if (tagptr->type==TAGTYPE) {
1842 printf(" tag=%lx\n",tagptr);
1848 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
1849 for(; tagindex<ao->___cachedCode___; tagindex++) {
1851 printf(" tag=%lx\n",ARRAYGET(ao,struct ___TagDescriptor___*,
1864 /* This function processes the task information to create queues for
1865 each parameter type. */
1867 void processtasks() {
1869 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1872 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
1873 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
1876 /* Build objectsets */
1877 for(j=0; j<task->numParameters; j++) {
1878 struct parameterdescriptor *param=task->descriptorarray[j];
1879 struct parameterwrapper *parameter=param->queue;
1880 parameter->objectset=allocateObjectHash(10);
1881 parameter->task=task;
1884 /* Build iterators for parameters */
1885 for(j=0; j<task->numParameters; j++) {
1886 struct parameterdescriptor *param=task->descriptorarray[j];
1887 struct parameterwrapper *parameter=param->queue;
1888 builditerators(task, j, parameter);
1893 void toiReset(struct tagobjectiterator * it) {
1896 } else if (it->numtags>0) {
1899 ObjectHashiterator(it->objectset, &it->it);
1903 int toiHasNext(struct tagobjectiterator *it,
1904 void ** objectarray OPTARG(int * failed)) {
1907 /* Get object with tags */
1908 struct ___Object___ *obj=objectarray[it->tagobjectslot];
1909 struct ___Object___ *tagptr=obj->___tags___;
1910 if (tagptr->type==TAGTYPE) {
1911 if ((it->tagobjindex==0)&& /* First object */
1912 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
1917 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
1918 int tagindex=it->tagobjindex;
1919 for(; tagindex<ao->___cachedCode___; tagindex++) {
1920 struct ___TagDescriptor___ *td=
1921 ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
1922 if (td->flag==it->tagid) {
1923 it->tagobjindex=tagindex; /* Found right type of tag */
1929 } else if (it->numtags>0) {
1930 /* Use tags to locate appropriate objects */
1931 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
1932 struct ___Object___ *objptr=tag->flagptr;
1934 if (objptr->type!=OBJECTARRAYTYPE) {
1935 if (it->tagobjindex>0)
1937 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
1939 for(i=1; i<it->numtags; i++) {
1940 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
1941 if (!containstag(objptr,tag2))
1946 struct ArrayObject *ao=(struct ArrayObject *) objptr;
1949 for(tagindex=it->tagobjindex;tagindex<ao->___cachedCode___;tagindex++){
1950 struct ___Object___ *objptr=
1951 ARRAYGET(ao,struct ___Object___*,tagindex);
1952 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
1954 for(i=1; i<it->numtags; i++) {
1955 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
1956 if (!containstag(objptr,tag2))
1959 it->tagobjindex=tagindex;
1964 it->tagobjindex=tagindex;
1968 return ObjhasNext(&it->it);
1972 int containstag(struct ___Object___ *ptr,
1973 struct ___TagDescriptor___ *tag) {
1975 struct ___Object___ * objptr=tag->flagptr;
1976 if (objptr->type==OBJECTARRAYTYPE) {
1977 struct ArrayObject *ao=(struct ArrayObject *)objptr;
1978 for(j=0; j<ao->___cachedCode___; j++) {
1979 if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
1989 void toiNext(struct tagobjectiterator *it,
1990 void ** objectarray OPTARG(int * failed)) {
1991 /* hasNext has all of the intelligence */
1994 /* Get object with tags */
1995 struct ___Object___ *obj=objectarray[it->tagobjectslot];
1996 struct ___Object___ *tagptr=obj->___tags___;
1997 if (tagptr->type==TAGTYPE) {
1999 objectarray[it->slot]=tagptr;
2001 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
2002 objectarray[it->slot]=
2003 ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
2005 } else if (it->numtags>0) {
2006 /* Use tags to locate appropriate objects */
2007 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
2008 struct ___Object___ *objptr=tag->flagptr;
2009 if (objptr->type!=OBJECTARRAYTYPE) {
2011 objectarray[it->slot]=objptr;
2013 struct ArrayObject *ao=(struct ArrayObject *) objptr;
2014 objectarray[it->slot]=
2015 ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
2018 /* Iterate object */
2019 objectarray[it->slot]=(void *)Objkey(&it->it);
2025 inline void profileTaskStart(char * taskname) {
2026 if(!taskInfoOverflow) {
2027 TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
2028 taskInfoArray[taskInfoIndex] = taskInfo;
2029 taskInfo->taskName = taskname;
2030 taskInfo->startTime = BAMBOO_GET_EXE_TIME();
2031 taskInfo->endTime = -1;
2032 taskInfo->exitIndex = -1;
2033 taskInfo->newObjs = NULL;
2037 inline void profileTaskEnd() {
2038 if(!taskInfoOverflow) {
2039 taskInfoArray[taskInfoIndex]->endTime = BAMBOO_GET_EXE_TIME();
2041 if(taskInfoIndex == TASKINFOLENGTH) {
2042 taskInfoOverflow = true;
2047 // output the profiling data
2048 void outputProfileData() {
2051 unsigned long long totaltasktime = 0;
2052 unsigned long long preprocessingtime = 0;
2053 unsigned long long objqueuecheckingtime = 0;
2054 unsigned long long postprocessingtime = 0;
2055 unsigned long long other = 0;
2056 unsigned long long averagetasktime = 0;
2059 printf("Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
2060 // output task related info
2061 for(i = 0; i < taskInfoIndex; i++) {
2062 TaskInfo* tmpTInfo = taskInfoArray[i];
2063 unsigned long long duration = tmpTInfo->endTime - tmpTInfo->startTime;
2064 printf("%s, %lld, %lld, %lld, %lld",
2065 tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime,
2066 duration, tmpTInfo->exitIndex);
2067 // summarize new obj info
2068 if(tmpTInfo->newObjs != NULL) {
2069 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
2070 struct RuntimeIterator * iter = NULL;
2071 while(0 == isEmpty(tmpTInfo->newObjs)) {
2072 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
2073 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
2075 RuntimeHashget(nobjtbl, (int)objtype, &num);
2076 RuntimeHashremovekey(nobjtbl, (int)objtype);
2078 RuntimeHashadd(nobjtbl, (int)objtype, num);
2080 RuntimeHashadd(nobjtbl, (int)objtype, 1);
2082 //printf(stderr, "new obj!\n");
2085 // output all new obj info
2086 iter = RuntimeHashcreateiterator(nobjtbl);
2087 while(RunhasNext(iter)) {
2088 char * objtype = (char *)Runkey(iter);
2089 int num = Runnext(iter);
2090 printf(", %s, %d", objtype, num);
2094 if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
2095 preprocessingtime += duration;
2096 } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
2097 postprocessingtime += duration;
2098 } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
2099 objqueuecheckingtime += duration;
2101 totaltasktime += duration;
2102 averagetasktime += duration;
2107 if(taskInfoOverflow) {
2108 printf("Caution: task info overflow!\n");
2111 other = totalexetime-totaltasktime-preprocessingtime-postprocessingtime;
2112 averagetasktime /= tasknum;
2114 printf("\nTotal time: %lld\n", totalexetime);
2115 printf("Total task execution time: %lld (%d%%)\n", totaltasktime,
2116 (int)(((double)totaltasktime/(double)totalexetime)*100));
2117 printf("Total objqueue checking time: %lld (%d%%)\n",
2118 objqueuecheckingtime,
2119 (int)(((double)objqueuecheckingtime/(double)totalexetime)*100));
2120 printf("Total pre-processing time: %lld (%d%%)\n", preprocessingtime,
2121 (int)(((double)preprocessingtime/(double)totalexetime)*100));
2122 printf("Total post-processing time: %lld (%d%%)\n", postprocessingtime,
2123 (int)(((double)postprocessingtime/(double)totalexetime)*100));
2124 printf("Other time: %lld (%d%%)\n", other,
2125 (int)(((double)other/(double)totalexetime)*100));
2128 printf("\nAverage task execution time: %lld\n", averagetasktime);
2134 BAMBOO_PRINT(0xdddd);
2135 // output task related info
2136 for(i= 0; i < taskInfoIndex; i++) {
2137 TaskInfo* tmpTInfo = taskInfoArray[i];
2138 char* tmpName = tmpTInfo->taskName;
2139 int nameLen = strlen(tmpName);
2140 BAMBOO_PRINT(0xddda);
2141 for(j = 0; j < nameLen; j++) {
2142 BAMBOO_PRINT_REG(tmpName[j]);
2144 BAMBOO_PRINT(0xdddb);
2145 BAMBOO_PRINT_REG(tmpTInfo->startTime);
2146 BAMBOO_PRINT_REG(tmpTInfo->endTime);
2147 BAMBOO_PRINT_REG(tmpTInfo->exitIndex);
2148 if(tmpTInfo->newObjs != NULL) {
2149 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
2150 struct RuntimeIterator * iter = NULL;
2151 while(0 == isEmpty(tmpTInfo->newObjs)) {
2152 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
2153 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
2155 RuntimeHashget(nobjtbl, (int)objtype, &num);
2156 RuntimeHashremovekey(nobjtbl, (int)objtype);
2158 RuntimeHashadd(nobjtbl, (int)objtype, num);
2160 RuntimeHashadd(nobjtbl, (int)objtype, 1);
2164 // ouput all new obj info
2165 iter = RuntimeHashcreateiterator(nobjtbl);
2166 while(RunhasNext(iter)) {
2167 char * objtype = (char *)Runkey(iter);
2168 int num = Runnext(iter);
2169 int nameLen = strlen(objtype);
2170 BAMBOO_PRINT(0xddda);
2171 for(j = 0; j < nameLen; j++) {
2172 BAMBOO_PRINT_REG(objtype[j]);
2174 BAMBOO_PRINT(0xdddb);
2175 BAMBOO_PRINT_REG(num);
2178 BAMBOO_PRINT(0xdddc);
2181 if(taskInfoOverflow) {
2182 BAMBOO_PRINT(0xefee);
2185 #ifdef PROFILE_INTERRUPT
2186 // output interrupt related info
2187 for(i = 0; i < interruptInfoIndex; i++) {
2188 InterruptInfo* tmpIInfo = interruptInfoArray[i];
2189 BAMBOO_PRINT(0xddde);
2190 BAMBOO_PRINT_REG(tmpIInfo->startTime);
2191 BAMBOO_PRINT_REG(tmpIInfo->endTime);
2192 BAMBOO_PRINT(0xdddf);
2195 if(interruptInfoOverflow) {
2196 BAMBOO_PRINT(0xefef);
2198 #endif // PROFILE_INTERRUPT
2200 BAMBOO_PRINT(0xeeee);
2203 #endif // #ifdef PROFILE