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