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