disable Timer interrupt and some bug fixing
[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 #ifndef INLINE
8 #define INLINE    inline __attribute__((always_inline))
9 #endif // #ifndef INLINE
10
11 //  data structures for task invocation
12 struct genhashtable * activetasks;
13 struct taskparamdescriptor * currtpd;
14 struct LockValue runtime_locks[MAXTASKPARAMS];
15 int runtime_locklen;
16
17 // specific functions used inside critical sections
18 void enqueueObject_I(void * ptr,
19                      struct parameterwrapper ** queues,
20                      int length);
21 int enqueuetasks_I(struct parameterwrapper *parameter,
22                    struct parameterwrapper *prevptr,
23                    struct ___Object___ *ptr,
24                    int * enterflags,
25                    int numenterflags);
26
27 #ifdef MULTICORE_GC
28 inline __attribute__((always_inline))
29 void setupsmemmode(void) {
30 #ifdef SMEML
31   bamboo_smem_mode = SMEMLOCAL;
32 #elif defined SMEMF
33   bamboo_smem_mode = SMEMFIXED;
34 #elif defined SMEMM
35   bamboo_smem_mode = SMEMMIXED;
36 #elif defined SMEMG
37   bamboo_smem_mode = SMEMGLOBAL;
38 #else
39   // defaultly using local mode
40   //bamboo_smem_mode = SMEMLOCAL;
41   bamboo_smem_mode = SMEMGLOBAL;
42 #endif
43 } // void setupsmemmode(void)
44 #endif
45
46 inline __attribute__((always_inline))
47 void initruntimedata() {
48   int i;
49   // initialize the arrays
50   if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
51     // startup core to initialize corestatus[]
52     for(i = 0; i < NUMCORESACTIVE; ++i) {
53       corestatus[i] = 1;
54       numsendobjs[i] = 0;
55       numreceiveobjs[i] = 0;
56 #ifdef PROFILE
57       // initialize the profile data arrays
58       profilestatus[i] = 1;
59 #endif
60 #ifdef MULTICORE_GC
61       gccorestatus[i] = 1;
62       gcnumsendobjs[i] = 0;
63       gcnumreceiveobjs[i] = 0;
64 #endif
65     } // for(i = 0; i < NUMCORESACTIVE; ++i)
66 #ifdef MULTICORE_GC
67     for(i = 0; i < NUMCORES4GC; ++i) {
68       gcloads[i] = 0;
69       gcrequiredmems[i] = 0;
70       gcstopblock[i] = 0;
71       gcfilledblocks[i] = 0;
72     } // for(i = 0; i < NUMCORES4GC; ++i)
73 #ifdef GC_PROFILE
74     gc_infoIndex = 0;
75     gc_infoOverflow = false;
76 #endif
77 #endif
78     numconfirm = 0;
79     waitconfirm = false;
80
81     // TODO for test
82     total_num_t6 = 0;
83   }
84
85   busystatus = true;
86   self_numsendobjs = 0;
87   self_numreceiveobjs = 0;
88
89   for(i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
90     msgdata[i] = -1;
91   }
92   msgdataindex = 0;
93   msgdatalast = 0;
94   msglength = BAMBOO_MSG_BUF_LENGTH;
95   msgdatafull = false;
96   for(i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
97     outmsgdata[i] = -1;
98   }
99   outmsgindex = 0;
100   outmsglast = 0;
101   outmsgleft = 0;
102   isMsgHanging = false;
103   //isMsgSending = false;
104
105   smemflag = true;
106   bamboo_cur_msp = NULL;
107   bamboo_smem_size = 0;
108   totransobjqueue = createQueue_I();
109
110 #ifdef MULTICORE_GC
111   gcflag = false;
112   gcprocessing = false;
113   gcphase = FINISHPHASE;
114   gccurr_heaptop = 0;
115   gcself_numsendobjs = 0;
116   gcself_numreceiveobjs = 0;
117   gcmarkedptrbound = 0;
118   //mgchashCreate(2000, 0.75);
119   gcpointertbl = allocateRuntimeHash_I(20);
120   //gcpointertbl = allocateMGCHash(20);
121   gcforwardobjtbl = allocateMGCHash_I(20, 3);
122   gcobj2map = 0;
123   gcmappedobj = 0;
124   gcismapped = false;
125   gcnumlobjs = 0;
126   gcheaptop = 0;
127   gctopcore = 0;
128   gctopblock = 0;
129   gcmovestartaddr = 0;
130   gctomove = false;
131   gcmovepending = 0;
132   gcblock2fill = 0;
133   gcsbstarttbl = BAMBOO_BASE_VA;
134   bamboo_smemtbl = (void *)gcsbstarttbl
135                    + (BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE)*sizeof(INTPTR);
136 #else
137   // create the lock table, lockresult table and obj queue
138   locktable.size = 20;
139   locktable.bucket =
140     (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
141   /* Set allocation blocks*/
142   locktable.listhead=NULL;
143   locktable.listtail=NULL;
144   /*Set data counts*/
145   locktable.numelements = 0;
146   lockobj = 0;
147   lock2require = 0;
148   lockresult = 0;
149   lockflag = false;
150   lockRedirectTbl = allocateRuntimeHash_I(20);
151   objRedirectLockTbl = allocateRuntimeHash_I(20);
152 #endif
153 #ifndef INTERRUPT
154   reside = false;
155 #endif
156   objqueue.head = NULL;
157   objqueue.tail = NULL;
158
159   currtpd = NULL;
160
161 #ifdef PROFILE
162   stall = false;
163   //isInterrupt = true;
164   totalexetime = -1;
165   //interrupttime = 0;
166   taskInfoIndex = 0;
167   taskInfoOverflow = false;
168   // TODO
169   interruptInfoIndex = 0;
170   interruptInfoOverflow = false;
171 #endif
172
173   for(i = 0; i < MAXTASKPARAMS; i++) {
174     runtime_locks[i].redirectlock = 0;
175     runtime_locks[i].value = 0;
176   }
177   runtime_locklen = 0;
178 }
179
180 inline __attribute__((always_inline))
181 void disruntimedata() {
182 #ifdef MULTICORE_GC
183   //mgchashDelete();
184   freeRuntimeHash(gcpointertbl);
185   //freeMGCHash(gcpointertbl);
186   freeMGCHash(gcforwardobjtbl);
187 #else
188   freeRuntimeHash(lockRedirectTbl);
189   freeRuntimeHash(objRedirectLockTbl);
190   RUNFREE(locktable.bucket);
191 #endif
192   if(activetasks != NULL) {
193     genfreehashtable(activetasks);
194   }
195   if(currtpd != NULL) {
196     RUNFREE(currtpd->parameterArray);
197     RUNFREE(currtpd);
198     currtpd = NULL;
199   }
200   BAMBOO_LOCAL_MEM_CLOSE();
201   BAMBOO_SHARE_MEM_CLOSE();
202 }
203
204 inline __attribute__((always_inline))
205 bool checkObjQueue() {
206   bool rflag = false;
207   struct transObjInfo * objInfo = NULL;
208   int grount = 0;
209
210 #ifdef PROFILE
211 #ifdef ACCURATEPROFILE
212   bool isChecking = false;
213   if(!isEmpty(&objqueue)) {
214     profileTaskStart("objqueue checking");
215     isChecking = true;
216   }       // if(!isEmpty(&objqueue))
217 #endif
218 #endif
219
220   while(!isEmpty(&objqueue)) {
221     void * obj = NULL;
222     BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
223 #ifdef DEBUG
224     BAMBOO_DEBUGPRINT(0xf001);
225 #endif
226 #ifdef PROFILE
227     //isInterrupt = false;
228 #endif
229 #ifdef DEBUG
230     BAMBOO_DEBUGPRINT(0xeee1);
231 #endif
232     rflag = true;
233     objInfo = (struct transObjInfo *)getItem(&objqueue);
234     obj = objInfo->objptr;
235 #ifdef DEBUG
236     BAMBOO_DEBUGPRINT_REG((int)obj);
237 #endif
238     // grab lock and flush the obj
239     grount = 0;
240     getwritelock_I(obj);
241     while(!lockflag) {
242       BAMBOO_WAITING_FOR_LOCK(0);
243           // check for outgoing sends
244           /*if (isMsgHanging) {
245                 extern inline void send_hanging_msg(bool);
246                 send_hanging_msg(true);
247           } */
248     }             // while(!lockflag)
249     grount = lockresult;
250 #ifdef DEBUG
251     BAMBOO_DEBUGPRINT_REG(grount);
252 #endif
253
254     lockresult = 0;
255     lockobj = 0;
256     lock2require = 0;
257     lockflag = false;
258 #ifndef INTERRUPT
259     reside = false;
260 #endif
261
262     if(grount == 1) {
263       int k = 0;
264       // flush the object
265 #ifdef CACHEFLUSH
266       BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
267       BAMBOO_CACHE_FLUSH_RANGE((int)obj,
268                                classsize[((struct ___Object___ *)obj)->type]);
269 #endif
270       // enqueue the object
271       for(k = 0; k < objInfo->length; ++k) {
272         int taskindex = objInfo->queues[2 * k];
273         int paramindex = objInfo->queues[2 * k + 1];
274         struct parameterwrapper ** queues =
275           &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
276 #ifdef DEBUG
277         BAMBOO_DEBUGPRINT_REG(taskindex);
278         BAMBOO_DEBUGPRINT_REG(paramindex);
279         struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
280         tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n",
281                 BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj,
282                 (long)obj, tmpptr->flag);
283 #endif
284         enqueueObject_I(obj, queues, 1);
285 #ifdef DEBUG
286         BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
287 #endif
288       }                   // for(k = 0; k < objInfo->length; ++k)
289       releasewritelock_I(obj);
290       RUNFREE(objInfo->queues);
291       RUNFREE(objInfo);
292     } else {
293       // can not get lock
294       // put it at the end of the queue if no update version in the queue
295       struct QueueItem * qitem = getHead(&objqueue);
296       struct QueueItem * prev = NULL;
297       while(qitem != NULL) {
298                   struct transObjInfo * tmpinfo =
299                           (struct transObjInfo *)(qitem->objectptr);
300                   if(tmpinfo->objptr == obj) {
301                           // the same object in the queue, which should be enqueued
302                           // recently. Current one is outdate, do not re-enqueue it
303                           RUNFREE(objInfo->queues);
304                           RUNFREE(objInfo);
305                           goto objqueuebreak;
306                   } else {
307                           prev = qitem;
308                   }                         // if(tmpinfo->objptr == obj)
309                   qitem = getNextQueueItem(prev);
310           }                   // while(qitem != NULL)
311                           // try to execute active tasks already enqueued first
312       addNewItem_I(&objqueue, objInfo);
313 #ifdef PROFILE
314       //isInterrupt = true;
315 #endif
316 objqueuebreak:
317       BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
318 #ifdef DEBUG
319       BAMBOO_DEBUGPRINT(0xf000);
320 #endif
321       break;
322     }             // if(grount == 1)
323     BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
324 #ifdef DEBUG
325     BAMBOO_DEBUGPRINT(0xf000);
326 #endif
327   }       // while(!isEmpty(&objqueue))
328
329 #ifdef PROFILE
330 #ifdef ACCURATEPROFILE
331   if(isChecking) {
332     profileTaskEnd();
333   }       // if(isChecking)
334 #endif
335 #endif
336
337 #ifdef DEBUG
338   BAMBOO_DEBUGPRINT(0xee02);
339 #endif
340   return rflag;
341 }
342
343 inline __attribute__((always_inline))
344 void checkCoreStatus() {
345   bool allStall = false;
346   int i = 0;
347   int sumsendobj = 0;
348   if((!waitconfirm) ||
349      (waitconfirm && (numconfirm == 0))) {
350 #ifdef DEBUG
351     BAMBOO_DEBUGPRINT(0xee04);
352     BAMBOO_DEBUGPRINT_REG(waitconfirm);
353 #endif
354     BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
355 #ifdef DEBUG
356     BAMBOO_DEBUGPRINT(0xf001);
357 #endif
358     corestatus[BAMBOO_NUM_OF_CORE] = 0;
359     numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
360     numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
361     // check the status of all cores
362     allStall = true;
363 #ifdef DEBUG
364     BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
365 #endif
366     for(i = 0; i < NUMCORESACTIVE; ++i) {
367 #ifdef DEBUG
368       BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
369 #endif
370       if(corestatus[i] != 0) {
371                   allStall = false;
372                   break;
373       }
374     }             // for(i = 0; i < NUMCORESACTIVE; ++i)
375     if(allStall) {
376       // check if the sum of send objs and receive obj are the same
377       // yes->check if the info is the latest; no->go on executing
378       sumsendobj = 0;
379       for(i = 0; i < NUMCORESACTIVE; ++i) {
380                   sumsendobj += numsendobjs[i];
381 #ifdef DEBUG
382                   BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
383 #endif
384       }                   // for(i = 0; i < NUMCORESACTIVE; ++i)
385       for(i = 0; i < NUMCORESACTIVE; ++i) {
386                   sumsendobj -= numreceiveobjs[i];
387 #ifdef DEBUG
388                   BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
389 #endif
390       }                   // for(i = 0; i < NUMCORESACTIVE; ++i)
391       if(0 == sumsendobj) {
392         if(!waitconfirm) {
393           // the first time found all cores stall
394           // send out status confirm msg to all other cores
395           // reset the corestatus array too
396 #ifdef DEBUG
397           BAMBOO_DEBUGPRINT(0xee05);
398 #endif
399           corestatus[BAMBOO_NUM_OF_CORE] = 1;
400           waitconfirm = true;
401           numconfirm = NUMCORESACTIVE - 1;
402           BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
403           for(i = 1; i < NUMCORESACTIVE; ++i) {
404             corestatus[i] = 1;
405             // send status confirm msg to core i
406             send_msg_1(i, STATUSCONFIRM, false);
407           }   // for(i = 1; i < NUMCORESACTIVE; ++i)
408           return;
409         } else {
410           // all the core status info are the latest
411           // terminate; for profiling mode, send request to all
412           // other cores to pour out profiling data
413 #ifdef DEBUG
414           BAMBOO_DEBUGPRINT(0xee06);
415 #endif
416
417 #ifdef USEIO
418           totalexetime = BAMBOO_GET_EXE_TIME() - bamboo_start_time;
419 #else
420 #ifdef PROFILE
421           //BAMBOO_DEBUGPRINT_REG(interrupttime);
422 #endif
423
424           BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME() - bamboo_start_time);
425           //BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
426           BAMBOO_DEBUGPRINT(0xbbbbbbbb);
427 #endif
428           // profile mode, send msgs to other cores to request pouring
429           // out progiling data
430 #ifdef PROFILE
431           BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
432 #ifdef DEBUG
433           BAMBOO_DEBUGPRINT(0xf000);
434 #endif
435           for(i = 1; i < NUMCORESACTIVE; ++i) {
436             // send profile request msg to core i
437             send_msg_2(i, PROFILEOUTPUT, totalexetime, false);
438           } // for(i = 1; i < NUMCORESACTIVE; ++i)
439           // pour profiling data on startup core
440           outputProfileData();
441           while(true) {
442             BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
443 #ifdef DEBUG
444             BAMBOO_DEBUGPRINT(0xf001);
445 #endif
446             profilestatus[BAMBOO_NUM_OF_CORE] = 0;
447             // check the status of all cores
448             allStall = true;
449 #ifdef DEBUG
450             BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
451 #endif
452             for(i = 0; i < NUMCORESACTIVE; ++i) {
453 #ifdef DEBUG
454               BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
455 #endif
456               if(profilestatus[i] != 0) {
457                 allStall = false;
458                 break;
459               }
460             }  // for(i = 0; i < NUMCORESACTIVE; ++i)
461             if(!allStall) {
462               int halt = 100;
463               BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
464 #ifdef DEBUG
465               BAMBOO_DEBUGPRINT(0xf000);
466 #endif
467               while(halt--) {
468               }
469             } else {
470               BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
471               break;
472             }                                     // if(!allStall)
473           }                               // while(true)
474 #endif
475
476           // gc_profile mode, ourput gc prfiling data
477 #ifdef MULTICORE_GC
478 #ifdef GC_PROFILE
479           gc_outputProfileData();
480 #endif // #ifdef GC_PROFILE
481 #endif // #ifdef MULTICORE_GC
482           disruntimedata();
483           BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
484           terminate();                               // All done.
485         }                         // if(!waitconfirm)
486       } else {
487         // still some objects on the fly on the network
488         // reset the waitconfirm and numconfirm
489 #ifdef DEBUG
490         BAMBOO_DEBUGPRINT(0xee07);
491 #endif
492         waitconfirm = false;
493         numconfirm = 0;
494       }                   //  if(0 == sumsendobj)
495     } else {
496       // not all cores are stall, keep on waiting
497 #ifdef DEBUG
498       BAMBOO_DEBUGPRINT(0xee08);
499 #endif
500       waitconfirm = false;
501       numconfirm = 0;
502     }             //  if(allStall)
503     BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
504 #ifdef DEBUG
505     BAMBOO_DEBUGPRINT(0xf000);
506 #endif
507   }       // if((!waitconfirm) ||
508 }
509
510 // main function for each core
511 inline void run(void * arg) {
512   int i = 0;
513   int argc = 1;
514   char ** argv = NULL;
515   bool sendStall = false;
516   bool isfirst = true;
517   bool tocontinue = false;
518
519   corenum = BAMBOO_GET_NUM_OF_CORE();
520 #ifdef DEBUG
521   BAMBOO_DEBUGPRINT(0xeeee);
522   BAMBOO_DEBUGPRINT_REG(corenum);
523   BAMBOO_DEBUGPRINT(STARTUPCORE);
524 #endif
525
526   // initialize runtime data structures
527   initruntimedata();
528
529   // other architecture related initialization
530   initialization();
531   initCommunication();
532
533   initializeexithandler();
534
535   // main process of the execution module
536   if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
537     // non-executing cores, only processing communications
538     activetasks = NULL;
539 /*#ifdef PROFILE
540         BAMBOO_DEBUGPRINT(0xee01);
541         BAMBOO_DEBUGPRINT_REG(taskInfoIndex);
542         BAMBOO_DEBUGPRINT_REG(taskInfoOverflow);
543                 profileTaskStart("msg handling");
544         }
545  #endif*/
546 #ifdef PROFILE
547     //isInterrupt = false;
548 #endif
549     fakeExecution();
550   } else {
551     /* Create queue of active tasks */
552     activetasks=
553       genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
554                            (int (*)(void *,void *)) &comparetpd);
555
556     /* Process task information */
557     processtasks();
558
559     if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
560       /* Create startup object */
561       createstartupobject(argc, argv);
562     }
563
564 #ifdef DEBUG
565     BAMBOO_DEBUGPRINT(0xee00);
566 #endif
567
568     while(true) {
569 #ifdef MULTICORE_GC
570       // check if need to do GC
571       gc(NULL);
572 #endif
573
574       // check if there are new active tasks can be executed
575       executetasks();
576       if(busystatus) {
577         sendStall = false;
578       }
579
580 #ifndef INTERRUPT
581       while(receiveObject() != -1) {
582       }
583 #endif
584
585 #ifdef DEBUG
586       BAMBOO_DEBUGPRINT(0xee01);
587 #endif
588
589       // check if there are some pending objects,
590       // if yes, enqueue them and executetasks again
591       tocontinue = checkObjQueue();
592
593       if(!tocontinue) {
594         // check if stop
595         if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
596           if(isfirst) {
597 #ifdef DEBUG
598             BAMBOO_DEBUGPRINT(0xee03);
599 #endif
600             isfirst = false;
601           }
602           checkCoreStatus();
603         } else {
604           if(!sendStall) {
605 #ifdef DEBUG
606             BAMBOO_DEBUGPRINT(0xee09);
607 #endif
608 #ifdef PROFILE
609             if(!stall) {
610 #endif
611             if(isfirst) {
612               // wait for some time
613               int halt = 10000;
614 #ifdef DEBUG
615               BAMBOO_DEBUGPRINT(0xee0a);
616 #endif
617               while(halt--) {
618               }
619               isfirst = false;
620             } else {
621               // send StallMsg to startup core
622 #ifdef DEBUG
623               BAMBOO_DEBUGPRINT(0xee0b);
624 #endif
625               // send stall msg
626               send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
627                          self_numsendobjs, self_numreceiveobjs, false);
628               sendStall = true;
629               isfirst = true;
630               busystatus = false;
631             }
632 #ifdef PROFILE
633           }
634 #endif
635           } else {
636             isfirst = true;
637             busystatus = false;
638 #ifdef DEBUG
639             BAMBOO_DEBUGPRINT(0xee0c);
640 #endif
641           }                         // if(!sendStall)
642         }                   // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
643       }             // if(!tocontinue)
644     }       // while(true)
645   } // if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)
646
647 } // run()
648
649 struct ___createstartupobject____I_locals {
650   INTPTR size;
651   void * next;
652   struct  ___StartupObject___ * ___startupobject___;
653   struct ArrayObject * ___stringarray___;
654 }; // struct ___createstartupobject____I_locals
655
656 void createstartupobject(int argc,
657                          char ** argv) {
658   int i;
659
660   /* Allocate startup object     */
661 #ifdef MULTICORE_GC
662   struct ___createstartupobject____I_locals ___locals___={2, NULL, NULL, NULL};
663   struct ___StartupObject___ *startupobject=
664     (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
665   ___locals___.___startupobject___ = startupobject;
666   struct ArrayObject * stringarray=
667     allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
668   ___locals___.___stringarray___ = stringarray;
669 #else
670   struct ___StartupObject___ *startupobject=
671     (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
672   struct ArrayObject * stringarray=
673     allocate_newarray(STRINGARRAYTYPE, argc-1);
674 #endif
675   /* Build array of strings */
676   startupobject->___parameters___=stringarray;
677   for(i=1; i<argc; i++) {
678     int length=strlen(argv[i]);
679 #ifdef MULTICORE_GC
680     struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
681 #else
682     struct ___String___ *newstring=NewString(argv[i],length);
683 #endif
684     ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
685       newstring;
686   }
687
688   startupobject->version = 0;
689   startupobject->lock = NULL;
690
691   /* Set initialized flag for startup object */
692   flagorandinit(startupobject,1,0xFFFFFFFF);
693   enqueueObject(startupobject, NULL, 0);
694 #ifdef CACHEFLUSH
695   BAMBOO_CACHE_FLUSH_ALL();
696 #endif
697 }
698
699 int hashCodetpd(struct taskparamdescriptor *ftd) {
700   int hash=(int)ftd->task;
701   int i;
702   for(i=0; i<ftd->numParameters; i++) {
703     hash^=(int)ftd->parameterArray[i];
704   }
705   return hash;
706 }
707
708 int comparetpd(struct taskparamdescriptor *ftd1,
709                struct taskparamdescriptor *ftd2) {
710   int i;
711   if (ftd1->task!=ftd2->task)
712     return 0;
713   for(i=0; i<ftd1->numParameters; i++)
714     if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
715       return 0;
716   return 1;
717 }
718
719 /* This function sets a tag. */
720 #ifdef MULTICORE_GC
721 void tagset(void *ptr,
722             struct ___Object___ * obj,
723             struct ___TagDescriptor___ * tagd) {
724 #else
725 void tagset(struct ___Object___ * obj,
726             struct ___TagDescriptor___ * tagd) {
727 #endif
728   struct ArrayObject * ao=NULL;
729   struct ___Object___ * tagptr=obj->___tags___;
730   if (tagptr==NULL) {
731     obj->___tags___=(struct ___Object___ *)tagd;
732   } else {
733     /* Have to check if it is already set */
734     if (tagptr->type==TAGTYPE) {
735       struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
736       if (td==tagd) {
737         return;
738       }
739 #ifdef MULTICORE_GC
740       int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
741       struct ArrayObject * ao=
742         allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
743       obj=(struct ___Object___ *)ptrarray[2];
744       tagd=(struct ___TagDescriptor___ *)ptrarray[3];
745       td=(struct ___TagDescriptor___ *) obj->___tags___;
746 #else
747       ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
748 #endif
749
750       ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
751       ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
752       obj->___tags___=(struct ___Object___ *) ao;
753       ao->___cachedCode___=2;
754     } else {
755       /* Array Case */
756       int i;
757       struct ArrayObject *ao=(struct ArrayObject *) tagptr;
758       for(i=0; i<ao->___cachedCode___; i++) {
759         struct ___TagDescriptor___ * td=
760           ARRAYGET(ao, struct ___TagDescriptor___*, i);
761         if (td==tagd) {
762           return;
763         }
764       }
765       if (ao->___cachedCode___<ao->___length___) {
766         ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
767         ao->___cachedCode___++;
768       } else {
769 #ifdef MULTICORE_GC
770         int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
771         struct ArrayObject * aonew=
772           allocate_newarray(&ptrarray,TAGARRAYTYPE,
773                             TAGARRAYINTERVAL+ao->___length___);
774         obj=(struct ___Object___ *)ptrarray[2];
775         tagd=(struct ___TagDescriptor___ *) ptrarray[3];
776         ao=(struct ArrayObject *)obj->___tags___;
777 #else
778         struct ArrayObject * aonew=
779           allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
780 #endif
781
782         aonew->___cachedCode___=ao->___length___+1;
783         for(i=0; i<ao->___length___; i++) {
784           ARRAYSET(aonew, struct ___TagDescriptor___*, i,
785                    ARRAYGET(ao, struct ___TagDescriptor___*, i));
786         }
787         ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
788       }
789     }
790   }
791
792   {
793     struct ___Object___ * tagset=tagd->flagptr;
794     if(tagset==NULL) {
795       tagd->flagptr=obj;
796     } else if (tagset->type!=OBJECTARRAYTYPE) {
797 #ifdef MULTICORE_GC
798       int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
799       struct ArrayObject * ao=
800         allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
801       obj=(struct ___Object___ *)ptrarray[2];
802       tagd=(struct ___TagDescriptor___ *)ptrarray[3];
803 #else
804       struct ArrayObject * ao=
805         allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
806 #endif
807       ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
808       ARRAYSET(ao, struct ___Object___ *, 1, obj);
809       ao->___cachedCode___=2;
810       tagd->flagptr=(struct ___Object___ *)ao;
811     } else {
812       struct ArrayObject *ao=(struct ArrayObject *) tagset;
813       if (ao->___cachedCode___<ao->___length___) {
814         ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
815       } else {
816         int i;
817 #ifdef MULTICORE_GC
818         int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
819         struct ArrayObject * aonew=
820           allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
821                             OBJECTARRAYINTERVAL+ao->___length___);
822         obj=(struct ___Object___ *)ptrarray[2];
823         tagd=(struct ___TagDescriptor___ *)ptrarray[3];
824         ao=(struct ArrayObject *)tagd->flagptr;
825 #else
826         struct ArrayObject * aonew=
827           allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
828 #endif
829         aonew->___cachedCode___=ao->___cachedCode___+1;
830         for(i=0; i<ao->___length___; i++) {
831           ARRAYSET(aonew, struct ___Object___*, i,
832                    ARRAYGET(ao, struct ___Object___*, i));
833         }
834         ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
835         tagd->flagptr=(struct ___Object___ *) aonew;
836       }
837     }
838   }
839 }
840
841 /* This function clears a tag. */
842 #ifdef MULTICORE_GC
843 void tagclear(void *ptr,
844               struct ___Object___ * obj,
845               struct ___TagDescriptor___ * tagd) {
846 #else
847 void tagclear(struct ___Object___ * obj,
848               struct ___TagDescriptor___ * tagd) {
849 #endif
850   /* We'll assume that tag is alway there.
851      Need to statically check for this of course. */
852   struct ___Object___ * tagptr=obj->___tags___;
853
854   if (tagptr->type==TAGTYPE) {
855     if ((struct ___TagDescriptor___ *)tagptr==tagd)
856       obj->___tags___=NULL;
857   } else {
858     struct ArrayObject *ao=(struct ArrayObject *) tagptr;
859     int i;
860     for(i=0; i<ao->___cachedCode___; i++) {
861       struct ___TagDescriptor___ * td=
862         ARRAYGET(ao, struct ___TagDescriptor___ *, i);
863       if (td==tagd) {
864         ao->___cachedCode___--;
865         if (i<ao->___cachedCode___)
866           ARRAYSET(ao, struct ___TagDescriptor___ *, i,
867                    ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
868         ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
869         if (ao->___cachedCode___==0)
870           obj->___tags___=NULL;
871         goto PROCESSCLEAR;
872       }
873     }
874   }
875 PROCESSCLEAR:
876   {
877     struct ___Object___ *tagset=tagd->flagptr;
878     if (tagset->type!=OBJECTARRAYTYPE) {
879       if (tagset==obj)
880         tagd->flagptr=NULL;
881     } else {
882       struct ArrayObject *ao=(struct ArrayObject *) tagset;
883       int i;
884       for(i=0; i<ao->___cachedCode___; i++) {
885         struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
886         if (tobj==obj) {
887           ao->___cachedCode___--;
888           if (i<ao->___cachedCode___)
889             ARRAYSET(ao, struct ___Object___ *, i,
890                      ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
891           ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
892           if (ao->___cachedCode___==0)
893             tagd->flagptr=NULL;
894           goto ENDCLEAR;
895         }
896       }
897     }
898   }
899 ENDCLEAR:
900   return;
901 }
902
903 /* This function allocates a new tag. */
904 #ifdef MULTICORE_GC
905 struct ___TagDescriptor___ * allocate_tag(void *ptr,
906                                           int index) {
907   struct ___TagDescriptor___ * v=
908     (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
909                                               classsize[TAGTYPE]);
910 #else
911 struct ___TagDescriptor___ * allocate_tag(int index) {
912   struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
913 #endif
914   v->type=TAGTYPE;
915   v->flag=index;
916   return v;
917 }
918
919
920
921 /* This function updates the flag for object ptr.  It or's the flag
922    with the or mask and and's it with the andmask. */
923
924 void flagbody(struct ___Object___ *ptr,
925               int flag,
926               struct parameterwrapper ** queues,
927               int length,
928               bool isnew);
929
930 int flagcomp(const int *val1, const int *val2) {
931   return (*val1)-(*val2);
932 }
933
934 void flagorand(void * ptr,
935                int ormask,
936                int andmask,
937                struct parameterwrapper ** queues,
938                int length) {
939   {
940     int oldflag=((int *)ptr)[1];
941     int flag=ormask|oldflag;
942     flag&=andmask;
943     flagbody(ptr, flag, queues, length, false);
944   }
945 }
946
947 bool intflagorand(void * ptr,
948                   int ormask,
949                   int andmask) {
950   {
951     int oldflag=((int *)ptr)[1];
952     int flag=ormask|oldflag;
953     flag&=andmask;
954     if (flag==oldflag)   /* Don't do anything */
955       return false;
956     else {
957       flagbody(ptr, flag, NULL, 0, false);
958       return true;
959     }
960   }
961 }
962
963 void flagorandinit(void * ptr,
964                    int ormask,
965                    int andmask) {
966   int oldflag=((int *)ptr)[1];
967   int flag=ormask|oldflag;
968   flag&=andmask;
969   flagbody(ptr,flag,NULL,0,true);
970 }
971
972 void flagbody(struct ___Object___ *ptr,
973               int flag,
974               struct parameterwrapper ** vqueues,
975               int vlength,
976               bool isnew) {
977   struct parameterwrapper * flagptr = NULL;
978   int i = 0;
979   struct parameterwrapper ** queues = vqueues;
980   int length = vlength;
981   int next;
982   int UNUSED, UNUSED2;
983   int * enterflags = NULL;
984   if((!isnew) && (queues == NULL)) {
985     if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
986       queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
987       length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
988     } else {
989       return;
990     }
991   }
992   ptr->flag=flag;
993
994   /*Remove object from all queues */
995   for(i = 0; i < length; ++i) {
996     flagptr = queues[i];
997     ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
998                   (int *) &enterflags, &UNUSED, &UNUSED2);
999     ObjectHashremove(flagptr->objectset, (int)ptr);
1000     if (enterflags!=NULL)
1001       RUNFREE(enterflags);
1002   }
1003 }
1004
1005 void enqueueObject(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 > NUMCORESACTIVE - 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=
1039           //(struct ___TagDescriptor___*) tagptr;
1040           for(i=0; i<parameter->numbertags; i++) {
1041             //slotid is parameter->tagarray[2*i];
1042             int tagid=parameter->tagarray[2*i+1];
1043             if (tagid!=tagptr->flag)
1044               goto nextloop;                                           /*We don't have this tag */
1045           }
1046         } else {                         //multiple tags
1047           struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1048           for(i=0; i<parameter->numbertags; i++) {
1049             //slotid is parameter->tagarray[2*i];
1050             int tagid=parameter->tagarray[2*i+1];
1051             int j;
1052             for(j=0; j<ao->___cachedCode___; j++) {
1053               if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1054                 goto foundtag;
1055             }
1056             goto nextloop;
1057 foundtag:
1058             ;
1059           }
1060         }
1061       }
1062
1063       /* Check flags */
1064       for(i=0; i<parameter->numberofterms; i++) {
1065         int andmask=parameter->intarray[i*2];
1066         int checkmask=parameter->intarray[i*2+1];
1067         if ((ptr->flag&andmask)==checkmask) {
1068           enqueuetasks(parameter, prevptr, ptr, NULL, 0);
1069           prevptr=parameter;
1070           break;
1071         }
1072       }
1073 nextloop:
1074       ;
1075     }
1076   }
1077 }
1078
1079 void enqueueObject_I(void * vptr,
1080                      struct parameterwrapper ** vqueues,
1081                      int vlength) {
1082   struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1083
1084   {
1085     //struct QueueItem *tmpptr;
1086     struct parameterwrapper * parameter=NULL;
1087     int j;
1088     int i;
1089     struct parameterwrapper * prevptr=NULL;
1090     struct ___Object___ *tagptr=NULL;
1091     struct parameterwrapper ** queues = vqueues;
1092     int length = vlength;
1093     if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1094       return;
1095     }
1096     if(queues == NULL) {
1097       queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1098       length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1099     }
1100     tagptr=ptr->___tags___;
1101
1102     /* Outer loop iterates through all parameter queues an object of
1103        this type could be in.  */
1104     for(j = 0; j < length; ++j) {
1105       parameter = queues[j];
1106       /* Check tags */
1107       if (parameter->numbertags>0) {
1108         if (tagptr==NULL)
1109           goto nextloop;                               //that means the object has no tag
1110         //but that param needs tag
1111         else if(tagptr->type==TAGTYPE) {                         //one tag
1112           //struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
1113           for(i=0; i<parameter->numbertags; i++) {
1114             //slotid is parameter->tagarray[2*i];
1115             int tagid=parameter->tagarray[2*i+1];
1116             if (tagid!=tagptr->flag)
1117               goto nextloop;                                           /*We don't have this tag */
1118           }
1119         } else {                         //multiple tags
1120           struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1121           for(i=0; i<parameter->numbertags; i++) {
1122             //slotid is parameter->tagarray[2*i];
1123             int tagid=parameter->tagarray[2*i+1];
1124             int j;
1125             for(j=0; j<ao->___cachedCode___; j++) {
1126               if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1127                 goto foundtag;
1128             }
1129             goto nextloop;
1130 foundtag:
1131             ;
1132           }
1133         }
1134       }
1135
1136       /* Check flags */
1137       for(i=0; i<parameter->numberofterms; i++) {
1138         int andmask=parameter->intarray[i*2];
1139         int checkmask=parameter->intarray[i*2+1];
1140         if ((ptr->flag&andmask)==checkmask) {
1141           enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1142           prevptr=parameter;
1143           break;
1144         }
1145       }
1146 nextloop:
1147       ;
1148     }
1149   }
1150 }
1151
1152
1153 int * getAliasLock(void ** ptrs,
1154                    int length,
1155                    struct RuntimeHash * tbl) {
1156   if(length == 0) {
1157     return (int*)(RUNMALLOC(sizeof(int)));
1158   } else {
1159     int i = 0;
1160     int locks[length];
1161     int locklen = 0;
1162     bool redirect = false;
1163     int redirectlock = 0;
1164     for(; i < length; i++) {
1165       struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1166       int lock = 0;
1167       int j = 0;
1168       if(ptr->lock == NULL) {
1169         lock = (int)(ptr);
1170       } else {
1171         lock = (int)(ptr->lock);
1172       }
1173       if(redirect) {
1174         if(lock != redirectlock) {
1175           RuntimeHashadd(tbl, lock, redirectlock);
1176         }
1177       } else {
1178         if(RuntimeHashcontainskey(tbl, lock)) {
1179           // already redirected
1180           redirect = true;
1181           RuntimeHashget(tbl, lock, &redirectlock);
1182           for(; j < locklen; j++) {
1183             if(locks[j] != redirectlock) {
1184               RuntimeHashadd(tbl, locks[j], redirectlock);
1185             }
1186           }
1187         } else {
1188           bool insert = true;
1189           for(j = 0; j < locklen; j++) {
1190             if(locks[j] == lock) {
1191               insert = false;
1192               break;
1193             } else if(locks[j] > lock) {
1194               break;
1195             }
1196           }
1197           if(insert) {
1198             int h = locklen;
1199             for(; h > j; h--) {
1200               locks[h] = locks[h-1];
1201             }
1202             locks[j] = lock;
1203             locklen++;
1204           }
1205         }
1206       }
1207     }
1208     if(redirect) {
1209       return (int *)redirectlock;
1210     } else {
1211       return (int *)(locks[0]);
1212     }
1213   }
1214 }
1215
1216 void addAliasLock(void * ptr,
1217                   int lock) {
1218   struct ___Object___ * obj = (struct ___Object___ *)ptr;
1219   if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1220     // originally no alias lock associated or have a different alias lock
1221     // flush it as the new one
1222     obj->lock = (int *)lock;
1223   }
1224 }
1225
1226 #ifdef PROFILE
1227 inline void setTaskExitIndex(int index) {
1228   taskInfoArray[taskInfoIndex]->exitIndex = index;
1229 }
1230
1231 inline void addNewObjInfo(void * nobj) {
1232   if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1233     taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1234   }
1235   addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1236 }
1237 #endif
1238
1239 #ifdef MULTICORE_GC
1240 void * localmalloc_I(int coren,
1241                      int isize,
1242                      int * allocsize) {
1243   void * mem = NULL;
1244   int i = 0;
1245   int j = 0;
1246   int tofindb = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1247   int totest = tofindb;
1248   int bound = BAMBOO_SMEM_SIZE_L;
1249   int foundsmem = 0;
1250   int size = 0;
1251   do {
1252     bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1253     int nsize = bamboo_smemtbl[totest];
1254     bool islocal = true;
1255     if(nsize < bound) {
1256       bool tocheck = true;
1257       // have some space in the block
1258       if(totest == tofindb) {
1259         // the first partition
1260         size = bound - nsize;
1261       } else if(nsize == 0) {
1262         // an empty partition, can be appended
1263         size += bound;
1264       } else {
1265         // not an empty partition, can not be appended
1266         // the last continuous block is not big enough, go to check the next
1267         // local block
1268         islocal = true;
1269         tocheck = false;
1270       }                   // if(totest == tofindb) else if(nsize == 0) else ...
1271       if(tocheck) {
1272         if(size >= isize) {
1273           // have enough space in the block, malloc
1274           foundsmem = 1;
1275           break;
1276         } else {
1277           // no enough space yet, try to append next continuous block
1278           islocal = false;
1279         }                         // if(size > isize) else ...
1280       }                   // if(tocheck)
1281     }             // if(nsize < bound)
1282     if(islocal) {
1283       // no space in the block, go to check the next block
1284       i++;
1285       if(2==i) {
1286         i = 0;
1287         j++;
1288       }
1289       tofindb = totest = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1290     } else {
1291       totest += 1;
1292     }             // if(islocal) else ...
1293     if(totest > gcnumblock-1-bamboo_reserved_smem) {
1294       // no more local mem, do not find suitable block
1295       foundsmem = 2;
1296       break;
1297     }             // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1298   } while(true);
1299
1300   if(foundsmem == 1) {
1301     // find suitable block
1302     mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1303                                             (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1304                                                                             (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1305     *allocsize = size;
1306     // set bamboo_smemtbl
1307     for(i = tofindb; i <= totest; i++) {
1308       bamboo_smemtbl[i]=(i<NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1309     }
1310   } else if(foundsmem == 2) {
1311     // no suitable block
1312     *allocsize = 0;
1313   }
1314
1315   return mem;
1316 } // void * localmalloc_I(int, int, int *)
1317
1318 void * globalmalloc_I(int coren,
1319                       int isize,
1320                       int * allocsize) {
1321   void * mem = NULL;
1322   int tofindb = bamboo_free_block;       //0;
1323   int totest = tofindb;
1324   int bound = BAMBOO_SMEM_SIZE_L;
1325   int foundsmem = 0;
1326   int size = 0;
1327   if(tofindb > gcnumblock-1-bamboo_reserved_smem) {
1328     *allocsize = 0;
1329     return NULL;
1330   }
1331   do {
1332     bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1333     int nsize = bamboo_smemtbl[totest];
1334     bool isnext = false;
1335     if(nsize < bound) {
1336       bool tocheck = true;
1337       // have some space in the block
1338       if(totest == tofindb) {
1339         // the first partition
1340         size = bound - nsize;
1341       } else if(nsize == 0) {
1342         // an empty partition, can be appended
1343         size += bound;
1344       } else {
1345         // not an empty partition, can not be appended
1346         // the last continuous block is not big enough, start another block
1347         isnext = true;
1348         tocheck = false;
1349       }                   // if(totest == tofindb) else if(nsize == 0) else ...
1350       if(tocheck) {
1351         if(size >= isize) {
1352           // have enough space in the block, malloc
1353           foundsmem = 1;
1354           break;
1355         }                         // if(size > isize)
1356       }                   // if(tocheck)
1357     } else {
1358       isnext = true;
1359     }            // if(nsize < bound) else ...
1360     totest += 1;
1361     if(totest > gcnumblock-1-bamboo_reserved_smem) {
1362       // no more local mem, do not find suitable block
1363       foundsmem = 2;
1364       break;
1365     }             // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1366     if(isnext) {
1367       // start another block
1368       tofindb = totest;
1369     }             // if(islocal)
1370   } while(true);
1371
1372   if(foundsmem == 1) {
1373     // find suitable block
1374     mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1375                                             (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1376                                                                             (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1377     *allocsize = size;
1378     // set bamboo_smemtbl
1379     for(int i = tofindb; i <= totest; i++) {
1380       bamboo_smemtbl[i]=(i<NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1381     }
1382     if(tofindb == bamboo_free_block) {
1383       bamboo_free_block = totest+1;
1384     }
1385   } else if(foundsmem == 2) {
1386     // no suitable block
1387     *allocsize = 0;
1388     mem = NULL;
1389   }
1390
1391   return mem;
1392 } // void * globalmalloc_I(int, int, int *)
1393 #endif // #ifdef MULTICORE_GC
1394
1395 // malloc from the shared memory
1396 void * smemalloc_I(int coren,
1397                    int size,
1398                    int * allocsize) {
1399   void * mem = NULL;
1400 #ifdef MULTICORE_GC
1401   int isize = size+(BAMBOO_CACHE_LINE_SIZE);
1402
1403   // go through the bamboo_smemtbl for suitable partitions
1404   switch(bamboo_smem_mode) {
1405   case SMEMLOCAL: {
1406     mem = localmalloc_I(coren, isize, allocsize);
1407     break;
1408   }
1409
1410   case SMEMFIXED: {
1411     // TODO not supported yet
1412     BAMBOO_EXIT(0xe001);
1413     break;
1414   }
1415
1416   case SMEMMIXED: {
1417     // TODO not supported yet
1418     BAMBOO_EXIT(0xe002);
1419     break;
1420   }
1421
1422   case SMEMGLOBAL: {
1423     mem = globalmalloc_I(coren, isize, allocsize);
1424     break;
1425   }
1426
1427   default:
1428     break;
1429   }
1430
1431   if(mem == NULL) {
1432 #else
1433   // TODO
1434 #ifdef PROFILE
1435   /*if(!interruptInfoOverflow) {
1436     InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
1437     interruptInfoArray[interruptInfoIndex] = intInfo;
1438     intInfo->startTime = BAMBOO_GET_EXE_TIME();
1439     intInfo->endTime = -1;
1440   }*/
1441 #endif  
1442   int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size) : (BAMBOO_SMEM_SIZE);
1443   //mem = mspace_calloc(bamboo_free_msp, 1, toallocate);
1444   if(toallocate > bamboo_free_smem_size) {
1445         // no enough mem
1446         mem = NULL;
1447   } else {
1448         mem = (void *)bamboo_free_smemp;
1449         bamboo_free_smemp = ((void*)bamboo_free_smemp) + toallocate;
1450         bamboo_free_smem_size -= toallocate;
1451         //BAMBOO_MEMSET_WH(mem, '\0', toallocate);
1452   }
1453   *allocsize = toallocate;
1454 #ifdef PROFILE
1455   /*if(!interruptInfoOverflow) {
1456     interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
1457     interruptInfoIndex++;
1458     if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
1459       interruptInfoOverflow = true;
1460     }
1461   }*/
1462 #endif
1463   if(mem == NULL) {
1464 #endif // MULTICORE_GC
1465     // no enough shared global memory
1466     *allocsize = 0;
1467 #ifdef MULTICORE_GC
1468     gcflag = true;
1469     return NULL;
1470 #else
1471     BAMBOO_DEBUGPRINT(0xa001);
1472     BAMBOO_EXIT(0xa001);
1473 #endif
1474   }
1475   return mem;
1476 }  // void * smemalloc_I(int, int, int)
1477
1478 INLINE int checkMsgLength_I(int size) {
1479 #ifdef DEBUG
1480 #ifndef TILERA
1481   BAMBOO_DEBUGPRINT(0xcccc);
1482 #endif
1483 #endif
1484   int type = msgdata[msgdataindex];
1485   switch(type) {
1486   case STATUSCONFIRM:
1487   case TERMINATE:
1488 #ifdef MULTICORE_GC
1489   case GCSTARTINIT:
1490   case GCSTART:
1491   case GCSTARTFLUSH:
1492   case GCFINISH:
1493   case GCMARKCONFIRM:
1494   case GCLOBJREQUEST:
1495 #endif
1496     {
1497       msglength = 1;
1498       break;
1499     }
1500
1501   case PROFILEOUTPUT:
1502   case PROFILEFINISH:
1503 #ifdef MULTICORE_GC
1504   case GCSTARTCOMPACT:
1505   case GCFINISHINIT:
1506   case GCFINISHFLUSH:
1507   case GCMARKEDOBJ:
1508 #endif
1509     {
1510       msglength = 2;
1511       break;
1512     }
1513
1514   case MEMREQUEST:
1515   case MEMRESPONSE:
1516 #ifdef MULTICORE_GC
1517   case GCMAPREQUEST:
1518   case GCMAPINFO:
1519   case GCLOBJMAPPING:
1520 #endif
1521     {
1522       msglength = 3;
1523       break;
1524     }
1525
1526   case TRANSTALL:
1527   case LOCKGROUNT:
1528   case LOCKDENY:
1529   case LOCKRELEASE:
1530   case REDIRECTGROUNT:
1531   case REDIRECTDENY:
1532   case REDIRECTRELEASE:
1533 #ifdef MULTICORE_GC
1534   case GCFINISHMARK:
1535   case GCMOVESTART:
1536 #endif
1537     {
1538       msglength = 4;
1539       break;
1540     }
1541
1542   case LOCKREQUEST:
1543   case STATUSREPORT:
1544 #ifdef MULTICORE_GC
1545   case GCFINISHCOMPACT:
1546   case GCMARKREPORT:
1547 #endif
1548     {
1549       msglength = 5;
1550       break;
1551     }
1552
1553   case REDIRECTLOCK:
1554   {
1555     msglength = 6;
1556     break;
1557   }
1558
1559   case TRANSOBJ:                // nonfixed size
1560 #ifdef MULTICORE_GC
1561   case GCLOBJINFO:
1562 #endif
1563     {             // nonfixed size
1564       if(size > 1) {
1565         msglength = msgdata[msgdataindex+1];
1566       } else {
1567         return -1;
1568       }
1569       break;
1570     }
1571
1572   default:
1573   {
1574     BAMBOO_DEBUGPRINT_REG(type);
1575         BAMBOO_DEBUGPRINT_REG(size);
1576     BAMBOO_DEBUGPRINT_REG(msgdataindex);
1577         BAMBOO_DEBUGPRINT_REG(msgdatalast);
1578         BAMBOO_DEBUGPRINT_REG(msgdatafull);
1579     int i = 6;
1580     while(i-- > 0) {
1581       BAMBOO_DEBUGPRINT(msgdata[msgdataindex+i]);
1582     }
1583     BAMBOO_EXIT(0xd005);
1584     break;
1585   }
1586   }
1587 #ifdef DEBUG
1588 #ifndef TILERA
1589   BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
1590 #endif
1591 #endif
1592 #ifdef DEBUG
1593 #ifndef TILERA
1594   BAMBOO_DEBUGPRINT(0xffff);
1595 #endif
1596 #endif
1597   return msglength;
1598 }
1599
1600 INLINE void processmsg_transobj_I() {
1601   MSG_INDEXINC_I();
1602   struct transObjInfo * transObj=RUNMALLOC_I(sizeof(struct transObjInfo));
1603   int k = 0;
1604 #ifdef DEBUG
1605 #ifndef CLOSE_PRINT
1606   BAMBOO_DEBUGPRINT(0xe880);
1607 #endif
1608 #endif
1609   if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1610 #ifndef CLOSE_PRINT
1611     BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
1612 #endif
1613     BAMBOO_EXIT(0xa002);
1614   }
1615   // store the object and its corresponding queue info, enqueue it later
1616   transObj->objptr = (void *)msgdata[msgdataindex];       //[2]
1617   MSG_INDEXINC_I();
1618   transObj->length = (msglength - 3) / 2;
1619   transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
1620   for(k = 0; k < transObj->length; ++k) {
1621     transObj->queues[2*k] = msgdata[msgdataindex];             //[3+2*k];
1622     MSG_INDEXINC_I();
1623 #ifdef DEBUG
1624 #ifndef CLOSE_PRINT
1625     //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
1626 #endif
1627 #endif
1628     transObj->queues[2*k+1] = msgdata[msgdataindex];        //[3+2*k+1];
1629     MSG_INDEXINC_I();
1630 #ifdef DEBUG
1631 #ifndef CLOSE_PRINT
1632     //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
1633 #endif
1634 #endif
1635   }
1636   // check if there is an existing duplicate item
1637   {
1638     struct QueueItem * qitem = getHead(&objqueue);
1639     struct QueueItem * prev = NULL;
1640     while(qitem != NULL) {
1641       struct transObjInfo * tmpinfo =
1642         (struct transObjInfo *)(qitem->objectptr);
1643       if(tmpinfo->objptr == transObj->objptr) {
1644         // the same object, remove outdate one
1645         RUNFREE(tmpinfo->queues);
1646         RUNFREE(tmpinfo);
1647         removeItem(&objqueue, qitem);
1648         //break;
1649       } else {
1650         prev = qitem;
1651       }
1652       if(prev == NULL) {
1653         qitem = getHead(&objqueue);
1654       } else {
1655         qitem = getNextQueueItem(prev);
1656       }
1657     }
1658     addNewItem_I(&objqueue, (void *)transObj);
1659   }
1660   ++(self_numreceiveobjs);
1661 }
1662
1663 INLINE void processmsg_transtall_I() {
1664   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1665     // non startup core can not receive stall msg
1666 #ifndef CLOSE_PRINT
1667     BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
1668 #endif
1669     BAMBOO_EXIT(0xa003);
1670   }
1671   int num_core = msgdata[msgdataindex];       //[1]
1672   MSG_INDEXINC_I();
1673   if(num_core < NUMCORESACTIVE) {
1674 #ifdef DEBUG
1675 #ifndef CLOSE_PRINT
1676     BAMBOO_DEBUGPRINT(0xe881);
1677 #endif
1678 #endif
1679     corestatus[num_core] = 0;
1680     numsendobjs[num_core] = msgdata[msgdataindex];             //[2];
1681     MSG_INDEXINC_I();
1682     numreceiveobjs[num_core] = msgdata[msgdataindex];             //[3];
1683     MSG_INDEXINC_I();
1684   }
1685 }
1686
1687 #ifndef MULTICORE_GC
1688 INLINE void processmsg_lockrequest_I() {
1689   // check to see if there is a lock exist for the required obj
1690   // msgdata[1] -> lock type
1691   int locktype = msgdata[msgdataindex];       //[1];
1692   MSG_INDEXINC_I();
1693   int data2 = msgdata[msgdataindex];       // obj pointer
1694   MSG_INDEXINC_I();
1695   int data3 = msgdata[msgdataindex];       // lock
1696   MSG_INDEXINC_I();
1697   int data4 = msgdata[msgdataindex];       // request core
1698   MSG_INDEXINC_I();
1699   // -1: redirected, 0: approved, 1: denied
1700   int deny=processlockrequest(locktype, data3, data2, data4, data4, true);
1701   if(deny == -1) {
1702     // this lock request is redirected
1703     return;
1704   } else {
1705     // send response msg
1706     // for 32 bit machine, the size is always 4 words, cache the msg first
1707     int tmp = deny==1 ? LOCKDENY : LOCKGROUNT;
1708     if(BAMBOO_CHECK_SEND_MODE()) {
1709     cache_msg_4(data4, tmp, locktype, data2, data3);
1710     } else {
1711     send_msg_4(data4, tmp, locktype, data2, data3, true);
1712     }
1713   }
1714 }
1715
1716 INLINE void processmsg_lockgrount_I() {
1717   MSG_INDEXINC_I();
1718   if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1719 #ifndef CLOSE_PRINT
1720     BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
1721 #endif
1722     BAMBOO_EXIT(0xa004);
1723   }
1724   int data2 = msgdata[msgdataindex];
1725   MSG_INDEXINC_I();
1726   int data3 = msgdata[msgdataindex];
1727   MSG_INDEXINC_I();
1728   if((lockobj == data2) && (lock2require == data3)) {
1729 #ifdef DEBUG
1730 #ifndef CLOSE_PRINT
1731     BAMBOO_DEBUGPRINT(0xe882);
1732 #endif
1733 #endif
1734     lockresult = 1;
1735     lockflag = true;
1736 #ifndef INTERRUPT
1737     reside = false;
1738 #endif
1739   } else {
1740     // conflicts on lockresults
1741 #ifndef CLOSE_PRINT
1742     BAMBOO_DEBUGPRINT_REG(data2);
1743 #endif
1744     BAMBOO_EXIT(0xa005);
1745   }
1746 }
1747
1748 INLINE void processmsg_lockdeny_I() {
1749   MSG_INDEXINC_I();
1750   int data2 = msgdata[msgdataindex];
1751   MSG_INDEXINC_I();
1752   int data3 = msgdata[msgdataindex];
1753   MSG_INDEXINC_I();
1754   if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1755 #ifndef CLOSE_PRINT
1756     BAMBOO_DEBUGPRINT_REG(data2);
1757 #endif
1758     BAMBOO_EXIT(0xa006);
1759   }
1760   if((lockobj == data2) && (lock2require == data3)) {
1761 #ifdef DEBUG
1762 #ifndef CLOSE_PRINT
1763     BAMBOO_DEBUGPRINT(0xe883);
1764 #endif
1765 #endif
1766     lockresult = 0;
1767     lockflag = true;
1768 #ifndef INTERRUPT
1769     reside = false;
1770 #endif
1771   } else {
1772     // conflicts on lockresults
1773 #ifndef CLOSE_PRINT
1774     BAMBOO_DEBUGPRINT_REG(data2);
1775 #endif
1776     BAMBOO_EXIT(0xa007);
1777   }
1778 }
1779
1780 INLINE void processmsg_lockrelease_I() {
1781   int data1 = msgdata[msgdataindex];
1782   MSG_INDEXINC_I();
1783   int data2 = msgdata[msgdataindex];
1784   MSG_INDEXINC_I();
1785   // receive lock release msg
1786   processlockrelease(data1, data2, 0, false);
1787 }
1788
1789 INLINE void processmsg_redirectlock_I() {
1790   // check to see if there is a lock exist for the required obj
1791   int data1 = msgdata[msgdataindex];
1792   MSG_INDEXINC_I();       //msgdata[1]; // lock type
1793   int data2 = msgdata[msgdataindex];
1794   MSG_INDEXINC_I();      //msgdata[2]; // obj pointer
1795   int data3 = msgdata[msgdataindex];
1796   MSG_INDEXINC_I();       //msgdata[3]; // redirect lock
1797   int data4 = msgdata[msgdataindex];
1798   MSG_INDEXINC_I();       //msgdata[4]; // root request core
1799   int data5 = msgdata[msgdataindex];
1800   MSG_INDEXINC_I();       //msgdata[5]; // request core
1801   int deny = processlockrequest(data1, data3, data2, data5, data4, true);
1802   if(deny == -1) {
1803     // this lock request is redirected
1804     return;
1805   } else {
1806     // send response msg
1807     // for 32 bit machine, the size is always 4 words, cache the msg first
1808     if(BAMBOO_CHECK_SEND_MODE()) {
1809     cache_msg_4(data4, deny==1 ? REDIRECTDENY : REDIRECTGROUNT,
1810                 data1, data2, data3);
1811     } else {
1812     send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
1813                data1, data2, data3, true);
1814     }
1815   }
1816 }
1817
1818 INLINE void processmsg_redirectgrount_I() {
1819   MSG_INDEXINC_I();
1820   int data2 = msgdata[msgdataindex];
1821   MSG_INDEXINC_I();
1822   if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1823 #ifndef CLOSE_PRINT
1824     BAMBOO_DEBUGPRINT_REG(data2);
1825 #endif
1826     BAMBOO_EXIT(0xa00a);
1827   }
1828   if(lockobj == data2) {
1829 #ifdef DEBUG
1830 #ifndef CLOSE_PRINT
1831     BAMBOO_DEBUGPRINT(0xe891);
1832 #endif
1833 #endif
1834     int data3 = msgdata[msgdataindex];
1835     MSG_INDEXINC_I();
1836     lockresult = 1;
1837     lockflag = true;
1838     RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
1839 #ifndef INTERRUPT
1840     reside = false;
1841 #endif
1842   } else {
1843     // conflicts on lockresults
1844 #ifndef CLOSE_PRINT
1845     BAMBOO_DEBUGPRINT_REG(data2);
1846 #endif
1847     BAMBOO_EXIT(0xa00b);
1848   }
1849 }
1850
1851 INLINE void processmsg_redirectdeny_I() {
1852   MSG_INDEXINC_I();
1853   int data2 = msgdata[msgdataindex];
1854   MSG_INDEXINC_I();
1855   if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1856 #ifndef CLOSE_PRINT
1857     BAMBOO_DEBUGPRINT_REG(data2);
1858 #endif
1859     BAMBOO_EXIT(0xa00c);
1860   }
1861   if(lockobj == data2) {
1862 #ifdef DEBUG
1863 #ifndef CLOSE_PRINT
1864     BAMBOO_DEBUGPRINT(0xe892);
1865 #endif
1866 #endif
1867     lockresult = 0;
1868     lockflag = true;
1869 #ifndef INTERRUPT
1870     reside = false;
1871 #endif
1872   } else {
1873     // conflicts on lockresults
1874 #ifndef CLOSE_PRINT
1875     BAMBOO_DEBUGPRINT_REG(data2);
1876 #endif
1877     BAMBOO_EXIT(0xa00d);
1878   }
1879 }
1880
1881 INLINE void processmsg_redirectrelease_I() {
1882   int data1 = msgdata[msgdataindex];
1883   MSG_INDEXINC_I();
1884   int data2 = msgdata[msgdataindex];
1885   MSG_INDEXINC_I();
1886   int data3 = msgdata[msgdataindex];
1887   MSG_INDEXINC_I();
1888   processlockrelease(data1, data2, data3, true);
1889 }
1890 #endif // #ifndef MULTICORE_GC
1891
1892 #ifdef PROFILE
1893 INLINE void processmsg_profileoutput_I() {
1894   if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
1895     // startup core can not receive profile output finish msg
1896     BAMBOO_EXIT(0xa008);
1897   }
1898 #ifdef DEBUG
1899 #ifndef CLOSE_PRINT
1900   BAMBOO_DEBUGPRINT(0xe885);
1901 #endif
1902 #endif
1903   stall = true;
1904   totalexetime = msgdata[msgdataindex];       //[1]
1905   MSG_INDEXINC_I();
1906   outputProfileData();
1907   // cache the msg first
1908   if(BAMBOO_CHECK_SEND_MODE()) {
1909   cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1910   } else {
1911   send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE, true);
1912   }
1913 }
1914
1915 INLINE void processmsg_profilefinish_I() {
1916   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1917     // non startup core can not receive profile output finish msg
1918 #ifndef CLOSE_PRINT
1919     BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex /*1*/]);
1920 #endif
1921     BAMBOO_EXIT(0xa009);
1922   }
1923 #ifdef DEBUG
1924 #ifndef CLOSE_PRINT
1925   BAMBOO_DEBUGPRINT(0xe886);
1926 #endif
1927 #endif
1928   int data1 = msgdata[msgdataindex];
1929   MSG_INDEXINC_I();
1930   profilestatus[data1] = 0;
1931 }
1932 #endif // #ifdef PROFILE
1933
1934 INLINE void processmsg_statusconfirm_I() {
1935   if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
1936      || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
1937     // wrong core to receive such msg
1938     BAMBOO_EXIT(0xa00e);
1939   } else {
1940     // send response msg
1941 #ifdef DEBUG
1942 #ifndef CLOSE_PRINT
1943     BAMBOO_DEBUGPRINT(0xe887);
1944 #endif
1945 #endif
1946     // cache the msg first
1947     if(BAMBOO_CHECK_SEND_MODE()) {
1948     cache_msg_5(STARTUPCORE, STATUSREPORT,
1949                 busystatus ? 1 : 0, BAMBOO_NUM_OF_CORE,
1950                 self_numsendobjs, self_numreceiveobjs);
1951     } else {
1952     send_msg_5(STARTUPCORE, STATUSREPORT, busystatus?1:0,
1953                BAMBOO_NUM_OF_CORE, self_numsendobjs,
1954                self_numreceiveobjs, true);
1955     }
1956   }
1957 }
1958
1959 INLINE void processmsg_statusreport_I() {
1960   int data1 = msgdata[msgdataindex];
1961   MSG_INDEXINC_I();
1962   int data2 = msgdata[msgdataindex];
1963   MSG_INDEXINC_I();
1964   int data3 = msgdata[msgdataindex];
1965   MSG_INDEXINC_I();
1966   int data4 = msgdata[msgdataindex];
1967   MSG_INDEXINC_I();
1968   // receive a status confirm info
1969   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1970     // wrong core to receive such msg
1971 #ifndef CLOSE_PRINT
1972     BAMBOO_DEBUGPRINT_REG(data2);
1973 #endif
1974     BAMBOO_EXIT(0xa00f);
1975   } else {
1976 #ifdef DEBUG
1977 #ifndef CLOSE_PRINT
1978     BAMBOO_DEBUGPRINT(0xe888);
1979 #endif
1980 #endif
1981     if(waitconfirm) {
1982       numconfirm--;
1983     }
1984     corestatus[data2] = data1;
1985     numsendobjs[data2] = data3;
1986     numreceiveobjs[data2] = data4;
1987   }
1988 }
1989
1990 INLINE void processmsg_terminate_I() {
1991 #ifdef DEBUG
1992 #ifndef CLOSE_PRINT
1993   BAMBOO_DEBUGPRINT(0xe889);
1994 #endif
1995 #endif
1996   disruntimedata();
1997   BAMBOO_EXIT_APP(0);
1998 }
1999
2000 INLINE void processmsg_memrequest_I() {
2001 #ifdef PROFILE
2002   if(!interruptInfoOverflow) {
2003     InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
2004     interruptInfoArray[interruptInfoIndex] = intInfo;
2005     intInfo->startTime = BAMBOO_GET_EXE_TIME();
2006     intInfo->endTime = -1;
2007   }
2008 #endif
2009   int data1 = msgdata[msgdataindex];
2010   MSG_INDEXINC_I();
2011   int data2 = msgdata[msgdataindex];
2012   MSG_INDEXINC_I();
2013   // receive a shared memory request msg
2014   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2015     // wrong core to receive such msg
2016 #ifndef CLOSE_PRINT
2017     BAMBOO_DEBUGPRINT_REG(data2);
2018 #endif
2019     BAMBOO_EXIT(0xa010);
2020   } else {
2021 #ifdef DEBUG
2022 #ifndef CLOSE_PRINT
2023     BAMBOO_DEBUGPRINT(0xe88a);
2024 #endif
2025 #endif
2026     int allocsize = 0;
2027     void * mem = NULL;
2028 #ifdef MULTICORE_GC
2029     if(gcprocessing) {
2030       // is currently doing gc, dump this msg
2031       if(INITPHASE == gcphase) {
2032         // if still in the initphase of gc, send a startinit msg again,
2033         // cache the msg first
2034         if(BAMBOO_CHECK_SEND_MODE()) {
2035         cache_msg_1(data2, GCSTARTINIT);
2036         } else {
2037         send_msg_1(data2, GCSTARTINIT, true);
2038         }
2039       }
2040     } else {
2041 #endif
2042     mem = smemalloc_I(data2, data1, &allocsize);
2043     if(mem != NULL) {
2044       // send the start_va to request core, cache the msg first
2045       if(BAMBOO_CHECK_SEND_MODE()) {
2046       cache_msg_3(data2, MEMRESPONSE, mem, allocsize);
2047       } else {
2048       send_msg_3(data2, MEMRESPONSE, mem, allocsize, true);
2049       }
2050     } // if mem == NULL, the gcflag of the startup core has been set
2051     // and the gc should be started later, then a GCSTARTINIT msg
2052     // will be sent to the requesting core to notice it to start gc
2053     // and try malloc again
2054 #ifdef MULTICORE_GC
2055   }
2056 #endif
2057   }
2058 #ifdef PROFILE
2059   if(!interruptInfoOverflow) {
2060     interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
2061     interruptInfoIndex++;
2062     if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
2063       interruptInfoOverflow = true;
2064     }
2065   }
2066 #endif
2067 }
2068
2069 INLINE void processmsg_memresponse_I() {
2070   int data1 = msgdata[msgdataindex];
2071   MSG_INDEXINC_I();
2072   int data2 = msgdata[msgdataindex];
2073   MSG_INDEXINC_I();
2074   // receive a shared memory response msg
2075 #ifdef DEBUG
2076 #ifndef CLOSE_PRINT
2077   BAMBOO_DEBUGPRINT(0xe88b);
2078 #endif
2079 #endif
2080 #ifdef MULTICORE_GC
2081   // if is currently doing gc, dump this msg
2082   if(!gcprocessing) {
2083 #endif
2084   if(data2 == 0) {
2085     bamboo_smem_size = 0;
2086     bamboo_cur_msp = 0;
2087   } else {
2088 #ifdef MULTICORE_GC
2089     // fill header to store the size of this mem block
2090     memset(data1, 0, BAMBOO_CACHE_LINE_SIZE);
2091     (*((int*)data1)) = data2;
2092     bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
2093     bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
2094 #else
2095     bamboo_smem_size = data2;
2096     bamboo_cur_msp =(void*)(data1);
2097 #endif
2098   }
2099   smemflag = true;
2100 #ifdef MULTICORE_GC
2101 }
2102 #endif
2103 }
2104
2105 #ifdef MULTICORE_GC
2106 INLINE void processmsg_gcstartinit_I() {
2107   gcflag = true;
2108   gcphase = INITPHASE;
2109   if(!smemflag) {
2110     // is waiting for response of mem request
2111     // let it return NULL and start gc
2112     bamboo_smem_size = 0;
2113     bamboo_cur_msp = NULL;
2114     smemflag = true;
2115   }
2116 }
2117
2118 INLINE void processmsg_gcstart_I() {
2119 #ifdef DEBUG
2120 #ifndef CLOSE_PRINT
2121   BAMBOO_DEBUGPRINT(0xe88c);
2122 #endif
2123 #endif
2124   // set the GC flag
2125   gcphase = MARKPHASE;
2126 }
2127
2128 INLINE void processmsg_gcstartcompact_I() {
2129   gcblock2fill = msgdata[msgdataindex];
2130   MSG_INDEXINC_I();       //msgdata[1];
2131   gcphase = COMPACTPHASE;
2132 }
2133
2134 INLINE void processmsg_gcstartflush_I() {
2135   gcphase = FLUSHPHASE;
2136 }
2137
2138 INLINE void processmsg_gcfinishinit_I() {
2139   int data1 = msgdata[msgdataindex];
2140   MSG_INDEXINC_I();
2141   // received a init phase finish msg
2142   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2143     // non startup core can not receive this msg
2144 #ifndef CLOSE_PRINT
2145     BAMBOO_DEBUGPRINT_REG(data1);
2146 #endif
2147     BAMBOO_EXIT(0xb001);
2148   }
2149 #ifdef DEBUG
2150   BAMBOO_DEBUGPRINT(0xe88c);
2151   BAMBOO_DEBUGPRINT_REG(data1);
2152 #endif
2153   // All cores should do init GC
2154   if(data1 < NUMCORESACTIVE) {
2155     gccorestatus[data1] = 0;
2156   }
2157 }
2158
2159 INLINE void processmsg_gcfinishmark_I() {
2160   int data1 = msgdata[msgdataindex];
2161   MSG_INDEXINC_I();
2162   int data2 = msgdata[msgdataindex];
2163   MSG_INDEXINC_I();
2164   int data3 = msgdata[msgdataindex];
2165   MSG_INDEXINC_I();
2166   // received a mark phase finish msg
2167   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2168     // non startup core can not receive this msg
2169 #ifndef CLOSE_PRINT
2170     BAMBOO_DEBUGPRINT_REG(data1);
2171 #endif
2172     BAMBOO_EXIT(0xb002);
2173   }
2174   // all cores should do mark
2175   if(data1 < NUMCORESACTIVE) {
2176     gccorestatus[data1] = 0;
2177     gcnumsendobjs[data1] = data2;
2178     gcnumreceiveobjs[data1] = data3;
2179   }
2180 }
2181
2182 INLINE void processmsg_gcfinishcompact_I() {
2183   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2184     // non startup core can not receive this msg
2185     // return -1
2186 #ifndef CLOSE_PRINT
2187     BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
2188 #endif
2189     BAMBOO_EXIT(0xb003);
2190   }
2191   int cnum = msgdata[msgdataindex];
2192   MSG_INDEXINC_I();       //msgdata[1];
2193   int filledblocks = msgdata[msgdataindex];
2194   MSG_INDEXINC_I();       //msgdata[2];
2195   int heaptop = msgdata[msgdataindex];
2196   MSG_INDEXINC_I();       //msgdata[3];
2197   int data4 = msgdata[msgdataindex];
2198   MSG_INDEXINC_I();       //msgdata[4];
2199   // only gc cores need to do compact
2200   if(cnum < NUMCORES4GC) {
2201     if(COMPACTPHASE == gcphase) {
2202       gcfilledblocks[cnum] = filledblocks;
2203       gcloads[cnum] = heaptop;
2204     }
2205     if(data4 > 0) {
2206       // ask for more mem
2207       int startaddr = 0;
2208       int tomove = 0;
2209       int dstcore = 0;
2210       if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
2211         // cache the msg first
2212         if(BAMBOO_CHECK_SEND_MODE()) {
2213         cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
2214         } else {
2215         send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove, true);
2216         }
2217       }
2218     } else {
2219       gccorestatus[cnum] = 0;
2220     }             // if(data4>0)
2221   }       // if(cnum < NUMCORES4GC)
2222 }
2223
2224 INLINE void processmsg_gcfinishflush_I() {
2225   int data1 = msgdata[msgdataindex];
2226   MSG_INDEXINC_I();
2227   // received a flush phase finish msg
2228   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2229     // non startup core can not receive this msg
2230     // return -1
2231 #ifndef CLOSE_PRINT
2232     BAMBOO_DEBUGPRINT_REG(data1);
2233 #endif
2234     BAMBOO_EXIT(0xb004);
2235   }
2236   // all cores should do flush
2237   if(data1 < NUMCORESACTIVE) {
2238     gccorestatus[data1] = 0;
2239   }
2240 }
2241
2242 INLINE void processmsg_gcmarkconfirm_I() {
2243   if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2244      || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2245     // wrong core to receive such msg
2246     BAMBOO_EXIT(0xb005);
2247   } else {
2248     // send response msg, cahce the msg first
2249     if(BAMBOO_CHECK_SEND_MODE()) {
2250     cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2251                 gcbusystatus, gcself_numsendobjs,
2252                 gcself_numreceiveobjs);
2253     } else {
2254     send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2255                gcbusystatus, gcself_numsendobjs,
2256                gcself_numreceiveobjs, true);
2257     }
2258   }
2259 }
2260
2261 INLINE void processmsg_gcmarkreport_I() {
2262   int data1 = msgdata[msgdataindex];
2263   MSG_INDEXINC_I();
2264   int data2 = msgdata[msgdataindex];
2265   MSG_INDEXINC_I();
2266   int data3 = msgdata[msgdataindex];
2267   MSG_INDEXINC_I();
2268   int data4 = msgdata[msgdataindex];
2269   MSG_INDEXINC_I();
2270   // received a marked phase finish confirm response msg
2271   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2272     // wrong core to receive such msg
2273 #ifndef CLOSE_PRINT
2274     BAMBOO_DEBUGPRINT_REG(data2);
2275 #endif
2276     BAMBOO_EXIT(0xb006);
2277   } else {
2278     if(waitconfirm) {
2279       numconfirm--;
2280     }
2281     gccorestatus[data1] = data2;
2282     gcnumsendobjs[data1] = data3;
2283     gcnumreceiveobjs[data1] = data4;
2284   }
2285 }
2286
2287 INLINE void processmsg_gcmarkedobj_I() {
2288   int data1 = msgdata[msgdataindex];
2289   MSG_INDEXINC_I();
2290   // received a markedObj msg
2291   if(((int *)data1)[6] == INIT) {
2292     // this is the first time that this object is discovered,
2293     // set the flag as DISCOVERED
2294     ((int *)data1)[6] = DISCOVERED;
2295     gc_enqueue_I(data1);
2296   }
2297   gcself_numreceiveobjs++;
2298   gcbusystatus = true;
2299 }
2300
2301 INLINE void processmsg_gcmovestart_I() {
2302   gctomove = true;
2303   gcdstcore = msgdata[msgdataindex];
2304   MSG_INDEXINC_I();       //msgdata[1];
2305   gcmovestartaddr = msgdata[msgdataindex];
2306   MSG_INDEXINC_I();       //msgdata[2];
2307   gcblock2fill = msgdata[msgdataindex];
2308   MSG_INDEXINC_I();       //msgdata[3];
2309 }
2310
2311 INLINE void processmsg_gcmaprequest_I() {
2312 #ifdef GC_PROFILE
2313   //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2314 #endif
2315   void * dstptr = NULL;
2316   int data1 = msgdata[msgdataindex];
2317   MSG_INDEXINC_I();
2318   //dstptr = mgchashSearch(msgdata[1]);
2319 #ifdef GC_PROFILE
2320   unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2321 #endif
2322   RuntimeHashget(gcpointertbl, data1, &dstptr);
2323 #ifdef GC_PROFILE
2324   flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2325 #endif
2326   int data2 = msgdata[msgdataindex];
2327   MSG_INDEXINC_I();
2328   //MGCHashget(gcpointertbl, msgdata[1], &dstptr);
2329 #ifdef GC_PROFILE
2330   unsigned long long ttimei = BAMBOO_GET_EXE_TIME();
2331 #endif
2332   if(NULL == dstptr) {
2333     // no such pointer in this core, something is wrong
2334 #ifdef DEBUG
2335     BAMBOO_DEBUGPRINT_REG(data1);
2336     BAMBOO_DEBUGPRINT_REG(data2);
2337 #endif
2338     BAMBOO_EXIT(0xb007);
2339     //assume that the object was not moved, use the original address
2340     /*if(isMsgSending) {
2341             cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2342        } else {
2343             send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2344        }*/
2345   } else {
2346     // send back the mapping info, cache the msg first
2347     if(BAMBOO_CHECK_SEND_MODE()) {
2348     cache_msg_3(data2, GCMAPINFO, data1, (int)dstptr);
2349     } else {
2350     send_msg_3(data2, GCMAPINFO, data1, (int)dstptr, true);
2351     }
2352   }
2353 #ifdef GC_PROFILE
2354   flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimei;
2355   //num_mapinforequest_i++;
2356 #endif
2357 }
2358
2359 INLINE void processmsg_gcmapinfo_I() {
2360 #ifdef GC_PROFILE
2361   //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2362 #endif
2363   int data1 = msgdata[msgdataindex];
2364   MSG_INDEXINC_I();
2365   if(data1 != gcobj2map) {
2366     // obj not matched, something is wrong
2367 #ifdef DEBUG
2368     BAMBOO_DEBUGPRINT_REG(gcobj2map);
2369     BAMBOO_DEBUGPRINT_REG(msgdata[1]);
2370 #endif
2371     BAMBOO_EXIT(0xb008);
2372   } else {
2373     gcmappedobj = msgdata[msgdataindex];  // [2]
2374     MSG_INDEXINC_I();
2375     //mgchashReplace_I(msgdata[1], msgdata[2]);
2376     //mgchashInsert_I(gcobj2map, gcmappedobj);
2377     RuntimeHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2378     //MGCHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2379   }
2380   gcismapped = true;
2381 #ifdef GC_PROFILE
2382   //flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2383 #endif
2384 }
2385
2386 INLINE void processmsg_gclobjinfo_I() {
2387   numconfirm--;
2388
2389   int data1 = msgdata[msgdataindex];
2390   MSG_INDEXINC_I();
2391   int data2 = msgdata[msgdataindex];
2392   MSG_INDEXINC_I();
2393   if(BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1) {
2394 #ifndef CLOSE_PRINT
2395     BAMBOO_DEBUGPRINT_REG(data2);
2396 #endif
2397     BAMBOO_EXIT(0xb009);
2398   }
2399   // store the mark result info
2400   int cnum = data2;
2401   gcloads[cnum] = msgdata[msgdataindex];
2402   MSG_INDEXINC_I();       // msgdata[3];
2403   int data4 = msgdata[msgdataindex];
2404   MSG_INDEXINC_I();
2405   if(gcheaptop < data4) {
2406     gcheaptop = data4;
2407   }
2408   // large obj info here
2409   for(int k = 5; k < data1; ) {
2410     int lobj = msgdata[msgdataindex];
2411     MSG_INDEXINC_I();             //msgdata[k++];
2412     int length = msgdata[msgdataindex];
2413     MSG_INDEXINC_I();             //msgdata[k++];
2414     gc_lobjenqueue_I(lobj, length, cnum);
2415     gcnumlobjs++;
2416   }       // for(int k = 5; k < msgdata[1];)
2417 }
2418
2419 INLINE void processmsg_gclobjmapping_I() {
2420   int data1 = msgdata[msgdataindex];
2421   MSG_INDEXINC_I();
2422   int data2 = msgdata[msgdataindex];
2423   MSG_INDEXINC_I();
2424   //mgchashInsert_I(msgdata[1], msgdata[2]);
2425   RuntimeHashadd_I(gcpointertbl, data1, data2);
2426   //MGCHashadd_I(gcpointertbl, msgdata[1], msgdata[2]);
2427 }
2428 #endif // #ifdef MULTICORE_GC
2429
2430 // receive object transferred from other cores
2431 // or the terminate message from other cores
2432 // Should be invoked in critical sections!!
2433 // NOTICE: following format is for threadsimulate version only
2434 //         RAW version please see previous description
2435 // format: type + object
2436 // type: -1--stall msg
2437 //      !-1--object
2438 // return value: 0--received an object
2439 //               1--received nothing
2440 //               2--received a Stall Msg
2441 //               3--received a lock Msg
2442 //               RAW version: -1 -- received nothing
2443 //                            otherwise -- received msg type
2444 int receiveObject(int send_port_pending) {
2445 msg:
2446   // get the incoming msgs
2447   if(receiveMsg(send_port_pending) == -1) {
2448     return -1;
2449   }
2450 processmsg:
2451   // processing received msgs
2452   int size = 0;
2453   MSG_REMAINSIZE_I(&size);
2454   if((size == 0) || (checkMsgLength_I(size) == -1)) {
2455     // not a whole msg
2456     // have new coming msg
2457     if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
2458       goto msg;
2459     } else {
2460       return -1;
2461     }
2462   }
2463
2464   if(msglength <= size) {
2465     // have some whole msg
2466     //if(msgdataindex == msglength) {
2467     // received a whole msg
2468     MSGTYPE type;
2469     type = msgdata[msgdataindex]; //[0]
2470     MSG_INDEXINC_I();
2471     msgdatafull = false;
2472     // TODO
2473     //tprintf("msg type: %x\n", type);
2474     switch(type) {
2475     case TRANSOBJ: {
2476       // receive a object transfer msg
2477       processmsg_transobj_I();
2478       break;
2479     }                     // case TRANSOBJ
2480
2481     case TRANSTALL: {
2482       // receive a stall msg
2483       processmsg_transtall_I();
2484       break;
2485     }                     // case TRANSTALL
2486
2487 // GC version have no lock msgs
2488 #ifndef MULTICORE_GC
2489     case LOCKREQUEST: {
2490       // receive lock request msg, handle it right now
2491       processmsg_lockrequest_I();
2492       break;
2493     }                     // case LOCKREQUEST
2494
2495     case LOCKGROUNT: {
2496       // receive lock grount msg
2497       processmsg_lockgrount_I();
2498       break;
2499     }                     // case LOCKGROUNT
2500
2501     case LOCKDENY: {
2502       // receive lock deny msg
2503       processmsg_lockdeny_I();
2504       break;
2505     }                     // case LOCKDENY
2506
2507     case LOCKRELEASE: {
2508       processmsg_lockrelease_I();
2509       break;
2510     }                     // case LOCKRELEASE
2511 #endif // #ifndef MULTICORE_GC
2512
2513 #ifdef PROFILE
2514     case PROFILEOUTPUT: {
2515       // receive an output profile data request msg
2516       processmsg_profileoutput_I();
2517       break;
2518     }                     // case PROFILEOUTPUT
2519
2520     case PROFILEFINISH: {
2521       // receive a profile output finish msg
2522       processmsg_profilefinish_I();
2523       break;
2524     }                     // case PROFILEFINISH
2525 #endif // #ifdef PROFILE
2526
2527 // GC version has no lock msgs
2528 #ifndef MULTICORE_GC
2529     case REDIRECTLOCK: {
2530       // receive a redirect lock request msg, handle it right now
2531       processmsg_redirectlock_I();
2532       break;
2533     }                     // case REDIRECTLOCK
2534
2535     case REDIRECTGROUNT: {
2536       // receive a lock grant msg with redirect info
2537       processmsg_redirectgrount_I();
2538       break;
2539     }                     // case REDIRECTGROUNT
2540
2541     case REDIRECTDENY: {
2542       // receive a lock deny msg with redirect info
2543       processmsg_redirectdeny_I();
2544       break;
2545     }                     // case REDIRECTDENY
2546
2547     case REDIRECTRELEASE: {
2548       // receive a lock release msg with redirect info
2549       processmsg_redirectrelease_I();
2550       break;
2551     }                     // case REDIRECTRELEASE
2552 #endif // #ifndef MULTICORE_GC
2553
2554     case STATUSCONFIRM: {
2555       // receive a status confirm info
2556       processmsg_statusconfirm_I();
2557       break;
2558     }                     // case STATUSCONFIRM
2559
2560     case STATUSREPORT: {
2561       processmsg_statusreport_I();
2562       break;
2563     }                     // case STATUSREPORT
2564
2565     case TERMINATE: {
2566       // receive a terminate msg
2567       processmsg_terminate_I();
2568       break;
2569     }                     // case TERMINATE
2570
2571     case MEMREQUEST: {
2572       processmsg_memrequest_I();
2573       break;
2574     }                     // case MEMREQUEST
2575
2576     case MEMRESPONSE: {
2577       processmsg_memresponse_I();
2578       break;
2579     }                     // case MEMRESPONSE
2580
2581 #ifdef MULTICORE_GC
2582     // GC msgs
2583     case GCSTARTINIT: {
2584       processmsg_gcstartinit_I();
2585       break;
2586     }                     // case GCSTARTINIT
2587
2588     case GCSTART: {
2589       // receive a start GC msg
2590       processmsg_gcstart_I();
2591       break;
2592     }                     // case GCSTART
2593
2594     case GCSTARTCOMPACT: {
2595       // a compact phase start msg
2596       processmsg_gcstartcompact_I();
2597       break;
2598     }                     // case GCSTARTCOMPACT
2599
2600     case GCSTARTFLUSH: {
2601       // received a flush phase start msg
2602       processmsg_gcstartflush_I();
2603       break;
2604     }                     // case GCSTARTFLUSH
2605
2606     case GCFINISHINIT: {
2607       processmsg_gcfinishinit_I();
2608       break;
2609     }                     // case GCFINISHINIT
2610
2611     case GCFINISHMARK: {
2612       processmsg_gcfinishmark_I();
2613       break;
2614     }                     // case GCFINISHMARK
2615
2616     case GCFINISHCOMPACT: {
2617       // received a compact phase finish msg
2618       processmsg_gcfinishcompact_I();
2619       break;
2620     }                     // case GCFINISHCOMPACT
2621
2622     case GCFINISHFLUSH: {
2623       processmsg_gcfinishflush_I();
2624       break;
2625     }                     // case GCFINISHFLUSH
2626
2627     case GCFINISH: {
2628       // received a GC finish msg
2629       gcphase = FINISHPHASE;
2630       break;
2631     }                     // case GCFINISH
2632
2633     case GCMARKCONFIRM: {
2634       // received a marked phase finish confirm request msg
2635       // all cores should do mark
2636       processmsg_gcmarkconfirm_I();
2637       break;
2638     }                     // case GCMARKCONFIRM
2639
2640     case GCMARKREPORT: {
2641       processmsg_gcmarkreport_I();
2642       break;
2643     }                     // case GCMARKREPORT
2644
2645     case GCMARKEDOBJ: {
2646       processmsg_gcmarkedobj_I();
2647       break;
2648     }                     // case GCMARKEDOBJ
2649
2650     case GCMOVESTART: {
2651       // received a start moving objs msg
2652       processmsg_gcmovestart_I();
2653       break;
2654     }                     // case GCMOVESTART
2655
2656     case GCMAPREQUEST: {
2657       // received a mapping info request msg
2658       processmsg_gcmaprequest_I();
2659       break;
2660     }                     // case GCMAPREQUEST
2661
2662     case GCMAPINFO: {
2663       // received a mapping info response msg
2664       processmsg_gcmapinfo_I();
2665       break;
2666     }                     // case GCMAPINFO
2667
2668     case GCLOBJREQUEST: {
2669       // received a large objs info request msg
2670       transferMarkResults_I();
2671       break;
2672     }                     // case GCLOBJREQUEST
2673
2674     case GCLOBJINFO: {
2675       // received a large objs info response msg
2676       processmsg_gclobjinfo_I();
2677       break;
2678     }                     // case GCLOBJINFO
2679
2680     case GCLOBJMAPPING: {
2681       // received a large obj mapping info msg
2682       processmsg_gclobjmapping_I();
2683       break;
2684     }                     // case GCLOBJMAPPING
2685
2686 #endif // #ifdef MULTICORE_GC
2687
2688     default:
2689       break;
2690     }             // switch(type)
2691     //memset(msgdata, '\0', sizeof(int) * msgdataindex);
2692     //msgdataindex = 0;
2693     msglength = BAMBOO_MSG_BUF_LENGTH;
2694     // TODO
2695     //printf("++ msg: %x \n", type);
2696
2697     if(msgdataindex != msgdatalast) {
2698       // still have available msg
2699       goto processmsg;
2700     }
2701 #ifdef DEBUG
2702 #ifndef CLOSE_PRINT
2703     BAMBOO_DEBUGPRINT(0xe88d);
2704 #endif
2705 #endif
2706
2707     // have new coming msg
2708     if(BAMBOO_MSG_AVAIL() != 0) {
2709       goto msg;
2710     } // TODO
2711
2712 #ifdef PROFILE
2713 /*if(isInterrupt) {
2714                 profileTaskEnd();
2715         }*/
2716 #endif
2717     return (int)type;
2718   } else {
2719     // not a whole msg
2720 #ifdef DEBUG
2721 #ifndef CLOSE_PRINT
2722     BAMBOO_DEBUGPRINT(0xe88e);
2723 #endif
2724 #endif
2725 #ifdef PROFILE
2726     /*  if(isInterrupt) {
2727                             profileTaskEnd();
2728                     }*/
2729 #endif
2730     return -2;
2731   }
2732 }
2733
2734 int enqueuetasks(struct parameterwrapper *parameter,
2735                  struct parameterwrapper *prevptr,
2736                  struct ___Object___ *ptr,
2737                  int * enterflags,
2738                  int numenterflags) {
2739   void * taskpointerarray[MAXTASKPARAMS];
2740   int j;
2741   //int numparams=parameter->task->numParameters;
2742   int numiterators=parameter->task->numTotal-1;
2743   int retval=1;
2744
2745   struct taskdescriptor * task=parameter->task;
2746
2747   //this add the object to parameterwrapper
2748   ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
2749                 numenterflags, enterflags==NULL);
2750
2751   /* Add enqueued object to parameter vector */
2752   taskpointerarray[parameter->slot]=ptr;
2753
2754   /* Reset iterators */
2755   for(j=0; j<numiterators; j++) {
2756     toiReset(&parameter->iterators[j]);
2757   }
2758
2759   /* Find initial state */
2760   for(j=0; j<numiterators; j++) {
2761 backtrackinit:
2762     if(toiHasNext(&parameter->iterators[j],taskpointerarray OPTARG(failed)))
2763       toiNext(&parameter->iterators[j], taskpointerarray OPTARG(failed));
2764     else if (j>0) {
2765       /* Need to backtrack */
2766       toiReset(&parameter->iterators[j]);
2767       j--;
2768       goto backtrackinit;
2769     } else {
2770       /* Nothing to enqueue */
2771       return retval;
2772     }
2773   }
2774
2775   while(1) {
2776     /* Enqueue current state */
2777     //int launch = 0;
2778     struct taskparamdescriptor *tpd=
2779       RUNMALLOC(sizeof(struct taskparamdescriptor));
2780     tpd->task=task;
2781     tpd->numParameters=numiterators+1;
2782     tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
2783
2784     for(j=0; j<=numiterators; j++) {
2785       //store the actual parameters
2786       tpd->parameterArray[j]=taskpointerarray[j];
2787     }
2788     /* Enqueue task */
2789     if (( /*!gencontains(failedtasks, tpd)&&*/
2790           !gencontains(activetasks,tpd))) {
2791       genputtable(activetasks, tpd, tpd);
2792     } else {
2793       RUNFREE(tpd->parameterArray);
2794       RUNFREE(tpd);
2795     }
2796
2797     /* This loop iterates to the next parameter combination */
2798     if (numiterators==0)
2799       return retval;
2800
2801     for(j=numiterators-1; j<numiterators; j++) {
2802 backtrackinc:
2803       if(toiHasNext(&parameter->iterators[j],taskpointerarray OPTARG(failed)))
2804         toiNext(&parameter->iterators[j], taskpointerarray OPTARG(failed));
2805       else if (j>0) {
2806         /* Need to backtrack */
2807         toiReset(&parameter->iterators[j]);
2808         j--;
2809         goto backtrackinc;
2810       } else {
2811         /* Nothing more to enqueue */
2812         return retval;
2813       }
2814     }
2815   }
2816   return retval;
2817 }
2818
2819 int enqueuetasks_I(struct parameterwrapper *parameter,
2820                    struct parameterwrapper *prevptr,
2821                    struct ___Object___ *ptr,
2822                    int * enterflags,
2823                    int numenterflags) {
2824   void * taskpointerarray[MAXTASKPARAMS];
2825   int j;
2826   //int numparams=parameter->task->numParameters;
2827   int numiterators=parameter->task->numTotal-1;
2828   int retval=1;
2829   //int addnormal=1;
2830   //int adderror=1;
2831
2832   struct taskdescriptor * task=parameter->task;
2833
2834   //this add the object to parameterwrapper
2835   ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
2836                   numenterflags, enterflags==NULL);
2837
2838   /* Add enqueued object to parameter vector */
2839   taskpointerarray[parameter->slot]=ptr;
2840
2841   /* Reset iterators */
2842   for(j=0; j<numiterators; j++) {
2843     toiReset(&parameter->iterators[j]);
2844   }
2845
2846   /* Find initial state */
2847   for(j=0; j<numiterators; j++) {
2848 backtrackinit:
2849     if(toiHasNext(&parameter->iterators[j],taskpointerarray OPTARG(failed)))
2850       toiNext(&parameter->iterators[j], taskpointerarray OPTARG(failed));
2851     else if (j>0) {
2852       /* Need to backtrack */
2853       toiReset(&parameter->iterators[j]);
2854       j--;
2855       goto backtrackinit;
2856     } else {
2857       /* Nothing to enqueue */
2858       return retval;
2859     }
2860   }
2861
2862   while(1) {
2863     /* Enqueue current state */
2864     //int launch = 0;
2865     struct taskparamdescriptor *tpd=
2866       RUNMALLOC_I(sizeof(struct taskparamdescriptor));
2867     tpd->task=task;
2868     tpd->numParameters=numiterators+1;
2869     tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
2870
2871     for(j=0; j<=numiterators; j++) {
2872       //store the actual parameters
2873       tpd->parameterArray[j]=taskpointerarray[j];
2874     }
2875     /* Enqueue task */
2876     if (( /*!gencontains(failedtasks, tpd)&&*/
2877           !gencontains(activetasks,tpd))) {
2878       genputtable_I(activetasks, tpd, tpd);
2879     } else {
2880       RUNFREE(tpd->parameterArray);
2881       RUNFREE(tpd);
2882     }
2883
2884     /* This loop iterates to the next parameter combination */
2885     if (numiterators==0)
2886       return retval;
2887
2888     for(j=numiterators-1; j<numiterators; j++) {
2889 backtrackinc:
2890       if(toiHasNext(&parameter->iterators[j], taskpointerarray OPTARG(failed)))
2891         toiNext(&parameter->iterators[j], taskpointerarray OPTARG(failed));
2892       else if (j>0) {
2893         /* Need to backtrack */
2894         toiReset(&parameter->iterators[j]);
2895         j--;
2896         goto backtrackinc;
2897       } else {
2898         /* Nothing more to enqueue */
2899         return retval;
2900       }
2901     }
2902   }
2903   return retval;
2904 }
2905
2906 #ifdef MULTICORE_GC
2907 #define OFFSET 2
2908 #else
2909 #define OFFSET 0
2910 #endif
2911
2912 int containstag(struct ___Object___ *ptr,
2913                 struct ___TagDescriptor___ *tag);
2914
2915 #ifndef MULTICORE_GC
2916 void releasewritelock_r(void * lock, void * redirectlock) {
2917   int targetcore = 0;
2918   int reallock = (int)lock;
2919   targetcore = (reallock >> 5) % NUMCORES;
2920
2921 #ifdef DEBUG
2922   BAMBOO_DEBUGPRINT(0xe671);
2923   BAMBOO_DEBUGPRINT_REG((int)lock);
2924   BAMBOO_DEBUGPRINT_REG(reallock);
2925   BAMBOO_DEBUGPRINT_REG(targetcore);
2926 #endif
2927
2928   if(targetcore == BAMBOO_NUM_OF_CORE) {
2929     BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2930 #ifdef DEBUG
2931     BAMBOO_DEBUGPRINT(0xf001);
2932 #endif
2933     // reside on this core
2934     if(!RuntimeHashcontainskey(locktbl, reallock)) {
2935       // no locks for this object, something is wrong
2936       BAMBOO_EXIT(0xa011);
2937     } else {
2938       int rwlock_obj = 0;
2939       struct LockValue * lockvalue = NULL;
2940 #ifdef DEBUG
2941       BAMBOO_DEBUGPRINT(0xe672);
2942 #endif
2943       RuntimeHashget(locktbl, reallock, &rwlock_obj);
2944       lockvalue = (struct LockValue *)rwlock_obj;
2945 #ifdef DEBUG
2946       BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2947 #endif
2948       lockvalue->value++;
2949       lockvalue->redirectlock = (int)redirectlock;
2950 #ifdef DEBUG
2951       BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2952 #endif
2953     }
2954     BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2955 #ifdef DEBUG
2956     BAMBOO_DEBUGPRINT(0xf000);
2957 #endif
2958     return;
2959   } else {
2960     // send lock release with redirect info msg
2961     // for 32 bit machine, the size is always 4 words
2962     send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock,
2963                (int)redirectlock, false);
2964   }
2965 }
2966 #endif
2967
2968 void executetasks() {
2969   void * taskpointerarray[MAXTASKPARAMS+OFFSET];
2970   int numparams=0;
2971   int numtotal=0;
2972   struct ___Object___ * tmpparam = NULL;
2973   struct parameterdescriptor * pd=NULL;
2974   struct parameterwrapper *pw=NULL;
2975   int j = 0;
2976   int x = 0;
2977   bool islock = true;
2978
2979   int grount = 0;
2980   int andmask=0;
2981   int checkmask=0;
2982
2983 newtask:
2984   while(hashsize(activetasks)>0) {
2985 #ifdef MULTICORE_GC
2986     gc(NULL);
2987 #endif
2988 #ifdef DEBUG
2989     BAMBOO_DEBUGPRINT(0xe990);
2990 #endif
2991
2992     /* See if there are any active tasks */
2993     //if (hashsize(activetasks)>0) {
2994     int i;
2995 #ifdef PROFILE
2996 #ifdef ACCURATEPROFILE
2997     profileTaskStart("tpd checking");
2998 #endif
2999 #endif
3000     //long clock1;
3001     //clock1 = BAMBOO_GET_EXE_TIME();
3002
3003     busystatus = true;
3004     currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
3005     genfreekey(activetasks, currtpd);
3006
3007     numparams=currtpd->task->numParameters;
3008     numtotal=currtpd->task->numTotal;
3009
3010     // clear the lockRedirectTbl
3011     // (TODO, this table should be empty after all locks are released)
3012     // reset all locks
3013     /*for(j = 0; j < MAXTASKPARAMS; j++) {
3014             runtime_locks[j].redirectlock = 0;
3015             runtime_locks[j].value = 0;
3016        }*/
3017     // get all required locks
3018     runtime_locklen = 0;
3019     // check which locks are needed
3020     for(i = 0; i < numparams; i++) {
3021       void * param = currtpd->parameterArray[i];
3022       int tmplock = 0;
3023       int j = 0;
3024       bool insert = true;
3025       if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
3026         islock = false;
3027         taskpointerarray[i+OFFSET]=param;
3028         goto execute;
3029       }
3030       if(((struct ___Object___ *)param)->lock == NULL) {
3031         tmplock = (int)param;
3032       } else {
3033         tmplock = (int)(((struct ___Object___ *)param)->lock);
3034       }
3035       // insert into the locks array
3036       for(j = 0; j < runtime_locklen; j++) {
3037         if(runtime_locks[j].value == tmplock) {
3038           insert = false;
3039           break;
3040         } else if(runtime_locks[j].value > tmplock) {
3041           break;
3042         }
3043       }
3044       if(insert) {
3045         int h = runtime_locklen;
3046         for(; h > j; h--) {
3047           runtime_locks[h].redirectlock = runtime_locks[h-1].redirectlock;
3048           runtime_locks[h].value = runtime_locks[h-1].value;
3049         }
3050         runtime_locks[j].value = tmplock;
3051         runtime_locks[j].redirectlock = (int)param;
3052         runtime_locklen++;
3053       }
3054     }       // line 2713: for(i = 0; i < numparams; i++)
3055             // grab these required locks
3056 #ifdef DEBUG
3057     BAMBOO_DEBUGPRINT(0xe991);
3058 #endif
3059     //long clock2;
3060     //clock2 = BAMBOO_GET_EXE_TIME();
3061
3062     for(i = 0; i < runtime_locklen; i++) {
3063       int * lock = (int *)(runtime_locks[i].redirectlock);
3064       islock = true;
3065       // require locks for this parameter if it is not a startup object
3066 #ifdef DEBUG
3067       BAMBOO_DEBUGPRINT_REG((int)lock);
3068       BAMBOO_DEBUGPRINT_REG((int)(runtime_locks[i].value));
3069 #endif
3070       getwritelock(lock);
3071       BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3072 #ifdef DEBUG
3073       BAMBOO_DEBUGPRINT(0xf001);
3074 #endif
3075 #ifdef PROFILE
3076       //isInterrupt = false;
3077 #endif
3078       while(!lockflag) {
3079         BAMBOO_WAITING_FOR_LOCK(0);
3080         // check for outgoing sends
3081     /*if (isMsgHanging) {
3082       extern inline void send_hanging_msg(bool);
3083       send_hanging_msg(true);
3084     } */
3085           }
3086 #ifndef INTERRUPT
3087       if(reside) {
3088         while(BAMBOO_WAITING_FOR_LOCK(0) != -1) {
3089           // check for outgoing sends
3090           /*if (isMsgHanging) {
3091                 extern inline void send_hanging_msg(bool);
3092                 send_hanging_msg(true);
3093           } */
3094         }
3095       }
3096 #endif
3097       grount = lockresult;
3098
3099       lockresult = 0;
3100       lockobj = 0;
3101       lock2require = 0;
3102       lockflag = false;
3103 #ifndef INTERRUPT
3104       reside = false;
3105 #endif
3106 #ifdef PROFILE
3107       //isInterrupt = true;
3108 #endif
3109       BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3110 #ifdef DEBUG
3111       BAMBOO_DEBUGPRINT(0xf000);
3112 #endif
3113
3114       if(grount == 0) {
3115 #ifdef DEBUG
3116         BAMBOO_DEBUGPRINT(0xe992);
3117         BAMBOO_DEBUGPRINT_REG(lock);
3118 #endif
3119         // check if has the lock already
3120         // can not get the lock, try later
3121         // release all grabbed locks for previous parameters
3122         for(j = 0; j < i; ++j) {
3123           lock = (int*)(runtime_locks[j].redirectlock);
3124           releasewritelock(lock);
3125         }
3126         genputtable(activetasks, currtpd, currtpd);
3127         if(hashsize(activetasks) == 1) {
3128           // only one task right now, wait a little while before next try
3129           int halt = 10000;
3130           while(halt--) {
3131           }
3132         }
3133 #ifdef PROFILE
3134 #ifdef ACCURATEPROFILE
3135         // fail, set the end of the checkTaskInfo
3136         profileTaskEnd();
3137 #endif
3138 #endif
3139         goto newtask;
3140         //}
3141       }
3142     }       // line 2752:  for(i = 0; i < runtime_locklen; i++)
3143
3144     /*long clock3;
3145        clock3 = BAMBOO_GET_EXE_TIME();
3146        //tprintf("sort: %d, grab: %d \n", clock2-clock1, clock3-clock2);*/
3147
3148 #ifdef DEBUG
3149     BAMBOO_DEBUGPRINT(0xe993);
3150 #endif
3151     /* Make sure that the parameters are still in the queues */
3152     for(i=0; i<numparams; i++) {
3153       void * parameter=currtpd->parameterArray[i];
3154
3155       // flush the object
3156 #ifdef CACHEFLUSH
3157       BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
3158                                classsize[((struct ___Object___ *)parameter)->type]);
3159 #endif
3160       tmpparam = (struct ___Object___ *)parameter;
3161       pd=currtpd->task->descriptorarray[i];
3162       pw=(struct parameterwrapper *) pd->queue;
3163       /* Check that object is still in queue */
3164       {
3165         if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
3166 #ifdef DEBUG
3167           BAMBOO_DEBUGPRINT(0xe994);
3168           BAMBOO_DEBUGPRINT_REG(parameter);
3169 #endif
3170           // release grabbed locks
3171           for(j = 0; j < runtime_locklen; ++j) {
3172             int * lock = (int *)(runtime_locks[j].redirectlock);
3173             releasewritelock(lock);
3174           }
3175           RUNFREE(currtpd->parameterArray);
3176           RUNFREE(currtpd);
3177           currtpd = NULL;
3178           goto newtask;
3179         }
3180       }   // line2865
3181           /* Check if the object's flags still meets requirements */
3182       {
3183         int tmpi = 0;
3184         bool ismet = false;
3185         for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
3186           andmask=pw->intarray[tmpi*2];
3187           checkmask=pw->intarray[tmpi*2+1];
3188           if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
3189             ismet = true;
3190             break;
3191           }
3192         }
3193         if (!ismet) {
3194           // flags are never suitable
3195           // remove this obj from the queue
3196           int next;
3197           int UNUSED, UNUSED2;
3198           int * enterflags;
3199 #ifdef DEBUG
3200           BAMBOO_DEBUGPRINT(0xe995);
3201           BAMBOO_DEBUGPRINT_REG(parameter);
3202 #endif
3203           ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
3204                         (int *) &enterflags, &UNUSED, &UNUSED2);
3205           ObjectHashremove(pw->objectset, (int)parameter);
3206           if (enterflags!=NULL)
3207             RUNFREE(enterflags);
3208           // release grabbed locks
3209           for(j = 0; j < runtime_locklen; ++j) {
3210             int * lock = (int *)(runtime_locks[j].redirectlock);
3211             releasewritelock(lock);
3212           }
3213           RUNFREE(currtpd->parameterArray);
3214           RUNFREE(currtpd);
3215           currtpd = NULL;
3216 #ifdef PROFILE
3217 #ifdef ACCURATEPROFILE
3218           // fail, set the end of the checkTaskInfo
3219           profileTaskEnd();
3220 #endif
3221 #endif
3222           goto newtask;
3223         }   // line 2878: if (!ismet)
3224       }   // line 2867
3225 parameterpresent:
3226       ;
3227       /* Check that object still has necessary tags */
3228       for(j=0; j<pd->numbertags; j++) {
3229         int slotid=pd->tagarray[2*j]+numparams;
3230         struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
3231         if (!containstag(parameter, tagd)) {
3232 #ifdef DEBUG
3233           BAMBOO_DEBUGPRINT(0xe996);
3234 #endif
3235           {
3236             // release grabbed locks
3237             int tmpj = 0;
3238             for(tmpj = 0; tmpj < runtime_locklen; ++tmpj) {
3239               int * lock = (int *)(runtime_locks[tmpj].redirectlock);
3240               releasewritelock(lock);
3241             }
3242           }
3243           RUNFREE(currtpd->parameterArray);
3244           RUNFREE(currtpd);
3245           currtpd = NULL;
3246           goto newtask;
3247         }   // line2911: if (!containstag(parameter, tagd))
3248       }   // line 2808: for(j=0; j<pd->numbertags; j++)
3249
3250       taskpointerarray[i+OFFSET]=parameter;
3251     }   // line 2824: for(i=0; i<numparams; i++)
3252         /* Copy the tags */
3253     for(; i<numtotal; i++) {
3254       taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
3255     }
3256
3257     {
3258 execute:
3259       /* Actually call task */
3260 #ifdef MULTICORE_GC
3261       ((int *)taskpointerarray)[0]=currtpd->numParameters;
3262       taskpointerarray[1]=NULL;
3263 #endif
3264 #ifdef PROFILE
3265 #ifdef ACCURATEPROFILE
3266       // check finish, set the end of the checkTaskInfo
3267       profileTaskEnd();
3268 #endif
3269       profileTaskStart(currtpd->task->name);
3270 #endif
3271       // TODO
3272       //long clock4;
3273       //clock4 = BAMBOO_GET_EXE_TIME();
3274       //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3275
3276 #ifdef DEBUG
3277       BAMBOO_DEBUGPRINT(0xe997);
3278 #endif
3279       ((void (*)(void **))currtpd->task->taskptr)(taskpointerarray);
3280       // TODO
3281       //long clock5;
3282       //clock5 = BAMBOO_GET_EXE_TIME();
3283       // tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3284
3285 #ifdef PROFILE
3286 #ifdef ACCURATEPROFILE
3287       // task finish, set the end of the checkTaskInfo
3288       profileTaskEnd();
3289       // new a PostTaskInfo for the post-task execution
3290       profileTaskStart("post task execution");
3291 #endif
3292 #endif
3293 #ifdef DEBUG
3294       BAMBOO_DEBUGPRINT(0xe998);
3295       BAMBOO_DEBUGPRINT_REG(islock);
3296 #endif
3297
3298       if(islock) {
3299 #ifdef DEBUG
3300         BAMBOO_DEBUGPRINT(0xe999);
3301 #endif
3302         for(i = 0; i < runtime_locklen; ++i) {
3303           void * ptr = (void *)(runtime_locks[i].redirectlock);
3304           int * lock = (int *)(runtime_locks[i].value);
3305 #ifdef DEBUG
3306           BAMBOO_DEBUGPRINT_REG((int)ptr);
3307           BAMBOO_DEBUGPRINT_REG((int)lock);
3308           BAMBOO_DEBUGPRINT_REG(*((int*)lock+5));
3309 #endif
3310 #ifndef MULTICORE_GC
3311           if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
3312             int redirectlock;
3313             RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
3314             RuntimeHashremovekey(lockRedirectTbl, (int)lock);
3315             releasewritelock_r(lock, (int *)redirectlock);
3316           } else {
3317 #else
3318           {
3319 #endif
3320             releasewritelock(ptr);
3321           }
3322         }
3323       }     // line 3015: if(islock)
3324
3325       //long clock6;
3326       //clock6 = BAMBOO_GET_EXE_TIME();
3327       //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3328
3329 #ifdef PROFILE
3330       // post task execution finish, set the end of the postTaskInfo
3331       profileTaskEnd();
3332 #endif
3333
3334       // Free up task parameter descriptor
3335       RUNFREE(currtpd->parameterArray);
3336       RUNFREE(currtpd);
3337       currtpd = NULL;
3338 #ifdef DEBUG
3339       BAMBOO_DEBUGPRINT(0xe99a);
3340 #endif
3341       //long clock7;
3342       //clock7 = BAMBOO_GET_EXE_TIME();
3343       //tprintf("sort: %d, grab: %d, check: %d, release: %d, other %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3), (int)(clock6-clock5), (int)(clock7-clock6));
3344
3345     }   //
3346     //} //  if (hashsize(activetasks)>0)
3347   } //  while(hashsize(activetasks)>0)
3348 #ifdef DEBUG
3349   BAMBOO_DEBUGPRINT(0xe99b);
3350 #endif
3351 }
3352
3353 /* This function processes an objects tags */
3354 void processtags(struct parameterdescriptor *pd,
3355                  int index,
3356                  struct parameterwrapper *parameter,
3357                  int * iteratorcount,
3358                  int *statusarray,
3359                  int numparams) {
3360   int i;
3361
3362   for(i=0; i<pd->numbertags; i++) {
3363     int slotid=pd->tagarray[2*i];
3364     int tagid=pd->tagarray[2*i+1];
3365
3366     if (statusarray[slotid+numparams]==0) {
3367       parameter->iterators[*iteratorcount].istag=1;
3368       parameter->iterators[*iteratorcount].tagid=tagid;
3369       parameter->iterators[*iteratorcount].slot=slotid+numparams;
3370       parameter->iterators[*iteratorcount].tagobjectslot=index;
3371       statusarray[slotid+numparams]=1;
3372       (*iteratorcount)++;
3373     }
3374   }
3375 }
3376
3377
3378 void processobject(struct parameterwrapper *parameter,
3379                    int index,
3380                    struct parameterdescriptor *pd,
3381                    int *iteratorcount,
3382                    int * statusarray,
3383                    int numparams) {
3384   int i;
3385   int tagcount=0;
3386   struct ObjectHash * objectset=
3387     ((struct parameterwrapper *)pd->queue)->objectset;
3388
3389   parameter->iterators[*iteratorcount].istag=0;
3390   parameter->iterators[*iteratorcount].slot=index;
3391   parameter->iterators[*iteratorcount].objectset=objectset;
3392   statusarray[index]=1;
3393
3394   for(i=0; i<pd->numbertags; i++) {
3395     int slotid=pd->tagarray[2*i];
3396     //int tagid=pd->tagarray[2*i+1];
3397     if (statusarray[slotid+numparams]!=0) {
3398       /* This tag has already been enqueued, use it to narrow search */
3399       parameter->iterators[*iteratorcount].tagbindings[tagcount]=
3400         slotid+numparams;
3401       tagcount++;
3402     }
3403   }
3404   parameter->iterators[*iteratorcount].numtags=tagcount;
3405
3406   (*iteratorcount)++;
3407 }
3408
3409 /* This function builds the iterators for a task & parameter */
3410
3411 void builditerators(struct taskdescriptor * task,
3412                     int index,
3413                     struct parameterwrapper * parameter) {
3414   int statusarray[MAXTASKPARAMS];
3415   int i;
3416   int numparams=task->numParameters;
3417   int iteratorcount=0;
3418   for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
3419
3420   statusarray[index]=1; /* Initial parameter */
3421   /* Process tags for initial iterator */
3422
3423   processtags(task->descriptorarray[index], index, parameter,
3424               &iteratorcount, statusarray, numparams);
3425
3426   while(1) {
3427 loopstart:
3428     /* Check for objects with existing tags */
3429     for(i=0; i<numparams; i++) {
3430       if (statusarray[i]==0) {
3431         struct parameterdescriptor *pd=task->descriptorarray[i];
3432         int j;
3433         for(j=0; j<pd->numbertags; j++) {
3434           int slotid=pd->tagarray[2*j];
3435           if(statusarray[slotid+numparams]!=0) {
3436             processobject(parameter, i, pd, &iteratorcount, statusarray,
3437                           numparams);
3438             processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3439             goto loopstart;
3440           }
3441         }
3442       }
3443     }
3444
3445     /* Next do objects w/ unbound tags*/
3446
3447     for(i=0; i<numparams; i++) {
3448       if (statusarray[i]==0) {
3449         struct parameterdescriptor *pd=task->descriptorarray[i];
3450         if (pd->numbertags>0) {
3451           processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3452           processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3453           goto loopstart;
3454         }
3455       }
3456     }
3457
3458     /* Nothing with a tag enqueued */
3459
3460     for(i=0; i<numparams; i++) {
3461       if (statusarray[i]==0) {
3462         struct parameterdescriptor *pd=task->descriptorarray[i];
3463         processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3464         processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3465         goto loopstart;
3466       }
3467     }
3468
3469     /* Nothing left */
3470     return;
3471   }
3472 }
3473
3474 void printdebug() {
3475   int i;
3476   int j;
3477   if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3478     return;
3479   }
3480   for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3481     struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3482 #ifndef RAW
3483     printf("%s\n", task->name);
3484 #endif
3485     for(j=0; j<task->numParameters; j++) {
3486       struct parameterdescriptor *param=task->descriptorarray[j];
3487       struct parameterwrapper *parameter=param->queue;
3488       struct ObjectHash * set=parameter->objectset;
3489       struct ObjectIterator objit;
3490 #ifndef RAW
3491       printf("  Parameter %d\n", j);
3492 #endif
3493       ObjectHashiterator(set, &objit);
3494       while(ObjhasNext(&objit)) {
3495         struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
3496         struct ___Object___ * tagptr=obj->___tags___;
3497         int nonfailed=Objdata4(&objit);
3498         int numflags=Objdata3(&objit);
3499         int flags=Objdata2(&objit);
3500         Objnext(&objit);
3501 #ifndef RAW
3502         printf("    Contains %lx\n", obj);
3503         printf("      flag=%d\n", obj->flag);
3504 #endif
3505         if (tagptr==NULL) {
3506         } else if (tagptr->type==TAGTYPE) {
3507 #ifndef RAW
3508           printf("      tag=%lx\n",tagptr);
3509 #else
3510           ;
3511 #endif
3512         } else {
3513           int tagindex=0;
3514           struct ArrayObject *ao=(struct ArrayObject *)tagptr;
3515           for(; tagindex<ao->___cachedCode___; tagindex++) {
3516 #ifndef RAW
3517             printf("      tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*,
3518                                               tagindex));
3519 #else
3520             ;
3521 #endif
3522           }
3523         }
3524       }
3525     }
3526   }
3527 }
3528
3529
3530 /* This function processes the task information to create queues for
3531    each parameter type. */
3532
3533 void processtasks() {
3534   int i;
3535   if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3536     return;
3537   }
3538   for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3539     struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3540     int j;
3541
3542     /* Build objectsets */
3543     for(j=0; j<task->numParameters; j++) {
3544       struct parameterdescriptor *param=task->descriptorarray[j];
3545       struct parameterwrapper *parameter=param->queue;
3546       parameter->objectset=allocateObjectHash(10);
3547       parameter->task=task;
3548     }
3549
3550     /* Build iterators for parameters */
3551     for(j=0; j<task->numParameters; j++) {
3552       struct parameterdescriptor *param=task->descriptorarray[j];
3553       struct parameterwrapper *parameter=param->queue;
3554       builditerators(task, j, parameter);
3555     }
3556   }
3557 }
3558
3559 void toiReset(struct tagobjectiterator * it) {
3560   if (it->istag) {
3561     it->tagobjindex=0;
3562   } else if (it->numtags>0) {
3563     it->tagobjindex=0;
3564   } else {
3565     ObjectHashiterator(it->objectset, &it->it);
3566   }
3567 }
3568
3569 int toiHasNext(struct tagobjectiterator *it,
3570                void ** objectarray OPTARG(int * failed)) {
3571   if (it->istag) {
3572     /* Iterate tag */
3573     /* Get object with tags */
3574     struct ___Object___ *obj=objectarray[it->tagobjectslot];
3575     struct ___Object___ *tagptr=obj->___tags___;
3576     if (tagptr->type==TAGTYPE) {
3577       if ((it->tagobjindex==0)&& /* First object */
3578           (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
3579         return 1;
3580       else
3581         return 0;
3582     } else {
3583       struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3584       int tagindex=it->tagobjindex;
3585       for(; tagindex<ao->___cachedCode___; tagindex++) {
3586         struct ___TagDescriptor___ *td=
3587           ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
3588         if (td->flag==it->tagid) {
3589           it->tagobjindex=tagindex; /* Found right type of tag */
3590           return 1;
3591         }
3592       }
3593       return 0;
3594     }
3595   } else if (it->numtags>0) {
3596     /* Use tags to locate appropriate objects */
3597     struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3598     struct ___Object___ *objptr=tag->flagptr;
3599     int i;
3600     if (objptr->type!=OBJECTARRAYTYPE) {
3601       if (it->tagobjindex>0)
3602         return 0;
3603       if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3604         return 0;
3605       for(i=1; i<it->numtags; i++) {
3606         struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3607         if (!containstag(objptr,tag2))
3608           return 0;
3609       }
3610       return 1;
3611     } else {
3612       struct ArrayObject *ao=(struct ArrayObject *) objptr;
3613       int tagindex;
3614       int i;
3615       for(tagindex=it->tagobjindex; tagindex<ao->___cachedCode___; tagindex++) {
3616         struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
3617         if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3618           continue;
3619         for(i=1; i<it->numtags; i++) {
3620           struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3621           if (!containstag(objptr,tag2))
3622             goto nexttag;
3623         }
3624         it->tagobjindex=tagindex;
3625         return 1;
3626 nexttag:
3627         ;
3628       }
3629       it->tagobjindex=tagindex;
3630       return 0;
3631     }
3632   } else {
3633     return ObjhasNext(&it->it);
3634   }
3635 }
3636
3637 int containstag(struct ___Object___ *ptr,
3638                 struct ___TagDescriptor___ *tag) {
3639   int j;
3640   struct ___Object___ * objptr=tag->flagptr;
3641   if (objptr->type==OBJECTARRAYTYPE) {
3642     struct ArrayObject *ao=(struct ArrayObject *)objptr;
3643     for(j=0; j<ao->___cachedCode___; j++) {
3644       if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
3645         return 1;
3646       }
3647     }
3648     return 0;
3649   } else {
3650     return objptr==ptr;
3651   }
3652 }
3653
3654 void toiNext(struct tagobjectiterator *it,
3655              void ** objectarray OPTARG(int * failed)) {
3656   /* hasNext has all of the intelligence */
3657   if(it->istag) {
3658     /* Iterate tag */
3659     /* Get object with tags */
3660     struct ___Object___ *obj=objectarray[it->tagobjectslot];
3661     struct ___Object___ *tagptr=obj->___tags___;
3662     if (tagptr->type==TAGTYPE) {
3663       it->tagobjindex++;
3664       objectarray[it->slot]=tagptr;
3665     } else {
3666       struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3667       objectarray[it->slot]=
3668         ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
3669     }
3670   } else if (it->numtags>0) {
3671     /* Use tags to locate appropriate objects */
3672     struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3673     struct ___Object___ *objptr=tag->flagptr;
3674     if (objptr->type!=OBJECTARRAYTYPE) {
3675       it->tagobjindex++;
3676       objectarray[it->slot]=objptr;
3677     } else {
3678       struct ArrayObject *ao=(struct ArrayObject *) objptr;
3679       objectarray[it->slot]=
3680         ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
3681     }
3682   } else {
3683     /* Iterate object */
3684     objectarray[it->slot]=(void *)Objkey(&it->it);
3685     Objnext(&it->it);
3686   }
3687 }
3688
3689 #ifdef PROFILE
3690 inline void profileTaskStart(char * taskname) {
3691   if(!taskInfoOverflow) {
3692     TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
3693     taskInfoArray[taskInfoIndex] = taskInfo;
3694     taskInfo->taskName = taskname;
3695     taskInfo->startTime = BAMBOO_GET_EXE_TIME();
3696     taskInfo->endTime = -1;
3697     taskInfo->exitIndex = -1;
3698     taskInfo->newObjs = NULL;
3699   }
3700 }
3701
3702 inline void profileTaskEnd() {
3703   if(!taskInfoOverflow) {
3704     taskInfoArray[taskInfoIndex]->endTime = BAMBOO_GET_EXE_TIME();
3705     taskInfoIndex++;
3706     if(taskInfoIndex == TASKINFOLENGTH) {
3707       taskInfoOverflow = true;
3708       //taskInfoIndex = 0;
3709     }
3710   }
3711 }
3712
3713 // output the profiling data
3714 void outputProfileData() {
3715 #ifdef USEIO
3716   int i;
3717   unsigned long long totaltasktime = 0;
3718   unsigned long long preprocessingtime = 0;
3719   unsigned long long objqueuecheckingtime = 0;
3720   unsigned long long postprocessingtime = 0;
3721   //int interruptiontime = 0;
3722   unsigned long long other = 0;
3723   unsigned long long averagetasktime = 0;
3724   int tasknum = 0;
3725
3726   printf("Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
3727   // output task related info
3728   for(i = 0; i < taskInfoIndex; i++) {
3729     TaskInfo* tmpTInfo = taskInfoArray[i];
3730     unsigned long long duration = tmpTInfo->endTime - tmpTInfo->startTime;
3731     printf("%s, %lld, %lld, %lld, %lld",
3732            tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime,
3733            duration, tmpTInfo->exitIndex);
3734     // summarize new obj info
3735     if(tmpTInfo->newObjs != NULL) {
3736       struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
3737       struct RuntimeIterator * iter = NULL;
3738       while(0 == isEmpty(tmpTInfo->newObjs)) {
3739         char * objtype = (char *)(getItem(tmpTInfo->newObjs));
3740         if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
3741           int num = 0;
3742           RuntimeHashget(nobjtbl, (int)objtype, &num);
3743           RuntimeHashremovekey(nobjtbl, (int)objtype);
3744           num++;
3745           RuntimeHashadd(nobjtbl, (int)objtype, num);
3746         } else {
3747           RuntimeHashadd(nobjtbl, (int)objtype, 1);
3748         }
3749         //printf(stderr, "new obj!\n");
3750       }
3751
3752       // output all new obj info
3753       iter = RuntimeHashcreateiterator(nobjtbl);
3754       while(RunhasNext(iter)) {
3755         char * objtype = (char *)Runkey(iter);
3756         int num = Runnext(iter);
3757         printf(", %s, %d", objtype, num);
3758       }
3759     }
3760     printf("\n");
3761     if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
3762       preprocessingtime += duration;
3763     } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
3764       postprocessingtime += duration;
3765     } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
3766       objqueuecheckingtime += duration;
3767     } else {
3768       totaltasktime += duration;
3769       averagetasktime += duration;
3770       tasknum++;
3771     }
3772   }
3773
3774   if(taskInfoOverflow) {
3775     printf("Caution: task info overflow!\n");
3776   }
3777
3778   other = totalexetime-totaltasktime-preprocessingtime-postprocessingtime;
3779   averagetasktime /= tasknum;
3780
3781   printf("\nTotal time: %lld\n", totalexetime);
3782   printf("Total task execution time: %lld (%d%%)\n", totaltasktime,
3783          (int)(((double)totaltasktime/(double)totalexetime)*100));
3784   printf("Total objqueue checking time: %lld (%d%%)\n",
3785          objqueuecheckingtime,
3786          (int)(((double)objqueuecheckingtime/(double)totalexetime)*100));
3787   printf("Total pre-processing time: %lld (%d%%)\n", preprocessingtime,
3788          (int)(((double)preprocessingtime/(double)totalexetime)*100));
3789   printf("Total post-processing time: %lld (%d%%)\n", postprocessingtime,
3790          (int)(((double)postprocessingtime/(double)totalexetime)*100));
3791   printf("Other time: %lld (%d%%)\n", other,
3792          (int)(((double)other/(double)totalexetime)*100));
3793
3794
3795   printf("\nAverage task execution time: %lld\n", averagetasktime);
3796
3797   //printf("\nTotal time spent for interruptions: %lld\n", interrupttime);
3798 #else
3799   int i = 0;
3800   int j = 0;
3801
3802   BAMBOO_DEBUGPRINT(0xdddd);
3803   // output task related info
3804   for(i= 0; i < taskInfoIndex; i++) {
3805     TaskInfo* tmpTInfo = taskInfoArray[i];
3806     char* tmpName = tmpTInfo->taskName;
3807     int nameLen = strlen(tmpName);
3808     BAMBOO_DEBUGPRINT(0xddda);
3809     for(j = 0; j < nameLen; j++) {
3810       BAMBOO_DEBUGPRINT_REG(tmpName[j]);
3811     }
3812     BAMBOO_DEBUGPRINT(0xdddb);
3813     BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
3814     BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
3815     BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
3816     if(tmpTInfo->newObjs != NULL) {
3817       struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
3818       struct RuntimeIterator * iter = NULL;
3819       while(0 == isEmpty(tmpTInfo->newObjs)) {
3820         char * objtype = (char *)(getItem(tmpTInfo->newObjs));
3821         if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
3822           int num = 0;
3823           RuntimeHashget(nobjtbl, (int)objtype, &num);
3824           RuntimeHashremovekey(nobjtbl, (int)objtype);
3825           num++;
3826           RuntimeHashadd(nobjtbl, (int)objtype, num);
3827         } else {
3828           RuntimeHashadd(nobjtbl, (int)objtype, 1);
3829         }
3830       }
3831
3832       // ouput all new obj info
3833       iter = RuntimeHashcreateiterator(nobjtbl);
3834       while(RunhasNext(iter)) {
3835         char * objtype = (char *)Runkey(iter);
3836         int num = Runnext(iter);
3837         int nameLen = strlen(objtype);
3838         BAMBOO_DEBUGPRINT(0xddda);
3839         for(j = 0; j < nameLen; j++) {
3840           BAMBOO_DEBUGPRINT_REG(objtype[j]);
3841         }
3842         BAMBOO_DEBUGPRINT(0xdddb);
3843         BAMBOO_DEBUGPRINT_REG(num);
3844       }
3845     }
3846     BAMBOO_DEBUGPRINT(0xdddc);
3847   }
3848
3849   if(taskInfoOverflow) {
3850     BAMBOO_DEBUGPRINT(0xefee);
3851   }
3852
3853   // output interrupt related info
3854   for(i = 0; i < interruptInfoIndex; i++) {
3855     InterruptInfo* tmpIInfo = interruptInfoArray[i];
3856     BAMBOO_DEBUGPRINT(0xddde);
3857     BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
3858     BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
3859     BAMBOO_DEBUGPRINT(0xdddf);
3860   }
3861
3862   if(interruptInfoOverflow) {
3863     BAMBOO_DEBUGPRINT(0xefef);
3864   }
3865
3866   BAMBOO_DEBUGPRINT(0xeeee);
3867 #endif
3868 }
3869 #endif  // #ifdef PROFILE
3870
3871 #endif