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