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