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