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