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