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