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