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