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