updates for multicore runtime to support Tilera
[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                                                           }
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                                                   }
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                                           }
456                                           BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
457 #ifdef DEBUG
458                                           BAMBOO_DEBUGPRINT(0xf000);
459 #endif
460                                   }
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                                   }
499                           }
500                   }
501           }
502   } // right-bracket for if-else of line 220
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           BAMBOO_DEBUGPRINT(0xe880);
1324 #endif
1325       if(corenum > NUMCORES - 1) {
1326                   BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1327                   BAMBOO_EXIT(0xa005);
1328       } /*else if((corenum == STARTUPCORE) && waitconfirm) {
1329                   waitconfirm = false;
1330                   numconfirm = 0;
1331           }*/
1332       // store the object and its corresponding queue info, enqueue it later
1333       transObj->objptr = (void *)msgdata[2];                                           // data1 is now size of the msg
1334       transObj->length = (msglength - 3) / 2;
1335       transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
1336       for(k = 0; k < transObj->length; ++k) {
1337                   transObj->queues[2*k] = msgdata[3+2*k];
1338 #ifdef DEBUG
1339                   BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
1340 #endif
1341                   transObj->queues[2*k+1] = msgdata[3+2*k+1];
1342 #ifdef DEBUG
1343                   BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
1344 #endif
1345       }
1346       // check if there is an existing duplicate item
1347       {
1348                   struct QueueItem * qitem = getTail(&objqueue);
1349                   struct QueueItem * prev = NULL;
1350                   while(qitem != NULL) {
1351                           struct transObjInfo * tmpinfo = (struct transObjInfo *)(qitem->objectptr);
1352                           if(tmpinfo->objptr == transObj->objptr) {
1353                                   // the same object, remove outdate one
1354                                   removeItem(&objqueue, qitem);
1355                           } else {
1356                                   prev = qitem;
1357                           }
1358                           if(prev == NULL) {
1359                                   qitem = getTail(&objqueue);
1360                           } else {
1361                                   qitem = getNextQueueItem(prev);
1362                           }
1363                   }
1364                   addNewItem_I(&objqueue, (void *)transObj);
1365           }
1366       ++(self_numreceiveobjs);
1367       break;
1368     }
1369
1370     case 1: {
1371       // receive a stall msg
1372       if(corenum != STARTUPCORE) {
1373                   // non startup core can not receive stall msg
1374                   // return -1
1375                   BAMBOO_DEBUGPRINT_REG(data1);
1376                   BAMBOO_EXIT(0xa006);
1377       } /*else if(waitconfirm) {
1378                   waitconfirm = false;
1379                   numconfirm = 0;
1380           }*/
1381       if(data1 < NUMCORES) {
1382 #ifdef DEBUG
1383                   BAMBOO_DEBUGPRINT(0xe881);
1384 #endif
1385                   corestatus[data1] = 0;
1386                   numsendobjs[data1] = msgdata[2];
1387                   numreceiveobjs[data1] = msgdata[3];
1388       }
1389       break;
1390     }
1391
1392     case 2: {
1393       // receive lock request msg, handle it right now
1394       // check to see if there is a lock exist in locktbl for the required obj
1395           // data1 -> lock type
1396           int data2 = msgdata[2]; // obj pointer
1397       int data3 = msgdata[3]; // lock
1398           int data4 = msgdata[4]; // request core
1399       deny = processlockrequest(data1, data3, data2, data4, data4, true);  // -1: redirected, 0: approved, 1: denied
1400           if(deny == -1) {
1401                   // this lock request is redirected
1402                   break;
1403           } else {
1404                   // send response msg
1405                   // for 32 bit machine, the size is always 4 words
1406                   int tmp = deny==1?4:3;
1407                   if(isMsgSending) {
1408                           cache_msg_4(data4, tmp, data1, data2, data3);
1409                   } else {
1410                           send_msg_4(data4, tmp, data1, data2, data3);
1411                   }
1412           }
1413       break;
1414     }
1415
1416     case 3: {
1417       // receive lock grount msg
1418       if(corenum > NUMCORES - 1) {
1419                   BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1420                   BAMBOO_EXIT(0xa007);
1421       } /*else if((corenum == STARTUPCORE) && waitconfirm) {
1422                   waitconfirm = false;
1423                   numconfirm = 0;
1424           }*/
1425       if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1426 #ifdef DEBUG
1427                   BAMBOO_DEBUGPRINT(0xe882);
1428 #endif
1429                   lockresult = 1;
1430                   lockflag = true;
1431 #ifndef INTERRUPT
1432                   reside = false;
1433 #endif
1434           } else {
1435                   // conflicts on lockresults
1436                   BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1437                   BAMBOO_EXIT(0xa008);
1438       }
1439       break;
1440     }
1441
1442     case 4: {
1443       // receive lock grount/deny msg
1444       if(corenum > NUMCORES - 1) {
1445                   BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1446                   BAMBOO_EXIT(0xa009);
1447       } /*else if((corenum == STARTUPCORE) && waitconfirm) {
1448                   waitconfirm = false;
1449                   numconfirm = 0;
1450           }*/
1451       if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1452 #ifdef DEBUG
1453                   BAMBOO_DEBUGPRINT(0xe883);
1454 #endif
1455                   lockresult = 0;
1456                   lockflag = true;
1457 #ifndef INTERRUPT
1458                   reside = false;
1459 #endif
1460       } else {
1461                   // conflicts on lockresults
1462                   BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1463                   BAMBOO_EXIT(0xa00a);
1464       }
1465       break;
1466     }
1467
1468     case 5: {
1469       // receive lock release msg
1470           /*if((corenum == STARTUPCORE) && waitconfirm) {
1471                   waitconfirm = false;
1472                   numconfirm = 0;
1473           }*/
1474       if(!RuntimeHashcontainskey(locktbl, msgdata[3])) {
1475                   // no locks for this object, something is wrong
1476                   BAMBOO_DEBUGPRINT_REG(msgdata[3]);
1477                   BAMBOO_EXIT(0xa00b);
1478       } else {
1479                   int rwlock_obj = 0;
1480                   struct LockValue * lockvalue = NULL;
1481                   RuntimeHashget(locktbl, msgdata[3], &rwlock_obj);
1482                   lockvalue = (struct LockValue*)(rwlock_obj);
1483 #ifdef DEBUG
1484                   BAMBOO_DEBUGPRINT(0xe884);
1485                   BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1486 #endif
1487                   if(data1 == 0) {
1488                           lockvalue->value--;
1489                   } else {
1490                           lockvalue->value++;
1491                   }
1492 #ifdef DEBUG
1493                   BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1494 #endif
1495       }
1496       break;
1497     }
1498
1499 #ifdef PROFILE
1500     case 6: {
1501       // receive an output profile data request msg
1502       if(corenum == STARTUPCORE) {
1503                   // startup core can not receive profile output finish msg
1504                   BAMBOO_EXIT(0xa00c);
1505       }
1506 #ifdef DEBUG
1507           BAMBOO_DEBUGPRINT(0xe885);
1508 #endif
1509           stall = true;
1510           totalexetime = data1;
1511           outputProfileData();
1512           if(isMsgSending) {
1513                   cache_msg_2(STARTUPCORE, 7, corenum);
1514           } else {
1515                   send_msg_2(STARTUPCORE, 7, corenum);
1516           }
1517       break;
1518     }
1519
1520     case 7: {
1521       // receive a profile output finish msg
1522       if(corenum != STARTUPCORE) {
1523                   // non startup core can not receive profile output finish msg
1524                   BAMBOO_DEBUGPRINT_REG(data1);
1525                   BAMBOO_EXIT(0xa00d);
1526       }
1527 #ifdef DEBUG
1528           BAMBOO_DEBUGPRINT(0xe886);
1529 #endif
1530       profilestatus[data1] = 0;
1531       break;
1532     }
1533 #endif
1534
1535         case 8: {
1536           // receive a redirect lock request msg, handle it right now
1537       // check to see if there is a lock exist in locktbl for the required obj
1538           // data1 -> lock type
1539           int data2 = msgdata[2]; // obj pointer
1540       int data3 = msgdata[3]; // redirect lock
1541           int data4 = msgdata[4]; // root request core
1542           int data5 = msgdata[5]; // request core
1543           deny = processlockrequest(data1, data3, data2, data5, data4, true);
1544           if(deny == -1) {
1545                   // this lock request is redirected
1546                   break;
1547           } else {
1548                   // send response msg
1549                   // for 32 bit machine, the size is always 4 words
1550                   if(isMsgSending) {
1551                           cache_msg_4(data4, deny==1?0xa:9, data1, data2, data3);
1552                   } else {
1553                           send_msg_4(data4, deny==1?0xa:9, data1, data2, data3);
1554                   }
1555           }
1556           break;
1557         }
1558
1559         case 9: {
1560                 // receive a lock grant msg with redirect info
1561                 if(corenum > NUMCORES - 1) {
1562                         BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1563                         BAMBOO_EXIT(0xa00e);
1564                 }/* else if((corenum == STARTUPCORE) && waitconfirm) {
1565                   waitconfirm = false;
1566                   numconfirm = 0;
1567           }*/
1568       if(lockobj == msgdata[2]) {
1569 #ifdef DEBUG
1570                   BAMBOO_DEBUGPRINT(0xe891);
1571 #endif
1572                   lockresult = 1;
1573                   lockflag = true;
1574                   RuntimeHashadd_I(objRedirectLockTbl, lockobj, msgdata[3]);
1575 #ifndef INTERRUPT
1576                   reside = false;
1577 #endif
1578       } else {
1579                   // conflicts on lockresults
1580                   BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1581                   BAMBOO_EXIT(0xa00f);
1582       }
1583                 break;
1584         }
1585         
1586         case 0xa: {
1587           // receive a lock deny msg with redirect info
1588           if(corenum > NUMCORES - 1) {
1589                   BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1590                   BAMBOO_EXIT(0xa010);
1591           }/* else if((corenum == STARTUPCORE) && waitconfirm) {
1592                   waitconfirm = false;
1593                   numconfirm = 0;
1594           }*/
1595       if(lockobj == msgdata[2]) {
1596 #ifdef DEBUG
1597                   BAMBOO_DEBUGPRINT(0xe892);
1598 #endif
1599                   lockresult = 0;
1600                   lockflag = true;
1601                   //RuntimeHashadd_I(objRedirectLockTbl, lockobj, msgdata[3]);
1602 #ifndef INTERRUPT
1603                   reside = false;
1604 #endif
1605       } else {
1606                   // conflicts on lockresults
1607                   BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1608                   BAMBOO_EXIT(0xa011);
1609       }
1610                 break;
1611         }
1612
1613         case 0xb: {
1614           // receive a lock release msg with redirect info
1615           /*if((corenum == STARTUPCORE) && waitconfirm) {
1616                   waitconfirm = false;
1617                   numconfirm = 0;
1618           }*/
1619           if(!RuntimeHashcontainskey(locktbl, msgdata[2])) {
1620                   // no locks for this object, something is wrong
1621                   BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1622                   BAMBOO_EXIT(0xa012);
1623       } else {
1624                   int rwlock_obj = 0;
1625                   struct LockValue * lockvalue = NULL;
1626                   RuntimeHashget(locktbl, msgdata[2], &rwlock_obj);
1627                   lockvalue = (struct LockValue*)(rwlock_obj);
1628 #ifdef DEBUG
1629                   BAMBOO_DEBUGPRINT(0xe893);
1630                   BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1631 #endif
1632                   if(data1 == 0) {
1633                           lockvalue->value--;
1634                   } else {
1635                           lockvalue->value++;
1636                   }
1637 #ifdef DEBUG
1638                   BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1639 #endif
1640                   lockvalue->redirectlock = msgdata[3];
1641           }
1642           break;
1643         }
1644         
1645         case 0xc: {
1646       // receive a status confirm info
1647           if((corenum == STARTUPCORE) || (corenum > NUMCORES - 1)) {
1648                   // wrong core to receive such msg
1649                   BAMBOO_EXIT(0xa013);
1650       } else {
1651                   // send response msg
1652 #ifdef DEBUG
1653                   BAMBOO_DEBUGPRINT(0xe887);
1654 #endif
1655                   if(isMsgSending) {
1656                           cache_msg_3(STARTUPCORE, 0xd, busystatus?1:0, corenum);
1657                   } else {
1658                           send_msg_3(STARTUPCORE, 0xd, busystatus?1:0, corenum);
1659                   }
1660       }
1661           break;
1662         }
1663
1664         case 0xd: {
1665           // receive a status confirm info
1666           if(corenum != STARTUPCORE) {
1667                   // wrong core to receive such msg
1668                   BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1669                   BAMBOO_EXIT(0xa014);
1670       } else {
1671 #ifdef DEBUG
1672                   BAMBOO_DEBUGPRINT(0xe888);
1673 #endif
1674                   if(waitconfirm) {
1675                           numconfirm--;
1676                   }
1677                   corestatus[msgdata[2]] = msgdata[1];
1678       }
1679           break;
1680         }
1681
1682         case 0xe: {
1683           // receive a terminate msg
1684 #ifdef DEBUG
1685                                   BAMBOO_DEBUGPRINT(0xe889);
1686 #endif
1687                                   BAMBOO_EXIT(0);
1688           break;
1689         }
1690         
1691     default:
1692       break;
1693     }
1694     for(msgdataindex--; msgdataindex > 0; --msgdataindex) {
1695       msgdata[msgdataindex] = -1;
1696     }
1697     msgtype = -1;
1698     msglength = 30;
1699 #ifdef DEBUG
1700     BAMBOO_DEBUGPRINT(0xe88a);
1701 #endif
1702
1703     if(BAMBOO_MSG_AVAIL() != 0) {
1704       goto msg;
1705     }
1706 #ifdef PROFILE
1707         /*if(isInterrupt) {
1708             profileTaskEnd();
1709     }*/
1710 #endif
1711     return type;
1712   } else {
1713     // not a whole msg
1714 #ifdef DEBUG
1715     BAMBOO_DEBUGPRINT(0xe88b);
1716 #endif
1717 #ifdef PROFILE
1718 /*    if(isInterrupt) {
1719           profileTaskEnd();
1720       }*/
1721 #endif
1722     return -2;
1723   }
1724 }
1725
1726 /* this function is to process lock requests. 
1727  * can only be invoked in receiveObject() */
1728 // if return -1: the lock request is redirected
1729 //            0: the lock request is approved
1730 //            1: the lock request is denied
1731 int processlockrequest(int locktype, int lock, int obj, int requestcore, int rootrequestcore, bool cache) {
1732   int deny = 0;
1733   if( ((lock >> 5) % BAMBOO_TOTALCORE) != corenum ) {
1734           // the lock should not be on this core
1735           BAMBOO_DEBUGPRINT_REG(requestcore);
1736           BAMBOO_EXIT(0xa015);
1737   }
1738   /*if((corenum == STARTUPCORE) && waitconfirm) {
1739           waitconfirm = false;
1740           numconfirm = 0;
1741   }*/
1742   if(!RuntimeHashcontainskey(locktbl, lock)) {
1743           // no locks for this object
1744           // first time to operate on this shared object
1745           // create a lock for it
1746           // the lock is an integer: 0 -- stall, >0 -- read lock, -1 -- write lock
1747           struct LockValue * lockvalue = (struct LockValue *)(RUNMALLOC_I(sizeof(struct LockValue)));
1748           lockvalue->redirectlock = 0;
1749 #ifdef DEBUG
1750           BAMBOO_DEBUGPRINT(0xe110);
1751 #endif
1752           if(locktype == 0) {
1753                   lockvalue->value = 1;
1754           } else {
1755                   lockvalue->value = -1;
1756           }
1757           RuntimeHashadd_I(locktbl, lock, (int)lockvalue);
1758   } else {
1759           int rwlock_obj = 0;
1760           struct LockValue * lockvalue = NULL;
1761 #ifdef DEBUG
1762           BAMBOO_DEBUGPRINT(0xe111);
1763 #endif
1764           RuntimeHashget(locktbl, lock, &rwlock_obj);
1765           lockvalue = (struct LockValue *)(rwlock_obj);
1766 #ifdef DEBUG
1767           BAMBOO_DEBUGPRINT_REG(lockvalue->redirectlock);
1768 #endif
1769           if(lockvalue->redirectlock != 0) {
1770                   // this lock is redirected
1771 #ifdef DEBUG
1772                   BAMBOO_DEBUGPRINT(0xe112);
1773 #endif
1774                   if(locktype == 0) {
1775                           getreadlock_I_r((void *)obj, (void *)lockvalue->redirectlock, rootrequestcore, cache);
1776                   } else {
1777                           getwritelock_I_r((void *)obj, (void *)lockvalue->redirectlock, rootrequestcore, cache);
1778                   }
1779                   return -1;  // redirected
1780           } else {
1781 #ifdef DEBUG
1782                   BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1783 #endif
1784                   if(0 == lockvalue->value) {
1785                           if(locktype == 0) {
1786                                   lockvalue->value = 1;
1787                           } else {
1788                                   lockvalue->value = -1;
1789                           }
1790                   } else if((lockvalue->value > 0) && (locktype == 0)) {
1791                           // read lock request and there are only read locks
1792                           lockvalue->value++;
1793                   } else {
1794                           deny = 1;
1795                   }
1796 #ifdef DEBUG
1797                   BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1798 #endif
1799           }
1800   }
1801   return deny;
1802 }
1803
1804 bool getreadlock(void * ptr) {
1805   int targetcore = 0;
1806   lockobj = (int)ptr;
1807   if(((struct ___Object___ *)ptr)->lock == NULL) {
1808         lock2require = lockobj;
1809   } else {
1810         lock2require = (int)(((struct ___Object___ *)ptr)->lock);
1811   }
1812   targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
1813   lockflag = false;
1814 #ifndef INTERRUPT
1815   reside = false;
1816 #endif
1817   lockresult = 0;
1818
1819   if(targetcore == corenum) {
1820     // reside on this core
1821     int deny = 0;
1822         BAMBOO_START_CRITICAL_SECTION_LOCK();
1823 #ifdef DEBUG
1824         BAMBOO_DEBUGPRINT(0xf001);
1825 #endif
1826         deny = processlockrequest(0, lock2require, (int)ptr, corenum, corenum, false);
1827         BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
1828 #ifdef DEBUG
1829         BAMBOO_DEBUGPRINT(0xf000);
1830 #endif
1831     if(deny == -1) {
1832                 // redirected
1833                 return true;
1834         } else {
1835                 if(lockobj == (int)ptr) {
1836                         if(deny) {
1837                                 lockresult = 0;
1838                         } else {
1839                                 lockresult = 1;
1840                         }
1841                         lockflag = true;
1842 #ifndef INTERRUPT
1843                         reside = true;
1844 #endif
1845                 } else {
1846                         // conflicts on lockresults
1847                         BAMBOO_EXIT(0xa016);
1848                 }
1849         }
1850     return true;
1851   } else {
1852           // send lock request msg
1853           // for 32 bit machine, the size is always 5 words
1854           send_msg_5(targetcore, 2, 0, (int)ptr, lock2require, corenum);
1855   }
1856   return true;
1857 }
1858
1859 void releasereadlock(void * ptr) {
1860   int targetcore = 0;
1861   int reallock = 0;
1862   if(((struct ___Object___ *)ptr)->lock == NULL) {
1863         reallock = (int)ptr;
1864   } else {
1865         reallock = (int)(((struct ___Object___ *)ptr)->lock);
1866   }
1867   targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
1868
1869   if(targetcore == corenum) {
1870         BAMBOO_START_CRITICAL_SECTION_LOCK();
1871 #ifdef DEBUG
1872         BAMBOO_DEBUGPRINT(0xf001);
1873 #endif
1874     // reside on this core
1875     if(!RuntimeHashcontainskey(locktbl, reallock)) {
1876       // no locks for this object, something is wrong
1877       BAMBOO_EXIT(0xa017);
1878     } else {
1879       int rwlock_obj = 0;
1880           struct LockValue * lockvalue = NULL;
1881       RuntimeHashget(locktbl, reallock, &rwlock_obj);
1882           lockvalue = (struct LockValue *)rwlock_obj;
1883       lockvalue->value--;
1884     }
1885         BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
1886 #ifdef DEBUG
1887         BAMBOO_DEBUGPRINT(0xf000);
1888 #endif
1889     return;
1890   } else {
1891         // send lock release msg
1892         // for 32 bit machine, the size is always 4 words
1893         send_msg_4(targetcore, 5, 0, (int)ptr, reallock);
1894   }
1895 }
1896
1897 // redirected lock request
1898 bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
1899   int targetcore = 0;
1900   
1901   if(core == corenum) {
1902           lockobj = (int)ptr;
1903           lock2require = (int)redirectlock;
1904           lockflag = false;
1905 #ifndef INTERRUPT
1906           reside = false;
1907 #endif
1908           lockresult = 0;
1909   }  
1910   targetcore = ((int)redirectlock >> 5) % BAMBOO_TOTALCORE;
1911   
1912   if(targetcore == corenum) {
1913     // reside on this core
1914     int deny = processlockrequest(0, (int)redirectlock, (int)ptr, corenum, core, cache);
1915         if(deny == -1) {
1916                 // redirected
1917                 return true;
1918         } else {
1919                 if(core == corenum) {
1920                         if(lockobj == (int)ptr) {
1921                                 if(deny) {
1922                                         lockresult = 0;
1923                                 } else {
1924                                         lockresult = 1;
1925                                         RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
1926                                 }
1927                                 lockflag = true;
1928 #ifndef INTERRUPT
1929                                 reside = true;
1930 #endif
1931                         } else {
1932                                 // conflicts on lockresults
1933                                 BAMBOO_EXIT(0xa018);
1934                         }
1935                         return true;
1936                 } else {
1937                         // send lock grant/deny request to the root requiring core
1938                         // check if there is still some msg on sending
1939                         if((!cache) || (cache && !isMsgSending)) {
1940                                 send_msg_4(core, deny==1?0xa:9, 0, (int)ptr, (int)redirectlock);
1941                         } else {
1942                                 cache_msg_4(core, deny==1?0xa:9, 0, (int)ptr, (int)redirectlock);
1943                         }
1944                 }
1945         }
1946   } else {
1947         // redirect the lock request
1948         // for 32 bit machine, the size is always 6 words
1949         if((!cache) || (cache && !isMsgSending)) {
1950                 send_msg_6(targetcore, 8, 0, (int)ptr, lock2require, core, corenum);
1951         } else {
1952                 cache_msg_6(targetcore, 8, 0, (int)ptr, lock2require, core, corenum);
1953         }
1954   }
1955   return true;
1956 }
1957
1958 // not reentrant
1959 bool getwritelock(void * ptr) {
1960   int targetcore = 0;
1961
1962   // for 32 bit machine, the size is always 5 words
1963   //int msgsize = 5;
1964
1965   lockobj = (int)ptr;
1966   if(((struct ___Object___ *)ptr)->lock == NULL) {
1967         lock2require = lockobj;
1968   } else {
1969         lock2require = (int)(((struct ___Object___ *)ptr)->lock);
1970   }
1971   targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
1972   lockflag = false;
1973 #ifndef INTERRUPT
1974   reside = false;
1975 #endif
1976   lockresult = 0;
1977
1978 #ifdef DEBUG
1979   BAMBOO_DEBUGPRINT(0xe551);
1980   BAMBOO_DEBUGPRINT_REG(lockobj);
1981   BAMBOO_DEBUGPRINT_REG(lock2require);
1982   BAMBOO_DEBUGPRINT_REG(targetcore);
1983 #endif
1984
1985   if(targetcore == corenum) {
1986     // reside on this core
1987     int deny = 0;
1988         BAMBOO_START_CRITICAL_SECTION_LOCK();
1989 #ifdef DEBUG
1990         BAMBOO_DEBUGPRINT(0xf001);
1991 #endif
1992         deny = processlockrequest(1, lock2require, (int)ptr, corenum, corenum, false);
1993         BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
1994 #ifdef DEBUG
1995         BAMBOO_DEBUGPRINT(0xf000);
1996 #endif
1997 #ifdef DEBUG
1998     BAMBOO_DEBUGPRINT(0xe555);
1999     BAMBOO_DEBUGPRINT_REG(lockresult);
2000 #endif
2001     if(deny == -1) {
2002                 // redirected
2003                 return true;
2004         } else {
2005                 if(lockobj == (int)ptr) {
2006                         if(deny) {
2007                                 lockresult = 0;
2008                         } else {
2009                                 lockresult = 1;
2010                         }
2011                         lockflag = true;
2012 #ifndef INTERRUPT
2013                         reside = true;
2014 #endif
2015                 } else {
2016                         // conflicts on lockresults
2017                         BAMBOO_EXIT(0xa019);
2018                 }
2019         }
2020     return true;
2021   } else {
2022           // send lock request msg
2023           // for 32 bit machine, the size is always 5 words
2024           send_msg_5(targetcore, 2, 1, (int)ptr, lock2require, corenum);
2025   }
2026   return true;
2027 }
2028
2029 void releasewritelock(void * ptr) {
2030   int targetcore = 0;
2031   int reallock = 0;
2032   if(((struct ___Object___ *)ptr)->lock == NULL) {
2033         reallock = (int)ptr;
2034   } else {
2035         reallock = (int)(((struct ___Object___ *)ptr)->lock);
2036   }
2037   targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2038
2039 #ifdef DEBUG
2040   BAMBOO_DEBUGPRINT(0xe661);
2041   BAMBOO_DEBUGPRINT_REG((int)ptr);
2042   BAMBOO_DEBUGPRINT_REG(reallock);
2043   BAMBOO_DEBUGPRINT_REG(targetcore);
2044 #endif
2045
2046   if(targetcore == corenum) {
2047         BAMBOO_START_CRITICAL_SECTION_LOCK();
2048 #ifdef DEBUG
2049         BAMBOO_DEBUGPRINT(0xf001);
2050 #endif
2051     // reside on this core
2052     if(!RuntimeHashcontainskey(locktbl, reallock)) {
2053       // no locks for this object, something is wrong
2054       BAMBOO_EXIT(0xa01a);
2055     } else {
2056       int rwlock_obj = 0;
2057           struct LockValue * lockvalue = NULL;
2058       RuntimeHashget(locktbl, reallock, &rwlock_obj);
2059           lockvalue = (struct LockValue *)rwlock_obj;
2060       lockvalue->value++;
2061     }
2062         BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
2063 #ifdef DEBUG
2064         BAMBOO_DEBUGPRINT(0xf000);
2065 #endif
2066     return;
2067   } else {
2068         // send lock release msg
2069         // for 32 bit machine, the size is always 4 words
2070         send_msg_4(targetcore, 5, 1, (int)ptr, reallock);
2071   }
2072 }
2073
2074 void releasewritelock_r(void * lock, void * redirectlock) {
2075   int targetcore = 0;
2076   int reallock = (int)lock;
2077   targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2078
2079 #ifdef DEBUG
2080   BAMBOO_DEBUGPRINT(0xe671);
2081   BAMBOO_DEBUGPRINT_REG((int)lock);
2082   BAMBOO_DEBUGPRINT_REG(reallock);
2083   BAMBOO_DEBUGPRINT_REG(targetcore);
2084 #endif
2085
2086   if(targetcore == corenum) {
2087         BAMBOO_START_CRITICAL_SECTION_LOCK();
2088 #ifdef DEBUG
2089         BAMBOO_DEBUGPRINT(0xf001);
2090 #endif
2091     // reside on this core
2092     if(!RuntimeHashcontainskey(locktbl, reallock)) {
2093       // no locks for this object, something is wrong
2094       BAMBOO_EXIT(0xa01b);
2095     } else {
2096       int rwlock_obj = 0;
2097           struct LockValue * lockvalue = NULL;
2098 #ifdef DEBUG
2099       BAMBOO_DEBUGPRINT(0xe672);
2100 #endif
2101       RuntimeHashget(locktbl, reallock, &rwlock_obj);
2102           lockvalue = (struct LockValue *)rwlock_obj;
2103 #ifdef DEBUG
2104       BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2105 #endif
2106       lockvalue->value++;
2107           lockvalue->redirectlock = (int)redirectlock;
2108 #ifdef DEBUG
2109       BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2110 #endif
2111     }
2112         BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
2113 #ifdef DEBUG
2114         BAMBOO_DEBUGPRINT(0xf000);
2115 #endif
2116     return;
2117   } else {
2118           // send lock release with redirect info msg
2119           // for 32 bit machine, the size is always 4 words
2120           send_msg_4(targetcore, 0xb, 1, (int)lock, (int)redirectlock);
2121   }
2122 }
2123
2124 bool getwritelock_I(void * ptr) {
2125   int targetcore = 0;
2126   lockobj = (int)ptr;
2127   if(((struct ___Object___ *)ptr)->lock == NULL) {
2128         lock2require = lockobj;
2129   } else {
2130         lock2require = (int)(((struct ___Object___ *)ptr)->lock);
2131   }
2132   targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
2133   lockflag = false;
2134 #ifndef INTERRUPT
2135   reside = false;
2136 #endif
2137   lockresult = 0;
2138
2139 #ifdef DEBUG
2140   BAMBOO_DEBUGPRINT(0xe561);
2141   BAMBOO_DEBUGPRINT_REG(lockobj);
2142   BAMBOO_DEBUGPRINT_REG(lock2require);
2143   BAMBOO_DEBUGPRINT_REG(targetcore);
2144 #endif
2145
2146   if(targetcore == corenum) {
2147     // reside on this core
2148         int deny = processlockrequest(1, (int)lock2require, (int)ptr, corenum, corenum, false);
2149         if(deny == -1) {
2150                 // redirected
2151                 return true;
2152         } else {
2153                 if(lockobj == (int)ptr) {
2154                         if(deny) {
2155                                 lockresult = 0;
2156 #ifdef DEBUG
2157                                 BAMBOO_DEBUGPRINT(0);
2158 #endif
2159                         } else {
2160                                 lockresult = 1;
2161 #ifdef DEBUG
2162                                 BAMBOO_DEBUGPRINT(1);
2163 #endif
2164                         }
2165                         lockflag = true;
2166 #ifndef INTERRUPT
2167                         reside = true;
2168 #endif
2169                 } else {
2170                         // conflicts on lockresults
2171                         BAMBOO_EXIT(0xa01c);
2172                 }
2173                 return true;
2174         }
2175   } else {
2176           // send lock request msg
2177           // for 32 bit machine, the size is always 5 words
2178           send_msg_5(targetcore, 2, 1, (int)ptr, lock2require, corenum);
2179   }
2180   return true;
2181 }
2182
2183 // redirected lock request
2184 bool getwritelock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
2185   int targetcore = 0;
2186
2187   if(core == corenum) {
2188           lockobj = (int)ptr;
2189           lock2require = (int)redirectlock;
2190           lockflag = false;
2191 #ifndef INTERRUPT
2192           reside = false;
2193 #endif
2194           lockresult = 0;
2195   }
2196   targetcore = ((int)redirectlock >> 5) % BAMBOO_TOTALCORE;
2197
2198 #ifdef DEBUG
2199   BAMBOO_DEBUGPRINT(0xe571);
2200   BAMBOO_DEBUGPRINT_REG((int)ptr);
2201   BAMBOO_DEBUGPRINT_REG((int)redirectlock);
2202   BAMBOO_DEBUGPRINT_REG(core);
2203   BAMBOO_DEBUGPRINT_REG((int)cache);
2204   BAMBOO_DEBUGPRINT_REG(targetcore);
2205 #endif
2206
2207
2208   if(targetcore == corenum) {
2209     // reside on this core
2210         int deny = processlockrequest(1, (int)redirectlock, (int)ptr, corenum, core, cache);
2211         if(deny == -1) {
2212                 // redirected
2213                 return true;
2214         } else {
2215                 if(core == corenum) {
2216                         if(lockobj == (int)ptr) {
2217                                 if(deny) {
2218                                         lockresult = 0;
2219                                 } else {
2220                                         lockresult = 1;
2221                                         RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
2222                                 }
2223                                 lockflag = true;
2224 #ifndef INTERRUPT
2225                                 reside = true;
2226 #endif
2227                         } else {
2228                                 // conflicts on lockresults
2229                                 BAMBOO_EXIT(0xa01d);
2230                         }
2231                         return true;
2232                 } else {
2233                         // send lock grant/deny request to the root requiring core
2234                         // check if there is still some msg on sending
2235                         if((!cache) || (cache && !isMsgSending)) {
2236                                 send_msg_4(core, deny==1?0xa:9, 1, (int)ptr, (int)redirectlock);
2237                         } else {
2238                                 cache_msg_4(core, deny==1?0xa:9, 1, (int)ptr, (int)redirectlock);
2239                         }
2240                 }
2241         }
2242   } else {
2243         // redirect the lock request
2244         // for 32 bit machine, the size is always 6 words
2245         if((!cache) || (cache && !isMsgSending)) {
2246                 send_msg_6(targetcore, 8, 1, (int)ptr, (int)redirectlock, core, corenum);
2247         } else {
2248                 cache_msg_6(targetcore, 8, 1, (int)ptr, (int)redirectlock, core, corenum);
2249         }
2250   }
2251   return true;
2252 }
2253
2254 void releasewritelock_I(void * ptr) {
2255   int targetcore = 0;
2256   int reallock = 0;
2257   if(((struct ___Object___ *)ptr)->lock == NULL) {
2258         reallock = (int)ptr;
2259   } else {
2260         reallock = (int)(((struct ___Object___ *)ptr)->lock);
2261   }
2262   targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2263
2264 #ifdef DEBUG
2265   BAMBOO_DEBUGPRINT(0xe681);
2266   BAMBOO_DEBUGPRINT_REG((int)ptr);
2267   BAMBOO_DEBUGPRINT_REG(reallock);
2268   BAMBOO_DEBUGPRINT_REG(targetcore);
2269 #endif
2270
2271   if(targetcore == corenum) {
2272     // reside on this core
2273     if(!RuntimeHashcontainskey(locktbl, reallock)) {
2274       // no locks for this object, something is wrong
2275       BAMBOO_EXIT(0xa01e);
2276     } else {
2277       int rwlock_obj = 0;
2278           struct LockValue * lockvalue = NULL;
2279       RuntimeHashget(locktbl, reallock, &rwlock_obj);
2280           lockvalue = (struct LockValue *)rwlock_obj;
2281       lockvalue->value++;
2282     }
2283     return;
2284   } else {
2285         // send lock release msg
2286         // for 32 bit machine, the size is always 4 words
2287         send_msg_4(targetcore, 5, 1, (int)ptr, reallock);
2288   }
2289 }
2290
2291 void releasewritelock_I_r(void * lock, void * redirectlock) {
2292   int targetcore = 0;
2293   int reallock = (int)lock;
2294   targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2295
2296 #ifdef DEBUG
2297   BAMBOO_DEBUGPRINT(0xe691);
2298   BAMBOO_DEBUGPRINT_REG((int)lock);
2299   BAMBOO_DEBUGPRINT_REG(reallock);
2300   BAMBOO_DEBUGPRINT_REG(targetcore);
2301 #endif
2302
2303   if(targetcore == corenum) {
2304     // reside on this core
2305     if(!RuntimeHashcontainskey(locktbl, reallock)) {
2306       // no locks for this object, something is wrong
2307       BAMBOO_EXIT(0xa01f);
2308     } else {
2309       int rwlock_obj = 0;
2310           struct LockValue * lockvalue = NULL;
2311 #ifdef DEBUG
2312       BAMBOO_DEBUGPRINT(0xe692);
2313 #endif
2314       RuntimeHashget(locktbl, reallock, &rwlock_obj);
2315           lockvalue = (struct LockValue *)rwlock_obj;
2316 #ifdef DEBUG
2317       BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2318 #endif
2319       lockvalue->value++;
2320           lockvalue->redirectlock = (int)redirectlock;
2321 #ifdef DEBUG
2322       BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2323 #endif
2324     }
2325     return;
2326   } else {
2327         // send lock release msg
2328         // for 32 bit machine, the size is always 4 words
2329         send_msg_4(targetcore, 0xb, 1, (int)lock, (int)redirectlock);
2330   }
2331 }
2332
2333 int enqueuetasks(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr, int * enterflags, int numenterflags) {
2334   void * taskpointerarray[MAXTASKPARAMS];
2335   int j;
2336   //int numparams=parameter->task->numParameters;
2337   int numiterators=parameter->task->numTotal-1;
2338   int retval=1;
2339   //int addnormal=1;
2340   //int adderror=1;
2341
2342   struct taskdescriptor * task=parameter->task;
2343
2344    //this add the object to parameterwrapper
2345    ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags, numenterflags, enterflags==NULL);
2346
2347   /* Add enqueued object to parameter vector */
2348   taskpointerarray[parameter->slot]=ptr;
2349
2350   /* Reset iterators */
2351   for(j=0; j<numiterators; j++) {
2352     toiReset(&parameter->iterators[j]);
2353   }
2354
2355   /* Find initial state */
2356   for(j=0; j<numiterators; j++) {
2357 backtrackinit:
2358     if(toiHasNext(&parameter->iterators[j], taskpointerarray OPTARG(failed)))
2359       toiNext(&parameter->iterators[j], taskpointerarray OPTARG(failed));
2360     else if (j>0) {
2361       /* Need to backtrack */
2362       toiReset(&parameter->iterators[j]);
2363       j--;
2364       goto backtrackinit;
2365     } else {
2366       /* Nothing to enqueue */
2367       return retval;
2368     }
2369   }
2370
2371   while(1) {
2372     /* Enqueue current state */
2373     //int launch = 0;
2374     struct taskparamdescriptor *tpd=RUNMALLOC(sizeof(struct taskparamdescriptor));
2375     tpd->task=task;
2376     tpd->numParameters=numiterators+1;
2377     tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
2378
2379     for(j=0; j<=numiterators; j++) {
2380       tpd->parameterArray[j]=taskpointerarray[j]; //store the actual parameters
2381     }
2382     /* Enqueue task */
2383     if ((/*!gencontains(failedtasks, tpd)&&*/ !gencontains(activetasks,tpd))) {
2384                 genputtable(activetasks, tpd, tpd);
2385     } else {
2386       RUNFREE(tpd->parameterArray);
2387       RUNFREE(tpd);
2388     }
2389
2390     /* This loop iterates to the next parameter combination */
2391     if (numiterators==0)
2392       return retval;
2393
2394     for(j=numiterators-1; j<numiterators; j++) {
2395 backtrackinc:
2396       if(toiHasNext(&parameter->iterators[j], taskpointerarray OPTARG(failed)))
2397         toiNext(&parameter->iterators[j], taskpointerarray OPTARG(failed));
2398       else if (j>0) {
2399         /* Need to backtrack */
2400         toiReset(&parameter->iterators[j]);
2401         j--;
2402         goto backtrackinc;
2403       } else {
2404         /* Nothing more to enqueue */
2405         return retval;
2406       }
2407     }
2408   }
2409   return retval;
2410 }
2411
2412 int enqueuetasks_I(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr, int * enterflags, int numenterflags) {
2413   void * taskpointerarray[MAXTASKPARAMS];
2414   int j;
2415   //int numparams=parameter->task->numParameters;
2416   int numiterators=parameter->task->numTotal-1;
2417   int retval=1;
2418   //int addnormal=1;
2419   //int adderror=1;
2420
2421   struct taskdescriptor * task=parameter->task;
2422
2423    //this add the object to parameterwrapper
2424    ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags, numenterflags, enterflags==NULL);  
2425
2426   /* Add enqueued object to parameter vector */
2427   taskpointerarray[parameter->slot]=ptr;
2428
2429   /* Reset iterators */
2430   for(j=0; j<numiterators; j++) {
2431     toiReset(&parameter->iterators[j]);
2432   }
2433
2434   /* Find initial state */
2435   for(j=0; j<numiterators; j++) {
2436 backtrackinit:
2437     if(toiHasNext(&parameter->iterators[j], taskpointerarray OPTARG(failed)))
2438       toiNext(&parameter->iterators[j], taskpointerarray OPTARG(failed));
2439     else if (j>0) {
2440       /* Need to backtrack */
2441       toiReset(&parameter->iterators[j]);
2442       j--;
2443       goto backtrackinit;
2444     } else {
2445       /* Nothing to enqueue */
2446       return retval;
2447     }
2448   }
2449
2450   while(1) {
2451     /* Enqueue current state */
2452     //int launch = 0;
2453     struct taskparamdescriptor *tpd=RUNMALLOC_I(sizeof(struct taskparamdescriptor));
2454     tpd->task=task;
2455     tpd->numParameters=numiterators+1;
2456     tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
2457
2458     for(j=0; j<=numiterators; j++) {
2459       tpd->parameterArray[j]=taskpointerarray[j]; //store the actual parameters
2460     }
2461     /* Enqueue task */
2462     if ((/*!gencontains(failedtasks, tpd)&&*/ !gencontains(activetasks,tpd))) {
2463                 genputtable_I(activetasks, tpd, tpd);
2464     } else {
2465       RUNFREE(tpd->parameterArray);
2466       RUNFREE(tpd);
2467     }
2468
2469     /* This loop iterates to the next parameter combination */
2470     if (numiterators==0)
2471       return retval;
2472
2473     for(j=numiterators-1; j<numiterators; j++) {
2474 backtrackinc:
2475       if(toiHasNext(&parameter->iterators[j], taskpointerarray OPTARG(failed)))
2476         toiNext(&parameter->iterators[j], taskpointerarray OPTARG(failed));
2477       else if (j>0) {
2478         /* Need to backtrack */
2479         toiReset(&parameter->iterators[j]);
2480         j--;
2481         goto backtrackinc;
2482       } else {
2483         /* Nothing more to enqueue */
2484         return retval;
2485       }
2486     }
2487   }
2488   return retval;
2489 }
2490
2491 /* Handler for signals. The signals catch null pointer errors and
2492    arithmatic errors. */
2493 #ifndef MULTICORE
2494 void myhandler(int sig, siginfo_t *info, void *uap) {
2495   sigset_t toclear;
2496 #ifdef DEBUG
2497   printf("sig=%d\n",sig);
2498   printf("signal\n");
2499 #endif
2500   sigemptyset(&toclear);
2501   sigaddset(&toclear, sig);
2502   sigprocmask(SIG_UNBLOCK, &toclear,NULL);
2503   longjmp(error_handler,1);
2504 }
2505 #endif
2506
2507 #ifndef MULTICORE
2508 fd_set readfds;
2509 int maxreadfd;
2510 struct RuntimeHash *fdtoobject;
2511
2512 void addreadfd(int fd) {
2513   if (fd>=maxreadfd)
2514     maxreadfd=fd+1;
2515   FD_SET(fd, &readfds);
2516 }
2517
2518 void removereadfd(int fd) {
2519   FD_CLR(fd, &readfds);
2520   if (maxreadfd==(fd+1)) {
2521     maxreadfd--;
2522     while(maxreadfd>0&&!FD_ISSET(maxreadfd-1, &readfds))
2523       maxreadfd--;
2524   }
2525 }
2526 #endif
2527
2528 #ifdef PRECISE_GC
2529 #define OFFSET 2
2530 #else
2531 #define OFFSET 0
2532 #endif
2533
2534 int containstag(struct ___Object___ *ptr, struct ___TagDescriptor___ *tag);
2535
2536 void executetasks() {
2537   void * taskpointerarray[MAXTASKPARAMS+OFFSET];
2538   int numparams=0;
2539   int numtotal=0;
2540   struct ___Object___ * tmpparam = NULL;
2541   struct parameterdescriptor * pd=NULL;
2542   struct parameterwrapper *pw=NULL;
2543   int j = 0;
2544   int x = 0;
2545   bool islock = true;
2546
2547   struct LockValue * locks[MAXTASKPARAMS];
2548   int locklen;
2549   int grount = 0;
2550   int andmask=0;
2551   int checkmask=0;
2552
2553   for(j = 0; j < MAXTASKPARAMS; j++) {
2554           locks[j] = (struct LockValue *)(RUNMALLOC(sizeof(struct LockValue)));
2555           locks[j]->redirectlock = 0;
2556           locks[j]->value = 0;
2557   }
2558
2559 #if 0
2560   /* Set up signal handlers */
2561   struct sigaction sig;
2562   sig.sa_sigaction=&myhandler;
2563   sig.sa_flags=SA_SIGINFO;
2564   sigemptyset(&sig.sa_mask);
2565
2566   /* Catch bus errors, segmentation faults, and floating point exceptions*/
2567   sigaction(SIGBUS,&sig,0);
2568   sigaction(SIGSEGV,&sig,0);
2569   sigaction(SIGFPE,&sig,0);
2570   sigaction(SIGPIPE,&sig,0);
2571 #endif  // #if 0: non-multicore
2572
2573 #if 0
2574   /* Zero fd set */
2575   FD_ZERO(&readfds);
2576 #endif
2577 #ifndef MULTICORE
2578   maxreadfd=0;
2579 #endif
2580 #if 0
2581   fdtoobject=allocateRuntimeHash(100);
2582 #endif
2583
2584 #if 0
2585   /* Map first block of memory to protected, anonymous page */
2586   mmap(0, 0x1000, 0, MAP_SHARED|MAP_FIXED|MAP_ANON, -1, 0);
2587 #endif
2588
2589 newtask:
2590 #ifdef MULTICORE
2591   while(hashsize(activetasks)>0) {
2592 #else
2593   while((hashsize(activetasks)>0)||(maxreadfd>0)) {
2594 #endif
2595
2596 #ifdef DEBUG
2597     BAMBOO_DEBUGPRINT(0xe990);
2598 #endif
2599 #if 0
2600     /* Check if any filedescriptors have IO pending */
2601     if (maxreadfd>0) {
2602       int i;
2603       struct timeval timeout={0,0};
2604       fd_set tmpreadfds;
2605       int numselect;
2606       tmpreadfds=readfds;
2607       numselect=select(maxreadfd, &tmpreadfds, NULL, NULL, &timeout);
2608       if (numselect>0) {
2609         /* Process ready fd's */
2610         int fd;
2611         for(fd=0; fd<maxreadfd; fd++) {
2612           if (FD_ISSET(fd, &tmpreadfds)) {
2613             /* Set ready flag on object */
2614             void * objptr;
2615             //      printf("Setting fd %d\n",fd);
2616             if (RuntimeHashget(fdtoobject, fd,(int *) &objptr)) {
2617               if(intflagorand(objptr,1,0xFFFFFFFF)) { /* Set the first flag to 1 */
2618                 enqueueObject(objptr, NULL, 0);
2619               }
2620             }
2621           }
2622         }
2623       }
2624     }
2625 #endif
2626
2627     /* See if there are any active tasks */
2628     if (hashsize(activetasks)>0) {
2629       int i;
2630 #ifdef PROFILE
2631           profileTaskStart("tpd checking");
2632 #endif
2633           busystatus = true;
2634       currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
2635       genfreekey(activetasks, currtpd);
2636
2637       numparams=currtpd->task->numParameters;
2638       numtotal=currtpd->task->numTotal;
2639
2640          // clear the lockRedirectTbl (TODO, this table should be empty after all locks are released)
2641           // get all required locks
2642           locklen = 0;
2643           // check which locks are needed
2644           for(i = 0; i < numparams; i++) {
2645                   void * param = currtpd->parameterArray[i];
2646                   int tmplock = 0;
2647                   int j = 0;
2648                   bool insert = true;
2649                   if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
2650                           islock = false;
2651                           taskpointerarray[i+OFFSET]=param;
2652                           goto execute;
2653                   }
2654                   if(((struct ___Object___ *)param)->lock == NULL) {
2655                           tmplock = (int)param;
2656                   } else {
2657                           tmplock = (int)(((struct ___Object___ *)param)->lock);
2658                   }
2659                   // insert into the locks array
2660                   for(j = 0; j < locklen; j++) {
2661                           if(locks[j]->value == tmplock) {
2662                                   insert = false;
2663                                   break;
2664                           } else if(locks[j]->value > tmplock) {
2665                                   break;
2666                           }
2667                   }
2668                   if(insert) {
2669                           int h = locklen;
2670                           for(; h > j; h--) {
2671                                   locks[h]->redirectlock = locks[h-1]->redirectlock;
2672                                   locks[h]->value = locks[h-1]->value;
2673                           }
2674                           locks[j]->value = tmplock;
2675                           locks[j]->redirectlock = (int)param;
2676                           locklen++;
2677                   }               
2678           }
2679           // grab these required locks
2680 #ifdef DEBUG
2681           BAMBOO_DEBUGPRINT(0xe991);
2682 #endif
2683           for(i = 0; i < locklen; i++) {
2684                   int * lock = (int *)(locks[i]->redirectlock);
2685                   islock = true;
2686                   // require locks for this parameter if it is not a startup object
2687 #ifdef DEBUG
2688                   BAMBOO_DEBUGPRINT_REG((int)lock);
2689                   BAMBOO_DEBUGPRINT_REG((int)(locks[i]->value));
2690 #endif
2691                   getwritelock(lock);
2692                   BAMBOO_START_CRITICAL_SECTION();
2693 #ifdef DEBUG
2694                   BAMBOO_DEBUGPRINT(0xf001);
2695 #endif
2696 #ifdef PROFILE
2697                   //isInterrupt = false;
2698 #endif 
2699                   while(!lockflag) { 
2700                           BAMBOO_WAITING_FOR_LOCK();
2701                   }
2702 #ifndef INTERRUPT
2703                   if(reside) {
2704                           while(BAMBOO_WAITING_FOR_LOCK() != -1) {
2705                           }
2706                   }
2707 #endif
2708                   grount = lockresult;
2709
2710                   lockresult = 0;
2711                   lockobj = 0;
2712                   lock2require = 0;
2713                   lockflag = false;
2714 #ifndef INTERRUPT
2715                   reside = false;
2716 #endif
2717 #ifdef PROFILE
2718                   //isInterrupt = true;
2719 #endif
2720                   BAMBOO_CLOSE_CRITICAL_SECTION();
2721 #ifdef DEBUG
2722                   BAMBOO_DEBUGPRINT(0xf000);
2723 #endif
2724
2725                   if(grount == 0) {
2726                           int j = 0;
2727 #ifdef DEBUG
2728                           BAMBOO_DEBUGPRINT(0xe992);
2729 #endif
2730                           // can not get the lock, try later
2731                           // releas all grabbed locks for previous parameters
2732                           for(j = 0; j < i; ++j) {
2733                                   lock = (int*)(locks[j]->redirectlock);
2734                                   releasewritelock(lock);
2735                           }
2736                           genputtable(activetasks, currtpd, currtpd);
2737                           if(hashsize(activetasks) == 1) {
2738                                   // only one task right now, wait a little while before next try
2739                                   int halt = 10000;
2740                                   while(halt--) {
2741                                   }
2742                           }
2743 #ifdef PROFILE
2744                           // fail, set the end of the checkTaskInfo
2745                           profileTaskEnd();
2746 #endif
2747                           goto newtask;
2748                   }
2749           }
2750
2751 #ifdef DEBUG
2752         BAMBOO_DEBUGPRINT(0xe993);
2753 #endif
2754       /* Make sure that the parameters are still in the queues */
2755       for(i=0; i<numparams; i++) {
2756         void * parameter=currtpd->parameterArray[i];
2757
2758         // flush the object
2759 #ifdef CACHEFLUSH
2760         BAMBOO_CACHE_FLUSH_RANGE((int)parameter, classsize[((struct ___Object___ *)parameter)->type]);
2761         /*
2762         BAMBOO_START_CRITICAL_SECTION_LOCK();
2763 #ifdef DEBUG
2764     BAMBOO_DEBUGPRINT(0xf001);
2765 #endif
2766         if(RuntimeHashcontainskey(objRedirectLockTbl, (int)parameter)) {
2767                 int redirectlock_r = 0;
2768                 RuntimeHashget(objRedirectLockTbl, (int)parameter, &redirectlock_r);
2769                 ((struct ___Object___ *)parameter)->lock = redirectlock_r;
2770                 RuntimeHashremovekey(objRedirectLockTbl, (int)parameter);
2771         }
2772         BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
2773 #ifdef DEBUG
2774     BAMBOO_DEBUGPRINT(0xf000);
2775 #endif
2776 */
2777 #endif
2778         tmpparam = (struct ___Object___ *)parameter;
2779         pd=currtpd->task->descriptorarray[i];
2780         pw=(struct parameterwrapper *) pd->queue;
2781         /* Check that object is still in queue */
2782         {
2783           if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
2784 #ifdef DEBUG
2785             BAMBOO_DEBUGPRINT(0xe994);
2786 #endif
2787             // release grabbed locks
2788             for(j = 0; j < locklen; ++j) {
2789                 int * lock = (int *)(locks[j]->redirectlock);
2790                 releasewritelock(lock);
2791             }
2792             RUNFREE(currtpd->parameterArray);
2793             RUNFREE(currtpd);
2794             goto newtask;
2795           }
2796         }
2797         /* Check if the object's flags still meets requirements */
2798         {
2799           int tmpi = 0;
2800           bool ismet = false;
2801           for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
2802             andmask=pw->intarray[tmpi*2];
2803             checkmask=pw->intarray[tmpi*2+1];
2804             if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
2805               ismet = true;
2806               break;
2807             }
2808           }
2809           if (!ismet) {
2810             // flags are never suitable
2811             // remove this obj from the queue
2812             int next;
2813             int UNUSED, UNUSED2;
2814             int * enterflags;
2815 #ifdef DEBUG
2816             BAMBOO_DEBUGPRINT(0xe995);
2817 #endif
2818             ObjectHashget(pw->objectset, (int) parameter, (int *) &next, (int *) &enterflags, &UNUSED, &UNUSED2);
2819             ObjectHashremove(pw->objectset, (int)parameter);
2820             if (enterflags!=NULL)
2821               RUNFREE(enterflags);
2822             // release grabbed locks
2823             for(j = 0; j < locklen; ++j) {
2824                  int * lock = (int *)(locks[j]->redirectlock);
2825                 releasewritelock(lock);
2826             }
2827             RUNFREE(currtpd->parameterArray);
2828             RUNFREE(currtpd);
2829 #ifdef PROFILE
2830             // fail, set the end of the checkTaskInfo
2831                 profileTaskEnd();
2832 #endif
2833             goto newtask;
2834           }
2835         }
2836 parameterpresent:
2837         ;
2838         /* Check that object still has necessary tags */
2839         for(j=0; j<pd->numbertags; j++) {
2840           int slotid=pd->tagarray[2*j]+numparams;
2841           struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
2842           if (!containstag(parameter, tagd)) {
2843 #ifdef DEBUG
2844             BAMBOO_DEBUGPRINT(0xe996);
2845 #endif
2846                 {
2847                 // release grabbed locks
2848                 int tmpj = 0;
2849             for(tmpj = 0; tmpj < locklen; ++tmpj) {
2850                  int * lock = (int *)(locks[tmpj]->redirectlock);
2851                 releasewritelock(lock);
2852             }
2853                 }
2854             RUNFREE(currtpd->parameterArray);
2855             RUNFREE(currtpd);
2856             goto newtask;
2857           }
2858         }
2859
2860         taskpointerarray[i+OFFSET]=parameter;
2861       }
2862       /* Copy the tags */
2863       for(; i<numtotal; i++) {
2864         taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
2865       }
2866
2867       {
2868 #if 0
2869 #ifndef RAW
2870         /* Checkpoint the state */
2871         forward=allocateRuntimeHash(100);
2872         reverse=allocateRuntimeHash(100);
2873         //void ** checkpoint=makecheckpoint(currtpd->task->numParameters, currtpd->parameterArray, forward, reverse);
2874 #endif
2875 #endif  // #if 0: for recovery
2876 #ifndef MULTICORE
2877         if (x=setjmp(error_handler)) {
2878           //int counter;
2879           /* Recover */
2880 #ifdef DEBUG
2881 #ifndef MULTICORE
2882           printf("Fatal Error=%d, Recovering!\n",x);
2883 #endif
2884 #endif
2885 #if 0
2886              genputtable(failedtasks,currtpd,currtpd);
2887              //restorecheckpoint(currtpd->task->numParameters, currtpd->parameterArray, checkpoint, forward, reverse);
2888
2889              freeRuntimeHash(forward);
2890              freeRuntimeHash(reverse);
2891              freemalloc();
2892              forward=NULL;
2893              reverse=NULL;
2894 #endif  // #if 0: for recovery
2895           BAMBOO_DEBUGPRINT_REG(x);
2896           BAMBOO_EXIT(0xa020);
2897         } else {
2898 #endif
2899 #if 0 
2900                 if (injectfailures) {
2901              if ((((double)random())/RAND_MAX)<failurechance) {
2902               printf("\nINJECTING TASK FAILURE to %s\n", currtpd->task->name);
2903               longjmp(error_handler,10);
2904              }
2905              }
2906 #endif  // #if 0: for recovery
2907           /* Actually call task */
2908 #if 0
2909 #ifdef PRECISE_GC
2910           ((int *)taskpointerarray)[0]=currtpd->numParameters;
2911           taskpointerarray[1]=NULL;
2912 #endif
2913 #endif  // #if 0: for garbage collection
2914 execute:
2915 #ifdef PROFILE
2916           // check finish, set the end of the checkTaskInfo
2917           profileTaskEnd();
2918           profileTaskStart(currtpd->task->name);
2919 #endif
2920
2921           if(debugtask) {
2922 #ifndef MULTICORE
2923         printf("ENTER %s count=%d\n",currtpd->task->name, (instaccum-instructioncount));
2924 #endif
2925             ((void(*) (void **))currtpd->task->taskptr)(taskpointerarray);
2926 #ifndef MULTICORE
2927             printf("EXIT %s count=%d\n",currtpd->task->name, (instaccum-instructioncount));
2928 #endif
2929           } else {
2930 #ifdef DEBUG
2931                   BAMBOO_DEBUGPRINT(0xe997);
2932 #endif
2933             ((void(*) (void **))currtpd->task->taskptr)(taskpointerarray);
2934           }
2935 #ifdef PROFILE
2936           // task finish, set the end of the checkTaskInfo
2937           profileTaskEnd();
2938           // new a PostTaskInfo for the post-task execution
2939           profileTaskStart("post task execution");
2940 #endif
2941 #ifdef DEBUG
2942           BAMBOO_DEBUGPRINT(0xe998);
2943           BAMBOO_DEBUGPRINT_REG(islock);
2944 #endif
2945
2946           if(islock) {
2947 #ifdef DEBUG
2948                   BAMBOO_DEBUGPRINT(0xe999);
2949 #endif
2950             for(i = 0; i < locklen; ++i) {
2951                   void * ptr = (void *)(locks[i]->redirectlock);
2952               int * lock = (int *)(locks[i]->value);
2953 #ifdef DEBUG
2954                   BAMBOO_DEBUGPRINT_REG((int)ptr);
2955                   BAMBOO_DEBUGPRINT_REG((int)lock);
2956 #endif
2957                   if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
2958                           int redirectlock;
2959                           RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
2960                           RuntimeHashremovekey(lockRedirectTbl, (int)lock);
2961                           releasewritelock_r(lock, (int *)redirectlock);
2962                   } else {
2963                 releasewritelock(ptr);
2964                   }
2965             }
2966           }
2967
2968 #ifdef PROFILE
2969           // post task execution finish, set the end of the postTaskInfo
2970           profileTaskEnd();
2971 #endif
2972
2973 #if 0
2974           freeRuntimeHash(forward);
2975           freeRuntimeHash(reverse);
2976           freemalloc();
2977 #endif
2978           // Free up task parameter descriptor
2979           RUNFREE(currtpd->parameterArray);
2980           RUNFREE(currtpd);
2981 #if 0
2982           forward=NULL;
2983           reverse=NULL;
2984 #endif
2985 #ifdef DEBUG
2986           BAMBOO_DEBUGPRINT(0xe99a);
2987 #endif
2988         }
2989       }
2990     }
2991 #ifndef MULTICORE
2992   }
2993 #endif
2994 #ifdef DEBUG
2995   BAMBOO_DEBUGPRINT(0xe99b);
2996 #endif
2997 }
2998
2999 /* This function processes an objects tags */
3000 void processtags(struct parameterdescriptor *pd, int index, struct parameterwrapper *parameter, int * iteratorcount, int *statusarray, int numparams) {
3001   int i;
3002
3003   for(i=0; i<pd->numbertags; i++) {
3004     int slotid=pd->tagarray[2*i];
3005     int tagid=pd->tagarray[2*i+1];
3006
3007     if (statusarray[slotid+numparams]==0) {
3008       parameter->iterators[*iteratorcount].istag=1;
3009       parameter->iterators[*iteratorcount].tagid=tagid;
3010       parameter->iterators[*iteratorcount].slot=slotid+numparams;
3011       parameter->iterators[*iteratorcount].tagobjectslot=index;
3012       statusarray[slotid+numparams]=1;
3013       (*iteratorcount)++;
3014     }
3015   }
3016 }
3017
3018
3019 void processobject(struct parameterwrapper *parameter, int index, struct parameterdescriptor *pd, int *iteratorcount, int * statusarray, int numparams) {
3020   int i;
3021   int tagcount=0;
3022   struct ObjectHash * objectset=((struct parameterwrapper *)pd->queue)->objectset;
3023
3024   parameter->iterators[*iteratorcount].istag=0;
3025   parameter->iterators[*iteratorcount].slot=index;
3026   parameter->iterators[*iteratorcount].objectset=objectset;
3027   statusarray[index]=1;
3028
3029   for(i=0; i<pd->numbertags; i++) {
3030     int slotid=pd->tagarray[2*i];
3031     //int tagid=pd->tagarray[2*i+1];
3032     if (statusarray[slotid+numparams]!=0) {
3033       /* This tag has already been enqueued, use it to narrow search */
3034       parameter->iterators[*iteratorcount].tagbindings[tagcount]=slotid+numparams;
3035       tagcount++;
3036     }
3037   }
3038   parameter->iterators[*iteratorcount].numtags=tagcount;
3039
3040   (*iteratorcount)++;
3041 }
3042
3043 /* This function builds the iterators for a task & parameter */
3044
3045 void builditerators(struct taskdescriptor * task, int index, struct parameterwrapper * parameter) {
3046   int statusarray[MAXTASKPARAMS];
3047   int i;
3048   int numparams=task->numParameters;
3049   int iteratorcount=0;
3050   for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
3051
3052   statusarray[index]=1; /* Initial parameter */
3053   /* Process tags for initial iterator */
3054
3055   processtags(task->descriptorarray[index], index, parameter, &iteratorcount, statusarray, numparams);
3056
3057   while(1) {
3058 loopstart:
3059     /* Check for objects with existing tags */
3060     for(i=0; i<numparams; i++) {
3061       if (statusarray[i]==0) {
3062         struct parameterdescriptor *pd=task->descriptorarray[i];
3063         int j;
3064         for(j=0; j<pd->numbertags; j++) {
3065           int slotid=pd->tagarray[2*j];
3066           if(statusarray[slotid+numparams]!=0) {
3067             processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3068             processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3069             goto loopstart;
3070           }
3071         }
3072       }
3073     }
3074
3075     /* Next do objects w/ unbound tags*/
3076
3077     for(i=0; i<numparams; i++) {
3078       if (statusarray[i]==0) {
3079         struct parameterdescriptor *pd=task->descriptorarray[i];
3080         if (pd->numbertags>0) {
3081           processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3082           processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3083           goto loopstart;
3084         }
3085       }
3086     }
3087
3088     /* Nothing with a tag enqueued */
3089
3090     for(i=0; i<numparams; i++) {
3091       if (statusarray[i]==0) {
3092         struct parameterdescriptor *pd=task->descriptorarray[i];
3093         processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3094         processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3095         goto loopstart;
3096       }
3097     }
3098
3099     /* Nothing left */
3100     return;
3101   }
3102 }
3103
3104 void printdebug() {
3105   int i;
3106   int j;
3107   if(corenum > NUMCORES - 1) {
3108     return;
3109   }
3110   for(i=0; i<numtasks[corenum]; i++) {
3111     struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3112 #ifndef MULTICORE
3113         printf("%s\n", task->name);
3114 #endif
3115     for(j=0; j<task->numParameters; j++) {
3116       struct parameterdescriptor *param=task->descriptorarray[j];
3117       struct parameterwrapper *parameter=param->queue;
3118       struct ObjectHash * set=parameter->objectset;
3119       struct ObjectIterator objit;
3120 #ifndef MULTICORE
3121           printf("  Parameter %d\n", j);
3122 #endif
3123       ObjectHashiterator(set, &objit);
3124       while(ObjhasNext(&objit)) {
3125         struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
3126         struct ___Object___ * tagptr=obj->___tags___;
3127         int nonfailed=Objdata4(&objit);
3128         int numflags=Objdata3(&objit);
3129         int flags=Objdata2(&objit);
3130         Objnext(&objit);
3131 #ifndef MULTICORE
3132         printf("    Contains %lx\n", obj);
3133         printf("      flag=%d\n", obj->flag);
3134 #endif
3135         if (tagptr==NULL) {
3136         } else if (tagptr->type==TAGTYPE) {
3137 #ifndef MULTICORE
3138           printf("      tag=%lx\n",tagptr);
3139 #else
3140           ;
3141 #endif
3142         } else {
3143           int tagindex=0;
3144           struct ArrayObject *ao=(struct ArrayObject *)tagptr;
3145           for(; tagindex<ao->___cachedCode___; tagindex++) {
3146 #ifndef MULTICORE
3147                   printf("      tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*, tagindex));
3148 #else
3149                   ;
3150 #endif
3151           }
3152         }
3153       }
3154     }
3155   }
3156 }
3157
3158
3159 /* This function processes the task information to create queues for
3160    each parameter type. */
3161
3162 void processtasks() {
3163   int i;
3164   if(corenum > NUMCORES - 1) {
3165     return;
3166   }
3167   for(i=0; i<numtasks[corenum]; i++) {
3168     struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3169     int j;
3170
3171     /* Build objectsets */
3172     for(j=0; j<task->numParameters; j++) {
3173       struct parameterdescriptor *param=task->descriptorarray[j];
3174       struct parameterwrapper *parameter=param->queue;
3175       parameter->objectset=allocateObjectHash(10);
3176       parameter->task=task;
3177     }
3178
3179     /* Build iterators for parameters */
3180     for(j=0; j<task->numParameters; j++) {
3181       struct parameterdescriptor *param=task->descriptorarray[j];
3182       struct parameterwrapper *parameter=param->queue;
3183       builditerators(task, j, parameter);
3184     }
3185   }
3186 }
3187
3188 void toiReset(struct tagobjectiterator * it) {
3189   if (it->istag) {
3190     it->tagobjindex=0;
3191   } else if (it->numtags>0) {
3192     it->tagobjindex=0;
3193   } else {
3194     ObjectHashiterator(it->objectset, &it->it);
3195   }
3196 }
3197
3198 int toiHasNext(struct tagobjectiterator *it, void ** objectarray OPTARG(int * failed)) {
3199   if (it->istag) {
3200     /* Iterate tag */
3201     /* Get object with tags */
3202     struct ___Object___ *obj=objectarray[it->tagobjectslot];
3203     struct ___Object___ *tagptr=obj->___tags___;
3204     if (tagptr->type==TAGTYPE) {
3205       if ((it->tagobjindex==0)&& /* First object */
3206           (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
3207         return 1;
3208       else
3209         return 0;
3210     } else {
3211       struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3212       int tagindex=it->tagobjindex;
3213       for(; tagindex<ao->___cachedCode___; tagindex++) {
3214         struct ___TagDescriptor___ *td=ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
3215         if (td->flag==it->tagid) {
3216           it->tagobjindex=tagindex; /* Found right type of tag */
3217           return 1;
3218         }
3219       }
3220       return 0;
3221     }
3222   } else if (it->numtags>0) {
3223     /* Use tags to locate appropriate objects */
3224     struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3225     struct ___Object___ *objptr=tag->flagptr;
3226     int i;
3227     if (objptr->type!=OBJECTARRAYTYPE) {
3228       if (it->tagobjindex>0)
3229         return 0;
3230       if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3231         return 0;
3232       for(i=1; i<it->numtags; i++) {
3233         struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3234         if (!containstag(objptr,tag2))
3235           return 0;
3236       }
3237       return 1;
3238     } else {
3239       struct ArrayObject *ao=(struct ArrayObject *) objptr;
3240       int tagindex;
3241       int i;
3242       for(tagindex=it->tagobjindex; tagindex<ao->___cachedCode___; tagindex++) {
3243         struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
3244         if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3245           continue;
3246         for(i=1; i<it->numtags; i++) {
3247           struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3248           if (!containstag(objptr,tag2))
3249             goto nexttag;
3250         }
3251         it->tagobjindex=tagindex;
3252         return 1;
3253 nexttag:
3254         ;
3255       }
3256       it->tagobjindex=tagindex;
3257       return 0;
3258     }
3259   } else {
3260     return ObjhasNext(&it->it);
3261   }
3262 }
3263
3264 int containstag(struct ___Object___ *ptr, struct ___TagDescriptor___ *tag) {
3265   int j;
3266   struct ___Object___ * objptr=tag->flagptr;
3267   if (objptr->type==OBJECTARRAYTYPE) {
3268     struct ArrayObject *ao=(struct ArrayObject *)objptr;
3269     for(j=0; j<ao->___cachedCode___; j++) {
3270       if (ptr==ARRAYGET(ao, struct ___Object___*, j))
3271         return 1;
3272     }
3273     return 0;
3274   } else
3275     return objptr==ptr;
3276 }
3277
3278 void toiNext(struct tagobjectiterator *it, void ** objectarray OPTARG(int * failed)) {
3279   /* hasNext has all of the intelligence */
3280   if(it->istag) {
3281     /* Iterate tag */
3282     /* Get object with tags */
3283     struct ___Object___ *obj=objectarray[it->tagobjectslot];
3284     struct ___Object___ *tagptr=obj->___tags___;
3285     if (tagptr->type==TAGTYPE) {
3286       it->tagobjindex++;
3287       objectarray[it->slot]=tagptr;
3288     } else {
3289       struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3290       objectarray[it->slot]=ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
3291     }
3292   } else if (it->numtags>0) {
3293     /* Use tags to locate appropriate objects */
3294     struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3295     struct ___Object___ *objptr=tag->flagptr;
3296     if (objptr->type!=OBJECTARRAYTYPE) {
3297       it->tagobjindex++;
3298       objectarray[it->slot]=objptr;
3299     } else {
3300       struct ArrayObject *ao=(struct ArrayObject *) objptr;
3301       objectarray[it->slot]=ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
3302     }
3303   } else {
3304     /* Iterate object */
3305     objectarray[it->slot]=(void *)Objkey(&it->it);
3306     Objnext(&it->it);
3307   }
3308 }
3309 #endif