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