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