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