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