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