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