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