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