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