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