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