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