bug fixes in multicore gc
[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;
1169 #ifdef MULTICORE_GC
1170         // go through free mem list for suitable blocks
1171         struct freeMemItem * freemem = bamboo_free_mem_list->head;
1172         struct freeMemItem * prev = NULL;
1173         do {
1174                 if(freemem->size >= isize) {
1175                         // found one
1176                         break;
1177                 }
1178                 prev = freemem;
1179                 freemem = freemem->next;
1180         } while(freemem != NULL);
1181         if(freemem != NULL) {
1182                 mem = (void *)(freemem->ptr);
1183                 // check the remaining space in this block
1184                 int remain = (int)(mem-(BAMBOO_BASE_VA));
1185                 int bound = (BAMBOO_SMEM_SIZE);
1186                 if(remain < BAMBOO_LARGE_SMEM_BOUND) {
1187                         bound = (BAMBOO_SMEM_SIZE_L);
1188                 }
1189                 remain = bound - remain%bound;
1190                 if(remain < isize) {
1191                         // this object acrosses blocks
1192                         // try to align the block if required a block
1193                         if((isize == BAMBOO_SMEM_SIZE) && (freemem->size >= isize + remain)) {
1194                                 isize += remain;
1195                         }
1196                 }
1197                 *allocsize = isize;
1198                 freemem->ptr = ((void*)freemem->ptr) + isize;
1199                 freemem->size -= isize;
1200         } else {
1201 #else
1202         mem = mspace_calloc(bamboo_free_msp, 1, isize);
1203         *allocsize = isize;
1204         if(mem == NULL) {
1205 #endif
1206                 // no enough shared global memory
1207                 *allocsize = 0;
1208 #ifdef MULTICORE_GC
1209                 gcflag = true;
1210                 return NULL;
1211 #else
1212                 BAMBOO_DEBUGPRINT(0xa001);
1213                 BAMBOO_EXIT(0xa001);
1214 #endif
1215         }
1216         return mem;
1217 }
1218
1219 // receive object transferred from other cores
1220 // or the terminate message from other cores
1221 // Should be invoked in critical sections!!
1222 // NOTICE: following format is for threadsimulate version only
1223 //         RAW version please see previous description
1224 // format: type + object
1225 // type: -1--stall msg
1226 //      !-1--object
1227 // return value: 0--received an object
1228 //               1--received nothing
1229 //               2--received a Stall Msg
1230 //               3--received a lock Msg
1231 //               RAW version: -1 -- received nothing
1232 //                            otherwise -- received msg type
1233 int receiveObject() {
1234   int deny = 0;
1235   
1236 msg:
1237   if(receiveMsg() == -1) {
1238           return -1;
1239   }
1240
1241   if(msgdataindex == msglength) {
1242     // received a whole msg
1243     MSGTYPE type; 
1244     type = msgdata[0];
1245     switch(type) {
1246     case TRANSOBJ: {
1247       // receive a object transfer msg
1248       struct transObjInfo * transObj = 
1249                                 RUNMALLOC_I(sizeof(struct transObjInfo));
1250       int k = 0;
1251 #ifdef DEBUG
1252 #ifndef TILERA
1253                         BAMBOO_DEBUGPRINT(0xe880);
1254 #endif
1255 #endif
1256       if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1257 #ifndef TILERA
1258                                 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1259 #endif
1260                                 BAMBOO_EXIT(0xa002);
1261                         } 
1262       // store the object and its corresponding queue info, enqueue it later
1263       transObj->objptr = (void *)msgdata[2]; 
1264       transObj->length = (msglength - 3) / 2;
1265       transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
1266       for(k = 0; k < transObj->length; ++k) {
1267                                 transObj->queues[2*k] = msgdata[3+2*k];
1268 #ifdef DEBUG
1269 #ifndef TILERA
1270                                 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
1271 #endif
1272 #endif
1273                                 transObj->queues[2*k+1] = msgdata[3+2*k+1];
1274 #ifdef DEBUG
1275 #ifndef TILERA
1276                                 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
1277 #endif
1278 #endif
1279                         }
1280       // check if there is an existing duplicate item
1281       {
1282                                 struct QueueItem * qitem = getHead(&objqueue);
1283                                 struct QueueItem * prev = NULL;
1284                                 while(qitem != NULL) {
1285                                         struct transObjInfo * tmpinfo = 
1286                                                 (struct transObjInfo *)(qitem->objectptr);
1287                                         if(tmpinfo->objptr == transObj->objptr) {
1288                                                 // the same object, remove outdate one
1289                                                 removeItem(&objqueue, qitem);
1290                                                 //break;
1291                                         } else {
1292                                                 prev = qitem;
1293                                         }
1294                                         if(prev == NULL) {
1295                                                 qitem = getHead(&objqueue);
1296                                         } else {
1297                                                 qitem = getNextQueueItem(prev);
1298                                         }
1299                                 }
1300                                 addNewItem_I(&objqueue, (void *)transObj);
1301                         }
1302       ++(self_numreceiveobjs);
1303       break;
1304     }
1305
1306     case TRANSTALL: {
1307       // receive a stall msg
1308       if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1309                   // non startup core can not receive stall msg
1310 #ifndef TILERA
1311                                 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1312 #endif
1313                                 BAMBOO_EXIT(0xa003);
1314       } 
1315       if(msgdata[1] < NUMCORES) {
1316 #ifdef DEBUG
1317 #ifndef TILERA
1318                                 BAMBOO_DEBUGPRINT(0xe881);
1319 #endif
1320 #endif
1321                                 corestatus[msgdata[1]] = 0;
1322                                 numsendobjs[msgdata[1]] = msgdata[2];
1323                                 numreceiveobjs[msgdata[1]] = msgdata[3];
1324       }
1325       break;
1326     }
1327
1328 // GC version have no lock msgs
1329 #ifndef MULTICORE_GC
1330     case LOCKREQUEST: {
1331       // receive lock request msg, handle it right now
1332       // check to see if there is a lock exist for the required obj
1333                         // msgdata[1] -> lock type
1334                         int data2 = msgdata[2]; // obj pointer
1335       int data3 = msgdata[3]; // lock
1336                         int data4 = msgdata[4]; // request core
1337                         // -1: redirected, 0: approved, 1: denied
1338       deny = processlockrequest(msgdata[1], data3, data2, 
1339                                                               data4, data4, true);  
1340                         if(deny == -1) {
1341                                 // this lock request is redirected
1342                                 break;
1343                         } else {
1344                                 // send response msg
1345                                 // for 32 bit machine, the size is always 4 words
1346                                 int tmp = deny==1?LOCKDENY:LOCKGROUNT;
1347                                 if(isMsgSending) {
1348                                         cache_msg_4(data4, tmp, msgdata[1], data2, data3);
1349                                 } else {
1350                                         send_msg_4(data4, tmp, msgdata[1], data2, data3);
1351                                 }
1352                         }
1353       break;
1354     }
1355
1356     case LOCKGROUNT: {
1357       // receive lock grount msg
1358       if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1359 #ifndef TILERA
1360                                 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1361 #endif
1362                                 BAMBOO_EXIT(0xa004);
1363       } 
1364       if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1365 #ifdef DEBUG
1366 #ifndef TILERA
1367                                 BAMBOO_DEBUGPRINT(0xe882);
1368 #endif
1369 #endif
1370                                 lockresult = 1;
1371                                 lockflag = true;
1372 #ifndef INTERRUPT
1373                                 reside = false;
1374 #endif
1375                         } else {
1376                                 // conflicts on lockresults
1377 #ifndef TILERA
1378                                 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1379 #endif
1380                                 BAMBOO_EXIT(0xa005);
1381       }
1382       break;
1383     }
1384
1385     case LOCKDENY: {
1386       // receive lock deny msg
1387       if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1388 #ifndef TILERA
1389                                 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1390 #endif
1391                                 BAMBOO_EXIT(0xa006);
1392       } 
1393       if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1394 #ifdef DEBUG
1395 #ifndef TILERA
1396                                 BAMBOO_DEBUGPRINT(0xe883);
1397 #endif
1398 #endif
1399                                 lockresult = 0;
1400                                 lockflag = true;
1401 #ifndef INTERRUPT
1402                                 reside = false;
1403 #endif
1404                                 } else {
1405                                 // conflicts on lockresults
1406 #ifndef TILERA
1407                                 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1408 #endif
1409                                 BAMBOO_EXIT(0xa007);
1410       }
1411       break;
1412     }
1413
1414     case LOCKRELEASE: {
1415       // receive lock release msg
1416                         processlockrelease(msgdata[1], msgdata[2], 0, false);
1417       break;
1418     }
1419 #endif
1420
1421 #ifdef PROFILE
1422     case PROFILEOUTPUT: {
1423       // receive an output profile data request msg
1424       if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
1425                                 // startup core can not receive profile output finish msg
1426                                 BAMBOO_EXIT(0xa008);
1427       }
1428 #ifdef DEBUG
1429 #ifndef TILEAR
1430                         BAMBOO_DEBUGPRINT(0xe885);
1431 #endif
1432 #endif
1433                         stall = true;
1434                         totalexetime = msgdata[1];
1435                         outputProfileData();
1436                         if(isMsgSending) {
1437                                 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1438                         } else {
1439                                 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1440                         }
1441       break;
1442     }
1443
1444     case PROFILEFINISH: {
1445       // receive a profile output finish msg
1446       if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1447                                 // non startup core can not receive profile output finish msg
1448 #ifndef TILERA
1449                                 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1450 #endif
1451                                 BAMBOO_EXIT(0xa009);
1452       }
1453 #ifdef DEBUG
1454 #ifndef TILERA
1455                         BAMBOO_DEBUGPRINT(0xe886);
1456 #endif
1457 #endif
1458                         profilestatus[msgdata[1]] = 0;
1459       break;
1460     }
1461 #endif
1462
1463 // GC version has no lock msgs
1464 #ifndef MULTICORE_GC
1465         case REDIRECTLOCK: {
1466           // receive a redirect lock request msg, handle it right now
1467                 // check to see if there is a lock exist for the required obj
1468           int data1 = msgdata[1]; // lock type
1469           int data2 = msgdata[2]; // obj pointer
1470                 int data3 = msgdata[3]; // redirect lock
1471           int data4 = msgdata[4]; // root request core
1472           int data5 = msgdata[5]; // request core
1473           deny = processlockrequest(msgdata[1], data3, data2, data5, data4, true);
1474           if(deny == -1) {
1475                   // this lock request is redirected
1476                   break;
1477           } else {
1478                   // send response msg
1479                   // for 32 bit machine, the size is always 4 words
1480                   if(isMsgSending) {
1481                           cache_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT, 
1482                                                         data1, data2, data3);
1483                   } else {
1484                           send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT, 
1485                                                        data1, data2, data3);
1486                   }
1487           }
1488           break;
1489         }
1490
1491         case REDIRECTGROUNT: {
1492                 // receive a lock grant msg with redirect info
1493                 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1494 #ifndef TILERA
1495                         BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1496 #endif
1497                         BAMBOO_EXIT(0xa00a);
1498                 }
1499                 if(lockobj == msgdata[2]) {
1500 #ifdef DEBUG
1501 #ifndef TILERA
1502                   BAMBOO_DEBUGPRINT(0xe891);
1503 #endif
1504 #endif
1505                   lockresult = 1;
1506                   lockflag = true;
1507                   RuntimeHashadd_I(objRedirectLockTbl, lockobj, msgdata[3]);
1508 #ifndef INTERRUPT
1509                   reside = false;
1510 #endif
1511                 } else {
1512                   // conflicts on lockresults
1513 #ifndef TILERA
1514                   BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1515 #endif
1516                   BAMBOO_EXIT(0xa00b);
1517                 }
1518                 break;
1519         }
1520         
1521         case REDIRECTDENY: {
1522           // receive a lock deny msg with redirect info
1523           if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1524 #ifndef TILERA
1525                   BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1526 #endif
1527                   BAMBOO_EXIT(0xa00c);
1528           }
1529                 if(lockobj == msgdata[2]) {
1530 #ifdef DEBUG
1531 #ifndef TILERA
1532                   BAMBOO_DEBUGPRINT(0xe892);
1533 #endif
1534 #endif
1535                   lockresult = 0;
1536                   lockflag = true;
1537 #ifndef INTERRUPT
1538                   reside = false;
1539 #endif
1540                 } else {
1541                   // conflicts on lockresults
1542 #ifndef TILERA
1543                   BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1544 #endif
1545                   BAMBOO_EXIT(0xa00d);
1546                 }
1547                 break;
1548         }
1549
1550         case REDIRECTRELEASE: {
1551           // receive a lock release msg with redirect info
1552                 processlockrelease(msgdata[1], msgdata[2], msgdata[3], true);
1553                 break;
1554         }
1555 #endif
1556         
1557         case STATUSCONFIRM: {
1558       // receive a status confirm info
1559           if((BAMBOO_NUM_OF_CORE == STARTUPCORE) 
1560                                 || (BAMBOO_NUM_OF_CORE > NUMCORES - 1)) {
1561                   // wrong core to receive such msg
1562                   BAMBOO_EXIT(0xa00e);
1563                 } else {
1564                   // send response msg
1565 #ifdef DEBUG
1566 #ifndef TILERA
1567                   BAMBOO_DEBUGPRINT(0xe887);
1568 #endif
1569 #endif
1570                   if(isMsgSending) {
1571                           cache_msg_5(STARTUPCORE, STATUSREPORT, 
1572                                                         busystatus?1:0, BAMBOO_NUM_OF_CORE,
1573                                                                                 self_numsendobjs, self_numreceiveobjs);
1574                   } else {
1575                           send_msg_5(STARTUPCORE, STATUSREPORT, 
1576                                                        busystatus?1:0, BAMBOO_NUM_OF_CORE,
1577                                                                          self_numsendobjs, self_numreceiveobjs);
1578                   }
1579                 }
1580           break;
1581         }
1582
1583         case STATUSREPORT: {
1584           // receive a status confirm info
1585           if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1586                   // wrong core to receive such msg
1587 #ifndef TILERA
1588                   BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1589 #endif
1590                   BAMBOO_EXIT(0xa00f);
1591                 } else {
1592 #ifdef DEBUG
1593 #ifndef TILERA
1594                   BAMBOO_DEBUGPRINT(0xe888);
1595 #endif
1596 #endif
1597                   if(waitconfirm) {
1598                           numconfirm--;
1599                   }
1600                   corestatus[msgdata[2]] = msgdata[1];
1601                         numsendobjs[msgdata[2]] = msgdata[3];
1602                         numreceiveobjs[msgdata[2]] = msgdata[4];
1603                 }
1604           break;
1605         }
1606
1607         case TERMINATE: {
1608           // receive a terminate msg
1609 #ifdef DEBUG
1610 #ifndef TILERA
1611                 BAMBOO_DEBUGPRINT(0xe889);
1612 #endif
1613 #endif
1614                 disruntimedata();
1615                 BAMBOO_EXIT(0);
1616           break;
1617         }
1618
1619         case MEMREQUEST: {
1620           // receive a shared memory request msg
1621           if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1622                   // wrong core to receive such msg
1623 #ifndef TILERA
1624                   BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1625 #endif
1626                   BAMBOO_EXIT(0xa010);
1627                 } else {
1628 #ifdef DEBUG
1629 #ifndef TILERA
1630                   BAMBOO_DEBUGPRINT(0xe88a);
1631 #endif
1632 #endif
1633 #ifdef MULTICORE_GC
1634                         if(gcprocessing) {
1635                                 // is currently doing gc, dump this msg
1636                                 break;
1637                         }
1638 #endif
1639                         int allocsize = 0;
1640                   void * mem = smemalloc(msgdata[1], &allocsize);
1641                         if(mem == NULL) {
1642                                 break;
1643                         }
1644                         // send the start_va to request core
1645                         if(isMsgSending) {
1646                                 cache_msg_3(msgdata[2], MEMRESPONSE, mem, allocsize);
1647                         } else {
1648                                 send_msg_3( msgdata[2], MEMRESPONSE, mem, allocsize);
1649                         } 
1650                 }
1651           break;
1652         }
1653
1654         case MEMRESPONSE: {
1655                 // receive a shared memory response msg
1656 #ifdef DEBUG
1657 #ifndef TILERA
1658           BAMBOO_DEBUGPRINT(0xe88b);
1659 #endif
1660 #endif
1661 #ifdef MULTICORE_GC
1662                 if(gcprocessing) {
1663                         // is currently doing gc, dump this msg
1664                         break;
1665                 }
1666 #endif
1667           if(msgdata[2] == 0) {
1668                   bamboo_smem_size = 0;
1669                   bamboo_cur_msp = 0;
1670           } else {
1671                         // fill header to store the size of this mem block
1672                         (*((int*)msgdata[1])) = msgdata[2];
1673                   bamboo_smem_size = msgdata[2] - BAMBOO_CACHE_LINE_SIZE;
1674 #ifdef MULTICORE_GC
1675                         bamboo_cur_msp = msgdata[1] + BAMBOO_CACHE_LINE_SIZE;
1676 #else
1677                   bamboo_cur_msp = 
1678                                 create_mspace_with_base((void*)(msgdata[1]+BAMBOO_CACHE_LINE_SIZE),
1679                                                          msgdata[2]-BAMBOO_CACHE_LINE_SIZE, 
1680                                                                                                                                  0);
1681 #endif
1682           }
1683           smemflag = true;
1684           break;
1685         }
1686
1687 #ifdef MULTICORE_GC
1688         // GC msgs
1689         case GCSTARTINIT: {
1690                 gcflag = true;
1691                 if(!smemflag) {
1692                         // is waiting for response of mem request
1693                         // let it return NULL and start gc
1694                         bamboo_smem_size = 0;
1695                         bamboo_cur_msp = NULL;
1696                         smemflag = true;
1697                 }
1698           break;
1699         }
1700
1701         case GCSTART: {
1702                 // receive a start GC msg
1703 #ifdef DEBUG
1704 #ifndef TILERA
1705           BAMBOO_DEBUGPRINT(0xe88c);
1706 #endif
1707 #endif
1708           // set the GC flag
1709                 gcphase = MARKPHASE;
1710           break;
1711         }
1712
1713         case GCSTARTCOMPACT: {
1714                 // a compact phase start msg
1715                 gcblock2fill = msgdata[1];
1716                 gcphase = COMPACTPHASE;
1717                 break;
1718         }
1719
1720         case GCSTARTFLUSH: {
1721                 // received a flush phase start msg
1722                 gcphase = FLUSHPHASE;
1723                 break;
1724         }
1725         
1726         case GCFINISHINIT: {
1727                 // received a init phase finish msg
1728                 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1729                   // non startup core can not receive this msg
1730 #ifndef TILERA
1731                   BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1732 #endif
1733                   BAMBOO_EXIT(0xb001);
1734                 } 
1735                 if(msgdata[1] < NUMCORES) {
1736                         gccorestatus[msgdata[1]] = 0;
1737                 }
1738         }
1739
1740         case GCFINISHMARK: {
1741                 // received a mark phase finish msg
1742                 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1743                   // non startup core can not receive this msg
1744 #ifndef TILERA
1745                   BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1746 #endif
1747                   BAMBOO_EXIT(0xb002);
1748                 } 
1749                 if(msgdata[1] < NUMCORES) {
1750                         gccorestatus[msgdata[1]] = 0;
1751                         gcnumsendobjs[msgdata[1]] = msgdata[2];
1752                         gcnumreceiveobjs[msgdata[1]] = msgdata[3];
1753                 }
1754           break;
1755         }
1756         
1757         case GCFINISHCOMPACT: {
1758                 // received a compact phase finish msg
1759                 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1760                   // non startup core can not receive this msg
1761                   // return -1
1762 #ifndef TILERA
1763                   BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1764 #endif
1765                   BAMBOO_EXIT(0xb003);
1766                 }
1767                 int cnum = msgdata[1];
1768                 int filledblocks = msgdata[2];
1769                 int heaptop = msgdata[3];
1770                 int data4 = msgdata[4];
1771                 if(cnum < NUMCORES) {
1772                         if(COMPACTPHASE == gcphase) {
1773                                 gcfilledblocks[cnum] = filledblocks;
1774                                 gcloads[cnum] = heaptop;
1775                         }
1776                         if(data4 > 0) {
1777                                 // ask for more mem
1778                                 int startaddr = 0;
1779                                 int tomove = 0;
1780                                 int dstcore = 0;
1781                                 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
1782                                         if(isMsgSending) {
1783                                                 cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
1784                                         } else {
1785                                                 send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
1786                                         }
1787                                 }
1788                         } else {
1789                                 gccorestatus[cnum] = 0;
1790                                 // check if there is pending move request
1791                                 /*if(gcmovepending > 0) {
1792                                         int j;
1793                                         for(j = 0; j < NUMCORES; j++) {
1794                                                 if(gcrequiredmems[j]>0) {
1795                                                         break;
1796                                                 }
1797                                         }
1798                                         if(j < NUMCORES) {
1799                                                 // find match
1800                                                 int tomove = 0;
1801                                                 int startaddr = 0;
1802                                                 gcrequiredmems[j] = assignSpareMem_I(cnum, 
1803                                                                                                                                                                                            gcrequiredmems[j], 
1804                                                                                                                                                                                            &tomove, 
1805                                                                                                                                                                                            &startaddr);
1806                                                 if(STARTUPCORE == j) {
1807                                                         gcdstcore = cnum;
1808                                                         gctomove = true;
1809                                                         gcmovestartaddr = startaddr;
1810                                                         gcblock2fill = tomove;
1811                                                 } else {
1812                                                         if(isMsgSending) {
1813                                                                 cache_msg_4(j, GCMOVESTART, cnum, startaddr, tomove);
1814                                                         } else {
1815                                                                 send_msg_4(j, GCMOVESTART, cnum, startaddr, tomove);
1816                                                         }
1817                                                 } // if(STARTUPCORE == j)
1818                                                 if(gcrequiredmems[j] == 0) {
1819                                                         gcmovepending--;
1820                                                 }
1821                                         } // if(j < NUMCORES)
1822                                 } // if(gcmovepending > 0) */
1823                         } // if(data4>0)
1824                 } // if(cnum < NUMCORES)
1825           break;
1826         }
1827
1828         case GCFINISHFLUSH: {
1829                 // received a flush phase finish msg
1830                 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1831                   // non startup core can not receive this msg
1832                   // return -1
1833 #ifndef TILERA
1834                   BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1835 #endif
1836                   BAMBOO_EXIT(0xb004);
1837                 } 
1838                 if(msgdata[1] < NUMCORES) {
1839                   gccorestatus[msgdata[1]] = 0;
1840                 }
1841           break;
1842         }
1843
1844         case GCFINISH: {
1845                 // received a GC finish msg
1846                 gcphase = FINISHPHASE;
1847                 break;
1848         }
1849
1850         case GCMARKCONFIRM: {
1851                 // received a marked phase finish confirm request msg
1852                 if((BAMBOO_NUM_OF_CORE == STARTUPCORE) 
1853                                 || (BAMBOO_NUM_OF_CORE > NUMCORES - 1)) {
1854                   // wrong core to receive such msg
1855                   BAMBOO_EXIT(0xb005);
1856                 } else {
1857                   // send response msg
1858                   if(isMsgSending) {
1859                           cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE, 
1860                                                         gcbusystatus, gcself_numsendobjs, 
1861                                                                                 gcself_numreceiveobjs);
1862                   } else {
1863                           send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE, 
1864                                                        gcbusystatus, gcself_numsendobjs, gcself_numreceiveobjs);
1865                   }
1866                 }
1867           break;
1868         }
1869
1870         case GCMARKREPORT: {
1871                 // received a marked phase finish confirm response msg
1872                 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1873                   // wrong core to receive such msg
1874 #ifndef TILERA
1875                   BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1876 #endif
1877                   BAMBOO_EXIT(0xb006);
1878                 } else {
1879                   if(waitconfirm) {
1880                           numconfirm--;
1881                   }
1882                   gccorestatus[msgdata[1]] = msgdata[2];
1883                   gcnumsendobjs[msgdata[1]] = msgdata[3];
1884                   gcnumreceiveobjs[msgdata[1]] = msgdata[4];
1885                 }
1886           break;
1887         }
1888
1889         case GCMARKEDOBJ: {
1890                 // received a markedObj msg
1891                 gc_enqueue_I(msgdata[1]);
1892                 gcself_numreceiveobjs++;
1893                 gcbusystatus = true;
1894                 break;
1895         }
1896
1897         case GCMOVESTART: {
1898                 // received a start moving objs msg
1899                 gctomove = true;
1900                 gcdstcore = msgdata[1];
1901                 gcmovestartaddr = msgdata[2];
1902                 gcblock2fill = msgdata[3];
1903                 break;
1904         }
1905         
1906         case GCMAPREQUEST: {
1907                 // received a mapping info request msg
1908                 void * dstptr = NULL;
1909                 RuntimeHashget(gcpointertbl, msgdata[1], &dstptr);
1910                 if(NULL == dstptr) {
1911                         // no such pointer in this core, something is wrong
1912                         BAMBOO_EXIT(0xb007);
1913                 } else {
1914                         // send back the mapping info
1915                         if(isMsgSending) {
1916                                 cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], (int)dstptr);
1917                         } else {
1918                                 send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], (int)dstptr);
1919                         }
1920                 }
1921                 break;
1922         }
1923
1924         case GCMAPINFO: {
1925                 // received a mapping info response msg
1926                 if(msgdata[1] != gcobj2map) {
1927                         // obj not matched, something is wrong
1928                         BAMBOO_EXIT(0xb008);
1929                 } else {
1930                         gcmappedobj = msgdata[2];
1931                         RuntimeHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
1932                 }
1933                 gcismapped = true;
1934                 break;
1935         }
1936
1937         case GCLOBJREQUEST: {
1938                 // received a large objs info request msg
1939                 transferMarkResults_I();
1940                 break;
1941         }
1942
1943         case GCLOBJINFO: {
1944                 // received a large objs info response msg
1945                 numconfirm--;
1946
1947                 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1948 #ifndef TILERA
1949                         BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1950 #endif
1951                         BAMBOO_EXIT(0xb009);
1952                 } 
1953                 // store the mark result info 
1954                 int cnum = msgdata[2];
1955                 gcloads[cnum] = msgdata[3];
1956                 if(gcheaptop < msgdata[4]) {
1957                         gcheaptop = msgdata[4];
1958                 }
1959                 // large obj info here
1960           for(int k = 5; k < msgdata[1];) {
1961                         gc_lobjenqueue_I(msgdata[k++], msgdata[k++], cnum);
1962                         gcnumlobjs++;
1963                 } // for(int k = 5; k < msgdata[1];)
1964                 break;
1965         }
1966         
1967         case GCLOBJMAPPING: {
1968                 // received a large obj mapping info msg
1969                 RuntimeHashadd_I(gcpointertbl, msgdata[1], msgdata[2]);
1970                 break;
1971         }
1972
1973 #endif
1974
1975         default:
1976                 break;
1977         }
1978         for(msgdataindex--; msgdataindex > 0; --msgdataindex) {
1979                 msgdata[msgdataindex] = -1;
1980         }
1981         msgtype = -1;
1982         msglength = 30;
1983 #ifdef DEBUG
1984 #ifndef TILERA
1985         BAMBOO_DEBUGPRINT(0xe88d);
1986 #endif
1987 #endif
1988
1989         if(BAMBOO_MSG_AVAIL() != 0) {
1990                 goto msg;
1991         }
1992 #ifdef PROFILE
1993 /*if(isInterrupt) {
1994                 profileTaskEnd();
1995         }*/
1996 #endif
1997         return (int)type;
1998 } else {
1999         // not a whole msg
2000 #ifdef DEBUG
2001 #ifndef TILERA
2002         BAMBOO_DEBUGPRINT(0xe88e);
2003 #endif
2004 #endif
2005 #ifdef PROFILE
2006 /*  if(isInterrupt) {
2007                   profileTaskEnd();
2008                 }*/
2009 #endif
2010     return -2;
2011   }
2012 }
2013
2014 int enqueuetasks(struct parameterwrapper *parameter, 
2015                              struct parameterwrapper *prevptr, 
2016                                                                  struct ___Object___ *ptr, 
2017                                                                  int * enterflags, 
2018                                                                  int numenterflags) {
2019   void * taskpointerarray[MAXTASKPARAMS];
2020   int j;
2021   //int numparams=parameter->task->numParameters;
2022   int numiterators=parameter->task->numTotal-1;
2023   int retval=1;
2024
2025   struct taskdescriptor * task=parameter->task;
2026
2027    //this add the object to parameterwrapper
2028    ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags, 
2029                                    numenterflags, enterflags==NULL);
2030
2031   /* Add enqueued object to parameter vector */
2032   taskpointerarray[parameter->slot]=ptr;
2033
2034   /* Reset iterators */
2035   for(j=0; j<numiterators; j++) {
2036     toiReset(&parameter->iterators[j]);
2037   }
2038
2039   /* Find initial state */
2040   for(j=0; j<numiterators; j++) {
2041 backtrackinit:
2042     if(toiHasNext(&parameter->iterators[j],taskpointerarray OPTARG(failed)))
2043       toiNext(&parameter->iterators[j], taskpointerarray OPTARG(failed));
2044     else if (j>0) {
2045       /* Need to backtrack */
2046       toiReset(&parameter->iterators[j]);
2047       j--;
2048       goto backtrackinit;
2049     } else {
2050       /* Nothing to enqueue */
2051       return retval;
2052     }
2053   }
2054
2055   while(1) {
2056     /* Enqueue current state */
2057     //int launch = 0;
2058     struct taskparamdescriptor *tpd=
2059                         RUNMALLOC(sizeof(struct taskparamdescriptor));
2060     tpd->task=task;
2061     tpd->numParameters=numiterators+1;
2062     tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
2063
2064     for(j=0; j<=numiterators; j++) {
2065                         //store the actual parameters
2066       tpd->parameterArray[j]=taskpointerarray[j]; 
2067     }
2068     /* Enqueue task */
2069     if ((/*!gencontains(failedtasks, tpd)&&*/ 
2070                                         !gencontains(activetasks,tpd))) {
2071                 genputtable(activetasks, tpd, tpd);
2072     } else {
2073       RUNFREE(tpd->parameterArray);
2074       RUNFREE(tpd);
2075     }
2076
2077     /* This loop iterates to the next parameter combination */
2078     if (numiterators==0)
2079       return retval;
2080
2081     for(j=numiterators-1; j<numiterators; j++) {
2082 backtrackinc:
2083       if(toiHasNext(&parameter->iterators[j],taskpointerarray OPTARG(failed)))
2084         toiNext(&parameter->iterators[j], taskpointerarray OPTARG(failed));
2085       else if (j>0) {
2086         /* Need to backtrack */
2087         toiReset(&parameter->iterators[j]);
2088         j--;
2089         goto backtrackinc;
2090       } else {
2091         /* Nothing more to enqueue */
2092         return retval;
2093       }
2094     }
2095   }
2096   return retval;
2097 }
2098
2099 int enqueuetasks_I(struct parameterwrapper *parameter, 
2100                                struct parameterwrapper *prevptr, 
2101                                                                          struct ___Object___ *ptr, 
2102                                                                          int * enterflags, 
2103                                                                          int numenterflags) {
2104   void * taskpointerarray[MAXTASKPARAMS];
2105   int j;
2106   //int numparams=parameter->task->numParameters;
2107   int numiterators=parameter->task->numTotal-1;
2108   int retval=1;
2109   //int addnormal=1;
2110   //int adderror=1;
2111
2112   struct taskdescriptor * task=parameter->task;
2113
2114    //this add the object to parameterwrapper
2115    ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags, 
2116                                      numenterflags, enterflags==NULL);  
2117
2118   /* Add enqueued object to parameter vector */
2119   taskpointerarray[parameter->slot]=ptr;
2120
2121   /* Reset iterators */
2122   for(j=0; j<numiterators; j++) {
2123     toiReset(&parameter->iterators[j]);
2124   }
2125
2126   /* Find initial state */
2127   for(j=0; j<numiterators; j++) {
2128 backtrackinit:
2129     if(toiHasNext(&parameter->iterators[j],taskpointerarray OPTARG(failed)))
2130       toiNext(&parameter->iterators[j], taskpointerarray OPTARG(failed));
2131     else if (j>0) {
2132       /* Need to backtrack */
2133       toiReset(&parameter->iterators[j]);
2134       j--;
2135       goto backtrackinit;
2136     } else {
2137       /* Nothing to enqueue */
2138       return retval;
2139     }
2140   }
2141
2142   while(1) {
2143     /* Enqueue current state */
2144     //int launch = 0;
2145     struct taskparamdescriptor *tpd=
2146                         RUNMALLOC_I(sizeof(struct taskparamdescriptor));
2147     tpd->task=task;
2148     tpd->numParameters=numiterators+1;
2149     tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
2150
2151     for(j=0; j<=numiterators; j++) {
2152                         //store the actual parameters
2153       tpd->parameterArray[j]=taskpointerarray[j]; 
2154     }
2155     /* Enqueue task */
2156     if ((/*!gencontains(failedtasks, tpd)&&*/ 
2157                                         !gencontains(activetasks,tpd))) {
2158                 genputtable_I(activetasks, tpd, tpd);
2159     } else {
2160       RUNFREE(tpd->parameterArray);
2161       RUNFREE(tpd);
2162     }
2163
2164     /* This loop iterates to the next parameter combination */
2165     if (numiterators==0)
2166       return retval;
2167
2168     for(j=numiterators-1; j<numiterators; j++) {
2169 backtrackinc:
2170       if(toiHasNext(&parameter->iterators[j], taskpointerarray OPTARG(failed)))
2171         toiNext(&parameter->iterators[j], taskpointerarray OPTARG(failed));
2172       else if (j>0) {
2173         /* Need to backtrack */
2174         toiReset(&parameter->iterators[j]);
2175         j--;
2176         goto backtrackinc;
2177       } else {
2178         /* Nothing more to enqueue */
2179         return retval;
2180       }
2181     }
2182   }
2183   return retval;
2184 }
2185
2186 #ifdef MULTICORE_GC
2187 #define OFFSET 2
2188 #else
2189 #define OFFSET 0
2190 #endif
2191
2192 int containstag(struct ___Object___ *ptr, 
2193                             struct ___TagDescriptor___ *tag);
2194
2195 #ifndef MULTICORE_GC
2196 void releasewritelock_r(void * lock, void * redirectlock) {
2197   int targetcore = 0;
2198   int reallock = (int)lock;
2199   targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2200
2201 #ifdef DEBUG
2202   BAMBOO_DEBUGPRINT(0xe671);
2203   BAMBOO_DEBUGPRINT_REG((int)lock);
2204   BAMBOO_DEBUGPRINT_REG(reallock);
2205   BAMBOO_DEBUGPRINT_REG(targetcore);
2206 #endif
2207
2208   if(targetcore == BAMBOO_NUM_OF_CORE) {
2209         BAMBOO_START_CRITICAL_SECTION_LOCK();
2210 #ifdef DEBUG
2211         BAMBOO_DEBUGPRINT(0xf001);
2212 #endif
2213     // reside on this core
2214     if(!RuntimeHashcontainskey(locktbl, reallock)) {
2215       // no locks for this object, something is wrong
2216       BAMBOO_EXIT(0xa011);
2217     } else {
2218       int rwlock_obj = 0;
2219           struct LockValue * lockvalue = NULL;
2220 #ifdef DEBUG
2221       BAMBOO_DEBUGPRINT(0xe672);
2222 #endif
2223       RuntimeHashget(locktbl, reallock, &rwlock_obj);
2224           lockvalue = (struct LockValue *)rwlock_obj;
2225 #ifdef DEBUG
2226       BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2227 #endif
2228       lockvalue->value++;
2229           lockvalue->redirectlock = (int)redirectlock;
2230 #ifdef DEBUG
2231       BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2232 #endif
2233     }
2234         BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
2235 #ifdef DEBUG
2236         BAMBOO_DEBUGPRINT(0xf000);
2237 #endif
2238     return;
2239   } else {
2240           // send lock release with redirect info msg
2241           // for 32 bit machine, the size is always 4 words
2242           send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock, (int)redirectlock);
2243   }
2244 }
2245 #endif
2246
2247 void executetasks() {
2248   void * taskpointerarray[MAXTASKPARAMS+OFFSET];
2249   int numparams=0;
2250   int numtotal=0;
2251   struct ___Object___ * tmpparam = NULL;
2252   struct parameterdescriptor * pd=NULL;
2253   struct parameterwrapper *pw=NULL;
2254   int j = 0;
2255   int x = 0;
2256   bool islock = true;
2257
2258   struct LockValue locks[MAXTASKPARAMS];
2259   int locklen = 0;
2260   int grount = 0;
2261   int andmask=0;
2262   int checkmask=0;
2263
2264
2265 newtask:
2266   while(hashsize(activetasks)>0) {
2267 #ifdef MULTICORE_GC
2268                 gc(NULL);
2269 #endif
2270 #ifdef DEBUG
2271     BAMBOO_DEBUGPRINT(0xe990);
2272 #endif
2273
2274     /* See if there are any active tasks */
2275     if (hashsize(activetasks)>0) {
2276       int i;
2277 #ifdef PROFILE
2278 #ifdef ACCURATEPROFILE
2279           profileTaskStart("tpd checking");
2280 #endif
2281 #endif
2282           busystatus = true;
2283       currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
2284       genfreekey(activetasks, currtpd);
2285
2286       numparams=currtpd->task->numParameters;
2287       numtotal=currtpd->task->numTotal;
2288
2289           // clear the lockRedirectTbl 
2290                 // (TODO, this table should be empty after all locks are released)
2291           // reset all locks
2292           for(j = 0; j < MAXTASKPARAMS; j++) {
2293                   locks[j].redirectlock = 0;
2294                   locks[j].value = 0;
2295           }
2296           // get all required locks
2297           locklen = 0;
2298           // check which locks are needed
2299           for(i = 0; i < numparams; i++) {
2300                   void * param = currtpd->parameterArray[i];
2301                   int tmplock = 0;
2302                   int j = 0;
2303                   bool insert = true;
2304                   if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
2305                           islock = false;
2306                           taskpointerarray[i+OFFSET]=param;
2307                           goto execute;
2308                   }
2309                   if(((struct ___Object___ *)param)->lock == NULL) {
2310                           tmplock = (int)param;
2311                   } else {
2312                           tmplock = (int)(((struct ___Object___ *)param)->lock);
2313                   }
2314                   // insert into the locks array
2315                   for(j = 0; j < locklen; j++) {
2316                           if(locks[j].value == tmplock) {
2317                                   insert = false;
2318                                   break;
2319                           } else if(locks[j].value > tmplock) {
2320                                   break;
2321                           }
2322                   }
2323                   if(insert) {
2324                           int h = locklen;
2325                           for(; h > j; h--) {
2326                                   locks[h].redirectlock = locks[h-1].redirectlock;
2327                                   locks[h].value = locks[h-1].value;
2328                           }
2329                           locks[j].value = tmplock;
2330                           locks[j].redirectlock = (int)param;
2331                           locklen++;
2332                   }               
2333           } // line 2713: for(i = 0; i < numparams; i++) 
2334           // grab these required locks
2335 #ifdef DEBUG
2336           BAMBOO_DEBUGPRINT(0xe991);
2337 #endif
2338           for(i = 0; i < locklen; i++) {
2339                   int * lock = (int *)(locks[i].redirectlock);
2340                   islock = true;
2341                   // require locks for this parameter if it is not a startup object
2342 #ifdef DEBUG
2343                   BAMBOO_DEBUGPRINT_REG((int)lock);
2344                   BAMBOO_DEBUGPRINT_REG((int)(locks[i].value));
2345 #endif
2346                   getwritelock(lock);
2347                   BAMBOO_START_CRITICAL_SECTION();
2348 #ifdef DEBUG
2349                   BAMBOO_DEBUGPRINT(0xf001);
2350 #endif
2351 #ifdef PROFILE
2352                   //isInterrupt = false;
2353 #endif 
2354                   while(!lockflag) { 
2355                           BAMBOO_WAITING_FOR_LOCK();
2356                   }
2357 #ifndef INTERRUPT
2358                   if(reside) {
2359                           while(BAMBOO_WAITING_FOR_LOCK() != -1) {
2360                           }
2361                   }
2362 #endif
2363                   grount = lockresult;
2364
2365                   lockresult = 0;
2366                   lockobj = 0;
2367                   lock2require = 0;
2368                   lockflag = false;
2369 #ifndef INTERRUPT
2370                   reside = false;
2371 #endif
2372 #ifdef PROFILE
2373                   //isInterrupt = true;
2374 #endif
2375                   BAMBOO_CLOSE_CRITICAL_SECTION();
2376 #ifdef DEBUG
2377                   BAMBOO_DEBUGPRINT(0xf000);
2378 #endif
2379
2380                   if(grount == 0) {
2381                           int j = 0;
2382 #ifdef DEBUG
2383                           BAMBOO_DEBUGPRINT(0xe992);
2384 #endif
2385                           // can not get the lock, try later
2386                           // releas all grabbed locks for previous parameters
2387                           for(j = 0; j < i; ++j) {
2388                                   lock = (int*)(locks[j].redirectlock);
2389                                   releasewritelock(lock);
2390                           }
2391                           genputtable(activetasks, currtpd, currtpd);
2392                           if(hashsize(activetasks) == 1) {
2393                                   // only one task right now, wait a little while before next try
2394                                   int halt = 10000;
2395                                   while(halt--) {
2396                                   }
2397                           }
2398 #ifdef PROFILE
2399 #ifdef ACCURATEPROFILE
2400                           // fail, set the end of the checkTaskInfo
2401                           profileTaskEnd();
2402 #endif
2403 #endif
2404                           goto newtask;
2405                   } // line 2794: if(grount == 0)
2406           } // line 2752:  for(i = 0; i < locklen; i++)
2407
2408 #ifdef DEBUG
2409         BAMBOO_DEBUGPRINT(0xe993);
2410 #endif
2411       /* Make sure that the parameters are still in the queues */
2412       for(i=0; i<numparams; i++) {
2413         void * parameter=currtpd->parameterArray[i];
2414
2415         // flush the object
2416 #ifdef CACHEFLUSH
2417         BAMBOO_CACHE_FLUSH_RANGE((int)parameter, 
2418                         classsize[((struct ___Object___ *)parameter)->type]);
2419 #endif
2420         tmpparam = (struct ___Object___ *)parameter;
2421         pd=currtpd->task->descriptorarray[i];
2422         pw=(struct parameterwrapper *) pd->queue;
2423         /* Check that object is still in queue */
2424         {
2425           if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
2426 #ifdef DEBUG
2427             BAMBOO_DEBUGPRINT(0xe994);
2428 #endif
2429             // release grabbed locks
2430             for(j = 0; j < locklen; ++j) {
2431                 int * lock = (int *)(locks[j].redirectlock);
2432                 releasewritelock(lock);
2433             }
2434             RUNFREE(currtpd->parameterArray);
2435             RUNFREE(currtpd);
2436                         currtpd = NULL;
2437             goto newtask;
2438           }
2439         } // line2865
2440         /* Check if the object's flags still meets requirements */
2441         {
2442           int tmpi = 0;
2443           bool ismet = false;
2444           for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
2445             andmask=pw->intarray[tmpi*2];
2446             checkmask=pw->intarray[tmpi*2+1];
2447             if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
2448               ismet = true;
2449               break;
2450             }
2451           }
2452           if (!ismet) {
2453             // flags are never suitable
2454             // remove this obj from the queue
2455             int next;
2456             int UNUSED, UNUSED2;
2457             int * enterflags;
2458 #ifdef DEBUG
2459             BAMBOO_DEBUGPRINT(0xe995);
2460 #endif
2461             ObjectHashget(pw->objectset, (int) parameter, (int *) &next, 
2462                                                   (int *) &enterflags, &UNUSED, &UNUSED2);
2463             ObjectHashremove(pw->objectset, (int)parameter);
2464             if (enterflags!=NULL)
2465               RUNFREE(enterflags);
2466             // release grabbed locks
2467             for(j = 0; j < locklen; ++j) {
2468                  int * lock = (int *)(locks[j].redirectlock);
2469                 releasewritelock(lock);
2470             }
2471             RUNFREE(currtpd->parameterArray);
2472             RUNFREE(currtpd);
2473                         currtpd = NULL;
2474 #ifdef PROFILE
2475 #ifdef ACCURATEPROFILE
2476             // fail, set the end of the checkTaskInfo
2477                 profileTaskEnd();
2478 #endif
2479 #endif
2480             goto newtask;
2481           } // line 2878: if (!ismet)
2482         } // line 2867
2483 parameterpresent:
2484         ;
2485         /* Check that object still has necessary tags */
2486         for(j=0; j<pd->numbertags; j++) {
2487           int slotid=pd->tagarray[2*j]+numparams;
2488           struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
2489           if (!containstag(parameter, tagd)) {
2490 #ifdef DEBUG
2491             BAMBOO_DEBUGPRINT(0xe996);
2492 #endif
2493                 {
2494                 // release grabbed locks
2495                 int tmpj = 0;
2496             for(tmpj = 0; tmpj < locklen; ++tmpj) {
2497                  int * lock = (int *)(locks[tmpj].redirectlock);
2498                 releasewritelock(lock);
2499             }
2500                 }
2501             RUNFREE(currtpd->parameterArray);
2502             RUNFREE(currtpd);
2503                         currtpd = NULL;
2504             goto newtask;
2505           } // line2911: if (!containstag(parameter, tagd))
2506         } // line 2808: for(j=0; j<pd->numbertags; j++)
2507
2508         taskpointerarray[i+OFFSET]=parameter;
2509       } // line 2824: for(i=0; i<numparams; i++)
2510       /* Copy the tags */
2511       for(; i<numtotal; i++) {
2512         taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
2513       }
2514
2515       {
2516 execute:
2517           /* Actually call task */
2518 #ifdef MULTICORE_GC
2519           ((int *)taskpointerarray)[0]=currtpd->numParameters;
2520           taskpointerarray[1]=NULL;
2521 #endif
2522 #ifdef PROFILE
2523 #ifdef ACCURATEPROFILE
2524           // check finish, set the end of the checkTaskInfo
2525           profileTaskEnd();
2526 #endif
2527           profileTaskStart(currtpd->task->name);
2528 #endif
2529
2530 #ifdef DEBUG
2531                 BAMBOO_DEBUGPRINT(0xe997);
2532 #endif
2533                 ((void(*) (void **))currtpd->task->taskptr)(taskpointerarray);
2534 #ifdef PROFILE
2535 #ifdef ACCURATEPROFILE
2536           // task finish, set the end of the checkTaskInfo
2537           profileTaskEnd();
2538           // new a PostTaskInfo for the post-task execution
2539           profileTaskStart("post task execution");
2540 #endif
2541 #endif
2542 #ifdef DEBUG
2543           BAMBOO_DEBUGPRINT(0xe998);
2544           BAMBOO_DEBUGPRINT_REG(islock);
2545 #endif
2546
2547           if(islock) {
2548 #ifdef DEBUG
2549                   BAMBOO_DEBUGPRINT(0xe999);
2550 #endif
2551             for(i = 0; i < locklen; ++i) {
2552                                 void * ptr = (void *)(locks[i].redirectlock);
2553               int * lock = (int *)(locks[i].value);
2554 #ifdef DEBUG
2555                   BAMBOO_DEBUGPRINT_REG((int)ptr);
2556                   BAMBOO_DEBUGPRINT_REG((int)lock);
2557 #endif
2558 #ifndef MULTICORE_GC
2559                   if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
2560                           int redirectlock;
2561                           RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
2562                           RuntimeHashremovekey(lockRedirectTbl, (int)lock);
2563                           releasewritelock_r(lock, (int *)redirectlock);
2564                   } else {
2565 #else
2566                                 {
2567 #endif
2568                 releasewritelock(ptr);
2569                   }
2570             }
2571           } // line 3015: if(islock)
2572
2573 #ifdef PROFILE
2574           // post task execution finish, set the end of the postTaskInfo
2575           profileTaskEnd();
2576 #endif
2577
2578           // Free up task parameter descriptor
2579           RUNFREE(currtpd->parameterArray);
2580           RUNFREE(currtpd);
2581                 currtpd = NULL;
2582 #ifdef DEBUG
2583           BAMBOO_DEBUGPRINT(0xe99a);
2584 #endif
2585       } //  
2586     } //  if (hashsize(activetasks)>0)  
2587   } //  while(hashsize(activetasks)>0)
2588 #ifdef DEBUG
2589   BAMBOO_DEBUGPRINT(0xe99b);
2590 #endif
2591 }
2592
2593 /* This function processes an objects tags */
2594 void processtags(struct parameterdescriptor *pd, 
2595                              int index, 
2596                                                                  struct parameterwrapper *parameter, 
2597                                                                  int * iteratorcount, 
2598                                                                  int *statusarray, 
2599                                                                  int numparams) {
2600   int i;
2601
2602   for(i=0; i<pd->numbertags; i++) {
2603     int slotid=pd->tagarray[2*i];
2604     int tagid=pd->tagarray[2*i+1];
2605
2606     if (statusarray[slotid+numparams]==0) {
2607       parameter->iterators[*iteratorcount].istag=1;
2608       parameter->iterators[*iteratorcount].tagid=tagid;
2609       parameter->iterators[*iteratorcount].slot=slotid+numparams;
2610       parameter->iterators[*iteratorcount].tagobjectslot=index;
2611       statusarray[slotid+numparams]=1;
2612       (*iteratorcount)++;
2613     }
2614   }
2615 }
2616
2617
2618 void processobject(struct parameterwrapper *parameter, 
2619                                int index, 
2620                                                                          struct parameterdescriptor *pd, 
2621                                                                          int *iteratorcount, 
2622                                                                          int * statusarray, 
2623                                                                          int numparams) {
2624   int i;
2625   int tagcount=0;
2626   struct ObjectHash * objectset=
2627                 ((struct parameterwrapper *)pd->queue)->objectset;
2628
2629   parameter->iterators[*iteratorcount].istag=0;
2630   parameter->iterators[*iteratorcount].slot=index;
2631   parameter->iterators[*iteratorcount].objectset=objectset;
2632   statusarray[index]=1;
2633
2634   for(i=0; i<pd->numbertags; i++) {
2635     int slotid=pd->tagarray[2*i];
2636     //int tagid=pd->tagarray[2*i+1];
2637     if (statusarray[slotid+numparams]!=0) {
2638       /* This tag has already been enqueued, use it to narrow search */
2639       parameter->iterators[*iteratorcount].tagbindings[tagcount]=
2640                                 slotid+numparams;
2641       tagcount++;
2642     }
2643   }
2644   parameter->iterators[*iteratorcount].numtags=tagcount;
2645
2646   (*iteratorcount)++;
2647 }
2648
2649 /* This function builds the iterators for a task & parameter */
2650
2651 void builditerators(struct taskdescriptor * task, 
2652                                 int index, 
2653                                                                                 struct parameterwrapper * parameter) {
2654   int statusarray[MAXTASKPARAMS];
2655   int i;
2656   int numparams=task->numParameters;
2657   int iteratorcount=0;
2658   for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
2659
2660   statusarray[index]=1; /* Initial parameter */
2661   /* Process tags for initial iterator */
2662
2663   processtags(task->descriptorarray[index], index, parameter, 
2664                                 &iteratorcount, statusarray, numparams);
2665
2666   while(1) {
2667 loopstart:
2668     /* Check for objects with existing tags */
2669     for(i=0; i<numparams; i++) {
2670       if (statusarray[i]==0) {
2671         struct parameterdescriptor *pd=task->descriptorarray[i];
2672         int j;
2673         for(j=0; j<pd->numbertags; j++) {
2674           int slotid=pd->tagarray[2*j];
2675           if(statusarray[slotid+numparams]!=0) {
2676             processobject(parameter, i, pd, &iteratorcount, statusarray, 
2677                                                   numparams);
2678             processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
2679             goto loopstart;
2680           }
2681         }
2682       }
2683     }
2684
2685     /* Next do objects w/ unbound tags*/
2686
2687     for(i=0; i<numparams; i++) {
2688       if (statusarray[i]==0) {
2689         struct parameterdescriptor *pd=task->descriptorarray[i];
2690         if (pd->numbertags>0) {
2691           processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
2692           processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
2693           goto loopstart;
2694         }
2695       }
2696     }
2697
2698     /* Nothing with a tag enqueued */
2699
2700     for(i=0; i<numparams; i++) {
2701       if (statusarray[i]==0) {
2702         struct parameterdescriptor *pd=task->descriptorarray[i];
2703         processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
2704         processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
2705         goto loopstart;
2706       }
2707     }
2708
2709     /* Nothing left */
2710     return;
2711   }
2712 }
2713
2714 void printdebug() {
2715   int i;
2716   int j;
2717   if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
2718     return;
2719   }
2720   for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
2721     struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
2722 #ifndef RAW 
2723         printf("%s\n", task->name);
2724 #endif
2725     for(j=0; j<task->numParameters; j++) {
2726       struct parameterdescriptor *param=task->descriptorarray[j];
2727       struct parameterwrapper *parameter=param->queue;
2728       struct ObjectHash * set=parameter->objectset;
2729       struct ObjectIterator objit;
2730 #ifndef RAW
2731           printf("  Parameter %d\n", j);
2732 #endif
2733       ObjectHashiterator(set, &objit);
2734       while(ObjhasNext(&objit)) {
2735         struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
2736         struct ___Object___ * tagptr=obj->___tags___;
2737         int nonfailed=Objdata4(&objit);
2738         int numflags=Objdata3(&objit);
2739         int flags=Objdata2(&objit);
2740         Objnext(&objit);
2741 #ifndef RAW
2742         printf("    Contains %lx\n", obj);
2743         printf("      flag=%d\n", obj->flag);
2744 #endif
2745         if (tagptr==NULL) {
2746         } else if (tagptr->type==TAGTYPE) {
2747 #ifndef RAW
2748           printf("      tag=%lx\n",tagptr);
2749 #else
2750           ;
2751 #endif
2752         } else {
2753           int tagindex=0;
2754           struct ArrayObject *ao=(struct ArrayObject *)tagptr;
2755           for(; tagindex<ao->___cachedCode___; tagindex++) {
2756 #ifndef RAW
2757                   printf("      tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*, 
2758                                                  tagindex));
2759 #else
2760                   ;
2761 #endif
2762           }
2763         }
2764       }
2765     }
2766   }
2767 }
2768
2769
2770 /* This function processes the task information to create queues for
2771    each parameter type. */
2772
2773 void processtasks() {
2774   int i;
2775   if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
2776     return;
2777   }
2778   for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
2779     struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
2780     int j;
2781
2782     /* Build objectsets */
2783     for(j=0; j<task->numParameters; j++) {
2784       struct parameterdescriptor *param=task->descriptorarray[j];
2785       struct parameterwrapper *parameter=param->queue;
2786       parameter->objectset=allocateObjectHash(10);
2787       parameter->task=task;
2788     }
2789
2790     /* Build iterators for parameters */
2791     for(j=0; j<task->numParameters; j++) {
2792       struct parameterdescriptor *param=task->descriptorarray[j];
2793       struct parameterwrapper *parameter=param->queue;
2794       builditerators(task, j, parameter);
2795     }
2796   }
2797 }
2798
2799 void toiReset(struct tagobjectiterator * it) {
2800   if (it->istag) {
2801     it->tagobjindex=0;
2802   } else if (it->numtags>0) {
2803     it->tagobjindex=0;
2804   } else {
2805     ObjectHashiterator(it->objectset, &it->it);
2806   }
2807 }
2808
2809 int toiHasNext(struct tagobjectiterator *it, 
2810                            void ** objectarray OPTARG(int * failed)) {
2811   if (it->istag) {
2812     /* Iterate tag */
2813     /* Get object with tags */
2814     struct ___Object___ *obj=objectarray[it->tagobjectslot];
2815     struct ___Object___ *tagptr=obj->___tags___;
2816     if (tagptr->type==TAGTYPE) {
2817       if ((it->tagobjindex==0)&& /* First object */
2818           (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
2819         return 1;
2820       else
2821         return 0;
2822     } else {
2823       struct ArrayObject *ao=(struct ArrayObject *) tagptr;
2824       int tagindex=it->tagobjindex;
2825       for(; tagindex<ao->___cachedCode___; tagindex++) {
2826         struct ___TagDescriptor___ *td=
2827                 ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
2828         if (td->flag==it->tagid) {
2829           it->tagobjindex=tagindex; /* Found right type of tag */
2830           return 1;
2831         }
2832       }
2833       return 0;
2834     }
2835   } else if (it->numtags>0) {
2836     /* Use tags to locate appropriate objects */
2837     struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
2838     struct ___Object___ *objptr=tag->flagptr;
2839     int i;
2840     if (objptr->type!=OBJECTARRAYTYPE) {
2841       if (it->tagobjindex>0)
2842         return 0;
2843       if (!ObjectHashcontainskey(it->objectset, (int) objptr))
2844         return 0;
2845       for(i=1; i<it->numtags; i++) {
2846         struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
2847         if (!containstag(objptr,tag2))
2848           return 0;
2849       }
2850       return 1;
2851     } else {
2852       struct ArrayObject *ao=(struct ArrayObject *) objptr;
2853       int tagindex;
2854       int i;
2855       for(tagindex=it->tagobjindex;tagindex<ao->___cachedCode___;tagindex++) {
2856         struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
2857         if (!ObjectHashcontainskey(it->objectset, (int) objptr))
2858           continue;
2859         for(i=1; i<it->numtags; i++) {
2860           struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
2861           if (!containstag(objptr,tag2))
2862             goto nexttag;
2863         }
2864         it->tagobjindex=tagindex;
2865         return 1;
2866 nexttag:
2867         ;
2868       }
2869       it->tagobjindex=tagindex;
2870       return 0;
2871     }
2872   } else {
2873     return ObjhasNext(&it->it);
2874   }
2875 }
2876
2877 int containstag(struct ___Object___ *ptr, 
2878                             struct ___TagDescriptor___ *tag) {
2879   int j;
2880   struct ___Object___ * objptr=tag->flagptr;
2881   if (objptr->type==OBJECTARRAYTYPE) {
2882     struct ArrayObject *ao=(struct ArrayObject *)objptr;
2883     for(j=0; j<ao->___cachedCode___; j++) {
2884       if (ptr==ARRAYGET(ao, struct ___Object___*, j))
2885         return 1;
2886     }
2887     return 0;
2888   } else
2889     return objptr==ptr;
2890 }
2891
2892 void toiNext(struct tagobjectiterator *it, 
2893                          void ** objectarray OPTARG(int * failed)) {
2894   /* hasNext has all of the intelligence */
2895   if(it->istag) {
2896     /* Iterate tag */
2897     /* Get object with tags */
2898     struct ___Object___ *obj=objectarray[it->tagobjectslot];
2899     struct ___Object___ *tagptr=obj->___tags___;
2900     if (tagptr->type==TAGTYPE) {
2901       it->tagobjindex++;
2902       objectarray[it->slot]=tagptr;
2903     } else {
2904       struct ArrayObject *ao=(struct ArrayObject *) tagptr;
2905       objectarray[it->slot]=
2906                                 ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
2907     }
2908   } else if (it->numtags>0) {
2909     /* Use tags to locate appropriate objects */
2910     struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
2911     struct ___Object___ *objptr=tag->flagptr;
2912     if (objptr->type!=OBJECTARRAYTYPE) {
2913       it->tagobjindex++;
2914       objectarray[it->slot]=objptr;
2915     } else {
2916       struct ArrayObject *ao=(struct ArrayObject *) objptr;
2917       objectarray[it->slot]=
2918                                 ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
2919     }
2920   } else {
2921     /* Iterate object */
2922     objectarray[it->slot]=(void *)Objkey(&it->it);
2923     Objnext(&it->it);
2924   }
2925 }
2926 #endif