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