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