change
[IRC.git] / Robust / src / Runtime / multicoretask.c
1 #ifdef TASK
2 #include "runtime.h"
3 #include "multicoreruntime.h"
4 #include "runtime_arch.h"
5 #include "GenericHashtable.h"
6
7 //  data structures for task invocation
8 struct genhashtable * activetasks;
9 struct taskparamdescriptor * currtpd;
10
11 // specific functions used inside critical sections
12 void enqueueObject_I(void * ptr, 
13                                  struct parameterwrapper ** queues, 
14                                                                                  int length);
15 int enqueuetasks_I(struct parameterwrapper *parameter, 
16                                struct parameterwrapper *prevptr, 
17                                                                          struct ___Object___ *ptr, 
18                                                                          int * enterflags, 
19                                                                          int numenterflags);
20
21 inline __attribute__((always_inline)) 
22 void initruntimedata() {
23         int i;
24         // initialize the arrays
25   if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
26     // startup core to initialize corestatus[]
27     for(i = 0; i < NUMCORES; ++i) {
28       corestatus[i] = 1;
29       numsendobjs[i] = 0; 
30       numreceiveobjs[i] = 0;
31 #ifdef PROFILE
32                         // initialize the profile data arrays
33                         profilestatus[i] = 1;
34 #endif
35 #ifdef MULTICORE_GC
36                         gccorestatus[i] = 1;
37                         gcnumsendobjs[i] = 0; 
38       gcnumreceiveobjs[i] = 0;
39                         gcloads[i] = 0;
40                         gcrequiredmems[i] = 0;
41                         gcstopblock[i] = 0;
42                         gcfilledblocks[i] = 0;
43 #endif
44     } // for(i = 0; i < NUMCORES; ++i)
45                 numconfirm = 0;
46                 waitconfirm = false; 
47                 
48                 // TODO for test
49                 total_num_t6 = 0;
50   }
51
52   busystatus = true;
53   self_numsendobjs = 0;
54   self_numreceiveobjs = 0;
55
56   for(i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
57     msgdata[i] = -1;
58   }
59   msgtype = -1;
60   msgdataindex = 0;
61   msglength = BAMBOO_MSG_BUF_LENGTH;
62   for(i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
63     outmsgdata[i] = -1;
64   }
65   outmsgindex = 0;
66   outmsglast = 0;
67   outmsgleft = 0;
68   isMsgHanging = false;
69   isMsgSending = false;
70
71   smemflag = true;
72   bamboo_cur_msp = NULL;
73   bamboo_smem_size = 0;
74         totransobjqueue = createQueue();
75
76 #ifdef MULTICORE_GC
77         gcflag = false;
78         gcprocessing = false;
79         gcphase = FINISHPHASE;
80         gccurr_heaptop = 0;
81         gcself_numsendobjs = 0;
82         gcself_numreceiveobjs = 0;
83         gcmarkedptrbound = 0;
84         gcpointertbl = allocateRuntimeHash(20);
85         gcobj2map = 0;
86         gcmappedobj = 0;
87         gcismapped = false;
88         gcnumlobjs = 0;
89         gcheaptop = 0;
90         gctopcore = 0;
91         gcheapdirection = 1;
92         gcmovestartaddr = 0;
93         gctomove = false;
94         gcmovepending = 0;
95         gcblock2fill = 0;
96         gcsbstarttbl = BAMBOO_BASE_VA;
97 #else
98         // create the lock table, lockresult table and obj queue
99   locktable.size = 20;
100   locktable.bucket = 
101                 (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
102   /* Set allocation blocks*/
103   locktable.listhead=NULL;
104   locktable.listtail=NULL;
105   /*Set data counts*/
106   locktable.numelements = 0;
107   lockobj = 0;
108   lock2require = 0;
109   lockresult = 0;
110   lockflag = false;
111         lockRedirectTbl = allocateRuntimeHash(20);
112   objRedirectLockTbl = allocateRuntimeHash(20);
113 #endif
114 #ifndef INTERRUPT
115   reside = false;
116 #endif  
117   objqueue.head = NULL;
118   objqueue.tail = NULL;
119
120         currtpd = NULL;
121
122 #ifdef PROFILE
123   stall = false;
124   //isInterrupt = true;
125   totalexetime = -1;
126   taskInfoIndex = 0;
127   taskInfoOverflow = false;
128   /*interruptInfoIndex = 0;
129   interruptInfoOverflow = false;*/
130 #endif
131 }
132
133 inline __attribute__((always_inline))
134 void disruntimedata() {
135 #ifdef MULTICORE_GC
136         freeRuntimeHash(gcpointertbl);
137 #else
138         freeRuntimeHash(lockRedirectTbl);
139         freeRuntimeHash(objRedirectLockTbl);
140         RUNFREE(locktable.bucket);
141 #endif
142         genfreehashtable(activetasks);
143         if(currtpd != NULL) {
144                 RUNFREE(currtpd->parameterArray);
145                 RUNFREE(currtpd);
146                 currtpd = NULL;
147         }
148 }
149
150 inline __attribute__((always_inline))
151 bool checkObjQueue() {
152         bool rflag = false;
153         struct transObjInfo * objInfo = NULL;
154         int grount = 0;
155
156 #ifdef PROFILE
157 #ifdef ACCURATEPROFILE
158         bool isChecking = false;
159         if(!isEmpty(&objqueue)) {
160                 profileTaskStart("objqueue checking");
161                 isChecking = true;
162         } // if(!isEmpty(&objqueue))
163 #endif
164 #endif
165
166         while(!isEmpty(&objqueue)) {
167                 void * obj = NULL;
168                 BAMBOO_START_CRITICAL_SECTION_OBJ_QUEUE();
169 #ifdef DEBUG
170                 BAMBOO_DEBUGPRINT(0xf001);
171 #endif
172 #ifdef PROFILE
173                 //isInterrupt = false;
174 #endif 
175 #ifdef DEBUG
176                 BAMBOO_DEBUGPRINT(0xeee1);
177 #endif
178                 rflag = true;
179                 objInfo = (struct transObjInfo *)getItem(&objqueue); 
180                 obj = objInfo->objptr;
181 #ifdef DEBUG
182                 BAMBOO_DEBUGPRINT_REG((int)obj);
183 #endif
184                 // grab lock and flush the obj
185                 grount = 0;
186                 getwritelock_I(obj);
187                 while(!lockflag) {
188                         BAMBOO_WAITING_FOR_LOCK();
189                 } // while(!lockflag)
190                 grount = lockresult;
191 #ifdef DEBUG
192                 BAMBOO_DEBUGPRINT_REG(grount);
193 #endif
194
195                 lockresult = 0;
196                 lockobj = 0;
197                 lock2require = 0;
198                 lockflag = false;
199 #ifndef INTERRUPT
200                 reside = false;
201 #endif
202
203                 if(grount == 1) {
204                         int k = 0;
205                         // flush the object
206 #ifdef CACHEFLUSH
207                         BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
208                         BAMBOO_CACHE_FLUSH_RANGE((int)obj, 
209                                         classsize[((struct ___Object___ *)obj)->type]);
210 #endif
211                         // enqueue the object
212                         for(k = 0; k < objInfo->length; ++k) {
213                                 int taskindex = objInfo->queues[2 * k];
214                                 int paramindex = objInfo->queues[2 * k + 1];
215                                 struct parameterwrapper ** queues = 
216                                         &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
217 #ifdef DEBUG
218                                 BAMBOO_DEBUGPRINT_REG(taskindex);
219                                 BAMBOO_DEBUGPRINT_REG(paramindex);
220                                 struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
221                                 tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n", 
222                                                                 BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj, 
223                                                                 (long)obj, tmpptr->flag);
224 #endif
225                                 enqueueObject_I(obj, queues, 1);
226 #ifdef DEBUG                             
227                                 BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
228 #endif
229                         } // for(k = 0; k < objInfo->length; ++k)
230                         releasewritelock_I(obj);
231                         RUNFREE(objInfo->queues);
232                         RUNFREE(objInfo);
233                 } else {
234                         // can not get lock
235                         // put it at the end of the queue if no update version in the queue
236                         struct QueueItem * qitem = getHead(&objqueue);
237                         struct QueueItem * prev = NULL;
238                         while(qitem != NULL) {
239                                 struct transObjInfo * tmpinfo = 
240                                         (struct transObjInfo *)(qitem->objectptr);
241                                 if(tmpinfo->objptr == obj) {
242                                         // the same object in the queue, which should be enqueued
243                                         // recently. Current one is outdate, do not re-enqueue it
244                                         RUNFREE(objInfo->queues);
245                                         RUNFREE(objInfo);
246                                         goto objqueuebreak;
247                                 } else {
248                                         prev = qitem;
249                                 } // if(tmpinfo->objptr == obj)
250                                 qitem = getNextQueueItem(prev);
251                         } // while(qitem != NULL)
252                         // try to execute active tasks already enqueued first
253                         addNewItem_I(&objqueue, objInfo);
254 #ifdef PROFILE
255                         //isInterrupt = true;
256 #endif
257 objqueuebreak:
258                         BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE();
259 #ifdef DEBUG
260                         BAMBOO_DEBUGPRINT(0xf000);
261 #endif
262                         break;
263                 } // if(grount == 1)
264                 BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE();
265 #ifdef DEBUG
266                 BAMBOO_DEBUGPRINT(0xf000);
267 #endif
268         } // while(!isEmpty(&objqueue))
269
270 #ifdef PROFILE
271 #ifdef ACCURATEPROFILE
272         if(isChecking) {
273                 profileTaskEnd();
274         } // if(isChecking)
275 #endif
276 #endif
277
278 #ifdef DEBUG
279         BAMBOO_DEBUGPRINT(0xee02);
280 #endif
281         return rflag;
282 }
283
284 inline __attribute__((always_inline))
285 void checkCoreStatus() {
286         bool allStall = false;
287         int i = 0;
288         int sumsendobj = 0;
289         if((!waitconfirm) || 
290                         (waitconfirm && (numconfirm == 0))) {
291 #ifdef DEBUG
292                 BAMBOO_DEBUGPRINT(0xee04);
293                 BAMBOO_DEBUGPRINT_REG(waitconfirm);
294 #endif
295                 BAMBOO_START_CRITICAL_SECTION_STATUS();
296 #ifdef DEBUG
297                 BAMBOO_DEBUGPRINT(0xf001);
298 #endif
299                 corestatus[BAMBOO_NUM_OF_CORE] = 0;
300                 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
301                 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
302                 // check the status of all cores
303                 allStall = true;
304 #ifdef DEBUG
305                 BAMBOO_DEBUGPRINT_REG(NUMCORES);
306 #endif
307                 for(i = 0; i < NUMCORES; ++i) {
308 #ifdef DEBUG
309                         BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
310 #endif
311                         if(corestatus[i] != 0) {
312                                 allStall = false;
313                                 break;
314                         }
315                 } // for(i = 0; i < NUMCORES; ++i)
316                 if(allStall) {
317                         // check if the sum of send objs and receive obj are the same
318                         // yes->check if the info is the latest; no->go on executing
319                         sumsendobj = 0;
320                         for(i = 0; i < NUMCORES; ++i) {
321                                 sumsendobj += numsendobjs[i];
322 #ifdef DEBUG
323                                 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
324 #endif
325                         } // for(i = 0; i < NUMCORES; ++i)      
326                         for(i = 0; i < NUMCORES; ++i) {
327                                 sumsendobj -= numreceiveobjs[i];
328 #ifdef DEBUG
329                                 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
330 #endif
331                         } // for(i = 0; i < NUMCORES; ++i)
332                         if(0 == sumsendobj) {
333                                 if(!waitconfirm) {
334                                         // the first time found all cores stall
335                                         // send out status confirm msg to all other cores
336                                         // reset the corestatus array too
337 #ifdef DEBUG
338                                         BAMBOO_DEBUGPRINT(0xee05);
339 #endif
340                                         corestatus[BAMBOO_NUM_OF_CORE] = 1;
341                                         for(i = 1; i < NUMCORES; ++i) { 
342                                                 corestatus[i] = 1;
343                                                 // send status confirm msg to core i
344                                                 send_msg_1(i, STATUSCONFIRM);
345                                         } // for(i = 1; i < NUMCORES; ++i)
346                                         waitconfirm = true;
347                                         numconfirm = NUMCORES - 1;
348                                 } else {
349                                         // all the core status info are the latest
350                                         // terminate; for profiling mode, send request to all
351                                         // other cores to pour out profiling data
352 #ifdef DEBUG
353                                         BAMBOO_DEBUGPRINT(0xee06);
354 #endif                                            
355                          
356 #ifdef USEIO
357                                         totalexetime = BAMBOO_GET_EXE_TIME();
358 #else
359                                         BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME());
360                                         BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
361                                         BAMBOO_DEBUGPRINT(0xbbbbbbbb);
362 #endif
363                                         // profile mode, send msgs to other cores to request pouring
364                                         // out progiling data
365 #ifdef PROFILE
366                                         BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
367 #ifdef DEBUG
368                                         BAMBOO_DEBUGPRINT(0xf000);
369 #endif
370                                         for(i = 1; i < NUMCORES; ++i) {
371                                                 // send profile request msg to core i
372                                                 send_msg_2(i, PROFILEOUTPUT, totalexetime);
373                                         } // for(i = 1; i < NUMCORES; ++i)
374                                         // pour profiling data on startup core
375                                         outputProfileData();
376                                         while(true) {
377                                                 BAMBOO_START_CRITICAL_SECTION_STATUS();
378 #ifdef DEBUG
379                                                 BAMBOO_DEBUGPRINT(0xf001);
380 #endif
381                                                 profilestatus[BAMBOO_NUM_OF_CORE] = 0;
382                                                 // check the status of all cores
383                                                 allStall = true;
384 #ifdef DEBUG
385                                                 BAMBOO_DEBUGPRINT_REG(NUMCORES);
386 #endif  
387                                                 for(i = 0; i < NUMCORES; ++i) {
388 #ifdef DEBUG
389                                                         BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
390 #endif
391                                                         if(profilestatus[i] != 0) {
392                                                                 allStall = false;
393                                                                 break;
394                                                         }
395                                                 }  // for(i = 0; i < NUMCORES; ++i)
396                                                 if(!allStall) {
397                                                         int halt = 100;
398                                                         BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
399 #ifdef DEBUG
400                                                         BAMBOO_DEBUGPRINT(0xf000);
401 #endif
402                                                         while(halt--) {
403                                                         }
404                                                 } else {
405                                                         break;
406                                                 } // if(!allStall)
407                                         } // while(true)
408 #endif
409                                         disruntimedata();
410                                         terminate(); // All done.
411                                 } // if(!waitconfirm)
412                         } else {
413                                 // still some objects on the fly on the network
414                                 // reset the waitconfirm and numconfirm
415 #ifdef DEBUG
416                                         BAMBOO_DEBUGPRINT(0xee07);
417 #endif
418                                 waitconfirm = false;
419                                 numconfirm = 0;
420                         } //  if(0 == sumsendobj)
421                 } else {
422                         // not all cores are stall, keep on waiting
423 #ifdef DEBUG
424                         BAMBOO_DEBUGPRINT(0xee08);
425 #endif
426                         waitconfirm = false;
427                         numconfirm = 0;
428                 } //  if(allStall)
429                 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
430 #ifdef DEBUG
431                 BAMBOO_DEBUGPRINT(0xf000);
432 #endif
433         } // if((!waitconfirm) ||
434 }
435
436 // main function for each core
437 inline void run(void * arg) {
438   int i = 0;
439   int argc = 1;
440   char ** argv = NULL;
441   bool sendStall = false;
442   bool isfirst = true;
443   bool tocontinue = false;
444
445   corenum = BAMBOO_GET_NUM_OF_CORE();
446 #ifdef DEBUG
447   BAMBOO_DEBUGPRINT(0xeeee);
448   BAMBOO_DEBUGPRINT_REG(corenum);
449   BAMBOO_DEBUGPRINT(STARTUPCORE);
450 #endif
451
452         // initialize runtime data structures
453         initruntimedata();
454
455   // other architecture related initialization
456   initialization();
457   initCommunication();
458
459   initializeexithandler();
460
461   // main process of the execution module
462   if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
463         // non-executing cores, only processing communications
464     activetasks = NULL;
465 /*#ifdef PROFILE
466         BAMBOO_DEBUGPRINT(0xee01);
467         BAMBOO_DEBUGPRINT_REG(taskInfoIndex);
468         BAMBOO_DEBUGPRINT_REG(taskInfoOverflow);
469                 profileTaskStart("msg handling");
470         }
471  #endif*/
472 #ifdef PROFILE
473     //isInterrupt = false;
474 #endif
475                 fakeExecution();
476   } else {
477           /* Create queue of active tasks */
478           activetasks=
479                         genallocatehashtable((unsigned int(*) (void *)) &hashCodetpd,
480                            (int(*) (void *,void *)) &comparetpd);
481           
482           /* Process task information */
483           processtasks();
484           
485           if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
486                   /* Create startup object */
487                   createstartupobject(argc, argv);
488           }
489
490 #ifdef DEBUG
491           BAMBOO_DEBUGPRINT(0xee00);
492 #endif
493
494           while(true) {
495 #ifdef MULTICORE_GC
496                         // check if need to do GC
497                         gc(NULL);
498 #endif
499
500                   // check if there are new active tasks can be executed
501                   executetasks();
502                         if(busystatus) {
503                                 sendStall = false;
504                         }
505
506 #ifndef INTERRUPT
507                   while(receiveObject() != -1) {
508                   }
509 #endif  
510
511 #ifdef DEBUG
512                   BAMBOO_DEBUGPRINT(0xee01);
513 #endif  
514                   
515                   // check if there are some pending objects, 
516                         // if yes, enqueue them and executetasks again
517                   tocontinue = checkObjQueue();
518
519                   if(!tocontinue) {
520                           // check if stop
521                           if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
522                                   if(isfirst) {
523 #ifdef DEBUG
524                                           BAMBOO_DEBUGPRINT(0xee03);
525 #endif
526                                           isfirst = false;
527                                   }
528                                         checkCoreStatus();
529                           } else {
530                                   if(!sendStall) {
531 #ifdef DEBUG
532                                           BAMBOO_DEBUGPRINT(0xee09);
533 #endif
534 #ifdef PROFILE
535                                           if(!stall) {
536 #endif
537                                                   if(isfirst) {
538                                                           // wait for some time
539                                                           int halt = 10000;
540 #ifdef DEBUG
541                                                           BAMBOO_DEBUGPRINT(0xee0a);
542 #endif
543                                                           while(halt--) {
544                                                           }
545                                                           isfirst = false;
546                                                   } else {
547                                                           // send StallMsg to startup core
548 #ifdef DEBUG
549                                                           BAMBOO_DEBUGPRINT(0xee0b);
550 #endif
551                                                           // send stall msg
552                                                           send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE, 
553                                                                                        self_numsendobjs, self_numreceiveobjs);
554                                                           sendStall = true;
555                                                           isfirst = true;
556                                                           busystatus = false;
557                                                   }
558 #ifdef PROFILE
559                                           }
560 #endif
561                                   } else {
562                                           isfirst = true;
563                                           busystatus = false;
564 #ifdef DEBUG
565                                           BAMBOO_DEBUGPRINT(0xee0c);
566 #endif
567                                   } // if(!sendStall)
568                           } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE) 
569                   } // if(!tocontinue)
570           } // while(true) 
571   } // if(BAMBOO_NUM_OF_CORE > NUMCORES - 1)
572
573 } // run()
574
575 struct ___createstartupobject____I_locals {
576   INTPTR size;
577   void * next;
578   struct  ___StartupObject___ * ___startupobject___;
579   struct ArrayObject * ___stringarray___;
580 }; // struct ___createstartupobject____I_locals
581
582 void createstartupobject(int argc, 
583                                      char ** argv) {
584   int i;
585
586   /* Allocate startup object     */
587 #ifdef MULTICORE_GC
588         struct ___createstartupobject____I_locals ___locals___={2, NULL, NULL, NULL};
589   struct ___StartupObject___ *startupobject=
590                 (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
591         ___locals___.___startupobject___ = startupobject;
592   struct ArrayObject * stringarray=
593                 allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
594         ___locals___.___stringarray___ = stringarray;
595 #else
596   struct ___StartupObject___ *startupobject=
597                 (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
598   struct ArrayObject * stringarray=
599                 allocate_newarray(STRINGARRAYTYPE, argc-1);
600 #endif
601   /* Build array of strings */
602   startupobject->___parameters___=stringarray;
603   for(i=1; i<argc; i++) {
604     int length=strlen(argv[i]);
605 #ifdef MULTICORE_GC
606     struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
607 #else
608     struct ___String___ *newstring=NewString(argv[i],length);
609 #endif
610     ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
611                         newstring;
612   }
613
614   startupobject->version = 0;
615   startupobject->lock = NULL;
616
617   /* Set initialized flag for startup object */
618   flagorandinit(startupobject,1,0xFFFFFFFF);
619   enqueueObject(startupobject, NULL, 0);
620 #ifdef CACHEFLUSH
621   BAMBOO_CACHE_FLUSH_ALL();
622 #endif
623 }
624
625 int hashCodetpd(struct taskparamdescriptor *ftd) {
626   int hash=(int)ftd->task;
627   int i;
628   for(i=0; i<ftd->numParameters; i++) {
629     hash^=(int)ftd->parameterArray[i];
630   }
631   return hash;
632 }
633
634 int comparetpd(struct taskparamdescriptor *ftd1, 
635                            struct taskparamdescriptor *ftd2) {
636   int i;
637   if (ftd1->task!=ftd2->task)
638     return 0;
639   for(i=0; i<ftd1->numParameters; i++)
640     if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
641       return 0;
642   return 1;
643 }
644
645 /* This function sets a tag. */
646 #ifdef MULTICORE_GC
647 void tagset(void *ptr, 
648                         struct ___Object___ * obj, 
649                                                 struct ___TagDescriptor___ * tagd) {
650 #else
651 void tagset(struct ___Object___ * obj, 
652                         struct ___TagDescriptor___ * tagd) {
653 #endif
654   struct ArrayObject * ao=NULL;
655   struct ___Object___ * tagptr=obj->___tags___;
656   if (tagptr==NULL) {
657     obj->___tags___=(struct ___Object___ *)tagd;
658   } else {
659     /* Have to check if it is already set */
660     if (tagptr->type==TAGTYPE) {
661       struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
662       if (td==tagd) {
663         return;
664       }
665 #ifdef MULTICORE_GC
666       int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
667       struct ArrayObject * ao=
668                                 allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
669       obj=(struct ___Object___ *)ptrarray[2];
670       tagd=(struct ___TagDescriptor___ *)ptrarray[3];
671       td=(struct ___TagDescriptor___ *) obj->___tags___;
672 #else
673       ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
674 #endif
675
676       ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
677       ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
678       obj->___tags___=(struct ___Object___ *) ao;
679       ao->___cachedCode___=2;
680     } else {
681       /* Array Case */
682       int i;
683       struct ArrayObject *ao=(struct ArrayObject *) tagptr;
684       for(i=0; i<ao->___cachedCode___; i++) {
685         struct ___TagDescriptor___ * td=
686                 ARRAYGET(ao, struct ___TagDescriptor___*, i);
687         if (td==tagd) {
688           return;
689         }
690       }
691       if (ao->___cachedCode___<ao->___length___) {
692         ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
693         ao->___cachedCode___++;
694       } else {
695 #ifdef MULTICORE_GC
696         int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
697         struct ArrayObject * aonew=
698                 allocate_newarray(&ptrarray,TAGARRAYTYPE,
699                                               TAGARRAYINTERVAL+ao->___length___);
700         obj=(struct ___Object___ *)ptrarray[2];
701         tagd=(struct ___TagDescriptor___ *) ptrarray[3];
702         ao=(struct ArrayObject *)obj->___tags___;
703 #else
704         struct ArrayObject * aonew=
705                 allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
706 #endif
707
708         aonew->___cachedCode___=ao->___length___+1;
709         for(i=0; i<ao->___length___; i++) {
710           ARRAYSET(aonew, struct ___TagDescriptor___*, i, 
711                                      ARRAYGET(ao, struct ___TagDescriptor___*, i));
712         }
713         ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
714       }
715     }
716   }
717
718   {
719     struct ___Object___ * tagset=tagd->flagptr;
720     if(tagset==NULL) {
721       tagd->flagptr=obj;
722     } else if (tagset->type!=OBJECTARRAYTYPE) {
723 #ifdef MULTICORE_GC
724       int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
725       struct ArrayObject * ao=
726                                 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
727       obj=(struct ___Object___ *)ptrarray[2];
728       tagd=(struct ___TagDescriptor___ *)ptrarray[3];
729 #else
730       struct ArrayObject * ao=
731                                 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
732 #endif
733       ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
734       ARRAYSET(ao, struct ___Object___ *, 1, obj);
735       ao->___cachedCode___=2;
736       tagd->flagptr=(struct ___Object___ *)ao;
737     } else {
738       struct ArrayObject *ao=(struct ArrayObject *) tagset;
739       if (ao->___cachedCode___<ao->___length___) {
740         ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
741       } else {
742         int i;
743 #ifdef MULTICORE_GC
744         int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
745         struct ArrayObject * aonew=
746                 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
747                                               OBJECTARRAYINTERVAL+ao->___length___);
748         obj=(struct ___Object___ *)ptrarray[2];
749         tagd=(struct ___TagDescriptor___ *)ptrarray[3];
750         ao=(struct ArrayObject *)tagd->flagptr;
751 #else
752         struct ArrayObject * aonew=
753                 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
754 #endif
755         aonew->___cachedCode___=ao->___cachedCode___+1;
756         for(i=0; i<ao->___length___; i++) {
757           ARRAYSET(aonew, struct ___Object___*, i, 
758                                      ARRAYGET(ao, struct ___Object___*, i));
759         }
760         ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
761         tagd->flagptr=(struct ___Object___ *) aonew;
762       }
763     }
764   }
765 }
766
767 /* This function clears a tag. */
768 #ifdef MULTICORE_GC
769 void tagclear(void *ptr, 
770                           struct ___Object___ * obj, 
771                                                         struct ___TagDescriptor___ * tagd) {
772 #else
773 void tagclear(struct ___Object___ * obj, 
774                           struct ___TagDescriptor___ * tagd) {
775 #endif
776   /* We'll assume that tag is alway there.
777      Need to statically check for this of course. */
778   struct ___Object___ * tagptr=obj->___tags___;
779
780   if (tagptr->type==TAGTYPE) {
781     if ((struct ___TagDescriptor___ *)tagptr==tagd)
782       obj->___tags___=NULL;
783   } else {
784     struct ArrayObject *ao=(struct ArrayObject *) tagptr;
785     int i;
786     for(i=0; i<ao->___cachedCode___; i++) {
787       struct ___TagDescriptor___ * td=
788                                 ARRAYGET(ao, struct ___TagDescriptor___ *, i);
789       if (td==tagd) {
790         ao->___cachedCode___--;
791         if (i<ao->___cachedCode___)
792           ARRAYSET(ao, struct ___TagDescriptor___ *, i, 
793                                 ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
794         ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
795         if (ao->___cachedCode___==0)
796           obj->___tags___=NULL;
797         goto PROCESSCLEAR;
798       }
799     }
800   }
801 PROCESSCLEAR:
802   {
803     struct ___Object___ *tagset=tagd->flagptr;
804     if (tagset->type!=OBJECTARRAYTYPE) {
805       if (tagset==obj)
806         tagd->flagptr=NULL;
807     } else {
808       struct ArrayObject *ao=(struct ArrayObject *) tagset;
809       int i;
810       for(i=0; i<ao->___cachedCode___; i++) {
811         struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
812         if (tobj==obj) {
813           ao->___cachedCode___--;
814           if (i<ao->___cachedCode___)
815             ARRAYSET(ao, struct ___Object___ *, i, 
816                                         ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
817           ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
818           if (ao->___cachedCode___==0)
819             tagd->flagptr=NULL;
820           goto ENDCLEAR;
821         }
822       }
823     }
824   }
825 ENDCLEAR:
826   return;
827 }
828
829 /* This function allocates a new tag. */
830 #ifdef MULTICORE_GC
831 struct ___TagDescriptor___ * allocate_tag(void *ptr, 
832                                                       int index) {
833   struct ___TagDescriptor___ * v=
834                 (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr, 
835                                                                       classsize[TAGTYPE]);
836 #else
837 struct ___TagDescriptor___ * allocate_tag(int index) {
838   struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
839 #endif
840   v->type=TAGTYPE;
841   v->flag=index;
842   return v;
843 }
844
845
846
847 /* This function updates the flag for object ptr.  It or's the flag
848    with the or mask and and's it with the andmask. */
849
850 void flagbody(struct ___Object___ *ptr, 
851                           int flag, 
852                                                         struct parameterwrapper ** queues, 
853                                                         int length, 
854                                                         bool isnew);
855
856 int flagcomp(const int *val1, const int *val2) {
857   return (*val1)-(*val2);
858 }
859
860 void flagorand(void * ptr, 
861                            int ormask, 
862                                                          int andmask, 
863                                                          struct parameterwrapper ** queues, 
864                                                          int length) {
865   {
866     int oldflag=((int *)ptr)[1];
867     int flag=ormask|oldflag;
868     flag&=andmask;
869     flagbody(ptr, flag, queues, length, false);
870   }
871 }
872
873 bool intflagorand(void * ptr, 
874                               int ormask, 
875                                                                         int andmask) {
876   {
877     int oldflag=((int *)ptr)[1];
878     int flag=ormask|oldflag;
879     flag&=andmask;
880     if (flag==oldflag)   /* Don't do anything */
881       return false;
882     else {
883       flagbody(ptr, flag, NULL, 0, false);
884       return true;
885     }
886   }
887 }
888
889 void flagorandinit(void * ptr, 
890                                int ormask, 
891                                                                          int andmask) {
892   int oldflag=((int *)ptr)[1];
893   int flag=ormask|oldflag;
894   flag&=andmask;
895   flagbody(ptr,flag,NULL,0,true);
896 }
897
898 void flagbody(struct ___Object___ *ptr, 
899                           int flag, 
900                                                         struct parameterwrapper ** vqueues, 
901                                                         int vlength, 
902                                                         bool isnew) {
903   struct parameterwrapper * flagptr = NULL;
904   int i = 0;
905   struct parameterwrapper ** queues = vqueues;
906   int length = vlength;
907   int next;
908   int UNUSED, UNUSED2;
909   int * enterflags = NULL;
910   if((!isnew) && (queues == NULL)) {
911     if(BAMBOO_NUM_OF_CORE < NUMCORES) {
912                 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
913                 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
914         } else {
915                 return;
916         }
917   }
918   ptr->flag=flag;
919
920   /*Remove object from all queues */
921   for(i = 0; i < length; ++i) {
922     flagptr = queues[i];
923     ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next, 
924                                           (int *) &enterflags, &UNUSED, &UNUSED2);
925     ObjectHashremove(flagptr->objectset, (int)ptr);
926     if (enterflags!=NULL)
927       RUNFREE(enterflags);
928   }
929 }
930
931 void enqueueObject(void * vptr, 
932                                struct parameterwrapper ** vqueues, 
933                                                                          int vlength) {
934         struct ___Object___ *ptr = (struct ___Object___ *)vptr;
935         
936         {
937                 //struct QueueItem *tmpptr;
938                 struct parameterwrapper * parameter=NULL;
939                 int j;
940                 int i;
941                 struct parameterwrapper * prevptr=NULL;
942                 struct ___Object___ *tagptr=NULL;
943                 struct parameterwrapper ** queues = vqueues;
944                 int length = vlength;
945                 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
946                         return;
947                 }
948                 if(queues == NULL) {
949                         queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
950                         length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
951                 }
952                 tagptr=ptr->___tags___;
953
954                 /* Outer loop iterates through all parameter queues an object of
955                    this type could be in.  */
956                 for(j = 0; j < length; ++j) {
957                         parameter = queues[j];     
958                         /* Check tags */
959                         if (parameter->numbertags>0) {
960                                 if (tagptr==NULL)
961                                         goto nextloop; //that means the object has no tag 
962                                                  //but that param needs tag
963                                 else if(tagptr->type==TAGTYPE) { //one tag
964                                         //struct ___TagDescriptor___ * tag=
965                                         //(struct ___TagDescriptor___*) tagptr;  
966                                         for(i=0; i<parameter->numbertags; i++) {
967                                                 //slotid is parameter->tagarray[2*i];
968                                                 int tagid=parameter->tagarray[2*i+1];
969                                                 if (tagid!=tagptr->flag)
970                                                         goto nextloop; /*We don't have this tag */
971                                         }
972                                 } else { //multiple tags
973                                         struct ArrayObject * ao=(struct ArrayObject *) tagptr;
974                                         for(i=0; i<parameter->numbertags; i++) {
975                                                 //slotid is parameter->tagarray[2*i];
976                                                 int tagid=parameter->tagarray[2*i+1];
977                                                 int j;
978                                                 for(j=0; j<ao->___cachedCode___; j++) {
979                                                         if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
980                                                                 goto foundtag;
981                                                 }
982                                                 goto nextloop;
983 foundtag:
984                                                 ;
985                                         }
986                                 }
987                         }
988         
989                         /* Check flags */
990                         for(i=0; i<parameter->numberofterms; i++) {
991                                 int andmask=parameter->intarray[i*2];
992                                 int checkmask=parameter->intarray[i*2+1];
993                                 if ((ptr->flag&andmask)==checkmask) {
994                                         enqueuetasks(parameter, prevptr, ptr, NULL, 0);
995                                         prevptr=parameter;
996                                         break;
997                                 }
998                         }
999 nextloop:
1000                         ;
1001                 }
1002         }
1003 }
1004
1005 void enqueueObject_I(void * vptr, 
1006                                  struct parameterwrapper ** vqueues, 
1007                                                                                  int vlength) {
1008         struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1009         
1010         {
1011                 //struct QueueItem *tmpptr;
1012                 struct parameterwrapper * parameter=NULL;
1013                 int j;
1014                 int i;
1015                 struct parameterwrapper * prevptr=NULL;
1016                 struct ___Object___ *tagptr=NULL;
1017                 struct parameterwrapper ** queues = vqueues;
1018                 int length = vlength;
1019                 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1020                         return;
1021                 }
1022                 if(queues == NULL) {
1023                         queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1024                         length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1025                 }
1026                 tagptr=ptr->___tags___;
1027
1028                 /* Outer loop iterates through all parameter queues an object of
1029                    this type could be in.  */
1030                 for(j = 0; j < length; ++j) {
1031                         parameter = queues[j];     
1032                         /* Check tags */
1033                         if (parameter->numbertags>0) {
1034                                 if (tagptr==NULL)
1035                                         goto nextloop; //that means the object has no tag 
1036                                                  //but that param needs tag
1037                                 else if(tagptr->type==TAGTYPE) { //one tag
1038                                         //struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;         
1039                                         for(i=0; i<parameter->numbertags; i++) {
1040                                                 //slotid is parameter->tagarray[2*i];
1041                                                 int tagid=parameter->tagarray[2*i+1];
1042                                                 if (tagid!=tagptr->flag)
1043                                                         goto nextloop; /*We don't have this tag */
1044                                         }
1045                                 } else { //multiple tags
1046                                         struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1047                                         for(i=0; i<parameter->numbertags; i++) {
1048                                                 //slotid is parameter->tagarray[2*i];
1049                                                 int tagid=parameter->tagarray[2*i+1];
1050                                                 int j;
1051                                                 for(j=0; j<ao->___cachedCode___; j++) {
1052                                                         if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1053                                                                 goto foundtag;
1054                                                 }
1055                                                 goto nextloop;
1056 foundtag:
1057                                                 ;
1058                                         }
1059                                 }
1060                         }
1061
1062                         /* Check flags */
1063                         for(i=0; i<parameter->numberofterms; i++) {
1064                                 int andmask=parameter->intarray[i*2];
1065                                 int checkmask=parameter->intarray[i*2+1];
1066                                 if ((ptr->flag&andmask)==checkmask) {
1067                                         enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1068                                         prevptr=parameter;
1069                                         break;
1070                                 }
1071                         }
1072 nextloop:
1073                         ;
1074                 }
1075         }
1076 }
1077
1078
1079 int * getAliasLock(void ** ptrs, 
1080                                int length, 
1081                                                                          struct RuntimeHash * tbl) {
1082         if(length == 0) {
1083                 return (int*)(RUNMALLOC(sizeof(int)));
1084         } else {
1085                 int i = 0;
1086                 int locks[length];
1087                 int locklen = 0;
1088                 bool redirect = false;
1089                 int redirectlock = 0;
1090                 for(; i < length; i++) {
1091                         struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1092                         int lock = 0;
1093                         int j = 0;
1094                         if(ptr->lock == NULL) {
1095                                 lock = (int)(ptr);
1096                         } else {
1097                                 lock = (int)(ptr->lock);
1098                         }
1099                         if(redirect) {
1100                                 if(lock != redirectlock) {
1101                                         RuntimeHashadd(tbl, lock, redirectlock);
1102                                 }
1103                         } else {
1104                                 if(RuntimeHashcontainskey(tbl, lock)) {
1105                                         // already redirected
1106                                         redirect = true;
1107                                         RuntimeHashget(tbl, lock, &redirectlock);
1108                                         for(; j < locklen; j++) {
1109                                                 if(locks[j] != redirectlock) {
1110                                                         RuntimeHashadd(tbl, locks[j], redirectlock);
1111                                                 }
1112                                         }
1113                                 } else {
1114                                         bool insert = true;
1115                                         for(j = 0; j < locklen; j++) {
1116                                                 if(locks[j] == lock) {
1117                                                         insert = false;
1118                                                         break;
1119                                                 } else if(locks[j] > lock) {
1120                                                         break;
1121                                                 }
1122                                         }
1123                                         if(insert) {
1124                                                 int h = locklen;
1125                                                 for(; h > j; h--) {
1126                                                         locks[h] = locks[h-1];
1127                                                 }       
1128                                                 locks[j] = lock;
1129                                                 locklen++;
1130                                         }
1131                                 }
1132                         }
1133                 }
1134                 if(redirect) {
1135                         return (int *)redirectlock;
1136                 } else {
1137                         return (int *)(locks[0]);
1138                 }
1139         }
1140 }
1141
1142 void addAliasLock(void * ptr, 
1143                               int lock) {
1144   struct ___Object___ * obj = (struct ___Object___ *)ptr;
1145   if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1146     // originally no alias lock associated or have a different alias lock
1147     // flush it as the new one
1148     obj->lock = (int *)lock;
1149   }
1150 }
1151
1152 #ifdef PROFILE
1153 inline void setTaskExitIndex(int index) {
1154         taskInfoArray[taskInfoIndex]->exitIndex = index;
1155 }
1156
1157 inline void addNewObjInfo(void * nobj) {
1158         if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1159                 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1160         }
1161         addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1162 }
1163 #endif
1164
1165 void * smemalloc(int size, 
1166                              int * allocsize) {
1167         void * mem = NULL;
1168         int isize = size+(BAMBOO_CACHE_LINE_SIZE);
1169         int toallocate = ((size+(BAMBOO_CACHE_LINE_SIZE))>(BAMBOO_SMEM_SIZE)) ? 
1170                                      (size+(BAMBOO_CACHE_LINE_SIZE)):(BAMBOO_SMEM_SIZE);
1171 #ifdef MULTICORE_GC
1172         // go through free mem list for suitable blocks
1173         struct freeMemItem * freemem = bamboo_free_mem_list->head;
1174         struct freeMemItem * prev = NULL;
1175         do {
1176                 if(freemem->size >= isize) {
1177                         // found one
1178                         break;
1179                 }
1180                 prev = freemem;
1181                 freemem = freemem->next;
1182         } while(freemem != NULL);
1183         if(freemem != NULL) {
1184                 mem = (void *)(freemem->ptr);
1185                 // check the remaining space in this block
1186                 int remain = (int)(mem-(BAMBOO_BASE_VA));
1187                 int bound = (BAMBOO_SMEM_SIZE);
1188                 if(remain < BAMBOO_LARGE_SMEM_BOUND) {
1189                         bound = (BAMBOO_SMEM_SIZE_L);
1190                 }
1191                 remain = bound - remain%bound;
1192                 if(remain < isize) {
1193                         // this object acrosses blocks
1194                         *allocsize = isize;
1195                 } else {
1196                         // round the asigned block to the end of the current block
1197                         *allocsize = remain;
1198                 }
1199                 freemem->ptr = ((void*)freemem->ptr) + (*allocsize);
1200                 freemem->size -= *allocsize;
1201         } else {
1202 #else
1203         mem = mspace_calloc(bamboo_free_msp, 1, isize);
1204         *allocsize = isize;
1205         if(mem == NULL) {
1206 #endif
1207                 // no enough shared global memory
1208                 *allocsize = 0;
1209 #ifdef MULTICORE_GC
1210                 gcflag = true;
1211                 return NULL;
1212 #else
1213                 BAMBOO_DEBUGPRINT(0xa001);
1214                 BAMBOO_EXIT(0xa001);
1215 #endif
1216         }
1217         return mem;
1218 }
1219
1220 // receive object transferred from other cores
1221 // or the terminate message from other cores
1222 // Should be invoked in critical sections!!
1223 // NOTICE: following format is for threadsimulate version only
1224 //         RAW version please see previous description
1225 // format: type + object
1226 // type: -1--stall msg
1227 //      !-1--object
1228 // return value: 0--received an object
1229 //               1--received nothing
1230 //               2--received a Stall Msg
1231 //               3--received a lock Msg
1232 //               RAW version: -1 -- received nothing
1233 //                            otherwise -- received msg type
1234 int receiveObject() {
1235   int deny = 0;
1236   
1237 msg:
1238   if(receiveMsg() == -1) {
1239           return -1;
1240   }
1241
1242   if(msgdataindex == msglength) {
1243     // received a whole msg
1244     MSGTYPE type; 
1245     type = msgdata[0];
1246     switch(type) {
1247     case TRANSOBJ: {
1248       // receive a object transfer msg
1249       struct transObjInfo * transObj = 
1250                                 RUNMALLOC_I(sizeof(struct transObjInfo));
1251       int k = 0;
1252 #ifdef DEBUG
1253 #ifndef TILERA
1254                         BAMBOO_DEBUGPRINT(0xe880);
1255 #endif
1256 #endif
1257       if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1258 #ifndef TILERA
1259                                 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1260 #endif
1261                                 BAMBOO_EXIT(0xa002);
1262                         } 
1263       // store the object and its corresponding queue info, enqueue it later
1264       transObj->objptr = (void *)msgdata[2]; 
1265       transObj->length = (msglength - 3) / 2;
1266       transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
1267       for(k = 0; k < transObj->length; ++k) {
1268                                 transObj->queues[2*k] = msgdata[3+2*k];
1269 #ifdef DEBUG
1270 #ifndef TILERA
1271                                 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
1272 #endif
1273 #endif
1274                                 transObj->queues[2*k+1] = msgdata[3+2*k+1];
1275 #ifdef DEBUG
1276 #ifndef TILERA
1277                                 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
1278 #endif
1279 #endif
1280                         }
1281       // check if there is an existing duplicate item
1282       {
1283                                 struct QueueItem * qitem = getHead(&objqueue);
1284                                 struct QueueItem * prev = NULL;
1285                                 while(qitem != NULL) {
1286                                         struct transObjInfo * tmpinfo = 
1287                                                 (struct transObjInfo *)(qitem->objectptr);
1288                                         if(tmpinfo->objptr == transObj->objptr) {
1289                                                 // the same object, remove outdate one
1290                                                 removeItem(&objqueue, qitem);
1291                                                 //break;
1292                                         } else {
1293                                                 prev = qitem;
1294                                         }
1295                                         if(prev == NULL) {
1296                                                 qitem = getHead(&objqueue);
1297                                         } else {
1298                                                 qitem = getNextQueueItem(prev);
1299                                         }
1300                                 }
1301                                 addNewItem_I(&objqueue, (void *)transObj);
1302                         }
1303       ++(self_numreceiveobjs);
1304       break;
1305     }
1306
1307     case TRANSTALL: {
1308       // receive a stall msg
1309       if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1310                   // non startup core can not receive stall msg
1311 #ifndef TILERA
1312                                 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1313 #endif
1314                                 BAMBOO_EXIT(0xa003);
1315       } 
1316       if(msgdata[1] < NUMCORES) {
1317 #ifdef DEBUG
1318 #ifndef TILERA
1319                                 BAMBOO_DEBUGPRINT(0xe881);
1320 #endif
1321 #endif
1322                                 corestatus[msgdata[1]] = 0;
1323                                 numsendobjs[msgdata[1]] = msgdata[2];
1324                                 numreceiveobjs[msgdata[1]] = msgdata[3];
1325       }
1326       break;
1327     }
1328
1329 // GC version have no lock msgs
1330 #ifndef MULTICORE_GC
1331     case LOCKREQUEST: {
1332       // receive lock request msg, handle it right now
1333       // check to see if there is a lock exist for the required obj
1334                         // msgdata[1] -> lock type
1335                         int data2 = msgdata[2]; // obj pointer
1336       int data3 = msgdata[3]; // lock
1337                         int data4 = msgdata[4]; // request core
1338                         // -1: redirected, 0: approved, 1: denied
1339       deny = processlockrequest(msgdata[1], data3, data2, 
1340                                                               data4, data4, true);  
1341                         if(deny == -1) {
1342                                 // this lock request is redirected
1343                                 break;
1344                         } else {
1345                                 // send response msg
1346                                 // for 32 bit machine, the size is always 4 words
1347                                 int tmp = deny==1?LOCKDENY:LOCKGROUNT;
1348                                 if(isMsgSending) {
1349                                         cache_msg_4(data4, tmp, msgdata[1], data2, data3);
1350                                 } else {
1351                                         send_msg_4(data4, tmp, msgdata[1], data2, data3);
1352                                 }
1353                         }
1354       break;
1355     }
1356
1357     case LOCKGROUNT: {
1358       // receive lock grount msg
1359       if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1360 #ifndef TILERA
1361                                 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1362 #endif
1363                                 BAMBOO_EXIT(0xa004);
1364       } 
1365       if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1366 #ifdef DEBUG
1367 #ifndef TILERA
1368                                 BAMBOO_DEBUGPRINT(0xe882);
1369 #endif
1370 #endif
1371                                 lockresult = 1;
1372                                 lockflag = true;
1373 #ifndef INTERRUPT
1374                                 reside = false;
1375 #endif
1376                         } else {
1377                                 // conflicts on lockresults
1378 #ifndef TILERA
1379                                 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1380 #endif
1381                                 BAMBOO_EXIT(0xa005);
1382       }
1383       break;
1384     }
1385
1386     case LOCKDENY: {
1387       // receive lock deny msg
1388       if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1389 #ifndef TILERA
1390                                 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1391 #endif
1392                                 BAMBOO_EXIT(0xa006);
1393       } 
1394       if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1395 #ifdef DEBUG
1396 #ifndef TILERA
1397                                 BAMBOO_DEBUGPRINT(0xe883);
1398 #endif
1399 #endif
1400                                 lockresult = 0;
1401                                 lockflag = true;
1402 #ifndef INTERRUPT
1403                                 reside = false;
1404 #endif
1405                                 } else {
1406                                 // conflicts on lockresults
1407 #ifndef TILERA
1408                                 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1409 #endif
1410                                 BAMBOO_EXIT(0xa007);
1411       }
1412       break;
1413     }
1414
1415     case LOCKRELEASE: {
1416       // receive lock release msg
1417                         processlockrelease(msgdata[1], msgdata[2], 0, false);
1418       break;
1419     }
1420 #endif
1421
1422 #ifdef PROFILE
1423     case PROFILEOUTPUT: {
1424       // receive an output profile data request msg
1425       if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
1426                                 // startup core can not receive profile output finish msg
1427                                 BAMBOO_EXIT(0xa008);
1428       }
1429 #ifdef DEBUG
1430 #ifndef TILEAR
1431                         BAMBOO_DEBUGPRINT(0xe885);
1432 #endif
1433 #endif
1434                         stall = true;
1435                         totalexetime = msgdata[1];
1436                         outputProfileData();
1437                         if(isMsgSending) {
1438                                 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1439                         } else {
1440                                 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1441                         }
1442       break;
1443     }
1444
1445     case PROFILEFINISH: {
1446       // receive a profile output finish msg
1447       if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1448                                 // non startup core can not receive profile output finish msg
1449 #ifndef TILERA
1450                                 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1451 #endif
1452                                 BAMBOO_EXIT(0xa009);
1453       }
1454 #ifdef DEBUG
1455 #ifndef TILERA
1456                         BAMBOO_DEBUGPRINT(0xe886);
1457 #endif
1458 #endif
1459                         profilestatus[msgdata[1]] = 0;
1460       break;
1461     }
1462 #endif
1463
1464 // GC version has no lock msgs
1465 #ifndef MULTICORE_GC
1466         case REDIRECTLOCK: {
1467           // receive a redirect lock request msg, handle it right now
1468                 // check to see if there is a lock exist for the required obj
1469           int data1 = msgdata[1]; // lock type
1470           int data2 = msgdata[2]; // obj pointer
1471                 int data3 = msgdata[3]; // redirect lock
1472           int data4 = msgdata[4]; // root request core
1473           int data5 = msgdata[5]; // request core
1474           deny = processlockrequest(msgdata[1], data3, data2, data5, data4, true);
1475           if(deny == -1) {
1476                   // this lock request is redirected
1477                   break;
1478           } else {
1479                   // send response msg
1480                   // for 32 bit machine, the size is always 4 words
1481                   if(isMsgSending) {
1482                           cache_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT, 
1483                                                         data1, data2, data3);
1484                   } else {
1485                           send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT, 
1486                                                        data1, data2, data3);
1487                   }
1488           }
1489           break;
1490         }
1491
1492         case REDIRECTGROUNT: {
1493                 // receive a lock grant msg with redirect info
1494                 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1495 #ifndef TILERA
1496                         BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1497 #endif
1498                         BAMBOO_EXIT(0xa00a);
1499                 }
1500                 if(lockobj == msgdata[2]) {
1501 #ifdef DEBUG
1502 #ifndef TILERA
1503                   BAMBOO_DEBUGPRINT(0xe891);
1504 #endif
1505 #endif
1506                   lockresult = 1;
1507                   lockflag = true;
1508                   RuntimeHashadd_I(objRedirectLockTbl, lockobj, msgdata[3]);
1509 #ifndef INTERRUPT
1510                   reside = false;
1511 #endif
1512                 } else {
1513                   // conflicts on lockresults
1514 #ifndef TILERA
1515                   BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1516 #endif
1517                   BAMBOO_EXIT(0xa00b);
1518                 }
1519                 break;
1520         }
1521         
1522         case REDIRECTDENY: {
1523           // receive a lock deny msg with redirect info
1524           if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1525 #ifndef TILERA
1526                   BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1527 #endif
1528                   BAMBOO_EXIT(0xa00c);
1529           }
1530                 if(lockobj == msgdata[2]) {
1531 #ifdef DEBUG
1532 #ifndef TILERA
1533                   BAMBOO_DEBUGPRINT(0xe892);
1534 #endif
1535 #endif
1536                   lockresult = 0;
1537                   lockflag = true;
1538 #ifndef INTERRUPT
1539                   reside = false;
1540 #endif
1541                 } else {
1542                   // conflicts on lockresults
1543 #ifndef TILERA
1544                   BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1545 #endif
1546                   BAMBOO_EXIT(0xa00d);
1547                 }
1548                 break;
1549         }
1550
1551         case REDIRECTRELEASE: {
1552           // receive a lock release msg with redirect info
1553                 processlockrelease(msgdata[1], msgdata[2], msgdata[3], true);
1554                 break;
1555         }
1556 #endif
1557         
1558         case STATUSCONFIRM: {
1559       // receive a status confirm info
1560           if((BAMBOO_NUM_OF_CORE == STARTUPCORE) 
1561                                 || (BAMBOO_NUM_OF_CORE > NUMCORES - 1)) {
1562                   // wrong core to receive such msg
1563                   BAMBOO_EXIT(0xa00e);
1564                 } else {
1565                   // send response msg
1566 #ifdef DEBUG
1567 #ifndef TILERA
1568                   BAMBOO_DEBUGPRINT(0xe887);
1569 #endif
1570 #endif
1571                   if(isMsgSending) {
1572                           cache_msg_5(STARTUPCORE, STATUSREPORT, 
1573                                                         busystatus?1:0, BAMBOO_NUM_OF_CORE,
1574                                                                                 self_numsendobjs, self_numreceiveobjs);
1575                   } else {
1576                           send_msg_5(STARTUPCORE, STATUSREPORT, 
1577                                                        busystatus?1:0, BAMBOO_NUM_OF_CORE,
1578                                                                          self_numsendobjs, self_numreceiveobjs);
1579                   }
1580                 }
1581           break;
1582         }
1583
1584         case STATUSREPORT: {
1585           // receive a status confirm info
1586           if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1587                   // wrong core to receive such msg
1588 #ifndef TILERA
1589                   BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1590 #endif
1591                   BAMBOO_EXIT(0xa00f);
1592                 } else {
1593 #ifdef DEBUG
1594 #ifndef TILERA
1595                   BAMBOO_DEBUGPRINT(0xe888);
1596 #endif
1597 #endif
1598                   if(waitconfirm) {
1599                           numconfirm--;
1600                   }
1601                   corestatus[msgdata[2]] = msgdata[1];
1602                         numsendobjs[msgdata[2]] = msgdata[3];
1603                         numreceiveobjs[msgdata[2]] = msgdata[4];
1604                 }
1605           break;
1606         }
1607
1608         case TERMINATE: {
1609           // receive a terminate msg
1610 #ifdef DEBUG
1611 #ifndef TILERA
1612                 BAMBOO_DEBUGPRINT(0xe889);
1613 #endif
1614 #endif
1615                 disruntimedata();
1616                 BAMBOO_EXIT(0);
1617           break;
1618         }
1619
1620         case MEMREQUEST: {
1621           // receive a shared memory request msg
1622           if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1623                   // wrong core to receive such msg
1624 #ifndef TILERA
1625                   BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1626 #endif
1627                   BAMBOO_EXIT(0xa010);
1628                 } else {
1629 #ifdef DEBUG
1630 #ifndef TILERA
1631                   BAMBOO_DEBUGPRINT(0xe88a);
1632 #endif
1633 #endif
1634 #ifdef MULTICORE_GC
1635                         if(gcprocessing) {
1636                                 // is currently doing gc, dump this msg
1637                                 break;
1638                         }
1639 #endif
1640                         int allocsize = 0;
1641                   void * mem = smemalloc(msgdata[1], &allocsize);
1642                         if(mem == NULL) {
1643                                 break;
1644                         }
1645                         // send the start_va to request core
1646                         if(isMsgSending) {
1647                                 cache_msg_3(msgdata[2], MEMRESPONSE, mem, allocsize);
1648                         } else {
1649                                 send_msg_3( msgdata[2], MEMRESPONSE, mem, allocsize);
1650                         } 
1651                 }
1652           break;
1653         }
1654
1655         case MEMRESPONSE: {
1656                 // receive a shared memory response msg
1657 #ifdef DEBUG
1658 #ifndef TILERA
1659           BAMBOO_DEBUGPRINT(0xe88b);
1660 #endif
1661 #endif
1662 #ifdef MULTICORE_GC
1663                 if(gcprocessing) {
1664                         // is currently doing gc, dump this msg
1665                         break;
1666                 }
1667 #endif
1668           if(msgdata[2] == 0) {
1669                   bamboo_smem_size = 0;
1670                   bamboo_cur_msp = 0;
1671           } else {
1672                         // fill header to store the size of this mem block
1673                         (*((int*)msgdata[1])) = msgdata[2];
1674                   bamboo_smem_size = msgdata[2] - BAMBOO_CACHE_LINE_SIZE;
1675 #ifdef MULTICORE_GC
1676                         bamboo_cur_msp = msgdata[1] + BAMBOO_CACHE_LINE_SIZE;
1677 #else
1678                   bamboo_cur_msp = 
1679                                 create_mspace_with_base((void*)(msgdata[1]+BAMBOO_CACHE_LINE_SIZE),
1680                                                          msgdata[2]-BAMBOO_CACHE_LINE_SIZE, 
1681                                                                                                                                  0);
1682 #endif
1683           }
1684           smemflag = true;
1685           break;
1686         }
1687
1688 #ifdef MULTICORE_GC
1689         // GC msgs
1690         case GCSTARTINIT: {
1691                 gcflag = true;
1692                 gcphase = INITPHASE;
1693                 if(!smemflag) {
1694                         // is waiting for response of mem request
1695                         // let it return NULL and start gc
1696                         bamboo_smem_size = 0;
1697                         bamboo_cur_msp = NULL;
1698                         smemflag = true;
1699                 }
1700           break;
1701         }
1702
1703         case GCSTART: {
1704                 // receive a start GC msg
1705 #ifdef DEBUG
1706 #ifndef TILERA
1707           BAMBOO_DEBUGPRINT(0xe88c);
1708 #endif
1709 #endif
1710           // set the GC flag
1711                 gcphase = MARKPHASE;
1712           break;
1713         }
1714
1715         case GCSTARTCOMPACT: {
1716                 // a compact phase start msg
1717                 gcblock2fill = msgdata[1];
1718                 gcphase = COMPACTPHASE;
1719                 break;
1720         }
1721
1722         case GCSTARTFLUSH: {
1723                 // received a flush phase start msg
1724                 gcphase = FLUSHPHASE;
1725                 break;
1726         }
1727         
1728         case GCFINISHINIT: {
1729                 // received a init phase finish msg
1730                 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1731                   // non startup core can not receive this msg
1732 #ifndef TILERA
1733                   BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1734 #endif
1735                   BAMBOO_EXIT(0xb001);
1736                 }
1737 #ifdef DEBUG
1738                 BAMBOO_DEBUGPRINT(0xe88c);
1739                 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1740 #endif
1741                 if(msgdata[1] < NUMCORES) {
1742                         gccorestatus[msgdata[1]] = 0;
1743                 }
1744         }
1745
1746         case GCFINISHMARK: {
1747                 // received a mark phase finish msg
1748                 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1749                   // non startup core can not receive this msg
1750 #ifndef TILERA
1751                   BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1752 #endif
1753                   BAMBOO_EXIT(0xb002);
1754                 } 
1755                 if(msgdata[1] < NUMCORES) {
1756                         gccorestatus[msgdata[1]] = 0;
1757                         gcnumsendobjs[msgdata[1]] = msgdata[2];
1758                         gcnumreceiveobjs[msgdata[1]] = msgdata[3];
1759                 }
1760           break;
1761         }
1762         
1763         case GCFINISHCOMPACT: {
1764                 // received a compact phase finish msg
1765                 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1766                   // non startup core can not receive this msg
1767                   // return -1
1768 #ifndef TILERA
1769                   BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1770 #endif
1771                   BAMBOO_EXIT(0xb003);
1772                 }
1773                 int cnum = msgdata[1];
1774                 int filledblocks = msgdata[2];
1775                 int heaptop = msgdata[3];
1776                 int data4 = msgdata[4];
1777                 if(cnum < NUMCORES) {
1778                         if(COMPACTPHASE == gcphase) {
1779                                 gcfilledblocks[cnum] = filledblocks;
1780                                 gcloads[cnum] = heaptop;
1781                         }
1782                         if(data4 > 0) {
1783                                 // ask for more mem
1784                                 int startaddr = 0;
1785                                 int tomove = 0;
1786                                 int dstcore = 0;
1787                                 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
1788                                         if(isMsgSending) {
1789                                                 cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
1790                                         } else {
1791                                                 send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
1792                                         }
1793                                 }
1794                         } else {
1795                                 gccorestatus[cnum] = 0;
1796                                 // check if there is pending move request
1797                                 /*if(gcmovepending > 0) {
1798                                         int j;
1799                                         for(j = 0; j < NUMCORES; j++) {
1800                                                 if(gcrequiredmems[j]>0) {
1801                                                         break;
1802                                                 }
1803                                         }
1804                                         if(j < NUMCORES) {
1805                                                 // find match
1806                                                 int tomove = 0;
1807                                                 int startaddr = 0;
1808                                                 gcrequiredmems[j] = assignSpareMem_I(cnum, 
1809                                                                                                                                                                                            gcrequiredmems[j], 
1810                                                                                                                                                                                            &tomove, 
1811                                                                                                                                                                                            &startaddr);
1812                                                 if(STARTUPCORE == j) {
1813                                                         gcdstcore = cnum;
1814                                                         gctomove = true;
1815                                                         gcmovestartaddr = startaddr;
1816                                                         gcblock2fill = tomove;
1817                                                 } else {
1818                                                         if(isMsgSending) {
1819                                                                 cache_msg_4(j, GCMOVESTART, cnum, startaddr, tomove);
1820                                                         } else {
1821                                                                 send_msg_4(j, GCMOVESTART, cnum, startaddr, tomove);
1822                                                         }
1823                                                 } // if(STARTUPCORE == j)
1824                                                 if(gcrequiredmems[j] == 0) {
1825                                                         gcmovepending--;
1826                                                 }
1827                                         } // if(j < NUMCORES)
1828                                 } // if(gcmovepending > 0) */
1829                         } // if(data4>0)
1830                 } // if(cnum < NUMCORES)
1831           break;
1832         }
1833
1834         case GCFINISHFLUSH: {
1835                 // received a flush phase finish msg
1836                 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1837                   // non startup core can not receive this msg
1838                   // return -1
1839 #ifndef TILERA
1840                   BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1841 #endif
1842                   BAMBOO_EXIT(0xb004);
1843                 } 
1844                 if(msgdata[1] < NUMCORES) {
1845                   gccorestatus[msgdata[1]] = 0;
1846                 }
1847           break;
1848         }
1849
1850         case GCFINISH: {
1851                 // received a GC finish msg
1852                 gcphase = FINISHPHASE;
1853                 break;
1854         }
1855
1856         case GCMARKCONFIRM: {
1857                 // received a marked phase finish confirm request msg
1858                 if((BAMBOO_NUM_OF_CORE == STARTUPCORE) 
1859                                 || (BAMBOO_NUM_OF_CORE > NUMCORES - 1)) {
1860                   // wrong core to receive such msg
1861                   BAMBOO_EXIT(0xb005);
1862                 } else {
1863                   // send response msg
1864                   if(isMsgSending) {
1865                           cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE, 
1866                                                         gcbusystatus, gcself_numsendobjs, 
1867                                                                                 gcself_numreceiveobjs);
1868                   } else {
1869                           send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE, 
1870                                                        gcbusystatus, gcself_numsendobjs, gcself_numreceiveobjs);
1871                   }
1872                 }
1873           break;
1874         }
1875
1876         case GCMARKREPORT: {
1877                 // received a marked phase finish confirm response msg
1878                 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1879                   // wrong core to receive such msg
1880 #ifndef TILERA
1881                   BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1882 #endif
1883                   BAMBOO_EXIT(0xb006);
1884                 } else {
1885                   if(waitconfirm) {
1886                           numconfirm--;
1887                   }
1888                   gccorestatus[msgdata[1]] = msgdata[2];
1889                   gcnumsendobjs[msgdata[1]] = msgdata[3];
1890                   gcnumreceiveobjs[msgdata[1]] = msgdata[4];
1891                 }
1892           break;
1893         }
1894
1895         case GCMARKEDOBJ: {
1896                 // received a markedObj msg
1897                 gc_enqueue_I(msgdata[1]);
1898                 gcself_numreceiveobjs++;
1899                 gcbusystatus = true;
1900                 break;
1901         }
1902
1903         case GCMOVESTART: {
1904                 // received a start moving objs msg
1905                 gctomove = true;
1906                 gcdstcore = msgdata[1];
1907                 gcmovestartaddr = msgdata[2];
1908                 gcblock2fill = msgdata[3];
1909                 break;
1910         }
1911         
1912         case GCMAPREQUEST: {
1913                 // received a mapping info request msg
1914                 void * dstptr = NULL;
1915                 RuntimeHashget(gcpointertbl, msgdata[1], &dstptr);
1916                 if(NULL == dstptr) {
1917                         // no such pointer in this core, something is wrong
1918 #ifdef DEBUG
1919                         BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1920                         BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1921 #endif
1922                         BAMBOO_EXIT(0xb007);
1923                 } else {
1924                         // send back the mapping info
1925                         if(isMsgSending) {
1926                                 cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], (int)dstptr);
1927                         } else {
1928                                 send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], (int)dstptr);
1929                         }
1930                 }
1931                 break;
1932         }
1933
1934         case GCMAPINFO: {
1935                 // received a mapping info response msg
1936                 if(msgdata[1] != gcobj2map) {
1937                         // obj not matched, something is wrong
1938 #ifdef DEBUG
1939                         BAMBOO_DEBUGPRINT_REG(gcobj2map);
1940                         BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1941 #endif
1942                         BAMBOO_EXIT(0xb008);
1943                 } else {
1944                         gcmappedobj = msgdata[2];
1945                         RuntimeHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
1946                 }
1947                 gcismapped = true;
1948                 break;
1949         }
1950
1951         case GCLOBJREQUEST: {
1952                 // received a large objs info request msg
1953                 transferMarkResults_I();
1954                 break;
1955         }
1956
1957         case GCLOBJINFO: {
1958                 // received a large objs info response msg
1959                 numconfirm--;
1960
1961                 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1962 #ifndef TILERA
1963                         BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1964 #endif
1965                         BAMBOO_EXIT(0xb009);
1966                 } 
1967                 // store the mark result info 
1968                 int cnum = msgdata[2];
1969                 gcloads[cnum] = msgdata[3];
1970                 if(gcheaptop < msgdata[4]) {
1971                         gcheaptop = msgdata[4];
1972                 }
1973                 // large obj info here
1974           for(int k = 5; k < msgdata[1];) {
1975                         int lobj = msgdata[k++];
1976                         int length = msgdata[k++];
1977                         gc_lobjenqueue_I(lobj, length, cnum);
1978                         gcnumlobjs++;
1979                 } // for(int k = 5; k < msgdata[1];)
1980                 break;
1981         }
1982         
1983         case GCLOBJMAPPING: {
1984                 // received a large obj mapping info msg
1985                 RuntimeHashadd_I(gcpointertbl, msgdata[1], msgdata[2]);
1986                 break;
1987         }
1988
1989 #endif
1990
1991         default:
1992                 break;
1993         }
1994         for(msgdataindex--; msgdataindex > 0; --msgdataindex) {
1995                 msgdata[msgdataindex] = -1;
1996         }
1997         msgtype = -1;
1998         msglength = 30;
1999 #ifdef DEBUG
2000 #ifndef TILERA
2001         BAMBOO_DEBUGPRINT(0xe88d);
2002 #endif
2003 #endif
2004
2005         if(BAMBOO_MSG_AVAIL() != 0) {
2006                 goto msg;
2007         }
2008 #ifdef PROFILE
2009 /*if(isInterrupt) {
2010                 profileTaskEnd();
2011         }*/
2012 #endif
2013         return (int)type;
2014 } else {
2015         // not a whole msg
2016 #ifdef DEBUG
2017 #ifndef TILERA
2018         BAMBOO_DEBUGPRINT(0xe88e);
2019 #endif
2020 #endif
2021 #ifdef PROFILE
2022 /*  if(isInterrupt) {
2023                   profileTaskEnd();
2024                 }*/
2025 #endif
2026     return -2;
2027   }
2028 }
2029
2030 int enqueuetasks(struct parameterwrapper *parameter, 
2031                              struct parameterwrapper *prevptr, 
2032                                                                  struct ___Object___ *ptr, 
2033                                                                  int * enterflags, 
2034                                                                  int numenterflags) {
2035   void * taskpointerarray[MAXTASKPARAMS];
2036   int j;
2037   //int numparams=parameter->task->numParameters;
2038   int numiterators=parameter->task->numTotal-1;
2039   int retval=1;
2040
2041   struct taskdescriptor * task=parameter->task;
2042
2043    //this add the object to parameterwrapper
2044    ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags, 
2045                                    numenterflags, enterflags==NULL);
2046
2047   /* Add enqueued object to parameter vector */
2048   taskpointerarray[parameter->slot]=ptr;
2049
2050   /* Reset iterators */
2051   for(j=0; j<numiterators; j++) {
2052     toiReset(&parameter->iterators[j]);
2053   }
2054
2055   /* Find initial state */
2056   for(j=0; j<numiterators; j++) {
2057 backtrackinit:
2058     if(toiHasNext(&parameter->iterators[j],taskpointerarray OPTARG(failed)))
2059       toiNext(&parameter->iterators[j], taskpointerarray OPTARG(failed));
2060     else if (j>0) {
2061       /* Need to backtrack */
2062       toiReset(&parameter->iterators[j]);
2063       j--;
2064       goto backtrackinit;
2065     } else {
2066       /* Nothing to enqueue */
2067       return retval;
2068     }
2069   }
2070
2071   while(1) {
2072     /* Enqueue current state */
2073     //int launch = 0;
2074     struct taskparamdescriptor *tpd=
2075                         RUNMALLOC(sizeof(struct taskparamdescriptor));
2076     tpd->task=task;
2077     tpd->numParameters=numiterators+1;
2078     tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
2079
2080     for(j=0; j<=numiterators; j++) {
2081                         //store the actual parameters
2082       tpd->parameterArray[j]=taskpointerarray[j]; 
2083     }
2084     /* Enqueue task */
2085     if ((/*!gencontains(failedtasks, tpd)&&*/ 
2086                                         !gencontains(activetasks,tpd))) {
2087                 genputtable(activetasks, tpd, tpd);
2088     } else {
2089       RUNFREE(tpd->parameterArray);
2090       RUNFREE(tpd);
2091     }
2092
2093     /* This loop iterates to the next parameter combination */
2094     if (numiterators==0)
2095       return retval;
2096
2097     for(j=numiterators-1; j<numiterators; j++) {
2098 backtrackinc:
2099       if(toiHasNext(&parameter->iterators[j],taskpointerarray OPTARG(failed)))
2100         toiNext(&parameter->iterators[j], taskpointerarray OPTARG(failed));
2101       else if (j>0) {
2102         /* Need to backtrack */
2103         toiReset(&parameter->iterators[j]);
2104         j--;
2105         goto backtrackinc;
2106       } else {
2107         /* Nothing more to enqueue */
2108         return retval;
2109       }
2110     }
2111   }
2112   return retval;
2113 }
2114
2115 int enqueuetasks_I(struct parameterwrapper *parameter, 
2116                                struct parameterwrapper *prevptr, 
2117                                                                          struct ___Object___ *ptr, 
2118                                                                          int * enterflags, 
2119                                                                          int numenterflags) {
2120   void * taskpointerarray[MAXTASKPARAMS];
2121   int j;
2122   //int numparams=parameter->task->numParameters;
2123   int numiterators=parameter->task->numTotal-1;
2124   int retval=1;
2125   //int addnormal=1;
2126   //int adderror=1;
2127
2128   struct taskdescriptor * task=parameter->task;
2129
2130    //this add the object to parameterwrapper
2131    ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags, 
2132                                      numenterflags, enterflags==NULL);  
2133
2134   /* Add enqueued object to parameter vector */
2135   taskpointerarray[parameter->slot]=ptr;
2136
2137   /* Reset iterators */
2138   for(j=0; j<numiterators; j++) {
2139     toiReset(&parameter->iterators[j]);
2140   }
2141
2142   /* Find initial state */
2143   for(j=0; j<numiterators; j++) {
2144 backtrackinit:
2145     if(toiHasNext(&parameter->iterators[j],taskpointerarray OPTARG(failed)))
2146       toiNext(&parameter->iterators[j], taskpointerarray OPTARG(failed));
2147     else if (j>0) {
2148       /* Need to backtrack */
2149       toiReset(&parameter->iterators[j]);
2150       j--;
2151       goto backtrackinit;
2152     } else {
2153       /* Nothing to enqueue */
2154       return retval;
2155     }
2156   }
2157
2158   while(1) {
2159     /* Enqueue current state */
2160     //int launch = 0;
2161     struct taskparamdescriptor *tpd=
2162                         RUNMALLOC_I(sizeof(struct taskparamdescriptor));
2163     tpd->task=task;
2164     tpd->numParameters=numiterators+1;
2165     tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
2166
2167     for(j=0; j<=numiterators; j++) {
2168                         //store the actual parameters
2169       tpd->parameterArray[j]=taskpointerarray[j]; 
2170     }
2171     /* Enqueue task */
2172     if ((/*!gencontains(failedtasks, tpd)&&*/ 
2173                                         !gencontains(activetasks,tpd))) {
2174                 genputtable_I(activetasks, tpd, tpd);
2175     } else {
2176       RUNFREE(tpd->parameterArray);
2177       RUNFREE(tpd);
2178     }
2179
2180     /* This loop iterates to the next parameter combination */
2181     if (numiterators==0)
2182       return retval;
2183
2184     for(j=numiterators-1; j<numiterators; j++) {
2185 backtrackinc:
2186       if(toiHasNext(&parameter->iterators[j], taskpointerarray OPTARG(failed)))
2187         toiNext(&parameter->iterators[j], taskpointerarray OPTARG(failed));
2188       else if (j>0) {
2189         /* Need to backtrack */
2190         toiReset(&parameter->iterators[j]);
2191         j--;
2192         goto backtrackinc;
2193       } else {
2194         /* Nothing more to enqueue */
2195         return retval;
2196       }
2197     }
2198   }
2199   return retval;
2200 }
2201
2202 #ifdef MULTICORE_GC
2203 #define OFFSET 2
2204 #else
2205 #define OFFSET 0
2206 #endif
2207
2208 int containstag(struct ___Object___ *ptr, 
2209                             struct ___TagDescriptor___ *tag);
2210
2211 #ifndef MULTICORE_GC
2212 void releasewritelock_r(void * lock, void * redirectlock) {
2213   int targetcore = 0;
2214   int reallock = (int)lock;
2215   targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2216
2217 #ifdef DEBUG
2218   BAMBOO_DEBUGPRINT(0xe671);
2219   BAMBOO_DEBUGPRINT_REG((int)lock);
2220   BAMBOO_DEBUGPRINT_REG(reallock);
2221   BAMBOO_DEBUGPRINT_REG(targetcore);
2222 #endif
2223
2224   if(targetcore == BAMBOO_NUM_OF_CORE) {
2225         BAMBOO_START_CRITICAL_SECTION_LOCK();
2226 #ifdef DEBUG
2227         BAMBOO_DEBUGPRINT(0xf001);
2228 #endif
2229     // reside on this core
2230     if(!RuntimeHashcontainskey(locktbl, reallock)) {
2231       // no locks for this object, something is wrong
2232       BAMBOO_EXIT(0xa011);
2233     } else {
2234       int rwlock_obj = 0;
2235           struct LockValue * lockvalue = NULL;
2236 #ifdef DEBUG
2237       BAMBOO_DEBUGPRINT(0xe672);
2238 #endif
2239       RuntimeHashget(locktbl, reallock, &rwlock_obj);
2240           lockvalue = (struct LockValue *)rwlock_obj;
2241 #ifdef DEBUG
2242       BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2243 #endif
2244       lockvalue->value++;
2245           lockvalue->redirectlock = (int)redirectlock;
2246 #ifdef DEBUG
2247       BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2248 #endif
2249     }
2250         BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
2251 #ifdef DEBUG
2252         BAMBOO_DEBUGPRINT(0xf000);
2253 #endif
2254     return;
2255   } else {
2256           // send lock release with redirect info msg
2257           // for 32 bit machine, the size is always 4 words
2258           send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock, (int)redirectlock);
2259   }
2260 }
2261 #endif
2262
2263 void executetasks() {
2264   void * taskpointerarray[MAXTASKPARAMS+OFFSET];
2265   int numparams=0;
2266   int numtotal=0;
2267   struct ___Object___ * tmpparam = NULL;
2268   struct parameterdescriptor * pd=NULL;
2269   struct parameterwrapper *pw=NULL;
2270   int j = 0;
2271   int x = 0;
2272   bool islock = true;
2273
2274   struct LockValue locks[MAXTASKPARAMS];
2275   int locklen = 0;
2276   int grount = 0;
2277   int andmask=0;
2278   int checkmask=0;
2279
2280
2281 newtask:
2282   while(hashsize(activetasks)>0) {
2283 #ifdef MULTICORE_GC
2284                 gc(NULL);
2285 #endif
2286 #ifdef DEBUG
2287     BAMBOO_DEBUGPRINT(0xe990);
2288 #endif
2289
2290     /* See if there are any active tasks */
2291     if (hashsize(activetasks)>0) {
2292       int i;
2293 #ifdef PROFILE
2294 #ifdef ACCURATEPROFILE
2295           profileTaskStart("tpd checking");
2296 #endif
2297 #endif
2298           busystatus = true;
2299       currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
2300       genfreekey(activetasks, currtpd);
2301
2302       numparams=currtpd->task->numParameters;
2303       numtotal=currtpd->task->numTotal;
2304
2305           // clear the lockRedirectTbl 
2306                 // (TODO, this table should be empty after all locks are released)
2307           // reset all locks
2308           for(j = 0; j < MAXTASKPARAMS; j++) {
2309                   locks[j].redirectlock = 0;
2310                   locks[j].value = 0;
2311           }
2312           // get all required locks
2313           locklen = 0;
2314           // check which locks are needed
2315           for(i = 0; i < numparams; i++) {
2316                   void * param = currtpd->parameterArray[i];
2317                   int tmplock = 0;
2318                   int j = 0;
2319                   bool insert = true;
2320                   if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
2321                           islock = false;
2322                           taskpointerarray[i+OFFSET]=param;
2323                           goto execute;
2324                   }
2325                   if(((struct ___Object___ *)param)->lock == NULL) {
2326                           tmplock = (int)param;
2327                   } else {
2328                           tmplock = (int)(((struct ___Object___ *)param)->lock);
2329                   }
2330                   // insert into the locks array
2331                   for(j = 0; j < locklen; j++) {
2332                           if(locks[j].value == tmplock) {
2333                                   insert = false;
2334                                   break;
2335                           } else if(locks[j].value > tmplock) {
2336                                   break;
2337                           }
2338                   }
2339                   if(insert) {
2340                           int h = locklen;
2341                           for(; h > j; h--) {
2342                                   locks[h].redirectlock = locks[h-1].redirectlock;
2343                                   locks[h].value = locks[h-1].value;
2344                           }
2345                           locks[j].value = tmplock;
2346                           locks[j].redirectlock = (int)param;
2347                           locklen++;
2348                   }               
2349           } // line 2713: for(i = 0; i < numparams; i++) 
2350           // grab these required locks
2351 #ifdef DEBUG
2352           BAMBOO_DEBUGPRINT(0xe991);
2353 #endif
2354           for(i = 0; i < locklen; i++) {
2355                   int * lock = (int *)(locks[i].redirectlock);
2356                   islock = true;
2357                   // require locks for this parameter if it is not a startup object
2358 #ifdef DEBUG
2359                   BAMBOO_DEBUGPRINT_REG((int)lock);
2360                   BAMBOO_DEBUGPRINT_REG((int)(locks[i].value));
2361 #endif
2362                   getwritelock(lock);
2363                   BAMBOO_START_CRITICAL_SECTION();
2364 #ifdef DEBUG
2365                   BAMBOO_DEBUGPRINT(0xf001);
2366 #endif
2367 #ifdef PROFILE
2368                   //isInterrupt = false;
2369 #endif 
2370                   while(!lockflag) { 
2371                           BAMBOO_WAITING_FOR_LOCK();
2372                   }
2373 #ifndef INTERRUPT
2374                   if(reside) {
2375                           while(BAMBOO_WAITING_FOR_LOCK() != -1) {
2376                           }
2377                   }
2378 #endif
2379                   grount = lockresult;
2380
2381                   lockresult = 0;
2382                   lockobj = 0;
2383                   lock2require = 0;
2384                   lockflag = false;
2385 #ifndef INTERRUPT
2386                   reside = false;
2387 #endif
2388 #ifdef PROFILE
2389                   //isInterrupt = true;
2390 #endif
2391                   BAMBOO_CLOSE_CRITICAL_SECTION();
2392 #ifdef DEBUG
2393                   BAMBOO_DEBUGPRINT(0xf000);
2394 #endif
2395
2396                   if(grount == 0) {
2397                           int j = 0;
2398 #ifdef DEBUG
2399                           BAMBOO_DEBUGPRINT(0xe992);
2400 #endif
2401                           // can not get the lock, try later
2402                           // releas all grabbed locks for previous parameters
2403                           for(j = 0; j < i; ++j) {
2404                                   lock = (int*)(locks[j].redirectlock);
2405                                   releasewritelock(lock);
2406                           }
2407                           genputtable(activetasks, currtpd, currtpd);
2408                           if(hashsize(activetasks) == 1) {
2409                                   // only one task right now, wait a little while before next try
2410                                   int halt = 10000;
2411                                   while(halt--) {
2412                                   }
2413                           }
2414 #ifdef PROFILE
2415 #ifdef ACCURATEPROFILE
2416                           // fail, set the end of the checkTaskInfo
2417                           profileTaskEnd();
2418 #endif
2419 #endif
2420                           goto newtask;
2421                   } // line 2794: if(grount == 0)
2422           } // line 2752:  for(i = 0; i < locklen; i++)
2423
2424 #ifdef DEBUG
2425         BAMBOO_DEBUGPRINT(0xe993);
2426 #endif
2427       /* Make sure that the parameters are still in the queues */
2428       for(i=0; i<numparams; i++) {
2429         void * parameter=currtpd->parameterArray[i];
2430
2431         // flush the object
2432 #ifdef CACHEFLUSH
2433         BAMBOO_CACHE_FLUSH_RANGE((int)parameter, 
2434                         classsize[((struct ___Object___ *)parameter)->type]);
2435 #endif
2436         tmpparam = (struct ___Object___ *)parameter;
2437         pd=currtpd->task->descriptorarray[i];
2438         pw=(struct parameterwrapper *) pd->queue;
2439         /* Check that object is still in queue */
2440         {
2441           if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
2442 #ifdef DEBUG
2443             BAMBOO_DEBUGPRINT(0xe994);
2444 #endif
2445             // release grabbed locks
2446             for(j = 0; j < locklen; ++j) {
2447                 int * lock = (int *)(locks[j].redirectlock);
2448                 releasewritelock(lock);
2449             }
2450             RUNFREE(currtpd->parameterArray);
2451             RUNFREE(currtpd);
2452                         currtpd = NULL;
2453             goto newtask;
2454           }
2455         } // line2865
2456         /* Check if the object's flags still meets requirements */
2457         {
2458           int tmpi = 0;
2459           bool ismet = false;
2460           for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
2461             andmask=pw->intarray[tmpi*2];
2462             checkmask=pw->intarray[tmpi*2+1];
2463             if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
2464               ismet = true;
2465               break;
2466             }
2467           }
2468           if (!ismet) {
2469             // flags are never suitable
2470             // remove this obj from the queue
2471             int next;
2472             int UNUSED, UNUSED2;
2473             int * enterflags;
2474 #ifdef DEBUG
2475             BAMBOO_DEBUGPRINT(0xe995);
2476 #endif
2477             ObjectHashget(pw->objectset, (int) parameter, (int *) &next, 
2478                                                   (int *) &enterflags, &UNUSED, &UNUSED2);
2479             ObjectHashremove(pw->objectset, (int)parameter);
2480             if (enterflags!=NULL)
2481               RUNFREE(enterflags);
2482             // release grabbed locks
2483             for(j = 0; j < locklen; ++j) {
2484                  int * lock = (int *)(locks[j].redirectlock);
2485                 releasewritelock(lock);
2486             }
2487             RUNFREE(currtpd->parameterArray);
2488             RUNFREE(currtpd);
2489                         currtpd = NULL;
2490 #ifdef PROFILE
2491 #ifdef ACCURATEPROFILE
2492             // fail, set the end of the checkTaskInfo
2493                 profileTaskEnd();
2494 #endif
2495 #endif
2496             goto newtask;
2497           } // line 2878: if (!ismet)
2498         } // line 2867
2499 parameterpresent:
2500         ;
2501         /* Check that object still has necessary tags */
2502         for(j=0; j<pd->numbertags; j++) {
2503           int slotid=pd->tagarray[2*j]+numparams;
2504           struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
2505           if (!containstag(parameter, tagd)) {
2506 #ifdef DEBUG
2507             BAMBOO_DEBUGPRINT(0xe996);
2508 #endif
2509                 {
2510                 // release grabbed locks
2511                 int tmpj = 0;
2512             for(tmpj = 0; tmpj < locklen; ++tmpj) {
2513                  int * lock = (int *)(locks[tmpj].redirectlock);
2514                 releasewritelock(lock);
2515             }
2516                 }
2517             RUNFREE(currtpd->parameterArray);
2518             RUNFREE(currtpd);
2519                         currtpd = NULL;
2520             goto newtask;
2521           } // line2911: if (!containstag(parameter, tagd))
2522         } // line 2808: for(j=0; j<pd->numbertags; j++)
2523
2524         taskpointerarray[i+OFFSET]=parameter;
2525       } // line 2824: for(i=0; i<numparams; i++)
2526       /* Copy the tags */
2527       for(; i<numtotal; i++) {
2528         taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
2529       }
2530
2531       {
2532 execute:
2533           /* Actually call task */
2534 #ifdef MULTICORE_GC
2535           ((int *)taskpointerarray)[0]=currtpd->numParameters;
2536           taskpointerarray[1]=NULL;
2537 #endif
2538 #ifdef PROFILE
2539 #ifdef ACCURATEPROFILE
2540           // check finish, set the end of the checkTaskInfo
2541           profileTaskEnd();
2542 #endif
2543           profileTaskStart(currtpd->task->name);
2544 #endif
2545
2546 #ifdef DEBUG
2547                 BAMBOO_DEBUGPRINT(0xe997);
2548 #endif
2549                 ((void(*) (void **))currtpd->task->taskptr)(taskpointerarray);
2550 #ifdef PROFILE
2551 #ifdef ACCURATEPROFILE
2552           // task finish, set the end of the checkTaskInfo
2553           profileTaskEnd();
2554           // new a PostTaskInfo for the post-task execution
2555           profileTaskStart("post task execution");
2556 #endif
2557 #endif
2558 #ifdef DEBUG
2559           BAMBOO_DEBUGPRINT(0xe998);
2560           BAMBOO_DEBUGPRINT_REG(islock);
2561 #endif
2562
2563           if(islock) {
2564 #ifdef DEBUG
2565                   BAMBOO_DEBUGPRINT(0xe999);
2566 #endif
2567             for(i = 0; i < locklen; ++i) {
2568                                 void * ptr = (void *)(locks[i].redirectlock);
2569               int * lock = (int *)(locks[i].value);
2570 #ifdef DEBUG
2571                   BAMBOO_DEBUGPRINT_REG((int)ptr);
2572                   BAMBOO_DEBUGPRINT_REG((int)lock);
2573 #endif
2574 #ifndef MULTICORE_GC
2575                   if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
2576                           int redirectlock;
2577                           RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
2578                           RuntimeHashremovekey(lockRedirectTbl, (int)lock);
2579                           releasewritelock_r(lock, (int *)redirectlock);
2580                   } else {
2581 #else
2582                                 {
2583 #endif
2584                 releasewritelock(ptr);
2585                   }
2586             }
2587           } // line 3015: if(islock)
2588
2589 #ifdef PROFILE
2590           // post task execution finish, set the end of the postTaskInfo
2591           profileTaskEnd();
2592 #endif
2593
2594           // Free up task parameter descriptor
2595           RUNFREE(currtpd->parameterArray);
2596           RUNFREE(currtpd);
2597                 currtpd = NULL;
2598 #ifdef DEBUG
2599           BAMBOO_DEBUGPRINT(0xe99a);
2600 #endif
2601       } //  
2602     } //  if (hashsize(activetasks)>0)  
2603   } //  while(hashsize(activetasks)>0)
2604 #ifdef DEBUG
2605   BAMBOO_DEBUGPRINT(0xe99b);
2606 #endif
2607 }
2608
2609 /* This function processes an objects tags */
2610 void processtags(struct parameterdescriptor *pd, 
2611                              int index, 
2612                                                                  struct parameterwrapper *parameter, 
2613                                                                  int * iteratorcount, 
2614                                                                  int *statusarray, 
2615                                                                  int numparams) {
2616   int i;
2617
2618   for(i=0; i<pd->numbertags; i++) {
2619     int slotid=pd->tagarray[2*i];
2620     int tagid=pd->tagarray[2*i+1];
2621
2622     if (statusarray[slotid+numparams]==0) {
2623       parameter->iterators[*iteratorcount].istag=1;
2624       parameter->iterators[*iteratorcount].tagid=tagid;
2625       parameter->iterators[*iteratorcount].slot=slotid+numparams;
2626       parameter->iterators[*iteratorcount].tagobjectslot=index;
2627       statusarray[slotid+numparams]=1;
2628       (*iteratorcount)++;
2629     }
2630   }
2631 }
2632
2633
2634 void processobject(struct parameterwrapper *parameter, 
2635                                int index, 
2636                                                                          struct parameterdescriptor *pd, 
2637                                                                          int *iteratorcount, 
2638                                                                          int * statusarray, 
2639                                                                          int numparams) {
2640   int i;
2641   int tagcount=0;
2642   struct ObjectHash * objectset=
2643                 ((struct parameterwrapper *)pd->queue)->objectset;
2644
2645   parameter->iterators[*iteratorcount].istag=0;
2646   parameter->iterators[*iteratorcount].slot=index;
2647   parameter->iterators[*iteratorcount].objectset=objectset;
2648   statusarray[index]=1;
2649
2650   for(i=0; i<pd->numbertags; i++) {
2651     int slotid=pd->tagarray[2*i];
2652     //int tagid=pd->tagarray[2*i+1];
2653     if (statusarray[slotid+numparams]!=0) {
2654       /* This tag has already been enqueued, use it to narrow search */
2655       parameter->iterators[*iteratorcount].tagbindings[tagcount]=
2656                                 slotid+numparams;
2657       tagcount++;
2658     }
2659   }
2660   parameter->iterators[*iteratorcount].numtags=tagcount;
2661
2662   (*iteratorcount)++;
2663 }
2664
2665 /* This function builds the iterators for a task & parameter */
2666
2667 void builditerators(struct taskdescriptor * task, 
2668                                 int index, 
2669                                                                                 struct parameterwrapper * parameter) {
2670   int statusarray[MAXTASKPARAMS];
2671   int i;
2672   int numparams=task->numParameters;
2673   int iteratorcount=0;
2674   for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
2675
2676   statusarray[index]=1; /* Initial parameter */
2677   /* Process tags for initial iterator */
2678
2679   processtags(task->descriptorarray[index], index, parameter, 
2680                                 &iteratorcount, statusarray, numparams);
2681
2682   while(1) {
2683 loopstart:
2684     /* Check for objects with existing tags */
2685     for(i=0; i<numparams; i++) {
2686       if (statusarray[i]==0) {
2687         struct parameterdescriptor *pd=task->descriptorarray[i];
2688         int j;
2689         for(j=0; j<pd->numbertags; j++) {
2690           int slotid=pd->tagarray[2*j];
2691           if(statusarray[slotid+numparams]!=0) {
2692             processobject(parameter, i, pd, &iteratorcount, statusarray, 
2693                                                   numparams);
2694             processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
2695             goto loopstart;
2696           }
2697         }
2698       }
2699     }
2700
2701     /* Next do objects w/ unbound tags*/
2702
2703     for(i=0; i<numparams; i++) {
2704       if (statusarray[i]==0) {
2705         struct parameterdescriptor *pd=task->descriptorarray[i];
2706         if (pd->numbertags>0) {
2707           processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
2708           processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
2709           goto loopstart;
2710         }
2711       }
2712     }
2713
2714     /* Nothing with a tag enqueued */
2715
2716     for(i=0; i<numparams; i++) {
2717       if (statusarray[i]==0) {
2718         struct parameterdescriptor *pd=task->descriptorarray[i];
2719         processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
2720         processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
2721         goto loopstart;
2722       }
2723     }
2724
2725     /* Nothing left */
2726     return;
2727   }
2728 }
2729
2730 void printdebug() {
2731   int i;
2732   int j;
2733   if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
2734     return;
2735   }
2736   for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
2737     struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
2738 #ifndef RAW 
2739         printf("%s\n", task->name);
2740 #endif
2741     for(j=0; j<task->numParameters; j++) {
2742       struct parameterdescriptor *param=task->descriptorarray[j];
2743       struct parameterwrapper *parameter=param->queue;
2744       struct ObjectHash * set=parameter->objectset;
2745       struct ObjectIterator objit;
2746 #ifndef RAW
2747           printf("  Parameter %d\n", j);
2748 #endif
2749       ObjectHashiterator(set, &objit);
2750       while(ObjhasNext(&objit)) {
2751         struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
2752         struct ___Object___ * tagptr=obj->___tags___;
2753         int nonfailed=Objdata4(&objit);
2754         int numflags=Objdata3(&objit);
2755         int flags=Objdata2(&objit);
2756         Objnext(&objit);
2757 #ifndef RAW
2758         printf("    Contains %lx\n", obj);
2759         printf("      flag=%d\n", obj->flag);
2760 #endif
2761         if (tagptr==NULL) {
2762         } else if (tagptr->type==TAGTYPE) {
2763 #ifndef RAW
2764           printf("      tag=%lx\n",tagptr);
2765 #else
2766           ;
2767 #endif
2768         } else {
2769           int tagindex=0;
2770           struct ArrayObject *ao=(struct ArrayObject *)tagptr;
2771           for(; tagindex<ao->___cachedCode___; tagindex++) {
2772 #ifndef RAW
2773                   printf("      tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*, 
2774                                                  tagindex));
2775 #else
2776                   ;
2777 #endif
2778           }
2779         }
2780       }
2781     }
2782   }
2783 }
2784
2785
2786 /* This function processes the task information to create queues for
2787    each parameter type. */
2788
2789 void processtasks() {
2790   int i;
2791   if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
2792     return;
2793   }
2794   for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
2795     struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
2796     int j;
2797
2798     /* Build objectsets */
2799     for(j=0; j<task->numParameters; j++) {
2800       struct parameterdescriptor *param=task->descriptorarray[j];
2801       struct parameterwrapper *parameter=param->queue;
2802       parameter->objectset=allocateObjectHash(10);
2803       parameter->task=task;
2804     }
2805
2806     /* Build iterators for parameters */
2807     for(j=0; j<task->numParameters; j++) {
2808       struct parameterdescriptor *param=task->descriptorarray[j];
2809       struct parameterwrapper *parameter=param->queue;
2810       builditerators(task, j, parameter);
2811     }
2812   }
2813 }
2814
2815 void toiReset(struct tagobjectiterator * it) {
2816   if (it->istag) {
2817     it->tagobjindex=0;
2818   } else if (it->numtags>0) {
2819     it->tagobjindex=0;
2820   } else {
2821     ObjectHashiterator(it->objectset, &it->it);
2822   }
2823 }
2824
2825 int toiHasNext(struct tagobjectiterator *it, 
2826                            void ** objectarray OPTARG(int * failed)) {
2827   if (it->istag) {
2828     /* Iterate tag */
2829     /* Get object with tags */
2830     struct ___Object___ *obj=objectarray[it->tagobjectslot];
2831     struct ___Object___ *tagptr=obj->___tags___;
2832     if (tagptr->type==TAGTYPE) {
2833       if ((it->tagobjindex==0)&& /* First object */
2834           (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
2835         return 1;
2836       else
2837         return 0;
2838     } else {
2839       struct ArrayObject *ao=(struct ArrayObject *) tagptr;
2840       int tagindex=it->tagobjindex;
2841       for(; tagindex<ao->___cachedCode___; tagindex++) {
2842         struct ___TagDescriptor___ *td=
2843                 ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
2844         if (td->flag==it->tagid) {
2845           it->tagobjindex=tagindex; /* Found right type of tag */
2846           return 1;
2847         }
2848       }
2849       return 0;
2850     }
2851   } else if (it->numtags>0) {
2852     /* Use tags to locate appropriate objects */
2853     struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
2854     struct ___Object___ *objptr=tag->flagptr;
2855     int i;
2856     if (objptr->type!=OBJECTARRAYTYPE) {
2857       if (it->tagobjindex>0)
2858         return 0;
2859       if (!ObjectHashcontainskey(it->objectset, (int) objptr))
2860         return 0;
2861       for(i=1; i<it->numtags; i++) {
2862         struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
2863         if (!containstag(objptr,tag2))
2864           return 0;
2865       }
2866       return 1;
2867     } else {
2868       struct ArrayObject *ao=(struct ArrayObject *) objptr;
2869       int tagindex;
2870       int i;
2871       for(tagindex=it->tagobjindex;tagindex<ao->___cachedCode___;tagindex++) {
2872         struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
2873         if (!ObjectHashcontainskey(it->objectset, (int) objptr))
2874           continue;
2875         for(i=1; i<it->numtags; i++) {
2876           struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
2877           if (!containstag(objptr,tag2))
2878             goto nexttag;
2879         }
2880         it->tagobjindex=tagindex;
2881         return 1;
2882 nexttag:
2883         ;
2884       }
2885       it->tagobjindex=tagindex;
2886       return 0;
2887     }
2888   } else {
2889     return ObjhasNext(&it->it);
2890   }
2891 }
2892
2893 int containstag(struct ___Object___ *ptr, 
2894                             struct ___TagDescriptor___ *tag) {
2895   int j;
2896   struct ___Object___ * objptr=tag->flagptr;
2897   if (objptr->type==OBJECTARRAYTYPE) {
2898     struct ArrayObject *ao=(struct ArrayObject *)objptr;
2899     for(j=0; j<ao->___cachedCode___; j++) {
2900       if (ptr==ARRAYGET(ao, struct ___Object___*, j))
2901         return 1;
2902     }
2903     return 0;
2904   } else
2905     return objptr==ptr;
2906 }
2907
2908 void toiNext(struct tagobjectiterator *it, 
2909                          void ** objectarray OPTARG(int * failed)) {
2910   /* hasNext has all of the intelligence */
2911   if(it->istag) {
2912     /* Iterate tag */
2913     /* Get object with tags */
2914     struct ___Object___ *obj=objectarray[it->tagobjectslot];
2915     struct ___Object___ *tagptr=obj->___tags___;
2916     if (tagptr->type==TAGTYPE) {
2917       it->tagobjindex++;
2918       objectarray[it->slot]=tagptr;
2919     } else {
2920       struct ArrayObject *ao=(struct ArrayObject *) tagptr;
2921       objectarray[it->slot]=
2922                                 ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
2923     }
2924   } else if (it->numtags>0) {
2925     /* Use tags to locate appropriate objects */
2926     struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
2927     struct ___Object___ *objptr=tag->flagptr;
2928     if (objptr->type!=OBJECTARRAYTYPE) {
2929       it->tagobjindex++;
2930       objectarray[it->slot]=objptr;
2931     } else {
2932       struct ArrayObject *ao=(struct ArrayObject *) objptr;
2933       objectarray[it->slot]=
2934                                 ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
2935     }
2936   } else {
2937     /* Iterate object */
2938     objectarray[it->slot]=(void *)Objkey(&it->it);
2939     Objnext(&it->it);
2940   }
2941 }
2942 #endif