Add a new shared memory allocation strategy: fixed mode. In this mode, the master...
[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 #ifndef INLINE
8 #define INLINE    inline __attribute__((always_inline))
9 #endif // #ifndef INLINE
10
11 //  data structures for task invocation
12 struct genhashtable * activetasks;
13 struct taskparamdescriptor * currtpd;
14 struct LockValue runtime_locks[MAXTASKPARAMS];
15 int runtime_locklen;
16
17 // specific functions used inside critical sections
18 void enqueueObject_I(void * ptr,
19                      struct parameterwrapper ** queues,
20                      int length);
21 int enqueuetasks_I(struct parameterwrapper *parameter,
22                    struct parameterwrapper *prevptr,
23                    struct ___Object___ *ptr,
24                    int * enterflags,
25                    int numenterflags);
26
27 #ifdef MULTICORE_GC
28 #ifdef SMEMF
29 #ifdef GC_1
30 int core2test[1][5] = {
31   {0, -1, -1, -1, -1}
32 };
33 #elif defined GC_56
34 int core2test[56][5] = {
35   { 0, -1,  7, -1,  1}, { 1, -1,  8,  0,  2}, { 2, -1,  9,  1,  3},
36   { 3, -1, 10,  2,  4}, { 4, -1, 11,  3,  5}, { 5, -1, 12,  4,  6},
37   { 6, -1, 13,  5, -1}, { 7,  0, 14, -1,  8}, { 8,  1, 15,  7,  9},
38   { 9,  2, 16,  8, 10}, {10,  3, 17,  9, 11}, {11,  4, 18, 10, 12},
39   {12,  5, 19, 11, 13}, {13,  6, 20, 12, -1}, {14,  7, 21, -1, 15},
40   {15,  8, 22, 14, 16}, {16,  9, 23, 15, 17}, {17, 10, 24, 16, 18},
41   {18, 11, 25, 17, 19}, {19, 12, 26, 18, 20}, {20, 13, 27, 19, -1},
42   {21, 14, 28, -1, 22}, {22, 15, 29, 21, 23}, {23, 16, 30, 22, 24},
43   {24, 17, 31, 23, 25}, {25, 18, 32, 24, 26}, {26, 19, 33, 25, 27},
44   {27, 20, 34, 26, -1}, {28, 21, 35, -1, 29}, {29, 22, 36, 28, 30},
45   {30, 23, 37, 29, 31}, {31, 24, 38, 30, 32}, {32, 25, 39, 31, 33},
46   {33, 26, 40, 32, 34}, {34, 27, 41, 33, -1}, {35, 28, 42, -1, 36},
47   {36, 29, 43, 35, 37}, {37, 30, 44, 36, 38}, {38, 31, 45, 37, 39},
48   {39, 32, 46, 38, 40}, {40, 33, 47, 39, 41}, {41, 34, 48, 40, -1},
49   {42, 35, 49, -1, 43}, {43, 36, 50, 42, 44}, {44, 37, 51, 43, 45},
50   {45, 38, 52, 44, 46}, {46, 39, 53, 45, 47}, {47, 40, 54, 46, 48},
51   {48, 41, 55, 47, -1}, {49, 42, -1, -1, 50}, {50, 43, -1, 49, 51},
52   {51, 44, -1, 50, 52}, {52, 45, -1, 51, 53}, {53, 46, -1, 52, 54},
53   {54, 47, -1, 53, 55}, {55, 48, -1, 54, -1}
54 };
55 #elif defined GC_62
56 int core2test[62][5] = {
57   { 0, -1,  6, -1,  1}, { 1, -1,  7,  0,  2}, { 2, -1,  8,  1,  3},
58   { 3, -1,  9,  2,  4}, { 4, -1, 10,  3,  5}, { 5, -1, 11,  4, -1},
59   { 6,  0, 14, -1,  7}, { 7,  1, 15,  6,  8}, { 8,  2, 16,  7,  9},
60   { 9,  3, 17,  8, 10}, {10,  4, 18,  9, 11}, {11,  5, 19, 10, 12},
61   {12, -1, 20, 11, 13}, {13, -1, 21, 12, -1}, {14,  6, 22, -1, 15},
62   {15,  7, 23, 14, 16}, {16,  8, 24, 15, 17}, {17,  9, 25, 16, 18},
63   {18, 10, 26, 17, 19}, {19, 11, 27, 18, 20}, {20, 12, 28, 19, 21},
64   {21, 13, 29, 28, -1}, {22, 14, 30, -1, 23}, {23, 15, 31, 22, 24},
65   {24, 16, 32, 23, 25}, {25, 17, 33, 24, 26}, {26, 18, 34, 25, 27},
66   {27, 19, 35, 26, 28}, {28, 20, 36, 27, 29}, {29, 21, 37, 28, -1},
67   {30, 22, 38, -1, 31}, {31, 23, 39, 30, 32}, {32, 24, 40, 31, 33},
68   {33, 25, 41, 32, 34}, {34, 26, 42, 33, 35}, {35, 27, 43, 34, 36},
69   {36, 28, 44, 35, 37}, {37, 29, 45, 36, -1}, {38, 30, 46, -1, 39},
70   {39, 31, 47, 38, 40}, {40, 32, 48, 39, 41}, {41, 33, 49, 40, 42},
71   {42, 34, 50, 41, 43}, {43, 35, 51, 42, 44}, {44, 36, 52, 43, 45},
72   {45, 37, 53, 44, -1}, {46, 38, 54, -1, 47}, {47, 39, 55, 46, 48},
73   {48, 40, 56, 47, 49}, {49, 41, 57, 48, 50}, {50, 42, 58, 49, 51},
74   {51, 43, 59, 50, 52}, {52, 44, 60, 51, 53}, {53, 45, 61, 52, -1},
75   {54, 46, -1, -1, 55}, {55, 47, -1, 54, 56}, {56, 48, -1, 55, 57},
76   {57, 49, -1, 56, 59}, {58, 50, -1, 57, 59}, {59, 51, -1, 58, 60},
77   {60, 52, -1, 59, 61}, {61, 53, -1, 60, -1}
78 };
79 #endif // GC_1
80 #elif defined SMEMM
81 #endif
82
83 inline __attribute__((always_inline))
84 void setupsmemmode(void) {
85 #ifdef SMEML
86   // Only allocate local mem chunks to each core.
87   // If a core has used up its local shared memory, start gc.
88   bamboo_smem_mode = SMEMLOCAL;
89 #elif defined SMEMF
90   // Allocate the local shared memory to each core with the highest priority,
91   // if a core has used up its local shared memory, try to allocate the 
92   // shared memory that belong to its neighbours, if also failed, start gc.
93   bamboo_smem_mode = SMEMFIXED;
94 #elif defined SMEMM
95   // Allocate the local shared memory to each core with the highest priority,
96   // if a core has used up its local shared memory, try to allocate the 
97   // shared memory that belong to its neighbours first, if failed, allocate 
98   // the shared memory globally.  If all the shared memory has been used up,
99   // start gc.
100   bamboo_smem_mode = SMEMMIXED;
101 #elif defined SMEMG
102   // Allocate all the memory chunks globally, do not consider the host cores
103   // When all the shared memory are used up, start gc.
104   bamboo_smem_mode = SMEMGLOBAL;
105 #else
106   // defaultly using local mode
107   //bamboo_smem_mode = SMEMLOCAL;
108   //bamboo_smem_mode = SMEMGLOBAL;
109   //bamboo_smem_mode = SMEMFIXED;
110 #endif
111 } // void setupsmemmode(void)
112 #endif
113
114 inline __attribute__((always_inline))
115 void initruntimedata() {
116   int i;
117   // initialize the arrays
118   if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
119     // startup core to initialize corestatus[]
120     for(i = 0; i < NUMCORESACTIVE; ++i) {
121       corestatus[i] = 1;
122       numsendobjs[i] = 0;
123       numreceiveobjs[i] = 0;
124 #ifdef PROFILE
125       // initialize the profile data arrays
126       profilestatus[i] = 1;
127 #endif
128 #ifdef MULTICORE_GC
129       gccorestatus[i] = 1;
130       gcnumsendobjs[i] = 0;
131       gcnumreceiveobjs[i] = 0;
132 #endif
133     } // for(i = 0; i < NUMCORESACTIVE; ++i)
134 #ifdef MULTICORE_GC
135     for(i = 0; i < NUMCORES4GC; ++i) {
136       gcloads[i] = 0;
137       gcrequiredmems[i] = 0;
138       gcstopblock[i] = 0;
139       gcfilledblocks[i] = 0;
140     } // for(i = 0; i < NUMCORES4GC; ++i)
141 #ifdef GC_PROFILE
142     gc_infoIndex = 0;
143     gc_infoOverflow = false;
144 #endif
145 #endif
146     numconfirm = 0;
147     waitconfirm = false;
148
149     // TODO for test
150     total_num_t6 = 0;
151   }
152
153   busystatus = true;
154   self_numsendobjs = 0;
155   self_numreceiveobjs = 0;
156
157   for(i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
158     msgdata[i] = -1;
159   }
160   msgdataindex = 0;
161   msgdatalast = 0;
162   msglength = BAMBOO_MSG_BUF_LENGTH;
163   msgdatafull = false;
164   for(i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
165     outmsgdata[i] = -1;
166   }
167   outmsgindex = 0;
168   outmsglast = 0;
169   outmsgleft = 0;
170   isMsgHanging = false;
171   //isMsgSending = false;
172
173   smemflag = true;
174   bamboo_cur_msp = NULL;
175   bamboo_smem_size = 0;
176   totransobjqueue = createQueue_I();
177
178 #ifdef MULTICORE_GC
179   gcflag = false;
180   gcprocessing = false;
181   gcphase = FINISHPHASE;
182   gccurr_heaptop = 0;
183   gcself_numsendobjs = 0;
184   gcself_numreceiveobjs = 0;
185   gcmarkedptrbound = 0;
186   //mgchashCreate(2000, 0.75);
187   gcpointertbl = allocateRuntimeHash_I(20);
188   //gcpointertbl = allocateMGCHash(20);
189   gcforwardobjtbl = allocateMGCHash_I(20, 3);
190   gcobj2map = 0;
191   gcmappedobj = 0;
192   //gcismapped = false;
193   gcnumlobjs = 0;
194   gcheaptop = 0;
195   gctopcore = 0;
196   gctopblock = 0;
197   gcmovestartaddr = 0;
198   gctomove = false;
199   gcmovepending = 0;
200   gcblock2fill = 0;
201   gcsbstarttbl = BAMBOO_BASE_VA;
202   bamboo_smemtbl = (void *)gcsbstarttbl
203                + (BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE)*sizeof(INTPTR);
204   if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
205         int t_size = ((BAMBOO_RMSP_SIZE)-sizeof(mgcsharedhashtbl_t)*2
206                 -128*sizeof(size_t))/sizeof(mgcsharedhashlistnode_t)-2;
207         int kk = 0;
208         unsigned int tmp_k = 1 << (sizeof(int)*8 -1);
209         while(((t_size & tmp_k) == 0) && (kk < sizeof(int)*8)) {
210           t_size = t_size << 1;
211           kk++;
212         }
213         t_size = tmp_k >> kk;
214         gcsharedptbl = mgcsharedhashCreate_I(t_size,0.30);//allocateGCSharedHash_I(20);
215   } else {
216         gcsharedptbl = NULL;
217   }
218   BAMBOO_MEMSET_WH(gcrpointertbls,0,sizeof(mgcsharedhashtbl_t *)*NUMCORES4GC);
219           //sizeof(struct RuntimeHash *)*NUMCORES4GC);
220 #else
221   // create the lock table, lockresult table and obj queue
222   locktable.size = 20;
223   locktable.bucket =
224     (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
225   /* Set allocation blocks*/
226   locktable.listhead=NULL;
227   locktable.listtail=NULL;
228   /*Set data counts*/
229   locktable.numelements = 0;
230   lockobj = 0;
231   lock2require = 0;
232   lockresult = 0;
233   lockflag = false;
234   lockRedirectTbl = allocateRuntimeHash_I(20);
235   objRedirectLockTbl = allocateRuntimeHash_I(20);
236 #endif
237 #ifndef INTERRUPT
238   reside = false;
239 #endif
240   objqueue.head = NULL;
241   objqueue.tail = NULL;
242
243   currtpd = NULL;
244
245 #ifdef PROFILE
246   stall = false;
247   //isInterrupt = true;
248   totalexetime = -1;
249   //interrupttime = 0;
250   taskInfoIndex = 0;
251   taskInfoOverflow = false;
252   // TODO
253   interruptInfoIndex = 0;
254   interruptInfoOverflow = false;
255 #endif
256
257   for(i = 0; i < MAXTASKPARAMS; i++) {
258     runtime_locks[i].redirectlock = 0;
259     runtime_locks[i].value = 0;
260   }
261   runtime_locklen = 0;
262 }
263
264 inline __attribute__((always_inline))
265 void disruntimedata() {
266 #ifdef MULTICORE_GC
267   //mgchashDelete();
268   freeRuntimeHash(gcpointertbl);
269   //freeMGCHash(gcpointertbl);
270   freeMGCHash(gcforwardobjtbl);
271   // for mapping info structures
272   //freeRuntimeHash(gcrcoretbl);
273 #else
274   freeRuntimeHash(lockRedirectTbl);
275   freeRuntimeHash(objRedirectLockTbl);
276   RUNFREE(locktable.bucket);
277 #endif
278   if(activetasks != NULL) {
279     genfreehashtable(activetasks);
280   }
281   if(currtpd != NULL) {
282     RUNFREE(currtpd->parameterArray);
283     RUNFREE(currtpd);
284     currtpd = NULL;
285   }
286   BAMBOO_LOCAL_MEM_CLOSE();
287   BAMBOO_SHARE_MEM_CLOSE();
288 }
289
290 inline __attribute__((always_inline))
291 bool checkObjQueue() {
292   bool rflag = false;
293   struct transObjInfo * objInfo = NULL;
294   int grount = 0;
295
296 #ifdef PROFILE
297 #ifdef ACCURATEPROFILE
298   bool isChecking = false;
299   if(!isEmpty(&objqueue)) {
300     profileTaskStart("objqueue checking");
301     isChecking = true;
302   }       // if(!isEmpty(&objqueue))
303 #endif
304 #endif
305
306   while(!isEmpty(&objqueue)) {
307     void * obj = NULL;
308     BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
309 #ifdef DEBUG
310     BAMBOO_DEBUGPRINT(0xf001);
311 #endif
312 #ifdef PROFILE
313     //isInterrupt = false;
314 #endif
315 #ifdef DEBUG
316     BAMBOO_DEBUGPRINT(0xeee1);
317 #endif
318     rflag = true;
319     objInfo = (struct transObjInfo *)getItem(&objqueue);
320     obj = objInfo->objptr;
321 #ifdef DEBUG
322     BAMBOO_DEBUGPRINT_REG((int)obj);
323 #endif
324     // grab lock and flush the obj
325     grount = 0;
326     getwritelock_I(obj);
327     while(!lockflag) {
328       BAMBOO_WAITING_FOR_LOCK(0);
329           // check for outgoing sends
330           /*if (isMsgHanging) {
331                 extern inline void send_hanging_msg(bool);
332                 send_hanging_msg(true);
333           } */
334     }             // while(!lockflag)
335     grount = lockresult;
336 #ifdef DEBUG
337     BAMBOO_DEBUGPRINT_REG(grount);
338 #endif
339
340     lockresult = 0;
341     lockobj = 0;
342     lock2require = 0;
343     lockflag = false;
344 #ifndef INTERRUPT
345     reside = false;
346 #endif
347
348     if(grount == 1) {
349       int k = 0;
350       // flush the object
351 #ifdef CACHEFLUSH
352       BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
353       BAMBOO_CACHE_FLUSH_RANGE((int)obj,
354                                classsize[((struct ___Object___ *)obj)->type]);
355 #endif
356       // enqueue the object
357       for(k = 0; k < objInfo->length; ++k) {
358         int taskindex = objInfo->queues[2 * k];
359         int paramindex = objInfo->queues[2 * k + 1];
360         struct parameterwrapper ** queues =
361           &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
362 #ifdef DEBUG
363         BAMBOO_DEBUGPRINT_REG(taskindex);
364         BAMBOO_DEBUGPRINT_REG(paramindex);
365         struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
366         tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n",
367                 BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj,
368                 (long)obj, tmpptr->flag);
369 #endif
370         enqueueObject_I(obj, queues, 1);
371 #ifdef DEBUG
372         BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
373 #endif
374       }                   // for(k = 0; k < objInfo->length; ++k)
375       releasewritelock_I(obj);
376       RUNFREE(objInfo->queues);
377       RUNFREE(objInfo);
378     } else {
379       // can not get lock
380       // put it at the end of the queue if no update version in the queue
381       struct QueueItem * qitem = getHead(&objqueue);
382       struct QueueItem * prev = NULL;
383       while(qitem != NULL) {
384                   struct transObjInfo * tmpinfo =
385                           (struct transObjInfo *)(qitem->objectptr);
386                   if(tmpinfo->objptr == obj) {
387                           // the same object in the queue, which should be enqueued
388                           // recently. Current one is outdate, do not re-enqueue it
389                           RUNFREE(objInfo->queues);
390                           RUNFREE(objInfo);
391                           goto objqueuebreak;
392                   } else {
393                           prev = qitem;
394                   }                         // if(tmpinfo->objptr == obj)
395                   qitem = getNextQueueItem(prev);
396           }                   // while(qitem != NULL)
397                           // try to execute active tasks already enqueued first
398       addNewItem_I(&objqueue, objInfo);
399 #ifdef PROFILE
400       //isInterrupt = true;
401 #endif
402 objqueuebreak:
403       BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
404 #ifdef DEBUG
405       BAMBOO_DEBUGPRINT(0xf000);
406 #endif
407       break;
408     }             // if(grount == 1)
409     BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
410 #ifdef DEBUG
411     BAMBOO_DEBUGPRINT(0xf000);
412 #endif
413   }       // while(!isEmpty(&objqueue))
414
415 #ifdef PROFILE
416 #ifdef ACCURATEPROFILE
417   if(isChecking) {
418     profileTaskEnd();
419   }       // if(isChecking)
420 #endif
421 #endif
422
423 #ifdef DEBUG
424   BAMBOO_DEBUGPRINT(0xee02);
425 #endif
426   return rflag;
427 }
428
429 inline __attribute__((always_inline))
430 void checkCoreStatus() {
431   bool allStall = false;
432   int i = 0;
433   int sumsendobj = 0;
434   if((!waitconfirm) ||
435      (waitconfirm && (numconfirm == 0))) {
436 #ifdef DEBUG
437     BAMBOO_DEBUGPRINT(0xee04);
438     BAMBOO_DEBUGPRINT_REG(waitconfirm);
439 #endif
440     BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
441 #ifdef DEBUG
442     BAMBOO_DEBUGPRINT(0xf001);
443 #endif
444     corestatus[BAMBOO_NUM_OF_CORE] = 0;
445     numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
446     numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
447     // check the status of all cores
448     allStall = true;
449 #ifdef DEBUG
450     BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
451 #endif
452     for(i = 0; i < NUMCORESACTIVE; ++i) {
453 #ifdef DEBUG
454       BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
455 #endif
456       if(corestatus[i] != 0) {
457                   allStall = false;
458                   break;
459       }
460     }             // for(i = 0; i < NUMCORESACTIVE; ++i)
461     if(allStall) {
462       // check if the sum of send objs and receive obj are the same
463       // yes->check if the info is the latest; no->go on executing
464       sumsendobj = 0;
465       for(i = 0; i < NUMCORESACTIVE; ++i) {
466                   sumsendobj += numsendobjs[i];
467 #ifdef DEBUG
468                   BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
469 #endif
470       }                   // for(i = 0; i < NUMCORESACTIVE; ++i)
471       for(i = 0; i < NUMCORESACTIVE; ++i) {
472                   sumsendobj -= numreceiveobjs[i];
473 #ifdef DEBUG
474                   BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
475 #endif
476       }                   // for(i = 0; i < NUMCORESACTIVE; ++i)
477       if(0 == sumsendobj) {
478         if(!waitconfirm) {
479           // the first time found all cores stall
480           // send out status confirm msg to all other cores
481           // reset the corestatus array too
482 #ifdef DEBUG
483           BAMBOO_DEBUGPRINT(0xee05);
484 #endif
485           corestatus[BAMBOO_NUM_OF_CORE] = 1;
486           waitconfirm = true;
487           numconfirm = NUMCORESACTIVE - 1;
488           BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
489           for(i = 1; i < NUMCORESACTIVE; ++i) {
490             corestatus[i] = 1;
491             // send status confirm msg to core i
492             send_msg_1(i, STATUSCONFIRM, false);
493           }   // for(i = 1; i < NUMCORESACTIVE; ++i)
494           return;
495         } else {
496           // all the core status info are the latest
497           // terminate; for profiling mode, send request to all
498           // other cores to pour out profiling data
499 #ifdef DEBUG
500           BAMBOO_DEBUGPRINT(0xee06);
501 #endif
502
503 #ifdef USEIO
504           totalexetime = BAMBOO_GET_EXE_TIME() - bamboo_start_time;
505 #else
506 #ifdef PROFILE
507           //BAMBOO_DEBUGPRINT_REG(interrupttime);
508 #endif
509
510           BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME() - bamboo_start_time);
511           //BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
512           BAMBOO_DEBUGPRINT(0xbbbbbbbb);
513 #endif
514           // profile mode, send msgs to other cores to request pouring
515           // out progiling data
516 #ifdef PROFILE
517           BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
518 #ifdef DEBUG
519           BAMBOO_DEBUGPRINT(0xf000);
520 #endif
521           for(i = 1; i < NUMCORESACTIVE; ++i) {
522             // send profile request msg to core i
523             send_msg_2(i, PROFILEOUTPUT, totalexetime, false);
524           } // for(i = 1; i < NUMCORESACTIVE; ++i)
525           // pour profiling data on startup core
526           outputProfileData();
527           while(true) {
528             BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
529 #ifdef DEBUG
530             BAMBOO_DEBUGPRINT(0xf001);
531 #endif
532             profilestatus[BAMBOO_NUM_OF_CORE] = 0;
533             // check the status of all cores
534             allStall = true;
535 #ifdef DEBUG
536             BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
537 #endif
538             for(i = 0; i < NUMCORESACTIVE; ++i) {
539 #ifdef DEBUG
540               BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
541 #endif
542               if(profilestatus[i] != 0) {
543                 allStall = false;
544                 break;
545               }
546             }  // for(i = 0; i < NUMCORESACTIVE; ++i)
547             if(!allStall) {
548               int halt = 100;
549               BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
550 #ifdef DEBUG
551               BAMBOO_DEBUGPRINT(0xf000);
552 #endif
553               while(halt--) {
554               }
555             } else {
556               BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
557               break;
558             }                                     // if(!allStall)
559           }                               // while(true)
560 #endif
561
562           // gc_profile mode, ourput gc prfiling data
563 #ifdef MULTICORE_GC
564 #ifdef GC_PROFILE
565           gc_outputProfileData();
566 #endif // #ifdef GC_PROFILE
567 #endif // #ifdef MULTICORE_GC
568           disruntimedata();
569           BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
570           terminate();                               // All done.
571         }                         // if(!waitconfirm)
572       } else {
573         // still some objects on the fly on the network
574         // reset the waitconfirm and numconfirm
575 #ifdef DEBUG
576         BAMBOO_DEBUGPRINT(0xee07);
577 #endif
578         waitconfirm = false;
579         numconfirm = 0;
580       }                   //  if(0 == sumsendobj)
581     } else {
582       // not all cores are stall, keep on waiting
583 #ifdef DEBUG
584       BAMBOO_DEBUGPRINT(0xee08);
585 #endif
586       waitconfirm = false;
587       numconfirm = 0;
588     }             //  if(allStall)
589     BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
590 #ifdef DEBUG
591     BAMBOO_DEBUGPRINT(0xf000);
592 #endif
593   }       // if((!waitconfirm) ||
594 }
595
596 // main function for each core
597 inline void run(void * arg) {
598   int i = 0;
599   int argc = 1;
600   char ** argv = NULL;
601   bool sendStall = false;
602   bool isfirst = true;
603   bool tocontinue = false;
604
605   corenum = BAMBOO_GET_NUM_OF_CORE();
606 #ifdef DEBUG
607   BAMBOO_DEBUGPRINT(0xeeee);
608   BAMBOO_DEBUGPRINT_REG(corenum);
609   BAMBOO_DEBUGPRINT(STARTUPCORE);
610 #endif
611
612   // initialize runtime data structures
613   initruntimedata();
614
615   // other architecture related initialization
616   initialization();
617   initCommunication();
618
619   initializeexithandler();
620
621   // main process of the execution module
622   if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
623     // non-executing cores, only processing communications
624     activetasks = NULL;
625 /*#ifdef PROFILE
626         BAMBOO_DEBUGPRINT(0xee01);
627         BAMBOO_DEBUGPRINT_REG(taskInfoIndex);
628         BAMBOO_DEBUGPRINT_REG(taskInfoOverflow);
629                 profileTaskStart("msg handling");
630         }
631  #endif*/
632 #ifdef PROFILE
633     //isInterrupt = false;
634 #endif
635     fakeExecution();
636   } else {
637     /* Create queue of active tasks */
638     activetasks=
639       genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
640                            (int (*)(void *,void *)) &comparetpd);
641
642     /* Process task information */
643     processtasks();
644
645     if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
646       /* Create startup object */
647       createstartupobject(argc, argv);
648     }
649
650 #ifdef DEBUG
651     BAMBOO_DEBUGPRINT(0xee00);
652 #endif
653
654     while(true) {
655 #ifdef MULTICORE_GC
656       // check if need to do GC
657       gc(NULL);
658 #endif
659
660       // check if there are new active tasks can be executed
661       executetasks();
662       if(busystatus) {
663         sendStall = false;
664       }
665
666 #ifndef INTERRUPT
667       while(receiveObject() != -1) {
668       }
669 #endif
670
671 #ifdef DEBUG
672       BAMBOO_DEBUGPRINT(0xee01);
673 #endif
674
675       // check if there are some pending objects,
676       // if yes, enqueue them and executetasks again
677       tocontinue = checkObjQueue();
678
679       if(!tocontinue) {
680         // check if stop
681         if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
682           if(isfirst) {
683 #ifdef DEBUG
684             BAMBOO_DEBUGPRINT(0xee03);
685 #endif
686             isfirst = false;
687           }
688           checkCoreStatus();
689         } else {
690           if(!sendStall) {
691 #ifdef DEBUG
692             BAMBOO_DEBUGPRINT(0xee09);
693 #endif
694 #ifdef PROFILE
695             if(!stall) {
696 #endif
697             if(isfirst) {
698               // wait for some time
699               int halt = 10000;
700 #ifdef DEBUG
701               BAMBOO_DEBUGPRINT(0xee0a);
702 #endif
703               while(halt--) {
704               }
705               isfirst = false;
706             } else {
707               // send StallMsg to startup core
708 #ifdef DEBUG
709               BAMBOO_DEBUGPRINT(0xee0b);
710 #endif
711               // send stall msg
712               send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
713                          self_numsendobjs, self_numreceiveobjs, false);
714               sendStall = true;
715               isfirst = true;
716               busystatus = false;
717             }
718 #ifdef PROFILE
719           }
720 #endif
721           } else {
722             isfirst = true;
723             busystatus = false;
724 #ifdef DEBUG
725             BAMBOO_DEBUGPRINT(0xee0c);
726 #endif
727           }                         // if(!sendStall)
728         }                   // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
729       }             // if(!tocontinue)
730     }       // while(true)
731   } // if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)
732
733 } // run()
734
735 struct ___createstartupobject____I_locals {
736   INTPTR size;
737   void * next;
738   struct  ___StartupObject___ * ___startupobject___;
739   struct ArrayObject * ___stringarray___;
740 }; // struct ___createstartupobject____I_locals
741
742 void createstartupobject(int argc,
743                          char ** argv) {
744   int i;
745
746   /* Allocate startup object     */
747 #ifdef MULTICORE_GC
748   struct ___createstartupobject____I_locals ___locals___={2, NULL, NULL, NULL};
749   struct ___StartupObject___ *startupobject=
750     (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
751   ___locals___.___startupobject___ = startupobject;
752   struct ArrayObject * stringarray=
753     allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
754   ___locals___.___stringarray___ = stringarray;
755 #else
756   struct ___StartupObject___ *startupobject=
757     (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
758   struct ArrayObject * stringarray=
759     allocate_newarray(STRINGARRAYTYPE, argc-1);
760 #endif
761   /* Build array of strings */
762   startupobject->___parameters___=stringarray;
763   for(i=1; i<argc; i++) {
764     int length=strlen(argv[i]);
765 #ifdef MULTICORE_GC
766     struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
767 #else
768     struct ___String___ *newstring=NewString(argv[i],length);
769 #endif
770     ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
771       newstring;
772   }
773
774   startupobject->version = 0;
775   startupobject->lock = NULL;
776
777   /* Set initialized flag for startup object */
778   flagorandinit(startupobject,1,0xFFFFFFFF);
779   enqueueObject(startupobject, NULL, 0);
780 #ifdef CACHEFLUSH
781   BAMBOO_CACHE_FLUSH_ALL();
782 #endif
783 }
784
785 int hashCodetpd(struct taskparamdescriptor *ftd) {
786   int hash=(int)ftd->task;
787   int i;
788   for(i=0; i<ftd->numParameters; i++) {
789     hash^=(int)ftd->parameterArray[i];
790   }
791   return hash;
792 }
793
794 int comparetpd(struct taskparamdescriptor *ftd1,
795                struct taskparamdescriptor *ftd2) {
796   int i;
797   if (ftd1->task!=ftd2->task)
798     return 0;
799   for(i=0; i<ftd1->numParameters; i++)
800     if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
801       return 0;
802   return 1;
803 }
804
805 /* This function sets a tag. */
806 #ifdef MULTICORE_GC
807 void tagset(void *ptr,
808             struct ___Object___ * obj,
809             struct ___TagDescriptor___ * tagd) {
810 #else
811 void tagset(struct ___Object___ * obj,
812             struct ___TagDescriptor___ * tagd) {
813 #endif
814   struct ArrayObject * ao=NULL;
815   struct ___Object___ * tagptr=obj->___tags___;
816   if (tagptr==NULL) {
817     obj->___tags___=(struct ___Object___ *)tagd;
818   } else {
819     /* Have to check if it is already set */
820     if (tagptr->type==TAGTYPE) {
821       struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
822       if (td==tagd) {
823         return;
824       }
825 #ifdef MULTICORE_GC
826       int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
827       struct ArrayObject * ao=
828         allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
829       obj=(struct ___Object___ *)ptrarray[2];
830       tagd=(struct ___TagDescriptor___ *)ptrarray[3];
831       td=(struct ___TagDescriptor___ *) obj->___tags___;
832 #else
833       ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
834 #endif
835
836       ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
837       ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
838       obj->___tags___=(struct ___Object___ *) ao;
839       ao->___cachedCode___=2;
840     } else {
841       /* Array Case */
842       int i;
843       struct ArrayObject *ao=(struct ArrayObject *) tagptr;
844       for(i=0; i<ao->___cachedCode___; i++) {
845         struct ___TagDescriptor___ * td=
846           ARRAYGET(ao, struct ___TagDescriptor___*, i);
847         if (td==tagd) {
848           return;
849         }
850       }
851       if (ao->___cachedCode___<ao->___length___) {
852         ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
853         ao->___cachedCode___++;
854       } else {
855 #ifdef MULTICORE_GC
856         int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
857         struct ArrayObject * aonew=
858           allocate_newarray(&ptrarray,TAGARRAYTYPE,
859                             TAGARRAYINTERVAL+ao->___length___);
860         obj=(struct ___Object___ *)ptrarray[2];
861         tagd=(struct ___TagDescriptor___ *) ptrarray[3];
862         ao=(struct ArrayObject *)obj->___tags___;
863 #else
864         struct ArrayObject * aonew=
865           allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
866 #endif
867
868         aonew->___cachedCode___=ao->___length___+1;
869         for(i=0; i<ao->___length___; i++) {
870           ARRAYSET(aonew, struct ___TagDescriptor___*, i,
871                    ARRAYGET(ao, struct ___TagDescriptor___*, i));
872         }
873         ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
874       }
875     }
876   }
877
878   {
879     struct ___Object___ * tagset=tagd->flagptr;
880     if(tagset==NULL) {
881       tagd->flagptr=obj;
882     } else if (tagset->type!=OBJECTARRAYTYPE) {
883 #ifdef MULTICORE_GC
884       int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
885       struct ArrayObject * ao=
886         allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
887       obj=(struct ___Object___ *)ptrarray[2];
888       tagd=(struct ___TagDescriptor___ *)ptrarray[3];
889 #else
890       struct ArrayObject * ao=
891         allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
892 #endif
893       ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
894       ARRAYSET(ao, struct ___Object___ *, 1, obj);
895       ao->___cachedCode___=2;
896       tagd->flagptr=(struct ___Object___ *)ao;
897     } else {
898       struct ArrayObject *ao=(struct ArrayObject *) tagset;
899       if (ao->___cachedCode___<ao->___length___) {
900         ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
901       } else {
902         int i;
903 #ifdef MULTICORE_GC
904         int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
905         struct ArrayObject * aonew=
906           allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
907                             OBJECTARRAYINTERVAL+ao->___length___);
908         obj=(struct ___Object___ *)ptrarray[2];
909         tagd=(struct ___TagDescriptor___ *)ptrarray[3];
910         ao=(struct ArrayObject *)tagd->flagptr;
911 #else
912         struct ArrayObject * aonew=
913           allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
914 #endif
915         aonew->___cachedCode___=ao->___cachedCode___+1;
916         for(i=0; i<ao->___length___; i++) {
917           ARRAYSET(aonew, struct ___Object___*, i,
918                    ARRAYGET(ao, struct ___Object___*, i));
919         }
920         ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
921         tagd->flagptr=(struct ___Object___ *) aonew;
922       }
923     }
924   }
925 }
926
927 /* This function clears a tag. */
928 #ifdef MULTICORE_GC
929 void tagclear(void *ptr,
930               struct ___Object___ * obj,
931               struct ___TagDescriptor___ * tagd) {
932 #else
933 void tagclear(struct ___Object___ * obj,
934               struct ___TagDescriptor___ * tagd) {
935 #endif
936   /* We'll assume that tag is alway there.
937      Need to statically check for this of course. */
938   struct ___Object___ * tagptr=obj->___tags___;
939
940   if (tagptr->type==TAGTYPE) {
941     if ((struct ___TagDescriptor___ *)tagptr==tagd)
942       obj->___tags___=NULL;
943   } else {
944     struct ArrayObject *ao=(struct ArrayObject *) tagptr;
945     int i;
946     for(i=0; i<ao->___cachedCode___; i++) {
947       struct ___TagDescriptor___ * td=
948         ARRAYGET(ao, struct ___TagDescriptor___ *, i);
949       if (td==tagd) {
950         ao->___cachedCode___--;
951         if (i<ao->___cachedCode___)
952           ARRAYSET(ao, struct ___TagDescriptor___ *, i,
953                    ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
954         ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
955         if (ao->___cachedCode___==0)
956           obj->___tags___=NULL;
957         goto PROCESSCLEAR;
958       }
959     }
960   }
961 PROCESSCLEAR:
962   {
963     struct ___Object___ *tagset=tagd->flagptr;
964     if (tagset->type!=OBJECTARRAYTYPE) {
965       if (tagset==obj)
966         tagd->flagptr=NULL;
967     } else {
968       struct ArrayObject *ao=(struct ArrayObject *) tagset;
969       int i;
970       for(i=0; i<ao->___cachedCode___; i++) {
971         struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
972         if (tobj==obj) {
973           ao->___cachedCode___--;
974           if (i<ao->___cachedCode___)
975             ARRAYSET(ao, struct ___Object___ *, i,
976                      ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
977           ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
978           if (ao->___cachedCode___==0)
979             tagd->flagptr=NULL;
980           goto ENDCLEAR;
981         }
982       }
983     }
984   }
985 ENDCLEAR:
986   return;
987 }
988
989 /* This function allocates a new tag. */
990 #ifdef MULTICORE_GC
991 struct ___TagDescriptor___ * allocate_tag(void *ptr,
992                                           int index) {
993   struct ___TagDescriptor___ * v=
994     (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
995                                               classsize[TAGTYPE]);
996 #else
997 struct ___TagDescriptor___ * allocate_tag(int index) {
998   struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
999 #endif
1000   v->type=TAGTYPE;
1001   v->flag=index;
1002   return v;
1003 }
1004
1005
1006
1007 /* This function updates the flag for object ptr.  It or's the flag
1008    with the or mask and and's it with the andmask. */
1009
1010 void flagbody(struct ___Object___ *ptr,
1011               int flag,
1012               struct parameterwrapper ** queues,
1013               int length,
1014               bool isnew);
1015
1016 int flagcomp(const int *val1, const int *val2) {
1017   return (*val1)-(*val2);
1018 }
1019
1020 void flagorand(void * ptr,
1021                int ormask,
1022                int andmask,
1023                struct parameterwrapper ** queues,
1024                int length) {
1025   {
1026     int oldflag=((int *)ptr)[1];
1027     int flag=ormask|oldflag;
1028     flag&=andmask;
1029     flagbody(ptr, flag, queues, length, false);
1030   }
1031 }
1032
1033 bool intflagorand(void * ptr,
1034                   int ormask,
1035                   int andmask) {
1036   {
1037     int oldflag=((int *)ptr)[1];
1038     int flag=ormask|oldflag;
1039     flag&=andmask;
1040     if (flag==oldflag)   /* Don't do anything */
1041       return false;
1042     else {
1043       flagbody(ptr, flag, NULL, 0, false);
1044       return true;
1045     }
1046   }
1047 }
1048
1049 void flagorandinit(void * ptr,
1050                    int ormask,
1051                    int andmask) {
1052   int oldflag=((int *)ptr)[1];
1053   int flag=ormask|oldflag;
1054   flag&=andmask;
1055   flagbody(ptr,flag,NULL,0,true);
1056 }
1057
1058 void flagbody(struct ___Object___ *ptr,
1059               int flag,
1060               struct parameterwrapper ** vqueues,
1061               int vlength,
1062               bool isnew) {
1063   struct parameterwrapper * flagptr = NULL;
1064   int i = 0;
1065   struct parameterwrapper ** queues = vqueues;
1066   int length = vlength;
1067   int next;
1068   int UNUSED, UNUSED2;
1069   int * enterflags = NULL;
1070   if((!isnew) && (queues == NULL)) {
1071     if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
1072       queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1073       length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1074     } else {
1075       return;
1076     }
1077   }
1078   ptr->flag=flag;
1079
1080   /*Remove object from all queues */
1081   for(i = 0; i < length; ++i) {
1082     flagptr = queues[i];
1083     ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
1084                   (int *) &enterflags, &UNUSED, &UNUSED2);
1085     ObjectHashremove(flagptr->objectset, (int)ptr);
1086     if (enterflags!=NULL)
1087       RUNFREE(enterflags);
1088   }
1089 }
1090
1091 void enqueueObject(void * vptr,
1092                    struct parameterwrapper ** vqueues,
1093                    int vlength) {
1094   struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1095
1096   {
1097     //struct QueueItem *tmpptr;
1098     struct parameterwrapper * parameter=NULL;
1099     int j;
1100     int i;
1101     struct parameterwrapper * prevptr=NULL;
1102     struct ___Object___ *tagptr=NULL;
1103     struct parameterwrapper ** queues = vqueues;
1104     int length = vlength;
1105     if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1106       return;
1107     }
1108     if(queues == NULL) {
1109       queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1110       length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1111     }
1112     tagptr=ptr->___tags___;
1113
1114     /* Outer loop iterates through all parameter queues an object of
1115        this type could be in.  */
1116     for(j = 0; j < length; ++j) {
1117       parameter = queues[j];
1118       /* Check tags */
1119       if (parameter->numbertags>0) {
1120         if (tagptr==NULL)
1121           goto nextloop;                               //that means the object has no tag
1122         //but that param needs tag
1123         else if(tagptr->type==TAGTYPE) {                         //one tag
1124           //struct ___TagDescriptor___ * tag=
1125           //(struct ___TagDescriptor___*) tagptr;
1126           for(i=0; i<parameter->numbertags; i++) {
1127             //slotid is parameter->tagarray[2*i];
1128             int tagid=parameter->tagarray[2*i+1];
1129             if (tagid!=tagptr->flag)
1130               goto nextloop;                                           /*We don't have this tag */
1131           }
1132         } else {                         //multiple tags
1133           struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1134           for(i=0; i<parameter->numbertags; i++) {
1135             //slotid is parameter->tagarray[2*i];
1136             int tagid=parameter->tagarray[2*i+1];
1137             int j;
1138             for(j=0; j<ao->___cachedCode___; j++) {
1139               if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1140                 goto foundtag;
1141             }
1142             goto nextloop;
1143 foundtag:
1144             ;
1145           }
1146         }
1147       }
1148
1149       /* Check flags */
1150       for(i=0; i<parameter->numberofterms; i++) {
1151         int andmask=parameter->intarray[i*2];
1152         int checkmask=parameter->intarray[i*2+1];
1153         if ((ptr->flag&andmask)==checkmask) {
1154           enqueuetasks(parameter, prevptr, ptr, NULL, 0);
1155           prevptr=parameter;
1156           break;
1157         }
1158       }
1159 nextloop:
1160       ;
1161     }
1162   }
1163 }
1164
1165 void enqueueObject_I(void * vptr,
1166                      struct parameterwrapper ** vqueues,
1167                      int vlength) {
1168   struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1169
1170   {
1171     //struct QueueItem *tmpptr;
1172     struct parameterwrapper * parameter=NULL;
1173     int j;
1174     int i;
1175     struct parameterwrapper * prevptr=NULL;
1176     struct ___Object___ *tagptr=NULL;
1177     struct parameterwrapper ** queues = vqueues;
1178     int length = vlength;
1179     if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1180       return;
1181     }
1182     if(queues == NULL) {
1183       queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1184       length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1185     }
1186     tagptr=ptr->___tags___;
1187
1188     /* Outer loop iterates through all parameter queues an object of
1189        this type could be in.  */
1190     for(j = 0; j < length; ++j) {
1191       parameter = queues[j];
1192       /* Check tags */
1193       if (parameter->numbertags>0) {
1194         if (tagptr==NULL)
1195           goto nextloop;                               //that means the object has no tag
1196         //but that param needs tag
1197         else if(tagptr->type==TAGTYPE) {                         //one tag
1198           //struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
1199           for(i=0; i<parameter->numbertags; i++) {
1200             //slotid is parameter->tagarray[2*i];
1201             int tagid=parameter->tagarray[2*i+1];
1202             if (tagid!=tagptr->flag)
1203               goto nextloop;                                           /*We don't have this tag */
1204           }
1205         } else {                         //multiple tags
1206           struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1207           for(i=0; i<parameter->numbertags; i++) {
1208             //slotid is parameter->tagarray[2*i];
1209             int tagid=parameter->tagarray[2*i+1];
1210             int j;
1211             for(j=0; j<ao->___cachedCode___; j++) {
1212               if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1213                 goto foundtag;
1214             }
1215             goto nextloop;
1216 foundtag:
1217             ;
1218           }
1219         }
1220       }
1221
1222       /* Check flags */
1223       for(i=0; i<parameter->numberofterms; i++) {
1224         int andmask=parameter->intarray[i*2];
1225         int checkmask=parameter->intarray[i*2+1];
1226         if ((ptr->flag&andmask)==checkmask) {
1227           enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1228           prevptr=parameter;
1229           break;
1230         }
1231       }
1232 nextloop:
1233       ;
1234     }
1235   }
1236 }
1237
1238
1239 int * getAliasLock(void ** ptrs,
1240                    int length,
1241                    struct RuntimeHash * tbl) {
1242   if(length == 0) {
1243     return (int*)(RUNMALLOC(sizeof(int)));
1244   } else {
1245     int i = 0;
1246     int locks[length];
1247     int locklen = 0;
1248     bool redirect = false;
1249     int redirectlock = 0;
1250     for(; i < length; i++) {
1251       struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1252       int lock = 0;
1253       int j = 0;
1254       if(ptr->lock == NULL) {
1255         lock = (int)(ptr);
1256       } else {
1257         lock = (int)(ptr->lock);
1258       }
1259       if(redirect) {
1260         if(lock != redirectlock) {
1261           RuntimeHashadd(tbl, lock, redirectlock);
1262         }
1263       } else {
1264         if(RuntimeHashcontainskey(tbl, lock)) {
1265           // already redirected
1266           redirect = true;
1267           RuntimeHashget(tbl, lock, &redirectlock);
1268           for(; j < locklen; j++) {
1269             if(locks[j] != redirectlock) {
1270               RuntimeHashadd(tbl, locks[j], redirectlock);
1271             }
1272           }
1273         } else {
1274           bool insert = true;
1275           for(j = 0; j < locklen; j++) {
1276             if(locks[j] == lock) {
1277               insert = false;
1278               break;
1279             } else if(locks[j] > lock) {
1280               break;
1281             }
1282           }
1283           if(insert) {
1284             int h = locklen;
1285             for(; h > j; h--) {
1286               locks[h] = locks[h-1];
1287             }
1288             locks[j] = lock;
1289             locklen++;
1290           }
1291         }
1292       }
1293     }
1294     if(redirect) {
1295       return (int *)redirectlock;
1296     } else {
1297       return (int *)(locks[0]);
1298     }
1299   }
1300 }
1301
1302 void addAliasLock(void * ptr,
1303                   int lock) {
1304   struct ___Object___ * obj = (struct ___Object___ *)ptr;
1305   if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1306     // originally no alias lock associated or have a different alias lock
1307     // flush it as the new one
1308     obj->lock = (int *)lock;
1309   }
1310 }
1311
1312 #ifdef PROFILE
1313 inline void setTaskExitIndex(int index) {
1314   taskInfoArray[taskInfoIndex]->exitIndex = index;
1315 }
1316
1317 inline void addNewObjInfo(void * nobj) {
1318   if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1319     taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1320   }
1321   addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1322 }
1323 #endif
1324
1325 #ifdef MULTICORE_GC
1326 // Only allocate local mem chunks to each core.
1327 // If a core has used up its local shared memory, start gc.
1328 void * localmalloc_I(int coren,
1329                      int isize,
1330                      int * allocsize) {
1331   void * mem = NULL;
1332   int i = 0;
1333   int j = 0;
1334   int tofindb = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1335   int totest = tofindb;
1336   int bound = BAMBOO_SMEM_SIZE_L;
1337   int foundsmem = 0;
1338   int size = 0;
1339   do {
1340     bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1341     int nsize = bamboo_smemtbl[totest];
1342     bool islocal = true;
1343     if(nsize < bound) {
1344       bool tocheck = true;
1345       // have some space in the block
1346       if(totest == tofindb) {
1347                 // the first partition
1348                 size = bound - nsize;
1349       } else if(nsize == 0) {
1350                 // an empty partition, can be appended
1351                 size += bound;
1352       } else {
1353                 // not an empty partition, can not be appended
1354                 // the last continuous block is not big enough, go to check the next
1355                 // local block
1356                 islocal = true;
1357                 tocheck = false;
1358       } // if(totest == tofindb) else if(nsize == 0) else ...
1359       if(tocheck) {
1360                 if(size >= isize) {
1361                   // have enough space in the block, malloc
1362                   foundsmem = 1;
1363                   break;
1364                 } else {
1365                   // no enough space yet, try to append next continuous block
1366                   islocal = false;
1367                 }  // if(size > isize) else ...
1368       }  // if(tocheck)
1369     } // if(nsize < bound)
1370     if(islocal) {
1371       // no space in the block, go to check the next block
1372       i++;
1373       if(2==i) {
1374                 i = 0;
1375                 j++;
1376       }
1377       tofindb = totest = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1378     } else {
1379       totest += 1;
1380     }  // if(islocal) else ...
1381     if(totest > gcnumblock-1-bamboo_reserved_smem) {
1382       // no more local mem, do not find suitable block
1383       foundsmem = 2;
1384       break;
1385     }  // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1386   } while(true);
1387
1388   if(foundsmem == 1) {
1389     // find suitable block
1390     mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1391           (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1392           (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1393     *allocsize = size;
1394     // set bamboo_smemtbl
1395     for(i = tofindb; i <= totest; i++) {
1396       bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1397     }
1398   } else if(foundsmem == 2) {
1399     // no suitable block
1400     *allocsize = 0;
1401   }
1402
1403   return mem;
1404 } // void * localmalloc_I(int, int, int *)
1405
1406 // Allocate the local shared memory to each core with the highest priority,
1407 // if a core has used up its local shared memory, try to allocate the 
1408 // shared memory that belong to its neighbours, if also failed, start gc.
1409 void * fixedmalloc_I(int coren,
1410                      int isize,
1411                      int * allocsize) {
1412   void * mem = NULL;
1413   int i = 0;
1414   int j = 0;
1415   int k = 0;
1416   //int core2test[5]={coren,-1,-1,-1,-1};//(x,y),(x-1,y),(x+1,y),(x,y-1),(x,y+1)
1417   int coords_x = bamboo_cpu2coords[coren*2];
1418   int coords_y = bamboo_cpu2coords[coren*2+1];
1419   int ii = 1;
1420   /*if(coords_x != 0) {
1421         core2test[ii++] = bamboo_coords2cpu[coords_x-1][coords_y]; 
1422   }
1423   if(coords_x != 7) {
1424         core2test[ii++] = bamboo_coords2cpu[coords_x+1][coords_y];
1425   }
1426   if(coords_y != 0) {
1427         core2test[ii++] = bamboo_coords2cpu[coords_x][coords_y-1];
1428   }
1429   if(coords_y != 7) {
1430         core2test[ii++] = bamboo_coords2cpu[coords_x][coords_y+1];
1431   }*/
1432   int tofindb = gc_core2block[2*core2test[coren][k]+i]+(NUMCORES4GC*2)*j;
1433   int totest = tofindb;
1434   int bound = BAMBOO_SMEM_SIZE_L;
1435   int foundsmem = 0;
1436   int size = 0;
1437   do {
1438     bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1439     int nsize = bamboo_smemtbl[totest];
1440     bool islocal = true;
1441     if(nsize < bound) {
1442       bool tocheck = true;
1443       // have some space in the block
1444       if(totest == tofindb) {
1445                 // the first partition
1446                 size = bound - nsize;
1447       } else if(nsize == 0) {
1448                 // an empty partition, can be appended
1449                 size += bound;
1450       } else {
1451                 // not an empty partition, can not be appended
1452                 // the last continuous block is not big enough, go to check the next
1453                 // local block
1454                 islocal = true;
1455                 tocheck = false;
1456       } // if(totest == tofindb) else if(nsize == 0) else ...
1457       if(tocheck) {
1458                 if(size >= isize) {
1459                   // have enough space in the block, malloc
1460                   foundsmem = 1;
1461                   break;
1462                 } else {
1463                   // no enough space yet, try to append next continuous block
1464                   // TODO may consider to go to next local block?
1465                   islocal = false;
1466                 }  // if(size > isize) else ...
1467       }  // if(tocheck)
1468     } // if(nsize < bound)
1469     if(islocal) {
1470       // no space in the block, go to check the next block
1471       i++;
1472       if(2==i) {
1473                 i = 0;
1474                 j++;
1475       }
1476       tofindb=totest=gc_core2block[2*core2test[coren][k]+i]+(NUMCORES4GC*2)*j;
1477     } else {
1478       totest += 1;
1479     }  // if(islocal) else ...
1480     if(totest > gcnumblock-1-bamboo_reserved_smem) {
1481       // no more local mem, do not find suitable block on local mem
1482           // try to malloc shared memory assigned to the neighbour cores
1483           do{
1484                 k++;
1485                 if(k > 4) {
1486                   // no more memory available on either coren or its neighbour cores
1487                   foundsmem = 2;
1488                   goto memsearchresult;
1489                 }
1490           } while(core2test[coren][k] == -1);
1491           i = 0;
1492           j = 0;
1493           tofindb=totest=gc_core2block[2*core2test[coren][k]+i]+(NUMCORES4GC*2)*j;
1494     }  // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1495   } while(true);
1496
1497 memsearchresult:
1498   if(foundsmem == 1) {
1499     // find suitable block
1500     mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1501           (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1502           (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1503     *allocsize = size;
1504     // set bamboo_smemtbl
1505     for(i = tofindb; i <= totest; i++) {
1506       bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1507     }
1508   } else if(foundsmem == 2) {
1509     // no suitable block
1510     *allocsize = 0;
1511   }
1512
1513   return mem;
1514 } // void * fixedmalloc_I(int, int, int *)
1515
1516 // Allocate all the memory chunks globally, do not consider the host cores
1517 // When all the shared memory are used up, start gc.
1518 void * globalmalloc_I(int coren,
1519                       int isize,
1520                       int * allocsize) {
1521   void * mem = NULL;
1522   int tofindb = bamboo_free_block;       //0;
1523   int totest = tofindb;
1524   int bound = BAMBOO_SMEM_SIZE_L;
1525   int foundsmem = 0;
1526   int size = 0;
1527   if(tofindb > gcnumblock-1-bamboo_reserved_smem) {
1528         // Out of shared memory
1529     *allocsize = 0;
1530     return NULL;
1531   }
1532   do {
1533     bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1534     int nsize = bamboo_smemtbl[totest];
1535     bool isnext = false;
1536     if(nsize < bound) {
1537       bool tocheck = true;
1538       // have some space in the block
1539       if(totest == tofindb) {
1540                 // the first partition
1541                 size = bound - nsize;
1542       } else if(nsize == 0) {
1543                 // an empty partition, can be appended
1544                 size += bound;
1545       } else {
1546                 // not an empty partition, can not be appended
1547                 // the last continuous block is not big enough, start another block
1548                 isnext = true;
1549                 tocheck = false;
1550       }  // if(totest == tofindb) else if(nsize == 0) else ...
1551       if(tocheck) {
1552                 if(size >= isize) {
1553                   // have enough space in the block, malloc
1554                   foundsmem = 1;
1555                   break;
1556                 }  // if(size > isize)
1557       }   // if(tocheck)
1558     } else {
1559       isnext = true;
1560     }            // if(nsize < bound) else ...
1561     totest += 1;
1562     if(totest > gcnumblock-1-bamboo_reserved_smem) {
1563       // no more local mem, do not find suitable block
1564       foundsmem = 2;
1565       break;
1566     }             // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1567     if(isnext) {
1568       // start another block
1569       tofindb = totest;
1570     } // if(islocal)
1571   } while(true);
1572
1573   if(foundsmem == 1) {
1574     // find suitable block
1575     mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1576           (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1577           (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1578     *allocsize = size;
1579     // set bamboo_smemtbl
1580     for(int i = tofindb; i <= totest; i++) {
1581       bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1582     }
1583     if(tofindb == bamboo_free_block) {
1584       bamboo_free_block = totest+1;
1585     }
1586   } else if(foundsmem == 2) {
1587     // no suitable block
1588     *allocsize = 0;
1589     mem = NULL;
1590   }
1591
1592   return mem;
1593 } // void * globalmalloc_I(int, int, int *)
1594 #endif // #ifdef MULTICORE_GC
1595
1596 // malloc from the shared memory
1597 void * smemalloc_I(int coren,
1598                    int size,
1599                    int * allocsize) {
1600   void * mem = NULL;
1601 #ifdef MULTICORE_GC
1602   int isize = size+(BAMBOO_CACHE_LINE_SIZE);
1603
1604   // go through the bamboo_smemtbl for suitable partitions
1605   switch(bamboo_smem_mode) {
1606   case SMEMLOCAL: {
1607     mem = localmalloc_I(coren, isize, allocsize);
1608     break;
1609   }
1610
1611   case SMEMFIXED: {
1612     // TODO not supported yet
1613     //BAMBOO_EXIT(0xe001);
1614         mem = fixedmalloc_I(coren, isize, allocsize);
1615     break;
1616   }
1617
1618   case SMEMMIXED: {
1619     // TODO not supported yet
1620     BAMBOO_EXIT(0xe002);
1621     break;
1622   }
1623
1624   case SMEMGLOBAL: {
1625     mem = globalmalloc_I(coren, isize, allocsize);
1626     break;
1627   }
1628
1629   default:
1630     break;
1631   }
1632
1633   if(mem == NULL) {
1634 #else
1635   // TODO
1636 #ifdef PROFILE
1637   /*if(!interruptInfoOverflow) {
1638     InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
1639     interruptInfoArray[interruptInfoIndex] = intInfo;
1640     intInfo->startTime = BAMBOO_GET_EXE_TIME();
1641     intInfo->endTime = -1;
1642   }*/
1643 #endif  
1644   int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size) : (BAMBOO_SMEM_SIZE);
1645   //mem = mspace_calloc(bamboo_free_msp, 1, toallocate);
1646   if(toallocate > bamboo_free_smem_size) {
1647         // no enough mem
1648         mem = NULL;
1649   } else {
1650         mem = (void *)bamboo_free_smemp;
1651         bamboo_free_smemp = ((void*)bamboo_free_smemp) + toallocate;
1652         bamboo_free_smem_size -= toallocate;
1653         //BAMBOO_MEMSET_WH(mem, '\0', toallocate);
1654   }
1655   *allocsize = toallocate;
1656 #ifdef PROFILE
1657   /*if(!interruptInfoOverflow) {
1658     interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
1659     interruptInfoIndex++;
1660     if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
1661       interruptInfoOverflow = true;
1662     }
1663   }*/
1664 #endif
1665   if(mem == NULL) {
1666 #endif // MULTICORE_GC
1667     // no enough shared global memory
1668     *allocsize = 0;
1669 #ifdef MULTICORE_GC
1670     gcflag = true;
1671     return NULL;
1672 #else
1673     BAMBOO_DEBUGPRINT(0xa001);
1674     BAMBOO_EXIT(0xa001);
1675 #endif
1676   }
1677   return mem;
1678 }  // void * smemalloc_I(int, int, int)
1679
1680 INLINE int checkMsgLength_I(int size) {
1681 #ifdef DEBUG
1682 #ifndef TILERA
1683   BAMBOO_DEBUGPRINT(0xcccc);
1684 #endif
1685 #endif
1686   int type = msgdata[msgdataindex];
1687   switch(type) {
1688   case STATUSCONFIRM:
1689   case TERMINATE:
1690 #ifdef MULTICORE_GC
1691   case GCSTARTINIT:
1692   case GCSTART:
1693   case GCSTARTMAPINFO:
1694   case GCSTARTFLUSH:
1695   case GCFINISH:
1696   case GCMARKCONFIRM:
1697   case GCLOBJREQUEST:
1698 #endif
1699     {
1700       msglength = 1;
1701       break;
1702     }
1703
1704   case PROFILEOUTPUT:
1705   case PROFILEFINISH:
1706 #ifdef MULTICORE_GC
1707   case GCSTARTCOMPACT:
1708   case GCMARKEDOBJ:
1709   case GCFINISHINIT:
1710   case GCFINISHMAPINFO:
1711   case GCFINISHFLUSH:
1712 #endif
1713     {
1714       msglength = 2;
1715       break;
1716     }
1717
1718   case MEMREQUEST:
1719   case MEMRESPONSE:
1720 #ifdef MULTICORE_GC
1721   case GCMAPREQUEST:
1722   case GCMAPINFO:
1723   case GCMAPTBL:
1724   case GCLOBJMAPPING:
1725 #endif
1726     {
1727       msglength = 3;
1728       break;
1729     }
1730
1731   case TRANSTALL:
1732   case LOCKGROUNT:
1733   case LOCKDENY:
1734   case LOCKRELEASE:
1735   case REDIRECTGROUNT:
1736   case REDIRECTDENY:
1737   case REDIRECTRELEASE:
1738 #ifdef MULTICORE_GC
1739   case GCFINISHMARK:
1740   case GCMOVESTART:
1741 #endif
1742     {
1743       msglength = 4;
1744       break;
1745     }
1746
1747   case LOCKREQUEST:
1748   case STATUSREPORT:
1749 #ifdef MULTICORE_GC
1750   case GCFINISHCOMPACT:
1751   case GCMARKREPORT:
1752 #endif
1753     {
1754       msglength = 5;
1755       break;
1756     }
1757
1758   case REDIRECTLOCK:
1759   {
1760     msglength = 6;
1761     break;
1762   }
1763
1764   case TRANSOBJ:                // nonfixed size
1765 #ifdef MULTICORE_GC
1766   case GCLOBJINFO:
1767 #endif
1768     {             // nonfixed size
1769       if(size > 1) {
1770         msglength = msgdata[msgdataindex+1];
1771       } else {
1772         return -1;
1773       }
1774       break;
1775     }
1776
1777   default:
1778   {
1779     BAMBOO_DEBUGPRINT_REG(type);
1780         BAMBOO_DEBUGPRINT_REG(size);
1781     BAMBOO_DEBUGPRINT_REG(msgdataindex);
1782         BAMBOO_DEBUGPRINT_REG(msgdatalast);
1783         BAMBOO_DEBUGPRINT_REG(msgdatafull);
1784     int i = 6;
1785     while(i-- > 0) {
1786       BAMBOO_DEBUGPRINT(msgdata[msgdataindex+i]);
1787     }
1788     BAMBOO_EXIT(0xd005);
1789     break;
1790   }
1791   }
1792 #ifdef DEBUG
1793 #ifndef TILERA
1794   BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
1795 #endif
1796 #endif
1797 #ifdef DEBUG
1798 #ifndef TILERA
1799   BAMBOO_DEBUGPRINT(0xffff);
1800 #endif
1801 #endif
1802   return msglength;
1803 }
1804
1805 INLINE void processmsg_transobj_I() {
1806   MSG_INDEXINC_I();
1807   struct transObjInfo * transObj=RUNMALLOC_I(sizeof(struct transObjInfo));
1808   int k = 0;
1809 #ifdef DEBUG
1810 #ifndef CLOSE_PRINT
1811   BAMBOO_DEBUGPRINT(0xe880);
1812 #endif
1813 #endif
1814   if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1815 #ifndef CLOSE_PRINT
1816     BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
1817 #endif
1818     BAMBOO_EXIT(0xa002);
1819   }
1820   // store the object and its corresponding queue info, enqueue it later
1821   transObj->objptr = (void *)msgdata[msgdataindex];       //[2]
1822   MSG_INDEXINC_I();
1823   transObj->length = (msglength - 3) / 2;
1824   transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
1825   for(k = 0; k < transObj->length; ++k) {
1826     transObj->queues[2*k] = msgdata[msgdataindex];             //[3+2*k];
1827     MSG_INDEXINC_I();
1828 #ifdef DEBUG
1829 #ifndef CLOSE_PRINT
1830     //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
1831 #endif
1832 #endif
1833     transObj->queues[2*k+1] = msgdata[msgdataindex];        //[3+2*k+1];
1834     MSG_INDEXINC_I();
1835 #ifdef DEBUG
1836 #ifndef CLOSE_PRINT
1837     //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
1838 #endif
1839 #endif
1840   }
1841   // check if there is an existing duplicate item
1842   {
1843     struct QueueItem * qitem = getHead(&objqueue);
1844     struct QueueItem * prev = NULL;
1845     while(qitem != NULL) {
1846       struct transObjInfo * tmpinfo =
1847         (struct transObjInfo *)(qitem->objectptr);
1848       if(tmpinfo->objptr == transObj->objptr) {
1849         // the same object, remove outdate one
1850         RUNFREE(tmpinfo->queues);
1851         RUNFREE(tmpinfo);
1852         removeItem(&objqueue, qitem);
1853         //break;
1854       } else {
1855         prev = qitem;
1856       }
1857       if(prev == NULL) {
1858         qitem = getHead(&objqueue);
1859       } else {
1860         qitem = getNextQueueItem(prev);
1861       }
1862     }
1863     addNewItem_I(&objqueue, (void *)transObj);
1864   }
1865   ++(self_numreceiveobjs);
1866 }
1867
1868 INLINE void processmsg_transtall_I() {
1869   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1870     // non startup core can not receive stall msg
1871 #ifndef CLOSE_PRINT
1872     BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
1873 #endif
1874     BAMBOO_EXIT(0xa003);
1875   }
1876   int num_core = msgdata[msgdataindex];       //[1]
1877   MSG_INDEXINC_I();
1878   if(num_core < NUMCORESACTIVE) {
1879 #ifdef DEBUG
1880 #ifndef CLOSE_PRINT
1881     BAMBOO_DEBUGPRINT(0xe881);
1882 #endif
1883 #endif
1884     corestatus[num_core] = 0;
1885     numsendobjs[num_core] = msgdata[msgdataindex];             //[2];
1886     MSG_INDEXINC_I();
1887     numreceiveobjs[num_core] = msgdata[msgdataindex];             //[3];
1888     MSG_INDEXINC_I();
1889   }
1890 }
1891
1892 #ifndef MULTICORE_GC
1893 INLINE void processmsg_lockrequest_I() {
1894   // check to see if there is a lock exist for the required obj
1895   // msgdata[1] -> lock type
1896   int locktype = msgdata[msgdataindex];       //[1];
1897   MSG_INDEXINC_I();
1898   int data2 = msgdata[msgdataindex];       // obj pointer
1899   MSG_INDEXINC_I();
1900   int data3 = msgdata[msgdataindex];       // lock
1901   MSG_INDEXINC_I();
1902   int data4 = msgdata[msgdataindex];       // request core
1903   MSG_INDEXINC_I();
1904   // -1: redirected, 0: approved, 1: denied
1905   int deny=processlockrequest(locktype, data3, data2, data4, data4, true);
1906   if(deny == -1) {
1907     // this lock request is redirected
1908     return;
1909   } else {
1910     // send response msg
1911     // for 32 bit machine, the size is always 4 words, cache the msg first
1912     int tmp = deny==1 ? LOCKDENY : LOCKGROUNT;
1913     if(BAMBOO_CHECK_SEND_MODE()) {
1914     cache_msg_4(data4, tmp, locktype, data2, data3);
1915     } else {
1916     send_msg_4(data4, tmp, locktype, data2, data3, true);
1917     }
1918   }
1919 }
1920
1921 INLINE void processmsg_lockgrount_I() {
1922   MSG_INDEXINC_I();
1923   if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1924 #ifndef CLOSE_PRINT
1925     BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
1926 #endif
1927     BAMBOO_EXIT(0xa004);
1928   }
1929   int data2 = msgdata[msgdataindex];
1930   MSG_INDEXINC_I();
1931   int data3 = msgdata[msgdataindex];
1932   MSG_INDEXINC_I();
1933   if((lockobj == data2) && (lock2require == data3)) {
1934 #ifdef DEBUG
1935 #ifndef CLOSE_PRINT
1936     BAMBOO_DEBUGPRINT(0xe882);
1937 #endif
1938 #endif
1939     lockresult = 1;
1940     lockflag = true;
1941 #ifndef INTERRUPT
1942     reside = false;
1943 #endif
1944   } else {
1945     // conflicts on lockresults
1946 #ifndef CLOSE_PRINT
1947     BAMBOO_DEBUGPRINT_REG(data2);
1948 #endif
1949     BAMBOO_EXIT(0xa005);
1950   }
1951 }
1952
1953 INLINE void processmsg_lockdeny_I() {
1954   MSG_INDEXINC_I();
1955   int data2 = msgdata[msgdataindex];
1956   MSG_INDEXINC_I();
1957   int data3 = msgdata[msgdataindex];
1958   MSG_INDEXINC_I();
1959   if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1960 #ifndef CLOSE_PRINT
1961     BAMBOO_DEBUGPRINT_REG(data2);
1962 #endif
1963     BAMBOO_EXIT(0xa006);
1964   }
1965   if((lockobj == data2) && (lock2require == data3)) {
1966 #ifdef DEBUG
1967 #ifndef CLOSE_PRINT
1968     BAMBOO_DEBUGPRINT(0xe883);
1969 #endif
1970 #endif
1971     lockresult = 0;
1972     lockflag = true;
1973 #ifndef INTERRUPT
1974     reside = false;
1975 #endif
1976   } else {
1977     // conflicts on lockresults
1978 #ifndef CLOSE_PRINT
1979     BAMBOO_DEBUGPRINT_REG(data2);
1980 #endif
1981     BAMBOO_EXIT(0xa007);
1982   }
1983 }
1984
1985 INLINE void processmsg_lockrelease_I() {
1986   int data1 = msgdata[msgdataindex];
1987   MSG_INDEXINC_I();
1988   int data2 = msgdata[msgdataindex];
1989   MSG_INDEXINC_I();
1990   // receive lock release msg
1991   processlockrelease(data1, data2, 0, false);
1992 }
1993
1994 INLINE void processmsg_redirectlock_I() {
1995   // check to see if there is a lock exist for the required obj
1996   int data1 = msgdata[msgdataindex];
1997   MSG_INDEXINC_I();       //msgdata[1]; // lock type
1998   int data2 = msgdata[msgdataindex];
1999   MSG_INDEXINC_I();      //msgdata[2]; // obj pointer
2000   int data3 = msgdata[msgdataindex];
2001   MSG_INDEXINC_I();       //msgdata[3]; // redirect lock
2002   int data4 = msgdata[msgdataindex];
2003   MSG_INDEXINC_I();       //msgdata[4]; // root request core
2004   int data5 = msgdata[msgdataindex];
2005   MSG_INDEXINC_I();       //msgdata[5]; // request core
2006   int deny = processlockrequest(data1, data3, data2, data5, data4, true);
2007   if(deny == -1) {
2008     // this lock request is redirected
2009     return;
2010   } else {
2011     // send response msg
2012     // for 32 bit machine, the size is always 4 words, cache the msg first
2013     if(BAMBOO_CHECK_SEND_MODE()) {
2014     cache_msg_4(data4, deny==1 ? REDIRECTDENY : REDIRECTGROUNT,
2015                 data1, data2, data3);
2016     } else {
2017     send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
2018                data1, data2, data3, true);
2019     }
2020   }
2021 }
2022
2023 INLINE void processmsg_redirectgrount_I() {
2024   MSG_INDEXINC_I();
2025   int data2 = msgdata[msgdataindex];
2026   MSG_INDEXINC_I();
2027   if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2028 #ifndef CLOSE_PRINT
2029     BAMBOO_DEBUGPRINT_REG(data2);
2030 #endif
2031     BAMBOO_EXIT(0xa00a);
2032   }
2033   if(lockobj == data2) {
2034 #ifdef DEBUG
2035 #ifndef CLOSE_PRINT
2036     BAMBOO_DEBUGPRINT(0xe891);
2037 #endif
2038 #endif
2039     int data3 = msgdata[msgdataindex];
2040     MSG_INDEXINC_I();
2041     lockresult = 1;
2042     lockflag = true;
2043     RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
2044 #ifndef INTERRUPT
2045     reside = false;
2046 #endif
2047   } else {
2048     // conflicts on lockresults
2049 #ifndef CLOSE_PRINT
2050     BAMBOO_DEBUGPRINT_REG(data2);
2051 #endif
2052     BAMBOO_EXIT(0xa00b);
2053   }
2054 }
2055
2056 INLINE void processmsg_redirectdeny_I() {
2057   MSG_INDEXINC_I();
2058   int data2 = msgdata[msgdataindex];
2059   MSG_INDEXINC_I();
2060   if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2061 #ifndef CLOSE_PRINT
2062     BAMBOO_DEBUGPRINT_REG(data2);
2063 #endif
2064     BAMBOO_EXIT(0xa00c);
2065   }
2066   if(lockobj == data2) {
2067 #ifdef DEBUG
2068 #ifndef CLOSE_PRINT
2069     BAMBOO_DEBUGPRINT(0xe892);
2070 #endif
2071 #endif
2072     lockresult = 0;
2073     lockflag = true;
2074 #ifndef INTERRUPT
2075     reside = false;
2076 #endif
2077   } else {
2078     // conflicts on lockresults
2079 #ifndef CLOSE_PRINT
2080     BAMBOO_DEBUGPRINT_REG(data2);
2081 #endif
2082     BAMBOO_EXIT(0xa00d);
2083   }
2084 }
2085
2086 INLINE void processmsg_redirectrelease_I() {
2087   int data1 = msgdata[msgdataindex];
2088   MSG_INDEXINC_I();
2089   int data2 = msgdata[msgdataindex];
2090   MSG_INDEXINC_I();
2091   int data3 = msgdata[msgdataindex];
2092   MSG_INDEXINC_I();
2093   processlockrelease(data1, data2, data3, true);
2094 }
2095 #endif // #ifndef MULTICORE_GC
2096
2097 #ifdef PROFILE
2098 INLINE void processmsg_profileoutput_I() {
2099   if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
2100     // startup core can not receive profile output finish msg
2101     BAMBOO_EXIT(0xa008);
2102   }
2103 #ifdef DEBUG
2104 #ifndef CLOSE_PRINT
2105   BAMBOO_DEBUGPRINT(0xe885);
2106 #endif
2107 #endif
2108   stall = true;
2109   totalexetime = msgdata[msgdataindex];       //[1]
2110   MSG_INDEXINC_I();
2111   outputProfileData();
2112   // cache the msg first
2113   if(BAMBOO_CHECK_SEND_MODE()) {
2114   cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
2115   } else {
2116   send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE, true);
2117   }
2118 }
2119
2120 INLINE void processmsg_profilefinish_I() {
2121   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2122     // non startup core can not receive profile output finish msg
2123 #ifndef CLOSE_PRINT
2124     BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex /*1*/]);
2125 #endif
2126     BAMBOO_EXIT(0xa009);
2127   }
2128 #ifdef DEBUG
2129 #ifndef CLOSE_PRINT
2130   BAMBOO_DEBUGPRINT(0xe886);
2131 #endif
2132 #endif
2133   int data1 = msgdata[msgdataindex];
2134   MSG_INDEXINC_I();
2135   profilestatus[data1] = 0;
2136 }
2137 #endif // #ifdef PROFILE
2138
2139 INLINE void processmsg_statusconfirm_I() {
2140   if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2141      || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2142     // wrong core to receive such msg
2143     BAMBOO_EXIT(0xa00e);
2144   } else {
2145     // send response msg
2146 #ifdef DEBUG
2147 #ifndef CLOSE_PRINT
2148     BAMBOO_DEBUGPRINT(0xe887);
2149 #endif
2150 #endif
2151     // cache the msg first
2152     if(BAMBOO_CHECK_SEND_MODE()) {
2153     cache_msg_5(STARTUPCORE, STATUSREPORT,
2154                 busystatus ? 1 : 0, BAMBOO_NUM_OF_CORE,
2155                 self_numsendobjs, self_numreceiveobjs);
2156     } else {
2157     send_msg_5(STARTUPCORE, STATUSREPORT, busystatus?1:0,
2158                BAMBOO_NUM_OF_CORE, self_numsendobjs,
2159                self_numreceiveobjs, true);
2160     }
2161   }
2162 }
2163
2164 INLINE void processmsg_statusreport_I() {
2165   int data1 = msgdata[msgdataindex];
2166   MSG_INDEXINC_I();
2167   int data2 = msgdata[msgdataindex];
2168   MSG_INDEXINC_I();
2169   int data3 = msgdata[msgdataindex];
2170   MSG_INDEXINC_I();
2171   int data4 = msgdata[msgdataindex];
2172   MSG_INDEXINC_I();
2173   // receive a status confirm info
2174   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2175     // wrong core to receive such msg
2176 #ifndef CLOSE_PRINT
2177     BAMBOO_DEBUGPRINT_REG(data2);
2178 #endif
2179     BAMBOO_EXIT(0xa00f);
2180   } else {
2181 #ifdef DEBUG
2182 #ifndef CLOSE_PRINT
2183     BAMBOO_DEBUGPRINT(0xe888);
2184 #endif
2185 #endif
2186     if(waitconfirm) {
2187       numconfirm--;
2188     }
2189     corestatus[data2] = data1;
2190     numsendobjs[data2] = data3;
2191     numreceiveobjs[data2] = data4;
2192   }
2193 }
2194
2195 INLINE void processmsg_terminate_I() {
2196 #ifdef DEBUG
2197 #ifndef CLOSE_PRINT
2198   BAMBOO_DEBUGPRINT(0xe889);
2199 #endif
2200 #endif
2201   disruntimedata();
2202   BAMBOO_EXIT_APP(0);
2203 }
2204
2205 INLINE void processmsg_memrequest_I() {
2206 #ifdef PROFILE
2207   if(!interruptInfoOverflow) {
2208     InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
2209     interruptInfoArray[interruptInfoIndex] = intInfo;
2210     intInfo->startTime = BAMBOO_GET_EXE_TIME();
2211     intInfo->endTime = -1;
2212   }
2213 #endif
2214   int data1 = msgdata[msgdataindex];
2215   MSG_INDEXINC_I();
2216   int data2 = msgdata[msgdataindex];
2217   MSG_INDEXINC_I();
2218   // receive a shared memory request msg
2219   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2220     // wrong core to receive such msg
2221 #ifndef CLOSE_PRINT
2222     BAMBOO_DEBUGPRINT_REG(data2);
2223 #endif
2224     BAMBOO_EXIT(0xa010);
2225   } else {
2226 #ifdef DEBUG
2227 #ifndef CLOSE_PRINT
2228     BAMBOO_DEBUGPRINT(0xe88a);
2229 #endif
2230 #endif
2231     int allocsize = 0;
2232     void * mem = NULL;
2233 #ifdef MULTICORE_GC
2234     if(gcprocessing) {
2235       // is currently doing gc, dump this msg
2236       if(INITPHASE == gcphase) {
2237         // if still in the initphase of gc, send a startinit msg again,
2238         // cache the msg first
2239         if(BAMBOO_CHECK_SEND_MODE()) {
2240         cache_msg_1(data2, GCSTARTINIT);
2241         } else {
2242         send_msg_1(data2, GCSTARTINIT, true);
2243         }
2244       }
2245     } else {
2246 #endif
2247     mem = smemalloc_I(data2, data1, &allocsize);
2248     if(mem != NULL) {
2249       // send the start_va to request core, cache the msg first
2250       if(BAMBOO_CHECK_SEND_MODE()) {
2251       cache_msg_3(data2, MEMRESPONSE, mem, allocsize);
2252       } else {
2253       send_msg_3(data2, MEMRESPONSE, mem, allocsize, true);
2254       }
2255     } // if mem == NULL, the gcflag of the startup core has been set
2256     // and the gc should be started later, then a GCSTARTINIT msg
2257     // will be sent to the requesting core to notice it to start gc
2258     // and try malloc again
2259 #ifdef MULTICORE_GC
2260   }
2261 #endif
2262   }
2263 #ifdef PROFILE
2264   if(!interruptInfoOverflow) {
2265     interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
2266     interruptInfoIndex++;
2267     if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
2268       interruptInfoOverflow = true;
2269     }
2270   }
2271 #endif
2272 }
2273
2274 INLINE void processmsg_memresponse_I() {
2275   int data1 = msgdata[msgdataindex];
2276   MSG_INDEXINC_I();
2277   int data2 = msgdata[msgdataindex];
2278   MSG_INDEXINC_I();
2279   // receive a shared memory response msg
2280 #ifdef DEBUG
2281 #ifndef CLOSE_PRINT
2282   BAMBOO_DEBUGPRINT(0xe88b);
2283 #endif
2284 #endif
2285 #ifdef MULTICORE_GC
2286   // if is currently doing gc, dump this msg
2287   if(!gcprocessing) {
2288 #endif
2289   if(data2 == 0) {
2290     bamboo_smem_size = 0;
2291     bamboo_cur_msp = 0;
2292   } else {
2293 #ifdef MULTICORE_GC
2294     // fill header to store the size of this mem block
2295     BAMBOO_MEMSET_WH(data1, '\0', BAMBOO_CACHE_LINE_SIZE); 
2296         //memset(data1, 0, BAMBOO_CACHE_LINE_SIZE);
2297     (*((int*)data1)) = data2;
2298     bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
2299     bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
2300 #else
2301     bamboo_smem_size = data2;
2302     bamboo_cur_msp =(void*)(data1);
2303 #endif
2304   }
2305   smemflag = true;
2306 #ifdef MULTICORE_GC
2307 }
2308 #endif
2309 }
2310
2311 #ifdef MULTICORE_GC
2312 INLINE void processmsg_gcstartinit_I() {
2313   gcflag = true;
2314   gcphase = INITPHASE;
2315   if(!smemflag) {
2316     // is waiting for response of mem request
2317     // let it return NULL and start gc
2318     bamboo_smem_size = 0;
2319     bamboo_cur_msp = NULL;
2320     smemflag = true;
2321   }
2322 }
2323
2324 INLINE void processmsg_gcstart_I() {
2325 #ifdef DEBUG
2326 #ifndef CLOSE_PRINT
2327   BAMBOO_DEBUGPRINT(0xe88c);
2328 #endif
2329 #endif
2330   // set the GC flag
2331   gcphase = MARKPHASE;
2332 }
2333
2334 INLINE void processmsg_gcstartcompact_I() {
2335   gcblock2fill = msgdata[msgdataindex];
2336   MSG_INDEXINC_I();       //msgdata[1];
2337   gcphase = COMPACTPHASE;
2338 }
2339
2340 INLINE void processmsg_gcstartmapinfo_I() {
2341   gcphase = MAPPHASE;
2342 }
2343
2344 INLINE void processmsg_gcstartflush_I() {
2345   gcphase = FLUSHPHASE;
2346 }
2347
2348 INLINE void processmsg_gcfinishinit_I() {
2349   int data1 = msgdata[msgdataindex];
2350   MSG_INDEXINC_I();
2351   // received a init phase finish msg
2352   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2353     // non startup core can not receive this msg
2354 #ifndef CLOSE_PRINT
2355     BAMBOO_DEBUGPRINT_REG(data1);
2356 #endif
2357     BAMBOO_EXIT(0xb001);
2358   }
2359 #ifdef DEBUG
2360   BAMBOO_DEBUGPRINT(0xe88c);
2361   BAMBOO_DEBUGPRINT_REG(data1);
2362 #endif
2363   // All cores should do init GC
2364   if(data1 < NUMCORESACTIVE) {
2365     gccorestatus[data1] = 0;
2366   }
2367 }
2368
2369 INLINE void processmsg_gcfinishmark_I() {
2370   int data1 = msgdata[msgdataindex];
2371   MSG_INDEXINC_I();
2372   int data2 = msgdata[msgdataindex];
2373   MSG_INDEXINC_I();
2374   int data3 = msgdata[msgdataindex];
2375   MSG_INDEXINC_I();
2376   // received a mark phase finish msg
2377   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2378     // non startup core can not receive this msg
2379 #ifndef CLOSE_PRINT
2380     BAMBOO_DEBUGPRINT_REG(data1);
2381 #endif
2382     BAMBOO_EXIT(0xb002);
2383   }
2384   // all cores should do mark
2385   if(data1 < NUMCORESACTIVE) {
2386     gccorestatus[data1] = 0;
2387     gcnumsendobjs[data1] = data2;
2388     gcnumreceiveobjs[data1] = data3;
2389   }
2390 }
2391
2392 INLINE void processmsg_gcfinishcompact_I() {
2393   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2394     // non startup core can not receive this msg
2395     // return -1
2396 #ifndef CLOSE_PRINT
2397     BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
2398 #endif
2399     BAMBOO_EXIT(0xb003);
2400   }
2401   int cnum = msgdata[msgdataindex];
2402   MSG_INDEXINC_I();       //msgdata[1];
2403   int filledblocks = msgdata[msgdataindex];
2404   MSG_INDEXINC_I();       //msgdata[2];
2405   int heaptop = msgdata[msgdataindex];
2406   MSG_INDEXINC_I();       //msgdata[3];
2407   int data4 = msgdata[msgdataindex];
2408   MSG_INDEXINC_I();       //msgdata[4];
2409   // only gc cores need to do compact
2410   if(cnum < NUMCORES4GC) {
2411     if(COMPACTPHASE == gcphase) {
2412       gcfilledblocks[cnum] = filledblocks;
2413       gcloads[cnum] = heaptop;
2414     }
2415     if(data4 > 0) {
2416       // ask for more mem
2417       int startaddr = 0;
2418       int tomove = 0;
2419       int dstcore = 0;
2420       if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
2421         // cache the msg first
2422         if(BAMBOO_CHECK_SEND_MODE()) {
2423         cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
2424         } else {
2425         send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove, true);
2426         }
2427       }
2428     } else {
2429       gccorestatus[cnum] = 0;
2430     }             // if(data4>0)
2431   }       // if(cnum < NUMCORES4GC)
2432 }
2433
2434 INLINE void processmsg_gcfinishmapinfo_I() {
2435   int data1 = msgdata[msgdataindex];
2436   MSG_INDEXINC_I();
2437   // received a map phase finish msg
2438   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2439     // non startup core can not receive this msg
2440     // return -1
2441 #ifndef CLOSE_PRINT
2442     BAMBOO_DEBUGPRINT_REG(data1);
2443 #endif
2444     BAMBOO_EXIT(0xb004);
2445   }
2446   // all cores should do flush
2447   if(data1 < NUMCORES4GC) {
2448     gccorestatus[data1] = 0;
2449   }
2450 }
2451
2452
2453 INLINE void processmsg_gcfinishflush_I() {
2454   int data1 = msgdata[msgdataindex];
2455   MSG_INDEXINC_I();
2456   // received a flush phase finish msg
2457   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2458     // non startup core can not receive this msg
2459     // return -1
2460 #ifndef CLOSE_PRINT
2461     BAMBOO_DEBUGPRINT_REG(data1);
2462 #endif
2463     BAMBOO_EXIT(0xb005);
2464   }
2465   // all cores should do flush
2466   if(data1 < NUMCORESACTIVE) {
2467     gccorestatus[data1] = 0;
2468   }
2469 }
2470
2471 INLINE void processmsg_gcmarkconfirm_I() {
2472   if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2473      || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2474     // wrong core to receive such msg
2475     BAMBOO_EXIT(0xb006);
2476   } else {
2477     // send response msg, cahce the msg first
2478     if(BAMBOO_CHECK_SEND_MODE()) {
2479     cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2480                 gcbusystatus, gcself_numsendobjs,
2481                 gcself_numreceiveobjs);
2482     } else {
2483     send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2484                gcbusystatus, gcself_numsendobjs,
2485                gcself_numreceiveobjs, true);
2486     }
2487   }
2488 }
2489
2490 INLINE void processmsg_gcmarkreport_I() {
2491   int data1 = msgdata[msgdataindex];
2492   MSG_INDEXINC_I();
2493   int data2 = msgdata[msgdataindex];
2494   MSG_INDEXINC_I();
2495   int data3 = msgdata[msgdataindex];
2496   MSG_INDEXINC_I();
2497   int data4 = msgdata[msgdataindex];
2498   MSG_INDEXINC_I();
2499   // received a marked phase finish confirm response msg
2500   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2501     // wrong core to receive such msg
2502 #ifndef CLOSE_PRINT
2503     BAMBOO_DEBUGPRINT_REG(data2);
2504 #endif
2505     BAMBOO_EXIT(0xb007);
2506   } else {
2507     if(waitconfirm) {
2508       numconfirm--;
2509     }
2510     gccorestatus[data1] = data2;
2511     gcnumsendobjs[data1] = data3;
2512     gcnumreceiveobjs[data1] = data4;
2513   }
2514 }
2515
2516 INLINE void processmsg_gcmarkedobj_I() {
2517   int data1 = msgdata[msgdataindex];
2518   MSG_INDEXINC_I();
2519   // received a markedObj msg
2520   if(((int *)data1)[6] == INIT) {
2521     // this is the first time that this object is discovered,
2522     // set the flag as DISCOVERED
2523     ((int *)data1)[6] = DISCOVERED;
2524     gc_enqueue_I(data1);
2525   } 
2526   // set the remote flag
2527   ((int *)data1)[6] |= REMOTEM;
2528   gcself_numreceiveobjs++;
2529   gcbusystatus = true;
2530 }
2531
2532 INLINE void processmsg_gcmovestart_I() {
2533   gctomove = true;
2534   gcdstcore = msgdata[msgdataindex];
2535   MSG_INDEXINC_I();       //msgdata[1];
2536   gcmovestartaddr = msgdata[msgdataindex];
2537   MSG_INDEXINC_I();       //msgdata[2];
2538   gcblock2fill = msgdata[msgdataindex];
2539   MSG_INDEXINC_I();       //msgdata[3];
2540 }
2541
2542 INLINE void processmsg_gcmaprequest_I() {
2543 #ifdef GC_PROFILE
2544   //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2545 #endif
2546   void * dstptr = NULL;
2547   int data1 = msgdata[msgdataindex];
2548   MSG_INDEXINC_I();
2549   //dstptr = mgchashSearch(msgdata[1]);
2550 #ifdef GC_PROFILE
2551   // TODO unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2552 #endif
2553   RuntimeHashget(gcpointertbl, data1, &dstptr);
2554 #ifdef GC_PROFILE
2555   // TODO flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2556 #endif
2557   int data2 = msgdata[msgdataindex];
2558   MSG_INDEXINC_I();
2559   //MGCHashget(gcpointertbl, msgdata[1], &dstptr);
2560 #ifdef GC_PROFILE
2561   // TODO unsigned long long ttimei = BAMBOO_GET_EXE_TIME();
2562 #endif
2563   if(NULL == dstptr) {
2564     // no such pointer in this core, something is wrong
2565 #ifdef DEBUG
2566     BAMBOO_DEBUGPRINT_REG(data1);
2567     BAMBOO_DEBUGPRINT_REG(data2);
2568 #endif
2569     BAMBOO_EXIT(0xb009);
2570     //assume that the object was not moved, use the original address
2571     /*if(isMsgSending) {
2572             cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2573        } else {
2574             send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2575        }*/
2576   } else {
2577     // send back the mapping info, cache the msg first
2578     if(BAMBOO_CHECK_SEND_MODE()) {
2579     cache_msg_3(data2, GCMAPINFO, data1, (int)dstptr);
2580     } else {
2581     send_msg_3(data2, GCMAPINFO, data1, (int)dstptr, true);
2582     }
2583   }
2584 #ifdef GC_PROFILE
2585   // TODO flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimei;
2586   //num_mapinforequest_i++;
2587 #endif
2588 }
2589
2590 INLINE void processmsg_gcmapinfo_I() {
2591 #ifdef GC_PROFILE
2592   //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2593 #endif
2594   int data1 = msgdata[msgdataindex];
2595   MSG_INDEXINC_I();
2596 #if 0
2597   if(data1 != gcobj2map) {
2598     // obj not matched, something is wrong
2599 #ifdef DEBUG
2600     BAMBOO_DEBUGPRINT_REG(gcobj2map);
2601     BAMBOO_DEBUGPRINT_REG(msgdata[1]);
2602 #endif
2603     BAMBOO_EXIT(0xb00a);
2604   } else {
2605 #endif
2606     gcmappedobj = msgdata[msgdataindex];  // [2]
2607     MSG_INDEXINC_I();
2608     //mgchashReplace_I(msgdata[1], msgdata[2]);
2609     //mgchashInsert_I(gcobj2map, gcmappedobj);
2610     RuntimeHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2611         /*struct nodemappinginfo * nodeinfo = 
2612          (struct nodemappinginfo *)RUNMALLOC_I(sizeof(struct nodemappinginfo));
2613         nodeinfo->ptr = (void *)gcmappedobj;
2614         nodeinfo->cores = NULL;
2615         RuntimeHashadd_I(gcpointertbl, data1, (int)nodeinfo);*/
2616     //MGCHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2617 //  }
2618   if(data1 == gcobj2map) {
2619         gcismapped = true;
2620   }
2621 #ifdef GC_PROFILE
2622   //flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2623 #endif
2624 }
2625
2626 INLINE void processmsg_gcmaptbl_I() {
2627   int data1 = msgdata[msgdataindex];
2628   MSG_INDEXINC_I();
2629   int data2 = msgdata[msgdataindex];
2630   MSG_INDEXINC_I();
2631   gcrpointertbls[data2] = (mgcsharedhashtbl_t *)data1; //(struct GCSharedHash *)data1;
2632 }
2633
2634 INLINE void processmsg_gclobjinfo_I() {
2635   numconfirm--;
2636
2637   int data1 = msgdata[msgdataindex];
2638   MSG_INDEXINC_I();
2639   int data2 = msgdata[msgdataindex];
2640   MSG_INDEXINC_I();
2641   if(BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1) {
2642 #ifndef CLOSE_PRINT
2643     BAMBOO_DEBUGPRINT_REG(data2);
2644 #endif
2645     BAMBOO_EXIT(0xb00b);
2646   }
2647   // store the mark result info
2648   int cnum = data2;
2649   gcloads[cnum] = msgdata[msgdataindex];
2650   MSG_INDEXINC_I();       // msgdata[3];
2651   int data4 = msgdata[msgdataindex];
2652   MSG_INDEXINC_I();
2653   if(gcheaptop < data4) {
2654     gcheaptop = data4;
2655   }
2656   // large obj info here
2657   for(int k = 5; k < data1; ) {
2658     int lobj = msgdata[msgdataindex];
2659     MSG_INDEXINC_I();             //msgdata[k++];
2660     int length = msgdata[msgdataindex];
2661     MSG_INDEXINC_I();             //msgdata[k++];
2662     gc_lobjenqueue_I(lobj, length, cnum);
2663     gcnumlobjs++;
2664   }       // for(int k = 5; k < msgdata[1];)
2665 }
2666
2667 INLINE void processmsg_gclobjmapping_I() {
2668   int data1 = msgdata[msgdataindex];
2669   MSG_INDEXINC_I();
2670   int data2 = msgdata[msgdataindex];
2671   MSG_INDEXINC_I();
2672   //mgchashInsert_I(msgdata[1], msgdata[2]);
2673   RuntimeHashadd_I(gcpointertbl, data1, data2);
2674   mgcsharedhashInsert_I(gcsharedptbl, data1, data2);
2675   //GCSharedHashadd_I(gcsharedptbl, data1, data2);
2676   //MGCHashadd_I(gcpointertbl, msgdata[1], msgdata[2]);
2677 }
2678 #endif // #ifdef MULTICORE_GC
2679
2680 // receive object transferred from other cores
2681 // or the terminate message from other cores
2682 // Should be invoked in critical sections!!
2683 // NOTICE: following format is for threadsimulate version only
2684 //         RAW version please see previous description
2685 // format: type + object
2686 // type: -1--stall msg
2687 //      !-1--object
2688 // return value: 0--received an object
2689 //               1--received nothing
2690 //               2--received a Stall Msg
2691 //               3--received a lock Msg
2692 //               RAW version: -1 -- received nothing
2693 //                            otherwise -- received msg type
2694 int receiveObject(int send_port_pending) {
2695 msg:
2696   // get the incoming msgs
2697   if(receiveMsg(send_port_pending) == -1) {
2698     return -1;
2699   }
2700 processmsg:
2701   // processing received msgs
2702   int size = 0;
2703   MSG_REMAINSIZE_I(&size);
2704   if((size == 0) || (checkMsgLength_I(size) == -1)) {
2705     // not a whole msg
2706     // have new coming msg
2707     if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
2708       goto msg;
2709     } else {
2710       return -1;
2711     }
2712   }
2713
2714   if(msglength <= size) {
2715     // have some whole msg
2716     //if(msgdataindex == msglength) {
2717     // received a whole msg
2718     MSGTYPE type;
2719     type = msgdata[msgdataindex]; //[0]
2720     MSG_INDEXINC_I();
2721     msgdatafull = false;
2722     // TODO
2723     //tprintf("msg type: %x\n", type);
2724     switch(type) {
2725     case TRANSOBJ: {
2726       // receive a object transfer msg
2727       processmsg_transobj_I();
2728       break;
2729     }                     // case TRANSOBJ
2730
2731     case TRANSTALL: {
2732       // receive a stall msg
2733       processmsg_transtall_I();
2734       break;
2735     }                     // case TRANSTALL
2736
2737 // GC version have no lock msgs
2738 #ifndef MULTICORE_GC
2739     case LOCKREQUEST: {
2740       // receive lock request msg, handle it right now
2741       processmsg_lockrequest_I();
2742       break;
2743     }                     // case LOCKREQUEST
2744
2745     case LOCKGROUNT: {
2746       // receive lock grount msg
2747       processmsg_lockgrount_I();
2748       break;
2749     }                     // case LOCKGROUNT
2750
2751     case LOCKDENY: {
2752       // receive lock deny msg
2753       processmsg_lockdeny_I();
2754       break;
2755     }                     // case LOCKDENY
2756
2757     case LOCKRELEASE: {
2758       processmsg_lockrelease_I();
2759       break;
2760     }                     // case LOCKRELEASE
2761 #endif // #ifndef MULTICORE_GC
2762
2763 #ifdef PROFILE
2764     case PROFILEOUTPUT: {
2765       // receive an output profile data request msg
2766       processmsg_profileoutput_I();
2767       break;
2768     }                     // case PROFILEOUTPUT
2769
2770     case PROFILEFINISH: {
2771       // receive a profile output finish msg
2772       processmsg_profilefinish_I();
2773       break;
2774     }                     // case PROFILEFINISH
2775 #endif // #ifdef PROFILE
2776
2777 // GC version has no lock msgs
2778 #ifndef MULTICORE_GC
2779     case REDIRECTLOCK: {
2780       // receive a redirect lock request msg, handle it right now
2781       processmsg_redirectlock_I();
2782       break;
2783     }                     // case REDIRECTLOCK
2784
2785     case REDIRECTGROUNT: {
2786       // receive a lock grant msg with redirect info
2787       processmsg_redirectgrount_I();
2788       break;
2789     }                     // case REDIRECTGROUNT
2790
2791     case REDIRECTDENY: {
2792       // receive a lock deny msg with redirect info
2793       processmsg_redirectdeny_I();
2794       break;
2795     }                     // case REDIRECTDENY
2796
2797     case REDIRECTRELEASE: {
2798       // receive a lock release msg with redirect info
2799       processmsg_redirectrelease_I();
2800       break;
2801     }                     // case REDIRECTRELEASE
2802 #endif // #ifndef MULTICORE_GC
2803
2804     case STATUSCONFIRM: {
2805       // receive a status confirm info
2806       processmsg_statusconfirm_I();
2807       break;
2808     }                     // case STATUSCONFIRM
2809
2810     case STATUSREPORT: {
2811       processmsg_statusreport_I();
2812       break;
2813     }                     // case STATUSREPORT
2814
2815     case TERMINATE: {
2816       // receive a terminate msg
2817       processmsg_terminate_I();
2818       break;
2819     }                     // case TERMINATE
2820
2821     case MEMREQUEST: {
2822       processmsg_memrequest_I();
2823       break;
2824     }                     // case MEMREQUEST
2825
2826     case MEMRESPONSE: {
2827       processmsg_memresponse_I();
2828       break;
2829     }                     // case MEMRESPONSE
2830
2831 #ifdef MULTICORE_GC
2832     // GC msgs
2833     case GCSTARTINIT: {
2834       processmsg_gcstartinit_I();
2835       break;
2836     }                     // case GCSTARTINIT
2837
2838     case GCSTART: {
2839       // receive a start GC msg
2840       processmsg_gcstart_I();
2841       break;
2842     }                     // case GCSTART
2843
2844     case GCSTARTCOMPACT: {
2845       // a compact phase start msg
2846       processmsg_gcstartcompact_I();
2847       break;
2848     }                     // case GCSTARTCOMPACT
2849
2850         case GCSTARTMAPINFO: {
2851       // received a flush phase start msg
2852       processmsg_gcstartmapinfo_I();
2853       break;
2854     }                     // case GCSTARTFLUSH
2855
2856     case GCSTARTFLUSH: {
2857       // received a flush phase start msg
2858       processmsg_gcstartflush_I();
2859       break;
2860     }                     // case GCSTARTFLUSH
2861
2862     case GCFINISHINIT: {
2863       processmsg_gcfinishinit_I();
2864       break;
2865     }                     // case GCFINISHINIT
2866
2867     case GCFINISHMARK: {
2868       processmsg_gcfinishmark_I();
2869       break;
2870     }                     // case GCFINISHMARK
2871
2872     case GCFINISHCOMPACT: {
2873       // received a compact phase finish msg
2874       processmsg_gcfinishcompact_I();
2875       break;
2876     }                     // case GCFINISHCOMPACT
2877
2878         case GCFINISHMAPINFO: {
2879       processmsg_gcfinishmapinfo_I();
2880       break;
2881     }                     // case GCFINISHMAPINFO
2882
2883     case GCFINISHFLUSH: {
2884       processmsg_gcfinishflush_I();
2885       break;
2886     }                     // case GCFINISHFLUSH
2887
2888     case GCFINISH: {
2889       // received a GC finish msg
2890       gcphase = FINISHPHASE;
2891       break;
2892     }                     // case GCFINISH
2893
2894     case GCMARKCONFIRM: {
2895       // received a marked phase finish confirm request msg
2896       // all cores should do mark
2897       processmsg_gcmarkconfirm_I();
2898       break;
2899     }                     // case GCMARKCONFIRM
2900
2901     case GCMARKREPORT: {
2902       processmsg_gcmarkreport_I();
2903       break;
2904     }                     // case GCMARKREPORT
2905
2906     case GCMARKEDOBJ: {
2907       processmsg_gcmarkedobj_I();
2908       break;
2909     }                     // case GCMARKEDOBJ
2910
2911     case GCMOVESTART: {
2912       // received a start moving objs msg
2913       processmsg_gcmovestart_I();
2914       break;
2915     }                     // case GCMOVESTART
2916
2917     case GCMAPREQUEST: {
2918       // received a mapping info request msg
2919       processmsg_gcmaprequest_I();
2920       break;
2921     }                     // case GCMAPREQUEST
2922
2923     case GCMAPINFO: {
2924       // received a mapping info response msg
2925       processmsg_gcmapinfo_I();
2926       break;
2927     }                     // case GCMAPINFO
2928
2929     case GCMAPTBL: {
2930       // received a mapping tbl response msg
2931       processmsg_gcmaptbl_I();
2932       break;
2933     }                     // case GCMAPTBL
2934         
2935         case GCLOBJREQUEST: {
2936       // received a large objs info request msg
2937       transferMarkResults_I();
2938       break;
2939     }                     // case GCLOBJREQUEST
2940
2941     case GCLOBJINFO: {
2942       // received a large objs info response msg
2943       processmsg_gclobjinfo_I();
2944       break;
2945     }                     // case GCLOBJINFO
2946
2947     case GCLOBJMAPPING: {
2948       // received a large obj mapping info msg
2949       processmsg_gclobjmapping_I();
2950       break;
2951     }                     // case GCLOBJMAPPING
2952
2953 #endif // #ifdef MULTICORE_GC
2954
2955     default:
2956       break;
2957     }             // switch(type)
2958     //memset(msgdata, '\0', sizeof(int) * msgdataindex);
2959     //msgdataindex = 0;
2960     msglength = BAMBOO_MSG_BUF_LENGTH;
2961     // TODO
2962     //printf("++ msg: %x \n", type);
2963
2964     if(msgdataindex != msgdatalast) {
2965       // still have available msg
2966       goto processmsg;
2967     }
2968 #ifdef DEBUG
2969 #ifndef CLOSE_PRINT
2970     BAMBOO_DEBUGPRINT(0xe88d);
2971 #endif
2972 #endif
2973
2974     // have new coming msg
2975     if(BAMBOO_MSG_AVAIL() != 0) {
2976       goto msg;
2977     } // TODO
2978
2979 #ifdef PROFILE
2980 /*if(isInterrupt) {
2981                 profileTaskEnd();
2982         }*/
2983 #endif
2984     return (int)type;
2985   } else {
2986     // not a whole msg
2987 #ifdef DEBUG
2988 #ifndef CLOSE_PRINT
2989     BAMBOO_DEBUGPRINT(0xe88e);
2990 #endif
2991 #endif
2992 #ifdef PROFILE
2993     /*  if(isInterrupt) {
2994                             profileTaskEnd();
2995                     }*/
2996 #endif
2997     return -2;
2998   }
2999 }
3000
3001 int enqueuetasks(struct parameterwrapper *parameter,
3002                  struct parameterwrapper *prevptr,
3003                  struct ___Object___ *ptr,
3004                  int * enterflags,
3005                  int numenterflags) {
3006   void * taskpointerarray[MAXTASKPARAMS];
3007   int j;
3008   //int numparams=parameter->task->numParameters;
3009   int numiterators=parameter->task->numTotal-1;
3010   int retval=1;
3011
3012   struct taskdescriptor * task=parameter->task;
3013
3014   //this add the object to parameterwrapper
3015   ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
3016                 numenterflags, enterflags==NULL);
3017
3018   /* Add enqueued object to parameter vector */
3019   taskpointerarray[parameter->slot]=ptr;
3020
3021   /* Reset iterators */
3022   for(j=0; j<numiterators; j++) {
3023     toiReset(&parameter->iterators[j]);
3024   }
3025
3026   /* Find initial state */
3027   for(j=0; j<numiterators; j++) {
3028 backtrackinit:
3029     if(toiHasNext(&parameter->iterators[j],taskpointerarray OPTARG(failed)))
3030       toiNext(&parameter->iterators[j], taskpointerarray OPTARG(failed));
3031     else if (j>0) {
3032       /* Need to backtrack */
3033       toiReset(&parameter->iterators[j]);
3034       j--;
3035       goto backtrackinit;
3036     } else {
3037       /* Nothing to enqueue */
3038       return retval;
3039     }
3040   }
3041
3042   while(1) {
3043     /* Enqueue current state */
3044     //int launch = 0;
3045     struct taskparamdescriptor *tpd=
3046       RUNMALLOC(sizeof(struct taskparamdescriptor));
3047     tpd->task=task;
3048     tpd->numParameters=numiterators+1;
3049     tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
3050
3051     for(j=0; j<=numiterators; j++) {
3052       //store the actual parameters
3053       tpd->parameterArray[j]=taskpointerarray[j];
3054     }
3055     /* Enqueue task */
3056     if (( /*!gencontains(failedtasks, tpd)&&*/
3057           !gencontains(activetasks,tpd))) {
3058       genputtable(activetasks, tpd, tpd);
3059     } else {
3060       RUNFREE(tpd->parameterArray);
3061       RUNFREE(tpd);
3062     }
3063
3064     /* This loop iterates to the next parameter combination */
3065     if (numiterators==0)
3066       return retval;
3067
3068     for(j=numiterators-1; j<numiterators; j++) {
3069 backtrackinc:
3070       if(toiHasNext(&parameter->iterators[j],taskpointerarray OPTARG(failed)))
3071         toiNext(&parameter->iterators[j], taskpointerarray OPTARG(failed));
3072       else if (j>0) {
3073         /* Need to backtrack */
3074         toiReset(&parameter->iterators[j]);
3075         j--;
3076         goto backtrackinc;
3077       } else {
3078         /* Nothing more to enqueue */
3079         return retval;
3080       }
3081     }
3082   }
3083   return retval;
3084 }
3085
3086 int enqueuetasks_I(struct parameterwrapper *parameter,
3087                    struct parameterwrapper *prevptr,
3088                    struct ___Object___ *ptr,
3089                    int * enterflags,
3090                    int numenterflags) {
3091   void * taskpointerarray[MAXTASKPARAMS];
3092   int j;
3093   //int numparams=parameter->task->numParameters;
3094   int numiterators=parameter->task->numTotal-1;
3095   int retval=1;
3096   //int addnormal=1;
3097   //int adderror=1;
3098
3099   struct taskdescriptor * task=parameter->task;
3100
3101   //this add the object to parameterwrapper
3102   ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
3103                   numenterflags, enterflags==NULL);
3104
3105   /* Add enqueued object to parameter vector */
3106   taskpointerarray[parameter->slot]=ptr;
3107
3108   /* Reset iterators */
3109   for(j=0; j<numiterators; j++) {
3110     toiReset(&parameter->iterators[j]);
3111   }
3112
3113   /* Find initial state */
3114   for(j=0; j<numiterators; j++) {
3115 backtrackinit:
3116     if(toiHasNext(&parameter->iterators[j],taskpointerarray OPTARG(failed)))
3117       toiNext(&parameter->iterators[j], taskpointerarray OPTARG(failed));
3118     else if (j>0) {
3119       /* Need to backtrack */
3120       toiReset(&parameter->iterators[j]);
3121       j--;
3122       goto backtrackinit;
3123     } else {
3124       /* Nothing to enqueue */
3125       return retval;
3126     }
3127   }
3128
3129   while(1) {
3130     /* Enqueue current state */
3131     //int launch = 0;
3132     struct taskparamdescriptor *tpd=
3133       RUNMALLOC_I(sizeof(struct taskparamdescriptor));
3134     tpd->task=task;
3135     tpd->numParameters=numiterators+1;
3136     tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
3137
3138     for(j=0; j<=numiterators; j++) {
3139       //store the actual parameters
3140       tpd->parameterArray[j]=taskpointerarray[j];
3141     }
3142     /* Enqueue task */
3143     if (( /*!gencontains(failedtasks, tpd)&&*/
3144           !gencontains(activetasks,tpd))) {
3145       genputtable_I(activetasks, tpd, tpd);
3146     } else {
3147       RUNFREE(tpd->parameterArray);
3148       RUNFREE(tpd);
3149     }
3150
3151     /* This loop iterates to the next parameter combination */
3152     if (numiterators==0)
3153       return retval;
3154
3155     for(j=numiterators-1; j<numiterators; j++) {
3156 backtrackinc:
3157       if(toiHasNext(&parameter->iterators[j], taskpointerarray OPTARG(failed)))
3158         toiNext(&parameter->iterators[j], taskpointerarray OPTARG(failed));
3159       else if (j>0) {
3160         /* Need to backtrack */
3161         toiReset(&parameter->iterators[j]);
3162         j--;
3163         goto backtrackinc;
3164       } else {
3165         /* Nothing more to enqueue */
3166         return retval;
3167       }
3168     }
3169   }
3170   return retval;
3171 }
3172
3173 #ifdef MULTICORE_GC
3174 #define OFFSET 2
3175 #else
3176 #define OFFSET 0
3177 #endif
3178
3179 int containstag(struct ___Object___ *ptr,
3180                 struct ___TagDescriptor___ *tag);
3181
3182 #ifndef MULTICORE_GC
3183 void releasewritelock_r(void * lock, void * redirectlock) {
3184   int targetcore = 0;
3185   int reallock = (int)lock;
3186   targetcore = (reallock >> 5) % NUMCORES;
3187
3188 #ifdef DEBUG
3189   BAMBOO_DEBUGPRINT(0xe671);
3190   BAMBOO_DEBUGPRINT_REG((int)lock);
3191   BAMBOO_DEBUGPRINT_REG(reallock);
3192   BAMBOO_DEBUGPRINT_REG(targetcore);
3193 #endif
3194
3195   if(targetcore == BAMBOO_NUM_OF_CORE) {
3196     BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3197 #ifdef DEBUG
3198     BAMBOO_DEBUGPRINT(0xf001);
3199 #endif
3200     // reside on this core
3201     if(!RuntimeHashcontainskey(locktbl, reallock)) {
3202       // no locks for this object, something is wrong
3203       BAMBOO_EXIT(0xa00b);
3204     } else {
3205       int rwlock_obj = 0;
3206       struct LockValue * lockvalue = NULL;
3207 #ifdef DEBUG
3208       BAMBOO_DEBUGPRINT(0xe672);
3209 #endif
3210       RuntimeHashget(locktbl, reallock, &rwlock_obj);
3211       lockvalue = (struct LockValue *)rwlock_obj;
3212 #ifdef DEBUG
3213       BAMBOO_DEBUGPRINT_REG(lockvalue->value);
3214 #endif
3215       lockvalue->value++;
3216       lockvalue->redirectlock = (int)redirectlock;
3217 #ifdef DEBUG
3218       BAMBOO_DEBUGPRINT_REG(lockvalue->value);
3219 #endif
3220     }
3221     BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3222 #ifdef DEBUG
3223     BAMBOO_DEBUGPRINT(0xf000);
3224 #endif
3225     return;
3226   } else {
3227     // send lock release with redirect info msg
3228     // for 32 bit machine, the size is always 4 words
3229     send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock,
3230                (int)redirectlock, false);
3231   }
3232 }
3233 #endif
3234
3235 void executetasks() {
3236   void * taskpointerarray[MAXTASKPARAMS+OFFSET];
3237   int numparams=0;
3238   int numtotal=0;
3239   struct ___Object___ * tmpparam = NULL;
3240   struct parameterdescriptor * pd=NULL;
3241   struct parameterwrapper *pw=NULL;
3242   int j = 0;
3243   int x = 0;
3244   bool islock = true;
3245
3246   int grount = 0;
3247   int andmask=0;
3248   int checkmask=0;
3249
3250 newtask:
3251   while(hashsize(activetasks)>0) {
3252 #ifdef MULTICORE_GC
3253     gc(NULL);
3254 #endif
3255 #ifdef DEBUG
3256     BAMBOO_DEBUGPRINT(0xe990);
3257 #endif
3258
3259     /* See if there are any active tasks */
3260     //if (hashsize(activetasks)>0) {
3261     int i;
3262 #ifdef PROFILE
3263 #ifdef ACCURATEPROFILE
3264     profileTaskStart("tpd checking");
3265 #endif
3266 #endif
3267     //long clock1;
3268     //clock1 = BAMBOO_GET_EXE_TIME();
3269
3270     busystatus = true;
3271     currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
3272     genfreekey(activetasks, currtpd);
3273
3274     numparams=currtpd->task->numParameters;
3275     numtotal=currtpd->task->numTotal;
3276
3277     // clear the lockRedirectTbl
3278     // (TODO, this table should be empty after all locks are released)
3279     // reset all locks
3280     /*for(j = 0; j < MAXTASKPARAMS; j++) {
3281             runtime_locks[j].redirectlock = 0;
3282             runtime_locks[j].value = 0;
3283        }*/
3284     // get all required locks
3285     runtime_locklen = 0;
3286     // check which locks are needed
3287     for(i = 0; i < numparams; i++) {
3288       void * param = currtpd->parameterArray[i];
3289       int tmplock = 0;
3290       int j = 0;
3291       bool insert = true;
3292       if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
3293         islock = false;
3294         taskpointerarray[i+OFFSET]=param;
3295         goto execute;
3296       }
3297       if(((struct ___Object___ *)param)->lock == NULL) {
3298         tmplock = (int)param;
3299       } else {
3300         tmplock = (int)(((struct ___Object___ *)param)->lock);
3301       }
3302       // insert into the locks array
3303       for(j = 0; j < runtime_locklen; j++) {
3304         if(runtime_locks[j].value == tmplock) {
3305           insert = false;
3306           break;
3307         } else if(runtime_locks[j].value > tmplock) {
3308           break;
3309         }
3310       }
3311       if(insert) {
3312         int h = runtime_locklen;
3313         for(; h > j; h--) {
3314           runtime_locks[h].redirectlock = runtime_locks[h-1].redirectlock;
3315           runtime_locks[h].value = runtime_locks[h-1].value;
3316         }
3317         runtime_locks[j].value = tmplock;
3318         runtime_locks[j].redirectlock = (int)param;
3319         runtime_locklen++;
3320       }
3321     }       // line 2713: for(i = 0; i < numparams; i++)
3322             // grab these required locks
3323 #ifdef DEBUG
3324     BAMBOO_DEBUGPRINT(0xe991);
3325 #endif
3326     //long clock2;
3327     //clock2 = BAMBOO_GET_EXE_TIME();
3328
3329     for(i = 0; i < runtime_locklen; i++) {
3330       int * lock = (int *)(runtime_locks[i].redirectlock);
3331       islock = true;
3332       // require locks for this parameter if it is not a startup object
3333 #ifdef DEBUG
3334       BAMBOO_DEBUGPRINT_REG((int)lock);
3335       BAMBOO_DEBUGPRINT_REG((int)(runtime_locks[i].value));
3336 #endif
3337       getwritelock(lock);
3338       BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3339 #ifdef DEBUG
3340       BAMBOO_DEBUGPRINT(0xf001);
3341 #endif
3342 #ifdef PROFILE
3343       //isInterrupt = false;
3344 #endif
3345       while(!lockflag) {
3346         BAMBOO_WAITING_FOR_LOCK(0);
3347         // check for outgoing sends
3348     /*if (isMsgHanging) {
3349       extern inline void send_hanging_msg(bool);
3350       send_hanging_msg(true);
3351     } */
3352           }
3353 #ifndef INTERRUPT
3354       if(reside) {
3355         while(BAMBOO_WAITING_FOR_LOCK(0) != -1) {
3356           // check for outgoing sends
3357           /*if (isMsgHanging) {
3358                 extern inline void send_hanging_msg(bool);
3359                 send_hanging_msg(true);
3360           } */
3361         }
3362       }
3363 #endif
3364       grount = lockresult;
3365
3366       lockresult = 0;
3367       lockobj = 0;
3368       lock2require = 0;
3369       lockflag = false;
3370 #ifndef INTERRUPT
3371       reside = false;
3372 #endif
3373 #ifdef PROFILE
3374       //isInterrupt = true;
3375 #endif
3376       BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3377 #ifdef DEBUG
3378       BAMBOO_DEBUGPRINT(0xf000);
3379 #endif
3380
3381       if(grount == 0) {
3382 #ifdef DEBUG
3383         BAMBOO_DEBUGPRINT(0xe992);
3384         BAMBOO_DEBUGPRINT_REG(lock);
3385 #endif
3386         // check if has the lock already
3387         // can not get the lock, try later
3388         // release all grabbed locks for previous parameters
3389         for(j = 0; j < i; ++j) {
3390           lock = (int*)(runtime_locks[j].redirectlock);
3391           releasewritelock(lock);
3392         }
3393         genputtable(activetasks, currtpd, currtpd);
3394         if(hashsize(activetasks) == 1) {
3395           // only one task right now, wait a little while before next try
3396           int halt = 10000;
3397           while(halt--) {
3398           }
3399         }
3400 #ifdef PROFILE
3401 #ifdef ACCURATEPROFILE
3402         // fail, set the end of the checkTaskInfo
3403         profileTaskEnd();
3404 #endif
3405 #endif
3406         goto newtask;
3407         //}
3408       }
3409     }       // line 2752:  for(i = 0; i < runtime_locklen; i++)
3410
3411     /*long clock3;
3412        clock3 = BAMBOO_GET_EXE_TIME();
3413        //tprintf("sort: %d, grab: %d \n", clock2-clock1, clock3-clock2);*/
3414
3415 #ifdef DEBUG
3416     BAMBOO_DEBUGPRINT(0xe993);
3417 #endif
3418     /* Make sure that the parameters are still in the queues */
3419     for(i=0; i<numparams; i++) {
3420       void * parameter=currtpd->parameterArray[i];
3421
3422       // flush the object
3423 #ifdef CACHEFLUSH
3424       BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
3425                                classsize[((struct ___Object___ *)parameter)->type]);
3426 #endif
3427       tmpparam = (struct ___Object___ *)parameter;
3428       pd=currtpd->task->descriptorarray[i];
3429       pw=(struct parameterwrapper *) pd->queue;
3430       /* Check that object is still in queue */
3431       {
3432         if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
3433 #ifdef DEBUG
3434           BAMBOO_DEBUGPRINT(0xe994);
3435           BAMBOO_DEBUGPRINT_REG(parameter);
3436 #endif
3437           // release grabbed locks
3438           for(j = 0; j < runtime_locklen; ++j) {
3439             int * lock = (int *)(runtime_locks[j].redirectlock);
3440             releasewritelock(lock);
3441           }
3442           RUNFREE(currtpd->parameterArray);
3443           RUNFREE(currtpd);
3444           currtpd = NULL;
3445           goto newtask;
3446         }
3447       }   // line2865
3448           /* Check if the object's flags still meets requirements */
3449       {
3450         int tmpi = 0;
3451         bool ismet = false;
3452         for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
3453           andmask=pw->intarray[tmpi*2];
3454           checkmask=pw->intarray[tmpi*2+1];
3455           if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
3456             ismet = true;
3457             break;
3458           }
3459         }
3460         if (!ismet) {
3461           // flags are never suitable
3462           // remove this obj from the queue
3463           int next;
3464           int UNUSED, UNUSED2;
3465           int * enterflags;
3466 #ifdef DEBUG
3467           BAMBOO_DEBUGPRINT(0xe995);
3468           BAMBOO_DEBUGPRINT_REG(parameter);
3469 #endif
3470           ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
3471                         (int *) &enterflags, &UNUSED, &UNUSED2);
3472           ObjectHashremove(pw->objectset, (int)parameter);
3473           if (enterflags!=NULL)
3474             RUNFREE(enterflags);
3475           // release grabbed locks
3476           for(j = 0; j < runtime_locklen; ++j) {
3477             int * lock = (int *)(runtime_locks[j].redirectlock);
3478             releasewritelock(lock);
3479           }
3480           RUNFREE(currtpd->parameterArray);
3481           RUNFREE(currtpd);
3482           currtpd = NULL;
3483 #ifdef PROFILE
3484 #ifdef ACCURATEPROFILE
3485           // fail, set the end of the checkTaskInfo
3486           profileTaskEnd();
3487 #endif
3488 #endif
3489           goto newtask;
3490         }   // line 2878: if (!ismet)
3491       }   // line 2867
3492 parameterpresent:
3493       ;
3494       /* Check that object still has necessary tags */
3495       for(j=0; j<pd->numbertags; j++) {
3496         int slotid=pd->tagarray[2*j]+numparams;
3497         struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
3498         if (!containstag(parameter, tagd)) {
3499 #ifdef DEBUG
3500           BAMBOO_DEBUGPRINT(0xe996);
3501 #endif
3502           {
3503             // release grabbed locks
3504             int tmpj = 0;
3505             for(tmpj = 0; tmpj < runtime_locklen; ++tmpj) {
3506               int * lock = (int *)(runtime_locks[tmpj].redirectlock);
3507               releasewritelock(lock);
3508             }
3509           }
3510           RUNFREE(currtpd->parameterArray);
3511           RUNFREE(currtpd);
3512           currtpd = NULL;
3513           goto newtask;
3514         }   // line2911: if (!containstag(parameter, tagd))
3515       }   // line 2808: for(j=0; j<pd->numbertags; j++)
3516
3517       taskpointerarray[i+OFFSET]=parameter;
3518     }   // line 2824: for(i=0; i<numparams; i++)
3519         /* Copy the tags */
3520     for(; i<numtotal; i++) {
3521       taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
3522     }
3523
3524     {
3525 execute:
3526       /* Actually call task */
3527 #ifdef MULTICORE_GC
3528       ((int *)taskpointerarray)[0]=currtpd->numParameters;
3529       taskpointerarray[1]=NULL;
3530 #endif
3531 #ifdef PROFILE
3532 #ifdef ACCURATEPROFILE
3533       // check finish, set the end of the checkTaskInfo
3534       profileTaskEnd();
3535 #endif
3536       profileTaskStart(currtpd->task->name);
3537 #endif
3538       // TODO
3539       //long clock4;
3540       //clock4 = BAMBOO_GET_EXE_TIME();
3541       //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3542
3543 #ifdef DEBUG
3544       BAMBOO_DEBUGPRINT(0xe997);
3545 #endif
3546       ((void (*)(void **))currtpd->task->taskptr)(taskpointerarray);
3547       // TODO
3548       //long clock5;
3549       //clock5 = BAMBOO_GET_EXE_TIME();
3550       // tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3551
3552 #ifdef PROFILE
3553 #ifdef ACCURATEPROFILE
3554       // task finish, set the end of the checkTaskInfo
3555       profileTaskEnd();
3556       // new a PostTaskInfo for the post-task execution
3557       profileTaskStart("post task execution");
3558 #endif
3559 #endif
3560 #ifdef DEBUG
3561       BAMBOO_DEBUGPRINT(0xe998);
3562       BAMBOO_DEBUGPRINT_REG(islock);
3563 #endif
3564
3565       if(islock) {
3566 #ifdef DEBUG
3567         BAMBOO_DEBUGPRINT(0xe999);
3568 #endif
3569         for(i = 0; i < runtime_locklen; ++i) {
3570           void * ptr = (void *)(runtime_locks[i].redirectlock);
3571           int * lock = (int *)(runtime_locks[i].value);
3572 #ifdef DEBUG
3573           BAMBOO_DEBUGPRINT_REG((int)ptr);
3574           BAMBOO_DEBUGPRINT_REG((int)lock);
3575           BAMBOO_DEBUGPRINT_REG(*((int*)lock+5));
3576 #endif
3577 #ifndef MULTICORE_GC
3578           if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
3579             int redirectlock;
3580             RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
3581             RuntimeHashremovekey(lockRedirectTbl, (int)lock);
3582             releasewritelock_r(lock, (int *)redirectlock);
3583           } else {
3584 #else
3585           {
3586 #endif
3587             releasewritelock(ptr);
3588           }
3589         }
3590       }     // line 3015: if(islock)
3591
3592       //long clock6;
3593       //clock6 = BAMBOO_GET_EXE_TIME();
3594       //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3595
3596 #ifdef PROFILE
3597       // post task execution finish, set the end of the postTaskInfo
3598       profileTaskEnd();
3599 #endif
3600
3601       // Free up task parameter descriptor
3602       RUNFREE(currtpd->parameterArray);
3603       RUNFREE(currtpd);
3604       currtpd = NULL;
3605 #ifdef DEBUG
3606       BAMBOO_DEBUGPRINT(0xe99a);
3607 #endif
3608       //long clock7;
3609       //clock7 = BAMBOO_GET_EXE_TIME();
3610       //tprintf("sort: %d, grab: %d, check: %d, release: %d, other %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3), (int)(clock6-clock5), (int)(clock7-clock6));
3611
3612     }   //
3613     //} //  if (hashsize(activetasks)>0)
3614   } //  while(hashsize(activetasks)>0)
3615 #ifdef DEBUG
3616   BAMBOO_DEBUGPRINT(0xe99b);
3617 #endif
3618 }
3619
3620 /* This function processes an objects tags */
3621 void processtags(struct parameterdescriptor *pd,
3622                  int index,
3623                  struct parameterwrapper *parameter,
3624                  int * iteratorcount,
3625                  int *statusarray,
3626                  int numparams) {
3627   int i;
3628
3629   for(i=0; i<pd->numbertags; i++) {
3630     int slotid=pd->tagarray[2*i];
3631     int tagid=pd->tagarray[2*i+1];
3632
3633     if (statusarray[slotid+numparams]==0) {
3634       parameter->iterators[*iteratorcount].istag=1;
3635       parameter->iterators[*iteratorcount].tagid=tagid;
3636       parameter->iterators[*iteratorcount].slot=slotid+numparams;
3637       parameter->iterators[*iteratorcount].tagobjectslot=index;
3638       statusarray[slotid+numparams]=1;
3639       (*iteratorcount)++;
3640     }
3641   }
3642 }
3643
3644
3645 void processobject(struct parameterwrapper *parameter,
3646                    int index,
3647                    struct parameterdescriptor *pd,
3648                    int *iteratorcount,
3649                    int * statusarray,
3650                    int numparams) {
3651   int i;
3652   int tagcount=0;
3653   struct ObjectHash * objectset=
3654     ((struct parameterwrapper *)pd->queue)->objectset;
3655
3656   parameter->iterators[*iteratorcount].istag=0;
3657   parameter->iterators[*iteratorcount].slot=index;
3658   parameter->iterators[*iteratorcount].objectset=objectset;
3659   statusarray[index]=1;
3660
3661   for(i=0; i<pd->numbertags; i++) {
3662     int slotid=pd->tagarray[2*i];
3663     //int tagid=pd->tagarray[2*i+1];
3664     if (statusarray[slotid+numparams]!=0) {
3665       /* This tag has already been enqueued, use it to narrow search */
3666       parameter->iterators[*iteratorcount].tagbindings[tagcount]=
3667         slotid+numparams;
3668       tagcount++;
3669     }
3670   }
3671   parameter->iterators[*iteratorcount].numtags=tagcount;
3672
3673   (*iteratorcount)++;
3674 }
3675
3676 /* This function builds the iterators for a task & parameter */
3677
3678 void builditerators(struct taskdescriptor * task,
3679                     int index,
3680                     struct parameterwrapper * parameter) {
3681   int statusarray[MAXTASKPARAMS];
3682   int i;
3683   int numparams=task->numParameters;
3684   int iteratorcount=0;
3685   for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
3686
3687   statusarray[index]=1; /* Initial parameter */
3688   /* Process tags for initial iterator */
3689
3690   processtags(task->descriptorarray[index], index, parameter,
3691               &iteratorcount, statusarray, numparams);
3692
3693   while(1) {
3694 loopstart:
3695     /* Check for objects with existing tags */
3696     for(i=0; i<numparams; i++) {
3697       if (statusarray[i]==0) {
3698         struct parameterdescriptor *pd=task->descriptorarray[i];
3699         int j;
3700         for(j=0; j<pd->numbertags; j++) {
3701           int slotid=pd->tagarray[2*j];
3702           if(statusarray[slotid+numparams]!=0) {
3703             processobject(parameter, i, pd, &iteratorcount, statusarray,
3704                           numparams);
3705             processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3706             goto loopstart;
3707           }
3708         }
3709       }
3710     }
3711
3712     /* Next do objects w/ unbound tags*/
3713
3714     for(i=0; i<numparams; i++) {
3715       if (statusarray[i]==0) {
3716         struct parameterdescriptor *pd=task->descriptorarray[i];
3717         if (pd->numbertags>0) {
3718           processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3719           processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3720           goto loopstart;
3721         }
3722       }
3723     }
3724
3725     /* Nothing with a tag enqueued */
3726
3727     for(i=0; i<numparams; i++) {
3728       if (statusarray[i]==0) {
3729         struct parameterdescriptor *pd=task->descriptorarray[i];
3730         processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3731         processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3732         goto loopstart;
3733       }
3734     }
3735
3736     /* Nothing left */
3737     return;
3738   }
3739 }
3740
3741 void printdebug() {
3742   int i;
3743   int j;
3744   if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3745     return;
3746   }
3747   for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3748     struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3749 #ifndef RAW
3750     printf("%s\n", task->name);
3751 #endif
3752     for(j=0; j<task->numParameters; j++) {
3753       struct parameterdescriptor *param=task->descriptorarray[j];
3754       struct parameterwrapper *parameter=param->queue;
3755       struct ObjectHash * set=parameter->objectset;
3756       struct ObjectIterator objit;
3757 #ifndef RAW
3758       printf("  Parameter %d\n", j);
3759 #endif
3760       ObjectHashiterator(set, &objit);
3761       while(ObjhasNext(&objit)) {
3762         struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
3763         struct ___Object___ * tagptr=obj->___tags___;
3764         int nonfailed=Objdata4(&objit);
3765         int numflags=Objdata3(&objit);
3766         int flags=Objdata2(&objit);
3767         Objnext(&objit);
3768 #ifndef RAW
3769         printf("    Contains %lx\n", obj);
3770         printf("      flag=%d\n", obj->flag);
3771 #endif
3772         if (tagptr==NULL) {
3773         } else if (tagptr->type==TAGTYPE) {
3774 #ifndef RAW
3775           printf("      tag=%lx\n",tagptr);
3776 #else
3777           ;
3778 #endif
3779         } else {
3780           int tagindex=0;
3781           struct ArrayObject *ao=(struct ArrayObject *)tagptr;
3782           for(; tagindex<ao->___cachedCode___; tagindex++) {
3783 #ifndef RAW
3784             printf("      tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*,
3785                                               tagindex));
3786 #else
3787             ;
3788 #endif
3789           }
3790         }
3791       }
3792     }
3793   }
3794 }
3795
3796
3797 /* This function processes the task information to create queues for
3798    each parameter type. */
3799
3800 void processtasks() {
3801   int i;
3802   if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3803     return;
3804   }
3805   for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3806     struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3807     int j;
3808
3809     /* Build objectsets */
3810     for(j=0; j<task->numParameters; j++) {
3811       struct parameterdescriptor *param=task->descriptorarray[j];
3812       struct parameterwrapper *parameter=param->queue;
3813       parameter->objectset=allocateObjectHash(10);
3814       parameter->task=task;
3815     }
3816
3817     /* Build iterators for parameters */
3818     for(j=0; j<task->numParameters; j++) {
3819       struct parameterdescriptor *param=task->descriptorarray[j];
3820       struct parameterwrapper *parameter=param->queue;
3821       builditerators(task, j, parameter);
3822     }
3823   }
3824 }
3825
3826 void toiReset(struct tagobjectiterator * it) {
3827   if (it->istag) {
3828     it->tagobjindex=0;
3829   } else if (it->numtags>0) {
3830     it->tagobjindex=0;
3831   } else {
3832     ObjectHashiterator(it->objectset, &it->it);
3833   }
3834 }
3835
3836 int toiHasNext(struct tagobjectiterator *it,
3837                void ** objectarray OPTARG(int * failed)) {
3838   if (it->istag) {
3839     /* Iterate tag */
3840     /* Get object with tags */
3841     struct ___Object___ *obj=objectarray[it->tagobjectslot];
3842     struct ___Object___ *tagptr=obj->___tags___;
3843     if (tagptr->type==TAGTYPE) {
3844       if ((it->tagobjindex==0)&& /* First object */
3845           (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
3846         return 1;
3847       else
3848         return 0;
3849     } else {
3850       struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3851       int tagindex=it->tagobjindex;
3852       for(; tagindex<ao->___cachedCode___; tagindex++) {
3853         struct ___TagDescriptor___ *td=
3854           ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
3855         if (td->flag==it->tagid) {
3856           it->tagobjindex=tagindex; /* Found right type of tag */
3857           return 1;
3858         }
3859       }
3860       return 0;
3861     }
3862   } else if (it->numtags>0) {
3863     /* Use tags to locate appropriate objects */
3864     struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3865     struct ___Object___ *objptr=tag->flagptr;
3866     int i;
3867     if (objptr->type!=OBJECTARRAYTYPE) {
3868       if (it->tagobjindex>0)
3869         return 0;
3870       if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3871         return 0;
3872       for(i=1; i<it->numtags; i++) {
3873         struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3874         if (!containstag(objptr,tag2))
3875           return 0;
3876       }
3877       return 1;
3878     } else {
3879       struct ArrayObject *ao=(struct ArrayObject *) objptr;
3880       int tagindex;
3881       int i;
3882       for(tagindex=it->tagobjindex; tagindex<ao->___cachedCode___; tagindex++) {
3883         struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
3884         if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3885           continue;
3886         for(i=1; i<it->numtags; i++) {
3887           struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3888           if (!containstag(objptr,tag2))
3889             goto nexttag;
3890         }
3891         it->tagobjindex=tagindex;
3892         return 1;
3893 nexttag:
3894         ;
3895       }
3896       it->tagobjindex=tagindex;
3897       return 0;
3898     }
3899   } else {
3900     return ObjhasNext(&it->it);
3901   }
3902 }
3903
3904 int containstag(struct ___Object___ *ptr,
3905                 struct ___TagDescriptor___ *tag) {
3906   int j;
3907   struct ___Object___ * objptr=tag->flagptr;
3908   if (objptr->type==OBJECTARRAYTYPE) {
3909     struct ArrayObject *ao=(struct ArrayObject *)objptr;
3910     for(j=0; j<ao->___cachedCode___; j++) {
3911       if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
3912         return 1;
3913       }
3914     }
3915     return 0;
3916   } else {
3917     return objptr==ptr;
3918   }
3919 }
3920
3921 void toiNext(struct tagobjectiterator *it,
3922              void ** objectarray OPTARG(int * failed)) {
3923   /* hasNext has all of the intelligence */
3924   if(it->istag) {
3925     /* Iterate tag */
3926     /* Get object with tags */
3927     struct ___Object___ *obj=objectarray[it->tagobjectslot];
3928     struct ___Object___ *tagptr=obj->___tags___;
3929     if (tagptr->type==TAGTYPE) {
3930       it->tagobjindex++;
3931       objectarray[it->slot]=tagptr;
3932     } else {
3933       struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3934       objectarray[it->slot]=
3935         ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
3936     }
3937   } else if (it->numtags>0) {
3938     /* Use tags to locate appropriate objects */
3939     struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3940     struct ___Object___ *objptr=tag->flagptr;
3941     if (objptr->type!=OBJECTARRAYTYPE) {
3942       it->tagobjindex++;
3943       objectarray[it->slot]=objptr;
3944     } else {
3945       struct ArrayObject *ao=(struct ArrayObject *) objptr;
3946       objectarray[it->slot]=
3947         ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
3948     }
3949   } else {
3950     /* Iterate object */
3951     objectarray[it->slot]=(void *)Objkey(&it->it);
3952     Objnext(&it->it);
3953   }
3954 }
3955
3956 #ifdef PROFILE
3957 inline void profileTaskStart(char * taskname) {
3958   if(!taskInfoOverflow) {
3959     TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
3960     taskInfoArray[taskInfoIndex] = taskInfo;
3961     taskInfo->taskName = taskname;
3962     taskInfo->startTime = BAMBOO_GET_EXE_TIME();
3963     taskInfo->endTime = -1;
3964     taskInfo->exitIndex = -1;
3965     taskInfo->newObjs = NULL;
3966   }
3967 }
3968
3969 inline void profileTaskEnd() {
3970   if(!taskInfoOverflow) {
3971     taskInfoArray[taskInfoIndex]->endTime = BAMBOO_GET_EXE_TIME();
3972     taskInfoIndex++;
3973     if(taskInfoIndex == TASKINFOLENGTH) {
3974       taskInfoOverflow = true;
3975       //taskInfoIndex = 0;
3976     }
3977   }
3978 }
3979
3980 // output the profiling data
3981 void outputProfileData() {
3982 #ifdef USEIO
3983   int i;
3984   unsigned long long totaltasktime = 0;
3985   unsigned long long preprocessingtime = 0;
3986   unsigned long long objqueuecheckingtime = 0;
3987   unsigned long long postprocessingtime = 0;
3988   //int interruptiontime = 0;
3989   unsigned long long other = 0;
3990   unsigned long long averagetasktime = 0;
3991   int tasknum = 0;
3992
3993   printf("Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
3994   // output task related info
3995   for(i = 0; i < taskInfoIndex; i++) {
3996     TaskInfo* tmpTInfo = taskInfoArray[i];
3997     unsigned long long duration = tmpTInfo->endTime - tmpTInfo->startTime;
3998     printf("%s, %lld, %lld, %lld, %lld",
3999            tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime,
4000            duration, tmpTInfo->exitIndex);
4001     // summarize new obj info
4002     if(tmpTInfo->newObjs != NULL) {
4003       struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
4004       struct RuntimeIterator * iter = NULL;
4005       while(0 == isEmpty(tmpTInfo->newObjs)) {
4006         char * objtype = (char *)(getItem(tmpTInfo->newObjs));
4007         if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
4008           int num = 0;
4009           RuntimeHashget(nobjtbl, (int)objtype, &num);
4010           RuntimeHashremovekey(nobjtbl, (int)objtype);
4011           num++;
4012           RuntimeHashadd(nobjtbl, (int)objtype, num);
4013         } else {
4014           RuntimeHashadd(nobjtbl, (int)objtype, 1);
4015         }
4016         //printf(stderr, "new obj!\n");
4017       }
4018
4019       // output all new obj info
4020       iter = RuntimeHashcreateiterator(nobjtbl);
4021       while(RunhasNext(iter)) {
4022         char * objtype = (char *)Runkey(iter);
4023         int num = Runnext(iter);
4024         printf(", %s, %d", objtype, num);
4025       }
4026     }
4027     printf("\n");
4028     if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
4029       preprocessingtime += duration;
4030     } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
4031       postprocessingtime += duration;
4032     } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
4033       objqueuecheckingtime += duration;
4034     } else {
4035       totaltasktime += duration;
4036       averagetasktime += duration;
4037       tasknum++;
4038     }
4039   }
4040
4041   if(taskInfoOverflow) {
4042     printf("Caution: task info overflow!\n");
4043   }
4044
4045   other = totalexetime-totaltasktime-preprocessingtime-postprocessingtime;
4046   averagetasktime /= tasknum;
4047
4048   printf("\nTotal time: %lld\n", totalexetime);
4049   printf("Total task execution time: %lld (%d%%)\n", totaltasktime,
4050          (int)(((double)totaltasktime/(double)totalexetime)*100));
4051   printf("Total objqueue checking time: %lld (%d%%)\n",
4052          objqueuecheckingtime,
4053          (int)(((double)objqueuecheckingtime/(double)totalexetime)*100));
4054   printf("Total pre-processing time: %lld (%d%%)\n", preprocessingtime,
4055          (int)(((double)preprocessingtime/(double)totalexetime)*100));
4056   printf("Total post-processing time: %lld (%d%%)\n", postprocessingtime,
4057          (int)(((double)postprocessingtime/(double)totalexetime)*100));
4058   printf("Other time: %lld (%d%%)\n", other,
4059          (int)(((double)other/(double)totalexetime)*100));
4060
4061
4062   printf("\nAverage task execution time: %lld\n", averagetasktime);
4063
4064   //printf("\nTotal time spent for interruptions: %lld\n", interrupttime);
4065 #else
4066   int i = 0;
4067   int j = 0;
4068
4069   BAMBOO_DEBUGPRINT(0xdddd);
4070   // output task related info
4071   for(i= 0; i < taskInfoIndex; i++) {
4072     TaskInfo* tmpTInfo = taskInfoArray[i];
4073     char* tmpName = tmpTInfo->taskName;
4074     int nameLen = strlen(tmpName);
4075     BAMBOO_DEBUGPRINT(0xddda);
4076     for(j = 0; j < nameLen; j++) {
4077       BAMBOO_DEBUGPRINT_REG(tmpName[j]);
4078     }
4079     BAMBOO_DEBUGPRINT(0xdddb);
4080     BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
4081     BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
4082     BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
4083     if(tmpTInfo->newObjs != NULL) {
4084       struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
4085       struct RuntimeIterator * iter = NULL;
4086       while(0 == isEmpty(tmpTInfo->newObjs)) {
4087         char * objtype = (char *)(getItem(tmpTInfo->newObjs));
4088         if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
4089           int num = 0;
4090           RuntimeHashget(nobjtbl, (int)objtype, &num);
4091           RuntimeHashremovekey(nobjtbl, (int)objtype);
4092           num++;
4093           RuntimeHashadd(nobjtbl, (int)objtype, num);
4094         } else {
4095           RuntimeHashadd(nobjtbl, (int)objtype, 1);
4096         }
4097       }
4098
4099       // ouput all new obj info
4100       iter = RuntimeHashcreateiterator(nobjtbl);
4101       while(RunhasNext(iter)) {
4102         char * objtype = (char *)Runkey(iter);
4103         int num = Runnext(iter);
4104         int nameLen = strlen(objtype);
4105         BAMBOO_DEBUGPRINT(0xddda);
4106         for(j = 0; j < nameLen; j++) {
4107           BAMBOO_DEBUGPRINT_REG(objtype[j]);
4108         }
4109         BAMBOO_DEBUGPRINT(0xdddb);
4110         BAMBOO_DEBUGPRINT_REG(num);
4111       }
4112     }
4113     BAMBOO_DEBUGPRINT(0xdddc);
4114   }
4115
4116   if(taskInfoOverflow) {
4117     BAMBOO_DEBUGPRINT(0xefee);
4118   }
4119
4120   // output interrupt related info
4121   for(i = 0; i < interruptInfoIndex; i++) {
4122     InterruptInfo* tmpIInfo = interruptInfoArray[i];
4123     BAMBOO_DEBUGPRINT(0xddde);
4124     BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
4125     BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
4126     BAMBOO_DEBUGPRINT(0xdddf);
4127   }
4128
4129   if(interruptInfoOverflow) {
4130     BAMBOO_DEBUGPRINT(0xefef);
4131   }
4132
4133   BAMBOO_DEBUGPRINT(0xeeee);
4134 #endif
4135 }
4136 #endif  // #ifdef PROFILE
4137
4138 #endif