3 #include "multicoreruntime.h"
4 #include "runtime_arch.h"
5 #include "GenericHashtable.h"
8 #define INLINE inline __attribute__((always_inline))
9 #endif // #ifndef INLINE
11 // data structures for task invocation
12 struct genhashtable * activetasks;
13 struct taskparamdescriptor * currtpd;
14 struct LockValue runtime_locks[MAXTASKPARAMS];
17 // specific functions used inside critical sections
18 void enqueueObject_I(void * ptr,
19 struct parameterwrapper ** queues,
21 int enqueuetasks_I(struct parameterwrapper *parameter,
22 struct parameterwrapper *prevptr,
23 struct ___Object___ *ptr,
29 #define NUM_CORES2TEST 5
31 int core2test[1][NUM_CORES2TEST] = {
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}
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}
82 unsigned int gcmem_mixed_threshold = 0;
83 unsigned int gcmem_mixed_usedmem = 0;
84 #define NUM_CORES2TEST 9
86 int core2test[1][NUM_CORES2TEST] = {
87 {0, -1, -1, -1, -1, -1, -1, -1, -1}
90 int core2test[56][NUM_CORES2TEST] = {
91 { 0, -1, 7, -1, 1, -1, 14, -1, 2},
92 { 1, -1, 8, 0, 2, -1, 15, -1, 3},
93 { 2, -1, 9, 1, 3, -1, 16, 0, 4},
94 { 3, -1, 10, 2, 4, -1, 17, 1, 5},
95 { 4, -1, 11, 3, 5, -1, 18, 2, 6},
96 { 5, -1, 12, 4, 6, -1, 19, 3, -1},
97 { 6, -1, 13, 5, -1, -1, 20, 4, -1},
98 { 7, 0, 14, -1, 8, -1, 21, -1, 9},
99 { 8, 1, 15, 7, 9, -1, 22, -1, 10},
100 { 9, 2, 16, 8, 10, -1, 23, 7, 11},
101 {10, 3, 17, 9, 11, -1, 24, 8, 12},
102 {11, 4, 18, 10, 12, -1, 25, 9, 13},
103 {12, 5, 19, 11, 13, -1, 26, 10, -1},
104 {13, 6, 20, 12, -1, -1, 27, 11, -1},
105 {14, 7, 21, -1, 15, 0, 28, -1, 16},
106 {15, 8, 22, 14, 16, 1, 29, -1, 17},
107 {16, 9, 23, 15, 17, 2, 30, 14, 18},
108 {17, 10, 24, 16, 18, 3, 31, 15, 19},
109 {18, 11, 25, 17, 19, 4, 32, 16, 20},
110 {19, 12, 26, 18, 20, 5, 33, 17, -1},
111 {20, 13, 27, 19, -1, 6, 34, 18, -1},
112 {21, 14, 28, -1, 22, 7, 35, -1, 23},
113 {22, 15, 29, 21, 23, 8, 36, -1, 24},
114 {23, 16, 30, 22, 24, 9, 37, 21, 25},
115 {24, 17, 31, 23, 25, 10, 38, 22, 26},
116 {25, 18, 32, 24, 26, 11, 39, 23, 27},
117 {26, 19, 33, 25, 27, 12, 40, 24, -1},
118 {27, 20, 34, 26, -1, 13, 41, 25, -1},
119 {28, 21, 35, -1, 29, 14, 42, -1, 30},
120 {29, 22, 36, 28, 30, 15, 43, -1, 31},
121 {30, 23, 37, 29, 31, 16, 44, 28, 32},
122 {31, 24, 38, 30, 32, 17, 45, 29, 33},
123 {32, 25, 39, 31, 33, 18, 46, 30, 34},
124 {33, 26, 40, 32, 34, 19, 47, 31, -1},
125 {34, 27, 41, 33, -1, 20, 48, 32, -1},
126 {35, 28, 42, -1, 36, 21, 49, -1, 37},
127 {36, 29, 43, 35, 37, 22, 50, -1, 38},
128 {37, 30, 44, 36, 38, 23, 51, 35, 39},
129 {38, 31, 45, 37, 39, 24, 52, 36, 40},
130 {39, 32, 46, 38, 40, 25, 53, 37, 41},
131 {40, 33, 47, 39, 41, 26, 54, 38, -1},
132 {41, 34, 48, 40, -1, 27, 55, 39, -1},
133 {42, 35, 49, -1, 43, 28, -1, -1, 44},
134 {43, 36, 50, 42, 44, 29, -1, -1, 45},
135 {44, 37, 51, 43, 45, 30, -1, 42, 46},
136 {45, 38, 52, 44, 46, 31, -1, 43, 47},
137 {46, 39, 53, 45, 47, 32, -1, 44, 48},
138 {47, 40, 54, 46, 48, 33, -1, 45, -1},
139 {48, 41, 55, 47, -1, 34, -1, 46, -1},
140 {49, 42, -1, -1, 50, 35, -1, -1, 51},
141 {50, 43, -1, 49, 51, 36, -1, -1, 52},
142 {51, 44, -1, 50, 52, 37, -1, 49, 53},
143 {52, 45, -1, 51, 53, 38, -1, 50, 54},
144 {53, 46, -1, 52, 54, 39, -1, 51, 55},
145 {54, 47, -1, 53, 55, 40, -1, 52, -1},
146 {55, 48, -1, 54, -1, 41, -1, 53, -1}
149 int core2test[62][NUM_CORES2TEST] = {
150 { 0, -1, 6, -1, 1, -1, 14, -1, 2},
151 { 1, -1, 7, 0, 2, -1, 15, -1, 3},
152 { 2, -1, 8, 1, 3, -1, 16, 0, 4},
153 { 3, -1, 9, 2, 4, -1, 17, 1, 5},
154 { 4, -1, 10, 3, 5, -1, 18, 2, -1},
155 { 5, -1, 11, 4, -1, -1, 19, 3, -1},
156 { 6, 0, 14, -1, 7, -1, 22, -1, 8},
157 { 7, 1, 15, 6, 8, -1, 23, -1, 9},
158 { 8, 2, 16, 7, 9, -1, 24, 6, 10},
159 { 9, 3, 17, 8, 10, -1, 25, 7, 11},
160 {10, 4, 18, 9, 11, -1, 26, 8, 12},
161 {11, 5, 19, 10, 12, -1, 27, 9, 13},
162 {12, -1, 20, 11, 13, -1, 28, 10, -1},
163 {13, -1, 21, 12, -1, -1, 29, 11, -1},
164 {14, 6, 22, -1, 15, 0, 30, -1, 16},
165 {15, 7, 23, 14, 16, 1, 31, -1, 17},
166 {16, 8, 24, 15, 17, 2, 32, 14, 18},
167 {17, 9, 25, 16, 18, 3, 33, 15, 19},
168 {18, 10, 26, 17, 19, 4, 34, 16, 20},
169 {19, 11, 27, 18, 20, 5, 35, 17, 21},
170 {20, 12, 28, 19, 21, -1, 36, 18, -1},
171 {21, 13, 29, 28, -1, -1, 37, 19, -1},
172 {22, 14, 30, -1, 23, 6, 38, -1, 24},
173 {23, 15, 31, 22, 24, 7, 39, -1, 25},
174 {24, 16, 32, 23, 25, 8, 40, 22, 26},
175 {25, 17, 33, 24, 26, 9, 41, 23, 27},
176 {26, 18, 34, 25, 27, 10, 42, 24, 28},
177 {27, 19, 35, 26, 28, 11, 43, 25, 29},
178 {28, 20, 36, 27, 29, 12, 44, 26, -1},
179 {29, 21, 37, 28, -1, 13, 45, 27, -1},
180 {30, 22, 38, -1, 31, 22, 46, -1, 32},
181 {31, 23, 39, 30, 32, 15, 47, -1, 33},
182 {32, 24, 40, 31, 33, 16, 48, 30, 34},
183 {33, 25, 41, 32, 34, 17, 49, 31, 35},
184 {34, 26, 42, 33, 35, 18, 50, 32, 36},
185 {35, 27, 43, 34, 36, 19, 51, 33, 37},
186 {36, 28, 44, 35, 37, 20, 52, 34, -1},
187 {37, 29, 45, 36, -1, 21, 53, 35, -1},
188 {38, 30, 46, -1, 39, 22, 54, -1, 40},
189 {39, 31, 47, 38, 40, 23, 55, -1, 41},
190 {40, 32, 48, 39, 41, 24, 56, 38, 42},
191 {41, 33, 49, 40, 42, 25, 57, 39, 43},
192 {42, 34, 50, 41, 43, 26, 58, 40, 44},
193 {43, 35, 51, 42, 44, 27, 59, 41, 45},
194 {44, 36, 52, 43, 45, 28, 60, 42, -1},
195 {45, 37, 53, 44, -1, 29, 61, 43, -1},
196 {46, 38, 54, -1, 47, 30, -1, -1, 48},
197 {47, 39, 55, 46, 48, 31, -1, -1, 49},
198 {48, 40, 56, 47, 49, 32, -1, 46, 50},
199 {49, 41, 57, 48, 50, 33, -1, 47, 51},
200 {50, 42, 58, 49, 51, 34, -1, 48, 52},
201 {51, 43, 59, 50, 52, 35, -1, 49, 53},
202 {52, 44, 60, 51, 53, 36, -1, 50, -1},
203 {53, 45, 61, 52, -1, 37, -1, 51, -1},
204 {54, 46, -1, -1, 55, 38, -1, -1, 56},
205 {55, 47, -1, 54, 56, 39, -1, -1, 57},
206 {56, 48, -1, 55, 57, 40, -1, 54, 58},
207 {57, 49, -1, 56, 59, 41, -1, 55, 59},
208 {58, 50, -1, 57, 59, 42, -1, 56, 60},
209 {59, 51, -1, 58, 60, 43, -1, 57, 61},
210 {60, 52, -1, 59, 61, 44, -1, 58, -1},
211 {61, 53, -1, 60, -1, 45, -1, 59, -1}
216 inline __attribute__((always_inline))
217 void setupsmemmode(void) {
219 // Only allocate local mem chunks to each core.
220 // If a core has used up its local shared memory, start gc.
221 bamboo_smem_mode = SMEMLOCAL;
223 // Allocate the local shared memory to each core with the highest priority,
224 // if a core has used up its local shared memory, try to allocate the
225 // shared memory that belong to its neighbours, if also failed, start gc.
226 bamboo_smem_mode = SMEMFIXED;
228 // Allocate the local shared memory to each core with the highest priority,
229 // if a core has used up its local shared memory, try to allocate the
230 // shared memory that belong to its neighbours first, if failed, check
231 // current memory allocation rate, if it has already reached the threshold,
232 // start gc, otherwise, allocate the shared memory globally. If all the
233 // shared memory has been used up, start gc.
234 bamboo_smem_mode = SMEMMIXED;
236 // Allocate all the memory chunks globally, do not consider the host cores
237 // When all the shared memory are used up, start gc.
238 bamboo_smem_mode = SMEMGLOBAL;
240 // defaultly using local mode
241 bamboo_smem_mode = SMEMLOCAL;
242 //bamboo_smem_mode = SMEMGLOBAL;
243 //bamboo_smem_mode = SMEMFIXED;
245 } // void setupsmemmode(void)
248 inline __attribute__((always_inline))
249 void initruntimedata() {
251 // initialize the arrays
252 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
253 // startup core to initialize corestatus[]
254 for(i = 0; i < NUMCORESACTIVE; ++i) {
257 numreceiveobjs[i] = 0;
259 // initialize the profile data arrays
260 profilestatus[i] = 1;
264 gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
265 gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
267 } // for(i = 0; i < NUMCORESACTIVE; ++i)
269 for(i = 0; i < NUMCORES4GC; ++i) {
271 gcrequiredmems[i] = 0;
273 gcfilledblocks[i] = 0;
274 } // for(i = 0; i < NUMCORES4GC; ++i)
277 gc_infoOverflow = false;
278 gc_num_livespace = 0;
279 gc_num_freespace = 0;
290 self_numsendobjs = 0;
291 self_numreceiveobjs = 0;
293 for(i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
298 msglength = BAMBOO_MSG_BUF_LENGTH;
300 for(i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
306 isMsgHanging = false;
307 //isMsgSending = false;
310 bamboo_cur_msp = NULL;
311 bamboo_smem_size = 0;
312 totransobjqueue = createQueue_I();
315 bamboo_smem_zero_top = NULL;
317 gcprocessing = false;
318 gcphase = FINISHPHASE;
322 gcself_numsendobjs = 0;
323 gcself_numreceiveobjs = 0;
324 gcmarkedptrbound = 0;
325 #ifdef LOCALHASHTBL_TEST
326 gcpointertbl = allocateRuntimeHash_I(20);
328 gcpointertbl = mgchashCreate_I(2000, 0.75);
330 //gcpointertbl = allocateMGCHash_I(20);
331 gcforwardobjtbl = allocateMGCHash_I(20, 3);
334 //gcismapped = false;
343 gcsbstarttbl = BAMBOO_BASE_VA;
344 bamboo_smemtbl = (void *)gcsbstarttbl
345 + (BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE)*sizeof(INTPTR);
346 if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
347 int t_size = ((BAMBOO_RMSP_SIZE)-sizeof(mgcsharedhashtbl_t)*2
348 -128*sizeof(size_t))/sizeof(mgcsharedhashlistnode_t)-2;
350 unsigned int tmp_k = 1 << (sizeof(int)*8 -1);
351 while(((t_size & tmp_k) == 0) && (kk < sizeof(int)*8)) {
352 t_size = t_size << 1;
355 t_size = tmp_k >> kk;
356 gcsharedptbl = mgcsharedhashCreate_I(t_size,0.30);//allocateGCSharedHash_I(20);
360 BAMBOO_MEMSET_WH(gcrpointertbls, 0,
361 sizeof(mgcsharedhashtbl_t *)*NUMCORES4GC);
362 //sizeof(struct RuntimeHash *)*NUMCORES4GC);
364 gcmem_mixed_threshold = (unsigned int)((BAMBOO_SHARED_MEM_SIZE
365 -bamboo_reserved_smem*BAMBOO_SMEM_SIZE)*0.8);
366 gcmem_mixed_usedmem = 0;
371 gc_num_forwardobj = 0;
372 gc_num_profiles = NUMCORESACTIVE - 1;
375 gc_num_flush_dtlb = 0;
377 gc_localheap_s = false;
378 #ifdef GC_CACHE_ADAPT
379 gccachestage = false;
380 // enable the timer interrupt
381 #ifdef GC_CACHE_SAMPLING
382 bamboo_tile_timer_set_next_event(GC_TILE_TIMER_EVENT_SETTING); // TODO
383 bamboo_unmask_timer_intr();
384 bamboo_dtlb_sampling_process();
385 #endif // GC_CACHE_SAMPLING
386 #endif // GC_CACHE_ADAPT
388 // create the lock table, lockresult table and obj queue
391 (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
392 /* Set allocation blocks*/
393 locktable.listhead=NULL;
394 locktable.listtail=NULL;
396 locktable.numelements = 0;
401 lockRedirectTbl = allocateRuntimeHash_I(20);
402 objRedirectLockTbl = allocateRuntimeHash_I(20);
407 objqueue.head = NULL;
408 objqueue.tail = NULL;
414 //isInterrupt = true;
418 taskInfoOverflow = false;
419 #ifdef PROFILE_INTERRUPT
420 interruptInfoIndex = 0;
421 interruptInfoOverflow = false;
422 #endif // PROFILE_INTERRUPT
425 for(i = 0; i < MAXTASKPARAMS; i++) {
426 runtime_locks[i].redirectlock = 0;
427 runtime_locks[i].value = 0;
432 inline __attribute__((always_inline))
433 void disruntimedata() {
435 #ifdef LOCALHASHTBL_TEST
436 freeRuntimeHash(gcpointertbl);
438 mgchashDelete(gcpointertbl);
440 //freeMGCHash(gcpointertbl);
441 freeMGCHash(gcforwardobjtbl);
442 // for mapping info structures
443 //freeRuntimeHash(gcrcoretbl);
445 freeRuntimeHash(lockRedirectTbl);
446 freeRuntimeHash(objRedirectLockTbl);
447 RUNFREE(locktable.bucket);
449 if(activetasks != NULL) {
450 genfreehashtable(activetasks);
452 if(currtpd != NULL) {
453 RUNFREE(currtpd->parameterArray);
457 BAMBOO_LOCAL_MEM_CLOSE();
458 BAMBOO_SHARE_MEM_CLOSE();
461 inline __attribute__((always_inline))
462 bool checkObjQueue() {
464 struct transObjInfo * objInfo = NULL;
468 #ifdef ACCURATEPROFILE
469 bool isChecking = false;
470 if(!isEmpty(&objqueue)) {
471 profileTaskStart("objqueue checking");
473 } // if(!isEmpty(&objqueue))
477 while(!isEmpty(&objqueue)) {
479 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
481 BAMBOO_DEBUGPRINT(0xf001);
484 //isInterrupt = false;
487 BAMBOO_DEBUGPRINT(0xeee1);
490 objInfo = (struct transObjInfo *)getItem(&objqueue);
491 obj = objInfo->objptr;
493 BAMBOO_DEBUGPRINT_REG((int)obj);
495 // grab lock and flush the obj
499 BAMBOO_WAITING_FOR_LOCK(0);
500 } // while(!lockflag)
503 BAMBOO_DEBUGPRINT_REG(grount);
518 BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
519 BAMBOO_CACHE_FLUSH_RANGE((int)obj,
520 classsize[((struct ___Object___ *)obj)->type]);
522 // enqueue the object
523 for(k = 0; k < objInfo->length; ++k) {
524 int taskindex = objInfo->queues[2 * k];
525 int paramindex = objInfo->queues[2 * k + 1];
526 struct parameterwrapper ** queues =
527 &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
529 BAMBOO_DEBUGPRINT_REG(taskindex);
530 BAMBOO_DEBUGPRINT_REG(paramindex);
531 struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
532 tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n",
533 BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj,
534 (long)obj, tmpptr->flag);
536 enqueueObject_I(obj, queues, 1);
538 BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
540 } // for(k = 0; k < objInfo->length; ++k)
541 releasewritelock_I(obj);
542 RUNFREE(objInfo->queues);
546 // put it at the end of the queue if no update version in the queue
547 struct QueueItem * qitem = getHead(&objqueue);
548 struct QueueItem * prev = NULL;
549 while(qitem != NULL) {
550 struct transObjInfo * tmpinfo =
551 (struct transObjInfo *)(qitem->objectptr);
552 if(tmpinfo->objptr == obj) {
553 // the same object in the queue, which should be enqueued
554 // recently. Current one is outdate, do not re-enqueue it
555 RUNFREE(objInfo->queues);
560 } // if(tmpinfo->objptr == obj)
561 qitem = getNextQueueItem(prev);
562 } // while(qitem != NULL)
563 // try to execute active tasks already enqueued first
564 addNewItem_I(&objqueue, objInfo);
566 //isInterrupt = true;
569 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
571 BAMBOO_DEBUGPRINT(0xf000);
575 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
577 BAMBOO_DEBUGPRINT(0xf000);
579 } // while(!isEmpty(&objqueue))
582 #ifdef ACCURATEPROFILE
590 BAMBOO_DEBUGPRINT(0xee02);
595 inline __attribute__((always_inline))
596 void checkCoreStatus() {
597 bool allStall = false;
601 (waitconfirm && (numconfirm == 0))) {
603 BAMBOO_DEBUGPRINT(0xee04);
604 BAMBOO_DEBUGPRINT_REG(waitconfirm);
606 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
608 BAMBOO_DEBUGPRINT(0xf001);
610 corestatus[BAMBOO_NUM_OF_CORE] = 0;
611 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
612 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
613 // check the status of all cores
616 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
618 for(i = 0; i < NUMCORESACTIVE; ++i) {
620 BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
622 if(corestatus[i] != 0) {
626 } // for(i = 0; i < NUMCORESACTIVE; ++i)
628 // check if the sum of send objs and receive obj are the same
629 // yes->check if the info is the latest; no->go on executing
631 for(i = 0; i < NUMCORESACTIVE; ++i) {
632 sumsendobj += numsendobjs[i];
634 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
636 } // for(i = 0; i < NUMCORESACTIVE; ++i)
637 for(i = 0; i < NUMCORESACTIVE; ++i) {
638 sumsendobj -= numreceiveobjs[i];
640 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
642 } // for(i = 0; i < NUMCORESACTIVE; ++i)
643 if(0 == sumsendobj) {
645 // the first time found all cores stall
646 // send out status confirm msg to all other cores
647 // reset the corestatus array too
649 BAMBOO_DEBUGPRINT(0xee05);
651 corestatus[BAMBOO_NUM_OF_CORE] = 1;
653 numconfirm = NUMCORESACTIVE - 1;
654 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
655 for(i = 1; i < NUMCORESACTIVE; ++i) {
657 // send status confirm msg to core i
658 send_msg_1(i, STATUSCONFIRM, false);
659 } // for(i = 1; i < NUMCORESACTIVE; ++i)
662 // all the core status info are the latest
663 // terminate; for profiling mode, send request to all
664 // other cores to pour out profiling data
666 BAMBOO_DEBUGPRINT(0xee06);
670 totalexetime = BAMBOO_GET_EXE_TIME() - bamboo_start_time;
673 //BAMBOO_DEBUGPRINT_REG(interrupttime);
676 BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME() - bamboo_start_time);
677 //BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
679 BAMBOO_DEBUGPRINT_REG(gc_num_flush_dtlb);
681 #ifndef BAMBOO_MEMPROF
682 BAMBOO_DEBUGPRINT(0xbbbbbbbb);
685 // profile mode, send msgs to other cores to request pouring
686 // out progiling data
688 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
690 BAMBOO_DEBUGPRINT(0xf000);
692 for(i = 1; i < NUMCORESACTIVE; ++i) {
693 // send profile request msg to core i
694 send_msg_2(i, PROFILEOUTPUT, totalexetime, false);
695 } // for(i = 1; i < NUMCORESACTIVE; ++i)
697 // pour profiling data on startup core
701 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
703 BAMBOO_DEBUGPRINT(0xf001);
705 profilestatus[BAMBOO_NUM_OF_CORE] = 0;
706 // check the status of all cores
709 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
711 for(i = 0; i < NUMCORESACTIVE; ++i) {
713 BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
715 if(profilestatus[i] != 0) {
719 } // for(i = 0; i < NUMCORESACTIVE; ++i)
722 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
724 BAMBOO_DEBUGPRINT(0xf000);
729 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
735 // gc_profile mode, output gc prfiling data
737 #ifdef GC_CACHE_ADAPT
738 bamboo_mask_timer_intr(); // disable the TILE_TIMER interrupt
739 #endif // GC_CACHE_ADAPT
741 gc_outputProfileData();
742 #endif // #ifdef GC_PROFILE
743 #endif // #ifdef MULTICORE_GC
745 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
746 terminate(); // All done.
747 } // if(!waitconfirm)
749 // still some objects on the fly on the network
750 // reset the waitconfirm and numconfirm
752 BAMBOO_DEBUGPRINT(0xee07);
756 } // if(0 == sumsendobj)
758 // not all cores are stall, keep on waiting
760 BAMBOO_DEBUGPRINT(0xee08);
765 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
767 BAMBOO_DEBUGPRINT(0xf000);
769 } // if((!waitconfirm) ||
772 // main function for each core
773 inline void run(void * arg) {
777 bool sendStall = false;
779 bool tocontinue = false;
781 corenum = BAMBOO_GET_NUM_OF_CORE();
783 BAMBOO_DEBUGPRINT(0xeeee);
784 BAMBOO_DEBUGPRINT_REG(corenum);
785 BAMBOO_DEBUGPRINT(STARTUPCORE);
787 //BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME()); // TODO
789 // initialize runtime data structures
792 // other architecture related initialization
796 initializeexithandler();
798 // main process of the execution module
799 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
800 // non-executing cores, only processing communications
803 //isInterrupt = false;
807 /* Create queue of active tasks */
809 genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
810 (int (*)(void *,void *)) &comparetpd);
812 /* Process task information */
815 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
816 /* Create startup object */
817 createstartupobject(argc, argv);
821 BAMBOO_DEBUGPRINT(0xee00);
827 // check if need to do GC
831 #endif // MULTICORE_GC
833 // check if there are new active tasks can be executed
840 while(receiveObject() != -1) {
845 BAMBOO_DEBUGPRINT(0xee01);
848 // check if there are some pending objects,
849 // if yes, enqueue them and executetasks again
850 tocontinue = checkObjQueue();
854 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
857 BAMBOO_DEBUGPRINT(0xee03);
865 BAMBOO_DEBUGPRINT(0xee09);
871 // wait for some time
874 BAMBOO_DEBUGPRINT(0xee0a);
880 // send StallMsg to startup core
882 BAMBOO_DEBUGPRINT(0xee0b);
885 send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
886 self_numsendobjs, self_numreceiveobjs, false);
898 BAMBOO_DEBUGPRINT(0xee0c);
901 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
904 } // if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)
908 struct ___createstartupobject____I_locals {
911 struct ___StartupObject___ * ___startupobject___;
912 struct ArrayObject * ___stringarray___;
913 }; // struct ___createstartupobject____I_locals
915 void createstartupobject(int argc,
919 /* Allocate startup object */
921 struct ___createstartupobject____I_locals ___locals___ =
922 {2, NULL, NULL, NULL};
923 struct ___StartupObject___ *startupobject=
924 (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
925 ___locals___.___startupobject___ = startupobject;
926 struct ArrayObject * stringarray=
927 allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
928 ___locals___.___stringarray___ = stringarray;
930 struct ___StartupObject___ *startupobject=
931 (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
932 struct ArrayObject * stringarray=
933 allocate_newarray(STRINGARRAYTYPE, argc-1);
935 /* Build array of strings */
936 startupobject->___parameters___=stringarray;
937 for(i=1; i<argc; i++) {
938 int length=strlen(argv[i]);
940 struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
942 struct ___String___ *newstring=NewString(argv[i],length);
944 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
948 startupobject->version = 0;
949 startupobject->lock = NULL;
951 /* Set initialized flag for startup object */
952 flagorandinit(startupobject,1,0xFFFFFFFF);
953 enqueueObject(startupobject, NULL, 0);
955 BAMBOO_CACHE_FLUSH_ALL();
959 int hashCodetpd(struct taskparamdescriptor *ftd) {
960 int hash=(int)ftd->task;
962 for(i=0; i<ftd->numParameters; i++) {
963 hash^=(int)ftd->parameterArray[i];
968 int comparetpd(struct taskparamdescriptor *ftd1,
969 struct taskparamdescriptor *ftd2) {
971 if (ftd1->task!=ftd2->task)
973 for(i=0; i<ftd1->numParameters; i++)
974 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
979 /* This function sets a tag. */
981 void tagset(void *ptr,
982 struct ___Object___ * obj,
983 struct ___TagDescriptor___ * tagd) {
985 void tagset(struct ___Object___ * obj,
986 struct ___TagDescriptor___ * tagd) {
988 struct ArrayObject * ao=NULL;
989 struct ___Object___ * tagptr=obj->___tags___;
991 obj->___tags___=(struct ___Object___ *)tagd;
993 /* Have to check if it is already set */
994 if (tagptr->type==TAGTYPE) {
995 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
1000 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
1001 struct ArrayObject * ao=
1002 allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
1003 obj=(struct ___Object___ *)ptrarray[2];
1004 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
1005 td=(struct ___TagDescriptor___ *) obj->___tags___;
1007 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
1010 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
1011 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
1012 obj->___tags___=(struct ___Object___ *) ao;
1013 ao->___cachedCode___=2;
1017 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
1018 for(i=0; i<ao->___cachedCode___; i++) {
1019 struct ___TagDescriptor___ * td=
1020 ARRAYGET(ao, struct ___TagDescriptor___*, i);
1025 if (ao->___cachedCode___<ao->___length___) {
1026 ARRAYSET(ao, struct ___TagDescriptor___ *,ao->___cachedCode___,tagd);
1027 ao->___cachedCode___++;
1030 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
1031 struct ArrayObject * aonew=
1032 allocate_newarray(&ptrarray,TAGARRAYTYPE,
1033 TAGARRAYINTERVAL+ao->___length___);
1034 obj=(struct ___Object___ *)ptrarray[2];
1035 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
1036 ao=(struct ArrayObject *)obj->___tags___;
1038 struct ArrayObject * aonew=
1039 allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
1042 aonew->___cachedCode___=ao->___length___+1;
1043 for(i=0; i<ao->___length___; i++) {
1044 ARRAYSET(aonew, struct ___TagDescriptor___*, i,
1045 ARRAYGET(ao, struct ___TagDescriptor___*, i));
1047 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___,tagd);
1053 struct ___Object___ * tagset=tagd->flagptr;
1056 } else if (tagset->type!=OBJECTARRAYTYPE) {
1058 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
1059 struct ArrayObject * ao=
1060 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
1061 obj=(struct ___Object___ *)ptrarray[2];
1062 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
1064 struct ArrayObject * ao=
1065 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
1067 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
1068 ARRAYSET(ao, struct ___Object___ *, 1, obj);
1069 ao->___cachedCode___=2;
1070 tagd->flagptr=(struct ___Object___ *)ao;
1072 struct ArrayObject *ao=(struct ArrayObject *) tagset;
1073 if (ao->___cachedCode___<ao->___length___) {
1074 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
1078 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
1079 struct ArrayObject * aonew=
1080 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
1081 OBJECTARRAYINTERVAL+ao->___length___);
1082 obj=(struct ___Object___ *)ptrarray[2];
1083 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
1084 ao=(struct ArrayObject *)tagd->flagptr;
1086 struct ArrayObject * aonew=allocate_newarray(OBJECTARRAYTYPE,
1087 OBJECTARRAYINTERVAL+ao->___length___);
1089 aonew->___cachedCode___=ao->___cachedCode___+1;
1090 for(i=0; i<ao->___length___; i++) {
1091 ARRAYSET(aonew, struct ___Object___*, i,
1092 ARRAYGET(ao, struct ___Object___*, i));
1094 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
1095 tagd->flagptr=(struct ___Object___ *) aonew;
1101 /* This function clears a tag. */
1103 void tagclear(void *ptr,
1104 struct ___Object___ * obj,
1105 struct ___TagDescriptor___ * tagd) {
1107 void tagclear(struct ___Object___ * obj,
1108 struct ___TagDescriptor___ * tagd) {
1110 /* We'll assume that tag is alway there.
1111 Need to statically check for this of course. */
1112 struct ___Object___ * tagptr=obj->___tags___;
1114 if (tagptr->type==TAGTYPE) {
1115 if ((struct ___TagDescriptor___ *)tagptr==tagd)
1116 obj->___tags___=NULL;
1118 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
1120 for(i=0; i<ao->___cachedCode___; i++) {
1121 struct ___TagDescriptor___ * td=
1122 ARRAYGET(ao, struct ___TagDescriptor___ *, i);
1124 ao->___cachedCode___--;
1125 if (i<ao->___cachedCode___)
1126 ARRAYSET(ao, struct ___TagDescriptor___ *, i,
1127 ARRAYGET(ao,struct ___TagDescriptor___*,ao->___cachedCode___));
1128 ARRAYSET(ao,struct ___TagDescriptor___ *,ao->___cachedCode___, NULL);
1129 if (ao->___cachedCode___==0)
1130 obj->___tags___=NULL;
1137 struct ___Object___ *tagset=tagd->flagptr;
1138 if (tagset->type!=OBJECTARRAYTYPE) {
1142 struct ArrayObject *ao=(struct ArrayObject *) tagset;
1144 for(i=0; i<ao->___cachedCode___; i++) {
1145 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
1147 ao->___cachedCode___--;
1148 if (i<ao->___cachedCode___)
1149 ARRAYSET(ao, struct ___Object___ *, i,
1150 ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
1151 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
1152 if (ao->___cachedCode___==0)
1163 /* This function allocates a new tag. */
1165 struct ___TagDescriptor___ * allocate_tag(void *ptr,
1167 struct ___TagDescriptor___ * v=
1168 (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
1169 classsize[TAGTYPE]);
1171 struct ___TagDescriptor___ * allocate_tag(int index) {
1172 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
1181 /* This function updates the flag for object ptr. It or's the flag
1182 with the or mask and and's it with the andmask. */
1184 void flagbody(struct ___Object___ *ptr,
1186 struct parameterwrapper ** queues,
1190 int flagcomp(const int *val1, const int *val2) {
1191 return (*val1)-(*val2);
1194 void flagorand(void * ptr,
1197 struct parameterwrapper ** queues,
1200 int oldflag=((int *)ptr)[1];
1201 int flag=ormask|oldflag;
1203 flagbody(ptr, flag, queues, length, false);
1207 bool intflagorand(void * ptr,
1211 int oldflag=((int *)ptr)[1];
1212 int flag=ormask|oldflag;
1214 if (flag==oldflag) /* Don't do anything */
1217 flagbody(ptr, flag, NULL, 0, false);
1223 void flagorandinit(void * ptr,
1226 int oldflag=((int *)ptr)[1];
1227 int flag=ormask|oldflag;
1229 flagbody(ptr,flag,NULL,0,true);
1232 void flagbody(struct ___Object___ *ptr,
1234 struct parameterwrapper ** vqueues,
1237 struct parameterwrapper * flagptr = NULL;
1239 struct parameterwrapper ** queues = vqueues;
1240 int length = vlength;
1242 int UNUSED, UNUSED2;
1243 int * enterflags = NULL;
1244 if((!isnew) && (queues == NULL)) {
1245 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
1246 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1247 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1254 /*Remove object from all queues */
1255 for(i = 0; i < length; ++i) {
1256 flagptr = queues[i];
1257 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
1258 (int *) &enterflags, &UNUSED, &UNUSED2);
1259 ObjectHashremove(flagptr->objectset, (int)ptr);
1260 if (enterflags!=NULL)
1261 RUNFREE(enterflags);
1265 void enqueueObject(void * vptr,
1266 struct parameterwrapper ** vqueues,
1268 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1271 //struct QueueItem *tmpptr;
1272 struct parameterwrapper * parameter=NULL;
1275 struct parameterwrapper * prevptr=NULL;
1276 struct ___Object___ *tagptr=NULL;
1277 struct parameterwrapper ** queues = vqueues;
1278 int length = vlength;
1279 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1282 if(queues == NULL) {
1283 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1284 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1286 tagptr=ptr->___tags___;
1288 /* Outer loop iterates through all parameter queues an object of
1289 this type could be in. */
1290 for(j = 0; j < length; ++j) {
1291 parameter = queues[j];
1293 if (parameter->numbertags>0) {
1295 goto nextloop; //that means the object has no tag
1296 //but that param needs tag
1297 else if(tagptr->type==TAGTYPE) { //one tag
1298 //struct ___TagDescriptor___ * tag=
1299 //(struct ___TagDescriptor___*) tagptr;
1300 for(i=0; i<parameter->numbertags; i++) {
1301 //slotid is parameter->tagarray[2*i];
1302 int tagid=parameter->tagarray[2*i+1];
1303 if (tagid!=tagptr->flag)
1304 goto nextloop; /*We don't have this tag */
1306 } else { //multiple tags
1307 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1308 for(i=0; i<parameter->numbertags; i++) {
1309 //slotid is parameter->tagarray[2*i];
1310 int tagid=parameter->tagarray[2*i+1];
1312 for(j=0; j<ao->___cachedCode___; j++) {
1313 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1324 for(i=0; i<parameter->numberofterms; i++) {
1325 int andmask=parameter->intarray[i*2];
1326 int checkmask=parameter->intarray[i*2+1];
1327 if ((ptr->flag&andmask)==checkmask) {
1328 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
1339 void enqueueObject_I(void * vptr,
1340 struct parameterwrapper ** vqueues,
1342 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1345 //struct QueueItem *tmpptr;
1346 struct parameterwrapper * parameter=NULL;
1349 struct parameterwrapper * prevptr=NULL;
1350 struct ___Object___ *tagptr=NULL;
1351 struct parameterwrapper ** queues = vqueues;
1352 int length = vlength;
1353 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1356 if(queues == NULL) {
1357 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1358 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1360 tagptr=ptr->___tags___;
1362 /* Outer loop iterates through all parameter queues an object of
1363 this type could be in. */
1364 for(j = 0; j < length; ++j) {
1365 parameter = queues[j];
1367 if (parameter->numbertags>0) {
1369 goto nextloop; //that means the object has no tag
1370 //but that param needs tag
1371 else if(tagptr->type==TAGTYPE) { //one tag
1372 //struct ___TagDescriptor___*tag=(struct ___TagDescriptor___*)tagptr;
1373 for(i=0; i<parameter->numbertags; i++) {
1374 //slotid is parameter->tagarray[2*i];
1375 int tagid=parameter->tagarray[2*i+1];
1376 if (tagid!=tagptr->flag)
1377 goto nextloop; /*We don't have this tag */
1379 } else { //multiple tags
1380 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1381 for(i=0; i<parameter->numbertags; i++) {
1382 //slotid is parameter->tagarray[2*i];
1383 int tagid=parameter->tagarray[2*i+1];
1385 for(j=0; j<ao->___cachedCode___; j++) {
1386 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1397 for(i=0; i<parameter->numberofterms; i++) {
1398 int andmask=parameter->intarray[i*2];
1399 int checkmask=parameter->intarray[i*2+1];
1400 if ((ptr->flag&andmask)==checkmask) {
1401 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1413 int * getAliasLock(void ** ptrs,
1415 struct RuntimeHash * tbl) {
1417 return (int*)(RUNMALLOC(sizeof(int)));
1422 bool redirect = false;
1423 int redirectlock = 0;
1424 for(; i < length; i++) {
1425 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1428 if(ptr->lock == NULL) {
1431 lock = (int)(ptr->lock);
1434 if(lock != redirectlock) {
1435 RuntimeHashadd(tbl, lock, redirectlock);
1438 if(RuntimeHashcontainskey(tbl, lock)) {
1439 // already redirected
1441 RuntimeHashget(tbl, lock, &redirectlock);
1442 for(; j < locklen; j++) {
1443 if(locks[j] != redirectlock) {
1444 RuntimeHashadd(tbl, locks[j], redirectlock);
1449 for(j = 0; j < locklen; j++) {
1450 if(locks[j] == lock) {
1453 } else if(locks[j] > lock) {
1460 locks[h] = locks[h-1];
1469 return (int *)redirectlock;
1471 return (int *)(locks[0]);
1476 void addAliasLock(void * ptr,
1478 struct ___Object___ * obj = (struct ___Object___ *)ptr;
1479 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1480 // originally no alias lock associated or have a different alias lock
1481 // flush it as the new one
1482 obj->lock = (int *)lock;
1487 inline void setTaskExitIndex(int index) {
1488 taskInfoArray[taskInfoIndex]->exitIndex = index;
1491 inline void addNewObjInfo(void * nobj) {
1492 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1493 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1495 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1500 // Only allocate local mem chunks to each core.
1501 // If a core has used up its local shared memory, start gc.
1502 void * localmalloc_I(int coren,
1506 int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
1509 int tofindb = gc_core2block[2*gccorenum+i]+(NUMCORES4GC*2)*j;
1510 int totest = tofindb;
1511 int bound = BAMBOO_SMEM_SIZE_L;
1515 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1516 int nsize = bamboo_smemtbl[totest];
1517 bool islocal = true;
1519 bool tocheck = true;
1520 // have some space in the block
1521 if(totest == tofindb) {
1522 // the first partition
1523 size = bound - nsize;
1524 } else if(nsize == 0) {
1525 // an empty partition, can be appended
1528 // not an empty partition, can not be appended
1529 // the last continuous block is not big enough, go to check the next
1533 } // if(totest == tofindb) else if(nsize == 0) else ...
1536 // have enough space in the block, malloc
1540 // no enough space yet, try to append next continuous block
1542 } // if(size > isize) else ...
1544 } // if(nsize < bound)
1546 // no space in the block, go to check the next block
1552 tofindb = totest = gc_core2block[2*gccorenum+i]+(NUMCORES4GC*2)*j;
1555 } // if(islocal) else ...
1556 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1557 // no more local mem, do not find suitable block
1560 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1563 if(foundsmem == 1) {
1564 // find suitable block
1565 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1566 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1567 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1569 // set bamboo_smemtbl
1570 for(i = tofindb; i <= totest; i++) {
1571 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1573 } else if(foundsmem == 2) {
1574 // no suitable block
1579 } // void * localmalloc_I(int, int, int *)
1582 // Allocate the local shared memory to each core with the highest priority,
1583 // if a core has used up its local shared memory, try to allocate the
1584 // shared memory that belong to its neighbours, if also failed, start gc.
1585 void * fixedmalloc_I(int coren,
1592 int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
1593 int coords_x = bamboo_cpu2coords[gccorenum*2];
1594 int coords_y = bamboo_cpu2coords[gccorenum*2+1];
1596 int tofindb = gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1597 int totest = tofindb;
1598 int bound = BAMBOO_SMEM_SIZE_L;
1602 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1603 int nsize = bamboo_smemtbl[totest];
1604 bool islocal = true;
1606 bool tocheck = true;
1607 // have some space in the block
1608 if(totest == tofindb) {
1609 // the first partition
1610 size = bound - nsize;
1611 } else if(nsize == 0) {
1612 // an empty partition, can be appended
1615 // not an empty partition, can not be appended
1616 // the last continuous block is not big enough, go to check the next
1620 } // if(totest == tofindb) else if(nsize == 0) else ...
1623 // have enough space in the block, malloc
1627 // no enough space yet, try to append next continuous block
1628 // TODO may consider to go to next local block?
1630 } // if(size > isize) else ...
1632 } // if(nsize < bound)
1634 // no space in the block, go to check the next block
1641 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1644 } // if(islocal) else ...
1645 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1646 // no more local mem, do not find suitable block on local mem
1647 // try to malloc shared memory assigned to the neighbour cores
1650 if(k >= NUM_CORES2TEST) {
1651 // no more memory available on either coren or its neighbour cores
1653 goto memsearchresult;
1655 } while(core2test[gccorenum][k] == -1);
1659 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1660 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1664 if(foundsmem == 1) {
1665 // find suitable block
1666 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1667 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1668 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1670 // set bamboo_smemtbl
1671 for(i = tofindb; i <= totest; i++) {
1672 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1674 } else if(foundsmem == 2) {
1675 // no suitable block
1680 } // void * fixedmalloc_I(int, int, int *)
1681 #endif // #ifdef SMEMF
1684 // Allocate the local shared memory to each core with the highest priority,
1685 // if a core has used up its local shared memory, try to allocate the
1686 // shared memory that belong to its neighbours first, if failed, check
1687 // current memory allocation rate, if it has already reached the threshold,
1688 // start gc, otherwise, allocate the shared memory globally. If all the
1689 // shared memory has been used up, start gc.
1690 void * mixedmalloc_I(int coren,
1697 int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
1699 int tofindb = gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1700 int totest = tofindb;
1701 int bound = BAMBOO_SMEM_SIZE_L;
1705 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1706 int nsize = bamboo_smemtbl[totest];
1707 bool islocal = true;
1709 bool tocheck = true;
1710 // have some space in the block
1711 if(totest == tofindb) {
1712 // the first partition
1713 size = bound - nsize;
1714 } else if(nsize == 0) {
1715 // an empty partition, can be appended
1718 // not an empty partition, can not be appended
1719 // the last continuous block is not big enough, go to check the next
1723 } // if(totest == tofindb) else if(nsize == 0) else ...
1726 // have enough space in the block, malloc
1730 // no enough space yet, try to append next continuous block
1731 // TODO may consider to go to next local block?
1733 } // if(size > isize) else ...
1735 } // if(nsize < bound)
1737 // no space in the block, go to check the next block
1744 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1747 } // if(islocal) else ...
1748 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1749 // no more local mem, do not find suitable block on local mem
1750 // try to malloc shared memory assigned to the neighbour cores
1753 if(k >= NUM_CORES2TEST) {
1754 if(gcmem_mixed_usedmem >= gcmem_mixed_threshold) {
1755 // no more memory available on either coren or its neighbour cores
1757 goto memmixedsearchresult;
1759 // try allocate globally
1760 mem = globalmalloc_I(coren, isize, allocsize);
1764 } while(core2test[gccorenum][k] == -1);
1768 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1769 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1772 memmixedsearchresult:
1773 if(foundsmem == 1) {
1774 // find suitable block
1775 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1776 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1777 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1779 // set bamboo_smemtbl
1780 for(i = tofindb; i <= totest; i++) {
1781 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1783 gcmem_mixed_usedmem += size;
1784 if(tofindb == bamboo_free_block) {
1785 bamboo_free_block = totest+1;
1787 } else if(foundsmem == 2) {
1788 // no suitable block
1793 } // void * mixedmalloc_I(int, int, int *)
1794 #endif // #ifdef SMEMM
1796 // Allocate all the memory chunks globally, do not consider the host cores
1797 // When all the shared memory are used up, start gc.
1798 void * globalmalloc_I(int coren,
1802 int tofindb = bamboo_free_block; //0;
1803 int totest = tofindb;
1804 int bound = BAMBOO_SMEM_SIZE_L;
1807 if(tofindb > gcnumblock-1-bamboo_reserved_smem) {
1808 // Out of shared memory
1813 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1814 int nsize = bamboo_smemtbl[totest];
1815 bool isnext = false;
1817 bool tocheck = true;
1818 // have some space in the block
1819 if(totest == tofindb) {
1820 // the first partition
1821 size = bound - nsize;
1822 } else if(nsize == 0) {
1823 // an empty partition, can be appended
1826 // not an empty partition, can not be appended
1827 // the last continuous block is not big enough, start another block
1830 } // if(totest == tofindb) else if(nsize == 0) else ...
1833 // have enough space in the block, malloc
1836 } // if(size > isize)
1840 } // if(nsize < bound) else ...
1842 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1843 // no more local mem, do not find suitable block
1846 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1848 // start another block
1853 if(foundsmem == 1) {
1854 // find suitable block
1855 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1856 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1857 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1859 // set bamboo_smemtbl
1860 for(int i = tofindb; i <= totest; i++) {
1861 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1863 if(tofindb == bamboo_free_block) {
1864 bamboo_free_block = totest+1;
1866 } else if(foundsmem == 2) {
1867 // no suitable block
1873 } // void * globalmalloc_I(int, int, int *)
1874 #endif // #ifdef MULTICORE_GC
1876 // malloc from the shared memory
1877 void * smemalloc_I(int coren,
1882 int isize = size+(BAMBOO_CACHE_LINE_SIZE);
1884 // go through the bamboo_smemtbl for suitable partitions
1885 switch(bamboo_smem_mode) {
1887 mem = localmalloc_I(coren, isize, allocsize);
1893 mem = fixedmalloc_I(coren, isize, allocsize);
1895 // not supported yet
1896 BAMBOO_EXIT(0xe001);
1903 mem = mixedmalloc_I(coren, isize, allocsize);
1905 // not supported yet
1906 BAMBOO_EXIT(0xe002);
1912 mem = globalmalloc_I(coren, isize, allocsize);
1922 int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size) : (BAMBOO_SMEM_SIZE);
1923 if(toallocate > bamboo_free_smem_size) {
1927 mem = (void *)bamboo_free_smemp;
1928 bamboo_free_smemp = ((void*)bamboo_free_smemp) + toallocate;
1929 bamboo_free_smem_size -= toallocate;
1931 *allocsize = toallocate;
1933 #endif // MULTICORE_GC
1934 // no enough shared global memory
1939 // inform other cores to stop and wait for gc
1941 for(int i = 0; i < NUMCORESACTIVE; i++) {
1942 // reuse the gcnumsendobjs & gcnumreceiveobjs
1943 gccorestatus[i] = 1;
1944 gcnumsendobjs[0][i] = 0;
1945 gcnumreceiveobjs[0][i] = 0;
1947 for(int i = 0; i < NUMCORESACTIVE; i++) {
1948 if(i != BAMBOO_NUM_OF_CORE) {
1949 if(BAMBOO_CHECK_SEND_MODE()) {
1950 cache_msg_1(i, GCSTARTPRE);
1952 send_msg_1(i, GCSTARTPRE, true);
1959 BAMBOO_DEBUGPRINT(0xe003);
1960 BAMBOO_EXIT(0xe003);
1964 } // void * smemalloc_I(int, int, int)
1966 INLINE int checkMsgLength_I(int size) {
1969 BAMBOO_DEBUGPRINT(0xcccc);
1972 int type = msgdata[msgdataindex];
1980 case GCSTARTMAPINFO:
1985 #ifdef GC_CACHE_ADAPT
1987 #endif // GC_CACHE_ADAPT
1988 #endif // MULTICORE_GC
1997 case GCSTARTCOMPACT:
2000 case GCFINISHMAPINFO:
2002 #ifdef GC_CACHE_ADAPT
2004 #endif // GC_CACHE_ADAPT
2005 #endif // MULTICORE_GC
2028 case REDIRECTGROUNT:
2030 case REDIRECTRELEASE:
2047 case GCFINISHCOMPACT:
2061 case TRANSOBJ: // nonfixed size
2067 msglength = msgdata[msgdataindex+1];
2076 BAMBOO_DEBUGPRINT_REG(type);
2077 BAMBOO_DEBUGPRINT_REG(size);
2078 BAMBOO_DEBUGPRINT_REG(msgdataindex);
2079 BAMBOO_DEBUGPRINT_REG(msgdatalast);
2080 BAMBOO_DEBUGPRINT_REG(msgdatafull);
2083 BAMBOO_DEBUGPRINT(msgdata[msgdataindex+i]);
2085 BAMBOO_EXIT(0xe004);
2091 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
2096 BAMBOO_DEBUGPRINT(0xffff);
2102 INLINE void processmsg_transobj_I() {
2103 #ifdef PROFILE_INTERRUPT
2104 /*if(!interruptInfoOverflow) {
2105 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
2106 interruptInfoArray[interruptInfoIndex] = intInfo;
2107 intInfo->startTime = BAMBOO_GET_EXE_TIME();
2108 intInfo->endTime = -1;
2112 struct transObjInfo * transObj=RUNMALLOC_I(sizeof(struct transObjInfo));
2116 BAMBOO_DEBUGPRINT(0xe880);
2119 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2121 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
2123 BAMBOO_EXIT(0xe005);
2125 // store the object and its corresponding queue info, enqueue it later
2126 transObj->objptr = (void *)msgdata[msgdataindex]; //[2]
2128 transObj->length = (msglength - 3) / 2;
2129 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
2130 for(k = 0; k < transObj->length; ++k) {
2131 transObj->queues[2*k] = msgdata[msgdataindex]; //[3+2*k];
2135 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
2138 transObj->queues[2*k+1] = msgdata[msgdataindex]; //[3+2*k+1];
2142 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
2146 // check if there is an existing duplicate item
2148 struct QueueItem * qitem = getHead(&objqueue);
2149 struct QueueItem * prev = NULL;
2150 while(qitem != NULL) {
2151 struct transObjInfo * tmpinfo =
2152 (struct transObjInfo *)(qitem->objectptr);
2153 if(tmpinfo->objptr == transObj->objptr) {
2154 // the same object, remove outdate one
2155 RUNFREE(tmpinfo->queues);
2157 removeItem(&objqueue, qitem);
2163 qitem = getHead(&objqueue);
2165 qitem = getNextQueueItem(prev);
2168 addNewItem_I(&objqueue, (void *)transObj);
2170 ++(self_numreceiveobjs);
2173 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
2174 // set the gcprecheck to enable checking again
2177 // send a update pregc information msg to the master core
2178 if(BAMBOO_CHECK_SEND_MODE()) {
2179 cache_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
2180 self_numsendobjs, self_numreceiveobjs);
2182 send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
2183 self_numsendobjs, self_numreceiveobjs, true);
2188 #ifdef PROFILE_INTERRUPT
2189 /*if(!interruptInfoOverflow) {
2190 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
2191 interruptInfoIndex++;
2192 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
2193 interruptInfoOverflow = true;
2199 INLINE void processmsg_transtall_I() {
2200 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2201 // non startup core can not receive stall msg
2203 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
2205 BAMBOO_EXIT(0xe006);
2207 int num_core = msgdata[msgdataindex]; //[1]
2209 if(num_core < NUMCORESACTIVE) {
2212 BAMBOO_DEBUGPRINT(0xe881);
2215 corestatus[num_core] = 0;
2216 numsendobjs[num_core] = msgdata[msgdataindex]; //[2];
2218 numreceiveobjs[num_core] = msgdata[msgdataindex]; //[3];
2223 #ifndef MULTICORE_GC
2224 INLINE void processmsg_lockrequest_I() {
2225 // check to see if there is a lock exist for the required obj
2226 // msgdata[1] -> lock type
2227 int locktype = msgdata[msgdataindex]; //[1];
2229 int data2 = msgdata[msgdataindex]; // obj pointer
2231 int data3 = msgdata[msgdataindex]; // lock
2233 int data4 = msgdata[msgdataindex]; // request core
2235 // -1: redirected, 0: approved, 1: denied
2236 int deny=processlockrequest(locktype, data3, data2, data4, data4, true);
2238 // this lock request is redirected
2241 // send response msg
2242 // for 32 bit machine, the size is always 4 words, cache the msg first
2243 int tmp = deny==1 ? LOCKDENY : LOCKGROUNT;
2244 if(BAMBOO_CHECK_SEND_MODE()) {
2245 cache_msg_4(data4, tmp, locktype, data2, data3);
2247 send_msg_4(data4, tmp, locktype, data2, data3, true);
2252 INLINE void processmsg_lockgrount_I() {
2254 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2256 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
2258 BAMBOO_EXIT(0xe007);
2260 int data2 = msgdata[msgdataindex];
2262 int data3 = msgdata[msgdataindex];
2264 if((lockobj == data2) && (lock2require == data3)) {
2267 BAMBOO_DEBUGPRINT(0xe882);
2276 // conflicts on lockresults
2278 BAMBOO_DEBUGPRINT_REG(data2);
2280 BAMBOO_EXIT(0xe008);
2284 INLINE void processmsg_lockdeny_I() {
2286 int data2 = msgdata[msgdataindex];
2288 int data3 = msgdata[msgdataindex];
2290 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2292 BAMBOO_DEBUGPRINT_REG(data2);
2294 BAMBOO_EXIT(0xe009);
2296 if((lockobj == data2) && (lock2require == data3)) {
2299 BAMBOO_DEBUGPRINT(0xe883);
2308 // conflicts on lockresults
2310 BAMBOO_DEBUGPRINT_REG(data2);
2312 BAMBOO_EXIT(0xe00a);
2316 INLINE void processmsg_lockrelease_I() {
2317 int data1 = msgdata[msgdataindex];
2319 int data2 = msgdata[msgdataindex];
2321 // receive lock release msg
2322 processlockrelease(data1, data2, 0, false);
2325 INLINE void processmsg_redirectlock_I() {
2326 // check to see if there is a lock exist for the required obj
2327 int data1 = msgdata[msgdataindex];
2328 MSG_INDEXINC_I(); //msgdata[1]; // lock type
2329 int data2 = msgdata[msgdataindex];
2330 MSG_INDEXINC_I(); //msgdata[2]; // obj pointer
2331 int data3 = msgdata[msgdataindex];
2332 MSG_INDEXINC_I(); //msgdata[3]; // redirect lock
2333 int data4 = msgdata[msgdataindex];
2334 MSG_INDEXINC_I(); //msgdata[4]; // root request core
2335 int data5 = msgdata[msgdataindex];
2336 MSG_INDEXINC_I(); //msgdata[5]; // request core
2337 int deny = processlockrequest(data1, data3, data2, data5, data4, true);
2339 // this lock request is redirected
2342 // send response msg
2343 // for 32 bit machine, the size is always 4 words, cache the msg first
2344 if(BAMBOO_CHECK_SEND_MODE()) {
2345 cache_msg_4(data4, deny==1 ? REDIRECTDENY : REDIRECTGROUNT,
2346 data1, data2, data3);
2348 send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
2349 data1, data2, data3, true);
2354 INLINE void processmsg_redirectgrount_I() {
2356 int data2 = msgdata[msgdataindex];
2358 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2360 BAMBOO_DEBUGPRINT_REG(data2);
2362 BAMBOO_EXIT(0xe00b);
2364 if(lockobj == data2) {
2367 BAMBOO_DEBUGPRINT(0xe891);
2370 int data3 = msgdata[msgdataindex];
2374 RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
2379 // conflicts on lockresults
2381 BAMBOO_DEBUGPRINT_REG(data2);
2383 BAMBOO_EXIT(0xe00c);
2387 INLINE void processmsg_redirectdeny_I() {
2389 int data2 = msgdata[msgdataindex];
2391 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2393 BAMBOO_DEBUGPRINT_REG(data2);
2395 BAMBOO_EXIT(0xe00d);
2397 if(lockobj == data2) {
2400 BAMBOO_DEBUGPRINT(0xe892);
2409 // conflicts on lockresults
2411 BAMBOO_DEBUGPRINT_REG(data2);
2413 BAMBOO_EXIT(0xe00e);
2417 INLINE void processmsg_redirectrelease_I() {
2418 int data1 = msgdata[msgdataindex];
2420 int data2 = msgdata[msgdataindex];
2422 int data3 = msgdata[msgdataindex];
2424 processlockrelease(data1, data2, data3, true);
2426 #endif // #ifndef MULTICORE_GC
2429 INLINE void processmsg_profileoutput_I() {
2430 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
2431 // startup core can not receive profile output finish msg
2432 BAMBOO_EXIT(0xe00f);
2436 BAMBOO_DEBUGPRINT(0xe885);
2440 totalexetime = msgdata[msgdataindex]; //[1]
2443 BAMBOO_DEBUGPRINT_REG(dot_num);
2445 outputProfileData();
2447 // cache the msg first
2448 if(BAMBOO_CHECK_SEND_MODE()) {
2449 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
2451 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE, true);
2455 INLINE void processmsg_profilefinish_I() {
2456 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2457 // non startup core can not receive profile output finish msg
2459 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex /*1*/]);
2461 BAMBOO_EXIT(0xe010);
2465 BAMBOO_DEBUGPRINT(0xe886);
2468 int data1 = msgdata[msgdataindex];
2470 profilestatus[data1] = 0;
2472 #endif // #ifdef PROFILE
2474 INLINE void processmsg_statusconfirm_I() {
2475 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2476 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2477 // wrong core to receive such msg
2478 BAMBOO_EXIT(0xe011);
2480 // send response msg
2483 BAMBOO_DEBUGPRINT(0xe887);
2486 // cache the msg first
2487 if(BAMBOO_CHECK_SEND_MODE()) {
2488 cache_msg_5(STARTUPCORE, STATUSREPORT,
2489 busystatus ? 1 : 0, BAMBOO_NUM_OF_CORE,
2490 self_numsendobjs, self_numreceiveobjs);
2492 send_msg_5(STARTUPCORE, STATUSREPORT, busystatus?1:0,
2493 BAMBOO_NUM_OF_CORE, self_numsendobjs,
2494 self_numreceiveobjs, true);
2499 INLINE void processmsg_statusreport_I() {
2500 int data1 = msgdata[msgdataindex];
2502 int data2 = msgdata[msgdataindex];
2504 int data3 = msgdata[msgdataindex];
2506 int data4 = msgdata[msgdataindex];
2508 // receive a status confirm info
2509 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2510 // wrong core to receive such msg
2512 BAMBOO_DEBUGPRINT_REG(data2);
2514 BAMBOO_EXIT(0xe012);
2518 BAMBOO_DEBUGPRINT(0xe888);
2524 corestatus[data2] = data1;
2525 numsendobjs[data2] = data3;
2526 numreceiveobjs[data2] = data4;
2530 INLINE void processmsg_terminate_I() {
2533 BAMBOO_DEBUGPRINT(0xe889);
2538 #ifdef GC_CACHE_ADAPT
2539 bamboo_mask_timer_intr(); // disable the TILE_TIMER interrupt
2540 #endif // GC_CACHE_ADAPT
2541 #endif // MULTICORE_GC
2545 INLINE void processmsg_memrequest_I() {
2546 #ifdef PROFILE_INTERRUPT
2547 /*if(!interruptInfoOverflow) {
2548 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
2549 interruptInfoArray[interruptInfoIndex] = intInfo;
2550 intInfo->startTime = BAMBOO_GET_EXE_TIME();
2551 intInfo->endTime = -1;
2554 int data1 = msgdata[msgdataindex];
2556 int data2 = msgdata[msgdataindex];
2558 // receive a shared memory request msg
2559 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2560 // wrong core to receive such msg
2562 BAMBOO_DEBUGPRINT_REG(data2);
2564 BAMBOO_EXIT(0xe013);
2568 BAMBOO_DEBUGPRINT(0xe88a);
2575 // is currently doing gc, dump this msg
2576 if(INITPHASE == gcphase) {
2577 // if still in the initphase of gc, send a startinit msg again,
2578 // cache the msg first
2579 if(BAMBOO_CHECK_SEND_MODE()) {
2580 cache_msg_1(data2, GCSTARTINIT);
2582 send_msg_1(data2, GCSTARTINIT, true);
2587 mem = smemalloc_I(data2, data1, &allocsize);
2589 // send the start_va to request core, cache the msg first
2590 if(BAMBOO_CHECK_SEND_MODE()) {
2591 cache_msg_3(data2, MEMRESPONSE, mem, allocsize);
2593 send_msg_3(data2, MEMRESPONSE, mem, allocsize, true);
2596 // if mem == NULL, the gcflag of the startup core has been set
2597 // and all the other cores have been informed to start gc
2602 #ifdef PROFILE_INTERRUPT
2603 /*if(!interruptInfoOverflow) {
2604 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
2605 interruptInfoIndex++;
2606 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
2607 interruptInfoOverflow = true;
2613 INLINE void processmsg_memresponse_I() {
2614 int data1 = msgdata[msgdataindex];
2616 int data2 = msgdata[msgdataindex];
2618 // receive a shared memory response msg
2621 BAMBOO_DEBUGPRINT(0xe88b);
2625 // if is currently doing gc, dump this msg
2629 bamboo_smem_size = 0;
2632 bamboo_smem_zero_top = 0;
2636 // fill header to store the size of this mem block
2637 BAMBOO_MEMSET_WH(data1, '\0', BAMBOO_CACHE_LINE_SIZE);
2638 //memset(data1, 0, BAMBOO_CACHE_LINE_SIZE);
2639 (*((int*)data1)) = data2;
2640 bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
2641 bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
2642 bamboo_smem_zero_top = bamboo_cur_msp;
2644 bamboo_smem_size = data2;
2645 bamboo_cur_msp =(void*)(data1);
2655 INLINE void processmsg_gcstartpre_I() {
2657 // already stall for gc
2658 // send a update pregc information msg to the master core
2659 if(BAMBOO_CHECK_SEND_MODE()) {
2660 cache_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
2661 self_numsendobjs, self_numreceiveobjs);
2663 send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
2664 self_numsendobjs, self_numreceiveobjs, true);
2667 // the first time to be informed to start gc
2670 // is waiting for response of mem request
2671 // let it return NULL and start gc
2672 bamboo_smem_size = 0;
2673 bamboo_cur_msp = NULL;
2675 bamboo_smem_zero_top = NULL;
2680 INLINE void processmsg_gcstartinit_I() {
2681 gcphase = INITPHASE;
2684 INLINE void processmsg_gcstart_I() {
2687 BAMBOO_DEBUGPRINT(0xe88c);
2691 gcphase = MARKPHASE;
2694 INLINE void processmsg_gcstartcompact_I() {
2695 gcblock2fill = msgdata[msgdataindex];
2696 MSG_INDEXINC_I(); //msgdata[1];
2697 gcphase = COMPACTPHASE;
2700 INLINE void processmsg_gcstartmapinfo_I() {
2704 INLINE void processmsg_gcstartflush_I() {
2705 gcphase = FLUSHPHASE;
2708 INLINE void processmsg_gcfinishpre_I() {
2709 int data1 = msgdata[msgdataindex];
2711 int data2 = msgdata[msgdataindex];
2713 int data3 = msgdata[msgdataindex];
2715 // received a init phase finish msg
2716 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2717 // non startup core can not receive this msg
2719 BAMBOO_DEBUGPRINT_REG(data1);
2721 BAMBOO_EXIT(0xe014);
2723 // All cores should do init GC
2727 gccorestatus[data1] = 0;
2728 gcnumsendobjs[0][data1] = data2;
2729 gcnumreceiveobjs[0][data1] = data3;
2732 INLINE void processmsg_gcfinishinit_I() {
2733 int data1 = msgdata[msgdataindex];
2735 // received a init phase finish msg
2736 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2737 // non startup core can not receive this msg
2739 BAMBOO_DEBUGPRINT_REG(data1);
2741 BAMBOO_EXIT(0xe015);
2744 BAMBOO_DEBUGPRINT(0xe88c);
2745 BAMBOO_DEBUGPRINT_REG(data1);
2747 // All cores should do init GC
2748 if(data1 < NUMCORESACTIVE) {
2749 gccorestatus[data1] = 0;
2753 INLINE void processmsg_gcfinishmark_I() {
2754 int data1 = msgdata[msgdataindex];
2756 int data2 = msgdata[msgdataindex];
2758 int data3 = msgdata[msgdataindex];
2760 // received a mark phase finish msg
2761 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2762 // non startup core can not receive this msg
2764 BAMBOO_DEBUGPRINT_REG(data1);
2766 BAMBOO_EXIT(0xe016);
2768 // all cores should do mark
2769 if(data1 < NUMCORESACTIVE) {
2770 gccorestatus[data1] = 0;
2771 int entry_index = 0;
2774 entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
2777 entry_index = gcnumsrobjs_index;
2779 gcnumsendobjs[entry_index][data1] = data2;
2780 gcnumreceiveobjs[entry_index][data1] = data3;
2784 INLINE void processmsg_gcfinishcompact_I() {
2785 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2786 // non startup core can not receive this msg
2789 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
2791 BAMBOO_EXIT(0xe017);
2793 int cnum = msgdata[msgdataindex];
2794 MSG_INDEXINC_I(); //msgdata[1];
2795 int filledblocks = msgdata[msgdataindex];
2796 MSG_INDEXINC_I(); //msgdata[2];
2797 int heaptop = msgdata[msgdataindex];
2798 MSG_INDEXINC_I(); //msgdata[3];
2799 int data4 = msgdata[msgdataindex];
2800 MSG_INDEXINC_I(); //msgdata[4];
2801 // only gc cores need to do compact
2802 if(cnum < NUMCORES4GC) {
2803 if(COMPACTPHASE == gcphase) {
2804 gcfilledblocks[cnum] = filledblocks;
2805 gcloads[cnum] = heaptop;
2812 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
2813 // cache the msg first
2814 if(BAMBOO_CHECK_SEND_MODE()) {
2815 cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
2817 send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove, true);
2821 gccorestatus[cnum] = 0;
2823 } // if(cnum < NUMCORES4GC)
2826 INLINE void processmsg_gcfinishmapinfo_I() {
2827 int data1 = msgdata[msgdataindex];
2829 // received a map phase finish msg
2830 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2831 // non startup core can not receive this msg
2833 BAMBOO_DEBUGPRINT_REG(data1);
2835 BAMBOO_EXIT(0xe018);
2837 // all cores should do flush
2838 if(data1 < NUMCORES4GC) {
2839 gccorestatus[data1] = 0;
2844 INLINE void processmsg_gcfinishflush_I() {
2845 int data1 = msgdata[msgdataindex];
2847 // received a flush phase finish msg
2848 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2849 // non startup core can not receive this msg
2851 BAMBOO_DEBUGPRINT_REG(data1);
2853 BAMBOO_EXIT(0xe019);
2855 // all cores should do flush
2856 if(data1 < NUMCORESACTIVE) {
2857 gccorestatus[data1] = 0;
2861 INLINE void processmsg_gcmarkconfirm_I() {
2862 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2863 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2864 // wrong core to receive such msg
2865 BAMBOO_EXIT(0xe01a);
2867 // send response msg, cahce the msg first
2868 if(BAMBOO_CHECK_SEND_MODE()) {
2869 cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2870 gcbusystatus, gcself_numsendobjs,
2871 gcself_numreceiveobjs);
2873 send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2874 gcbusystatus, gcself_numsendobjs,
2875 gcself_numreceiveobjs, true);
2880 INLINE void processmsg_gcmarkreport_I() {
2881 int data1 = msgdata[msgdataindex];
2883 int data2 = msgdata[msgdataindex];
2885 int data3 = msgdata[msgdataindex];
2887 int data4 = msgdata[msgdataindex];
2889 // received a marked phase finish confirm response msg
2890 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2891 // wrong core to receive such msg
2893 BAMBOO_DEBUGPRINT_REG(data2);
2895 BAMBOO_EXIT(0xe01b);
2897 int entry_index = 0;
2901 entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
2903 // can never reach here
2905 entry_index = gcnumsrobjs_index;
2907 gccorestatus[data1] = data2;
2908 gcnumsendobjs[entry_index][data1] = data3;
2909 gcnumreceiveobjs[entry_index][data1] = data4;
2913 INLINE void processmsg_gcmarkedobj_I() {
2914 int data1 = msgdata[msgdataindex];
2916 // received a markedObj msg
2917 if(((int *)data1)[6] == INIT) {
2918 // this is the first time that this object is discovered,
2919 // set the flag as DISCOVERED
2920 ((int *)data1)[6] = DISCOVERED;
2921 gc_enqueue_I(data1);
2923 // set the remote flag
2924 ((int *)data1)[6] |= REMOTEM;
2925 gcself_numreceiveobjs++;
2926 gcbusystatus = true;
2929 INLINE void processmsg_gcmovestart_I() {
2931 gcdstcore = msgdata[msgdataindex];
2932 MSG_INDEXINC_I(); //msgdata[1];
2933 gcmovestartaddr = msgdata[msgdataindex];
2934 MSG_INDEXINC_I(); //msgdata[2];
2935 gcblock2fill = msgdata[msgdataindex];
2936 MSG_INDEXINC_I(); //msgdata[3];
2939 INLINE void processmsg_gcmaprequest_I() {
2941 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2943 void * dstptr = NULL;
2944 int data1 = msgdata[msgdataindex];
2947 // TODO unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2949 #ifdef LOCALHASHTBL_TEST
2950 RuntimeHashget(gcpointertbl, data1, &dstptr);
2952 dstptr = mgchashSearch(gcpointertbl, data1);
2954 //MGCHashget(gcpointertbl, data1, &dstptr);
2956 // TODO flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2958 int data2 = msgdata[msgdataindex];
2961 // TODO unsigned long long ttimei = BAMBOO_GET_EXE_TIME();
2963 if(NULL == dstptr) {
2964 // no such pointer in this core, something is wrong
2966 BAMBOO_DEBUGPRINT_REG(data1);
2967 BAMBOO_DEBUGPRINT_REG(data2);
2969 BAMBOO_EXIT(0xe01c);
2970 //assume that the object was not moved, use the original address
2971 /*if(isMsgSending) {
2972 cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2974 send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2977 // send back the mapping info, cache the msg first
2978 if(BAMBOO_CHECK_SEND_MODE()) {
2979 cache_msg_3(data2, GCMAPINFO, data1, (int)dstptr);
2981 send_msg_3(data2, GCMAPINFO, data1, (int)dstptr, true);
2985 // TODO flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimei;
2986 //num_mapinforequest_i++;
2990 INLINE void processmsg_gcmapinfo_I() {
2992 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2994 int data1 = msgdata[msgdataindex];
2996 gcmappedobj = msgdata[msgdataindex]; // [2]
2998 #ifdef LOCALHASHTBL_TEST
2999 RuntimeHashadd_I(gcpointertbl, data1, gcmappedobj);
3001 mgchashInsert_I(gcpointertbl, data1, gcmappedobj);
3003 //MGCHashadd_I(gcpointertbl, data1, gcmappedobj);
3004 if(data1 == gcobj2map) {
3008 //flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
3012 INLINE void processmsg_gcmaptbl_I() {
3013 int data1 = msgdata[msgdataindex];
3015 int data2 = msgdata[msgdataindex];
3017 gcrpointertbls[data2] = (mgcsharedhashtbl_t *)data1; //(struct GCSharedHash *)data1;
3020 INLINE void processmsg_gclobjinfo_I() {
3023 int data1 = msgdata[msgdataindex];
3025 int data2 = msgdata[msgdataindex];
3027 if(BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1) {
3029 BAMBOO_DEBUGPRINT_REG(data2);
3031 BAMBOO_EXIT(0xe01d);
3033 // store the mark result info
3035 gcloads[cnum] = msgdata[msgdataindex];
3036 MSG_INDEXINC_I(); // msgdata[3];
3037 int data4 = msgdata[msgdataindex];
3039 if(gcheaptop < data4) {
3042 // large obj info here
3043 for(int k = 5; k < data1; ) {
3044 int lobj = msgdata[msgdataindex];
3045 MSG_INDEXINC_I(); //msgdata[k++];
3046 int length = msgdata[msgdataindex];
3047 MSG_INDEXINC_I(); //msgdata[k++];
3048 gc_lobjenqueue_I(lobj, length, cnum);
3050 } // for(int k = 5; k < msgdata[1];)
3053 INLINE void processmsg_gclobjmapping_I() {
3054 int data1 = msgdata[msgdataindex];
3056 int data2 = msgdata[msgdataindex];
3058 #ifdef LOCALHASHTBL_TEST
3059 RuntimeHashadd_I(gcpointertbl, data1, data2);
3061 mgchashInsert_I(gcpointertbl, data1, data2);
3063 //MGCHashadd_I(gcpointertbl, data1, data2);
3064 mgcsharedhashInsert_I(gcsharedptbl, data1, data2);
3068 INLINE void processmsg_gcprofiles_I() {
3069 int data1 = msgdata[msgdataindex];
3071 int data2 = msgdata[msgdataindex];
3073 int data3 = msgdata[msgdataindex];
3075 gc_num_obj += data1;
3076 gc_num_liveobj += data2;
3077 gc_num_forwardobj += data3;
3080 #endif // GC_PROFILE
3082 #ifdef GC_CACHE_ADAPT
3083 INLINE void processmsg_gcstartpref_I() {
3084 gcphase = PREFINISHPHASE;
3087 INLINE void processmsg_gcfinishpref_I() {
3088 int data1 = msgdata[msgdataindex];
3090 // received a flush phase finish msg
3091 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
3092 // non startup core can not receive this msg
3094 BAMBOO_DEBUGPRINT_REG(data1);
3096 BAMBOO_EXIT(0xe01e);
3098 // all cores should do flush
3099 if(data1 < NUMCORESACTIVE) {
3100 gccorestatus[data1] = 0;
3103 #endif // GC_CACHE_ADAPT
3104 #endif // #ifdef MULTICORE_GC
3106 // receive object transferred from other cores
3107 // or the terminate message from other cores
3108 // Should be invoked in critical sections!!
3109 // NOTICE: following format is for threadsimulate version only
3110 // RAW version please see previous description
3111 // format: type + object
3112 // type: -1--stall msg
3114 // return value: 0--received an object
3115 // 1--received nothing
3116 // 2--received a Stall Msg
3117 // 3--received a lock Msg
3118 // RAW version: -1 -- received nothing
3119 // otherwise -- received msg type
3120 int receiveObject(int send_port_pending) {
3121 #ifdef PROFILE_INTERRUPT
3122 if(!interruptInfoOverflow) {
3123 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
3124 interruptInfoArray[interruptInfoIndex] = intInfo;
3125 intInfo->startTime = BAMBOO_GET_EXE_TIME();
3126 intInfo->endTime = -1;
3130 // get the incoming msgs
3131 if(receiveMsg(send_port_pending) == -1) {
3135 // processing received msgs
3137 MSG_REMAINSIZE_I(&size);
3138 if((size == 0) || (checkMsgLength_I(size) == -1)) {
3140 // have new coming msg
3141 if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
3148 if(msglength <= size) {
3149 // have some whole msg
3151 type = msgdata[msgdataindex]; //[0]
3153 msgdatafull = false;
3155 //tprintf("msg type: %x\n", type);
3158 // receive a object transfer msg
3159 processmsg_transobj_I();
3164 // receive a stall msg
3165 processmsg_transtall_I();
3169 // GC version have no lock msgs
3170 #ifndef MULTICORE_GC
3172 // receive lock request msg, handle it right now
3173 processmsg_lockrequest_I();
3175 } // case LOCKREQUEST
3178 // receive lock grount msg
3179 processmsg_lockgrount_I();
3181 } // case LOCKGROUNT
3184 // receive lock deny msg
3185 processmsg_lockdeny_I();
3190 processmsg_lockrelease_I();
3192 } // case LOCKRELEASE
3193 #endif // #ifndef MULTICORE_GC
3196 case PROFILEOUTPUT: {
3197 // receive an output profile data request msg
3198 processmsg_profileoutput_I();
3200 } // case PROFILEOUTPUT
3202 case PROFILEFINISH: {
3203 // receive a profile output finish msg
3204 processmsg_profilefinish_I();
3206 } // case PROFILEFINISH
3207 #endif // #ifdef PROFILE
3209 // GC version has no lock msgs
3210 #ifndef MULTICORE_GC
3211 case REDIRECTLOCK: {
3212 // receive a redirect lock request msg, handle it right now
3213 processmsg_redirectlock_I();
3215 } // case REDIRECTLOCK
3217 case REDIRECTGROUNT: {
3218 // receive a lock grant msg with redirect info
3219 processmsg_redirectgrount_I();
3221 } // case REDIRECTGROUNT
3223 case REDIRECTDENY: {
3224 // receive a lock deny msg with redirect info
3225 processmsg_redirectdeny_I();
3227 } // case REDIRECTDENY
3229 case REDIRECTRELEASE: {
3230 // receive a lock release msg with redirect info
3231 processmsg_redirectrelease_I();
3233 } // case REDIRECTRELEASE
3234 #endif // #ifndef MULTICORE_GC
3236 case STATUSCONFIRM: {
3237 // receive a status confirm info
3238 processmsg_statusconfirm_I();
3240 } // case STATUSCONFIRM
3242 case STATUSREPORT: {
3243 processmsg_statusreport_I();
3245 } // case STATUSREPORT
3248 // receive a terminate msg
3249 processmsg_terminate_I();
3254 processmsg_memrequest_I();
3256 } // case MEMREQUEST
3259 processmsg_memresponse_I();
3261 } // case MEMRESPONSE
3266 processmsg_gcstartpre_I();
3268 } // case GCSTARTPRE
3271 processmsg_gcstartinit_I();
3273 } // case GCSTARTINIT
3276 // receive a start GC msg
3277 processmsg_gcstart_I();
3281 case GCSTARTCOMPACT: {
3282 // a compact phase start msg
3283 processmsg_gcstartcompact_I();
3285 } // case GCSTARTCOMPACT
3287 case GCSTARTMAPINFO: {
3288 // received a flush phase start msg
3289 processmsg_gcstartmapinfo_I();
3291 } // case GCSTARTFLUSH
3293 case GCSTARTFLUSH: {
3294 // received a flush phase start msg
3295 processmsg_gcstartflush_I();
3297 } // case GCSTARTFLUSH
3300 processmsg_gcfinishpre_I();
3302 } // case GCFINISHPRE
3304 case GCFINISHINIT: {
3305 processmsg_gcfinishinit_I();
3307 } // case GCFINISHINIT
3309 case GCFINISHMARK: {
3310 processmsg_gcfinishmark_I();
3312 } // case GCFINISHMARK
3314 case GCFINISHCOMPACT: {
3315 // received a compact phase finish msg
3316 processmsg_gcfinishcompact_I();
3318 } // case GCFINISHCOMPACT
3320 case GCFINISHMAPINFO: {
3321 processmsg_gcfinishmapinfo_I();
3323 } // case GCFINISHMAPINFO
3325 case GCFINISHFLUSH: {
3326 processmsg_gcfinishflush_I();
3328 } // case GCFINISHFLUSH
3331 // received a GC finish msg
3332 gcphase = FINISHPHASE;
3336 case GCMARKCONFIRM: {
3337 // received a marked phase finish confirm request msg
3338 // all cores should do mark
3339 processmsg_gcmarkconfirm_I();
3341 } // case GCMARKCONFIRM
3343 case GCMARKREPORT: {
3344 processmsg_gcmarkreport_I();
3346 } // case GCMARKREPORT
3349 processmsg_gcmarkedobj_I();
3351 } // case GCMARKEDOBJ
3354 // received a start moving objs msg
3355 processmsg_gcmovestart_I();
3357 } // case GCMOVESTART
3359 case GCMAPREQUEST: {
3360 // received a mapping info request msg
3361 processmsg_gcmaprequest_I();
3363 } // case GCMAPREQUEST
3366 // received a mapping info response msg
3367 processmsg_gcmapinfo_I();
3372 // received a mapping tbl response msg
3373 processmsg_gcmaptbl_I();
3377 case GCLOBJREQUEST: {
3378 // received a large objs info request msg
3379 transferMarkResults_I();
3381 } // case GCLOBJREQUEST
3384 // received a large objs info response msg
3385 processmsg_gclobjinfo_I();
3387 } // case GCLOBJINFO
3389 case GCLOBJMAPPING: {
3390 // received a large obj mapping info msg
3391 processmsg_gclobjmapping_I();
3393 } // case GCLOBJMAPPING
3397 // received a gcprofiles msg
3398 processmsg_gcprofiles_I();
3401 #endif // GC_PROFILE
3403 #ifdef GC_CACHE_ADAPT
3405 // received a gcstartpref msg
3406 processmsg_gcstartpref_I();
3410 case GCFINISHPREF: {
3411 // received a gcfinishpref msg
3412 processmsg_gcfinishpref_I();
3415 #endif // GC_CACHE_ADAPT
3416 #endif // #ifdef MULTICORE_GC
3421 msglength = BAMBOO_MSG_BUF_LENGTH;
3423 //printf("++ msg: %x \n", type);
3425 if(msgdataindex != msgdatalast) {
3426 // still have available msg
3431 BAMBOO_DEBUGPRINT(0xe88d);
3435 // have new coming msg
3436 if(BAMBOO_MSG_AVAIL() != 0) {
3440 #ifdef PROFILE_INTERRUPT
3441 if(!interruptInfoOverflow) {
3442 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
3443 interruptInfoIndex++;
3444 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
3445 interruptInfoOverflow = true;
3454 BAMBOO_DEBUGPRINT(0xe88e);
3461 int enqueuetasks(struct parameterwrapper *parameter,
3462 struct parameterwrapper *prevptr,
3463 struct ___Object___ *ptr,
3465 int numenterflags) {
3466 void * taskpointerarray[MAXTASKPARAMS];
3468 //int numparams=parameter->task->numParameters;
3469 int numiterators=parameter->task->numTotal-1;
3472 struct taskdescriptor * task=parameter->task;
3474 //this add the object to parameterwrapper
3475 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
3476 numenterflags, enterflags==NULL);
3478 /* Add enqueued object to parameter vector */
3479 taskpointerarray[parameter->slot]=ptr;
3481 /* Reset iterators */
3482 for(j=0; j<numiterators; j++) {
3483 toiReset(¶meter->iterators[j]);
3486 /* Find initial state */
3487 for(j=0; j<numiterators; j++) {
3489 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3490 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3492 /* Need to backtrack */
3493 toiReset(¶meter->iterators[j]);
3497 /* Nothing to enqueue */
3503 /* Enqueue current state */
3505 struct taskparamdescriptor *tpd=
3506 RUNMALLOC(sizeof(struct taskparamdescriptor));
3508 tpd->numParameters=numiterators+1;
3509 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
3511 for(j=0; j<=numiterators; j++) {
3512 //store the actual parameters
3513 tpd->parameterArray[j]=taskpointerarray[j];
3516 if (( /*!gencontains(failedtasks, tpd)&&*/
3517 !gencontains(activetasks,tpd))) {
3518 genputtable(activetasks, tpd, tpd);
3520 RUNFREE(tpd->parameterArray);
3524 /* This loop iterates to the next parameter combination */
3525 if (numiterators==0)
3528 for(j=numiterators-1; j<numiterators; j++) {
3531 ¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3532 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3534 /* Need to backtrack */
3535 toiReset(¶meter->iterators[j]);
3539 /* Nothing more to enqueue */
3547 int enqueuetasks_I(struct parameterwrapper *parameter,
3548 struct parameterwrapper *prevptr,
3549 struct ___Object___ *ptr,
3551 int numenterflags) {
3552 void * taskpointerarray[MAXTASKPARAMS];
3554 //int numparams=parameter->task->numParameters;
3555 int numiterators=parameter->task->numTotal-1;
3560 struct taskdescriptor * task=parameter->task;
3562 //this add the object to parameterwrapper
3563 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
3564 numenterflags, enterflags==NULL);
3566 /* Add enqueued object to parameter vector */
3567 taskpointerarray[parameter->slot]=ptr;
3569 /* Reset iterators */
3570 for(j=0; j<numiterators; j++) {
3571 toiReset(¶meter->iterators[j]);
3574 /* Find initial state */
3575 for(j=0; j<numiterators; j++) {
3577 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3578 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3580 /* Need to backtrack */
3581 toiReset(¶meter->iterators[j]);
3585 /* Nothing to enqueue */
3591 /* Enqueue current state */
3593 struct taskparamdescriptor *tpd=
3594 RUNMALLOC_I(sizeof(struct taskparamdescriptor));
3596 tpd->numParameters=numiterators+1;
3597 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
3599 for(j=0; j<=numiterators; j++) {
3600 //store the actual parameters
3601 tpd->parameterArray[j]=taskpointerarray[j];
3604 if (( /*!gencontains(failedtasks, tpd)&&*/
3605 !gencontains(activetasks,tpd))) {
3606 genputtable_I(activetasks, tpd, tpd);
3608 RUNFREE(tpd->parameterArray);
3612 /* This loop iterates to the next parameter combination */
3613 if (numiterators==0)
3616 for(j=numiterators-1; j<numiterators; j++) {
3619 ¶meter->iterators[j], taskpointerarray OPTARG(failed)))
3620 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3622 /* Need to backtrack */
3623 toiReset(¶meter->iterators[j]);
3627 /* Nothing more to enqueue */
3641 int containstag(struct ___Object___ *ptr,
3642 struct ___TagDescriptor___ *tag);
3644 #ifndef MULTICORE_GC
3645 void releasewritelock_r(void * lock, void * redirectlock) {
3647 int reallock = (int)lock;
3648 targetcore = (reallock >> 5) % NUMCORES;
3651 BAMBOO_DEBUGPRINT(0xe671);
3652 BAMBOO_DEBUGPRINT_REG((int)lock);
3653 BAMBOO_DEBUGPRINT_REG(reallock);
3654 BAMBOO_DEBUGPRINT_REG(targetcore);
3657 if(targetcore == BAMBOO_NUM_OF_CORE) {
3658 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3660 BAMBOO_DEBUGPRINT(0xf001);
3662 // reside on this core
3663 if(!RuntimeHashcontainskey(locktbl, reallock)) {
3664 // no locks for this object, something is wrong
3665 BAMBOO_EXIT(0xe01f);
3668 struct LockValue * lockvalue = NULL;
3670 BAMBOO_DEBUGPRINT(0xe672);
3672 RuntimeHashget(locktbl, reallock, &rwlock_obj);
3673 lockvalue = (struct LockValue *)rwlock_obj;
3675 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
3678 lockvalue->redirectlock = (int)redirectlock;
3680 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
3683 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3685 BAMBOO_DEBUGPRINT(0xf000);
3689 // send lock release with redirect info msg
3690 // for 32 bit machine, the size is always 4 words
3691 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock,
3692 (int)redirectlock, false);
3697 void executetasks() {
3698 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
3701 struct ___Object___ * tmpparam = NULL;
3702 struct parameterdescriptor * pd=NULL;
3703 struct parameterwrapper *pw=NULL;
3713 while(hashsize(activetasks)>0) {
3715 if(gcflag) gc(NULL);
3718 BAMBOO_DEBUGPRINT(0xe990);
3721 /* See if there are any active tasks */
3722 //if (hashsize(activetasks)>0) {
3725 #ifdef ACCURATEPROFILE
3726 profileTaskStart("tpd checking");
3730 //clock1 = BAMBOO_GET_EXE_TIME();
3733 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
3734 genfreekey(activetasks, currtpd);
3736 numparams=currtpd->task->numParameters;
3737 numtotal=currtpd->task->numTotal;
3739 // clear the lockRedirectTbl
3740 // (TODO, this table should be empty after all locks are released)
3742 /*for(j = 0; j < MAXTASKPARAMS; j++) {
3743 runtime_locks[j].redirectlock = 0;
3744 runtime_locks[j].value = 0;
3746 // get all required locks
3747 runtime_locklen = 0;
3748 // check which locks are needed
3749 for(i = 0; i < numparams; i++) {
3750 void * param = currtpd->parameterArray[i];
3754 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
3756 taskpointerarray[i+OFFSET]=param;
3759 if(((struct ___Object___ *)param)->lock == NULL) {
3760 tmplock = (int)param;
3762 tmplock = (int)(((struct ___Object___ *)param)->lock);
3764 // insert into the locks array
3765 for(j = 0; j < runtime_locklen; j++) {
3766 if(runtime_locks[j].value == tmplock) {
3769 } else if(runtime_locks[j].value > tmplock) {
3774 int h = runtime_locklen;
3776 runtime_locks[h].redirectlock = runtime_locks[h-1].redirectlock;
3777 runtime_locks[h].value = runtime_locks[h-1].value;
3779 runtime_locks[j].value = tmplock;
3780 runtime_locks[j].redirectlock = (int)param;
3783 } // line 2713: for(i = 0; i < numparams; i++)
3784 // grab these required locks
3786 BAMBOO_DEBUGPRINT(0xe991);
3789 //clock2 = BAMBOO_GET_EXE_TIME();
3791 for(i = 0; i < runtime_locklen; i++) {
3792 int * lock = (int *)(runtime_locks[i].redirectlock);
3794 // require locks for this parameter if it is not a startup object
3796 BAMBOO_DEBUGPRINT_REG((int)lock);
3797 BAMBOO_DEBUGPRINT_REG((int)(runtime_locks[i].value));
3800 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3802 BAMBOO_DEBUGPRINT(0xf001);
3805 //isInterrupt = false;
3808 BAMBOO_WAITING_FOR_LOCK(0);
3812 while(BAMBOO_WAITING_FOR_LOCK(0) != -1) {
3816 grount = lockresult;
3826 //isInterrupt = true;
3828 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3830 BAMBOO_DEBUGPRINT(0xf000);
3835 BAMBOO_DEBUGPRINT(0xe992);
3836 BAMBOO_DEBUGPRINT_REG(lock);
3838 // check if has the lock already
3839 // can not get the lock, try later
3840 // release all grabbed locks for previous parameters
3841 for(j = 0; j < i; ++j) {
3842 lock = (int*)(runtime_locks[j].redirectlock);
3843 releasewritelock(lock);
3845 genputtable(activetasks, currtpd, currtpd);
3846 if(hashsize(activetasks) == 1) {
3847 // only one task right now, wait a little while before next try
3853 #ifdef ACCURATEPROFILE
3854 // fail, set the end of the checkTaskInfo
3861 } // line 2752: for(i = 0; i < runtime_locklen; i++)
3864 clock3 = BAMBOO_GET_EXE_TIME();
3865 //tprintf("sort: %d, grab: %d \n", clock2-clock1, clock3-clock2);*/
3868 BAMBOO_DEBUGPRINT(0xe993);
3870 /* Make sure that the parameters are still in the queues */
3871 for(i=0; i<numparams; i++) {
3872 void * parameter=currtpd->parameterArray[i];
3876 BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
3877 classsize[((struct ___Object___ *)parameter)->type]);
3879 tmpparam = (struct ___Object___ *)parameter;
3880 pd=currtpd->task->descriptorarray[i];
3881 pw=(struct parameterwrapper *) pd->queue;
3882 /* Check that object is still in queue */
3884 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
3886 BAMBOO_DEBUGPRINT(0xe994);
3887 BAMBOO_DEBUGPRINT_REG(parameter);
3889 // release grabbed locks
3890 for(j = 0; j < runtime_locklen; ++j) {
3891 int * lock = (int *)(runtime_locks[j].redirectlock);
3892 releasewritelock(lock);
3894 RUNFREE(currtpd->parameterArray);
3900 /* Check if the object's flags still meets requirements */
3904 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
3905 andmask=pw->intarray[tmpi*2];
3906 checkmask=pw->intarray[tmpi*2+1];
3907 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
3913 // flags are never suitable
3914 // remove this obj from the queue
3916 int UNUSED, UNUSED2;
3919 BAMBOO_DEBUGPRINT(0xe995);
3920 BAMBOO_DEBUGPRINT_REG(parameter);
3922 ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
3923 (int *) &enterflags, &UNUSED, &UNUSED2);
3924 ObjectHashremove(pw->objectset, (int)parameter);
3925 if (enterflags!=NULL)
3926 RUNFREE(enterflags);
3927 // release grabbed locks
3928 for(j = 0; j < runtime_locklen; ++j) {
3929 int * lock = (int *)(runtime_locks[j].redirectlock);
3930 releasewritelock(lock);
3932 RUNFREE(currtpd->parameterArray);
3936 #ifdef ACCURATEPROFILE
3937 // fail, set the end of the checkTaskInfo
3942 } // line 2878: if (!ismet)
3946 /* Check that object still has necessary tags */
3947 for(j=0; j<pd->numbertags; j++) {
3948 int slotid=pd->tagarray[2*j]+numparams;
3949 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
3950 if (!containstag(parameter, tagd)) {
3952 BAMBOO_DEBUGPRINT(0xe996);
3955 // release grabbed locks
3957 for(tmpj = 0; tmpj < runtime_locklen; ++tmpj) {
3958 int * lock = (int *)(runtime_locks[tmpj].redirectlock);
3959 releasewritelock(lock);
3962 RUNFREE(currtpd->parameterArray);
3966 } // line2911: if (!containstag(parameter, tagd))
3967 } // line 2808: for(j=0; j<pd->numbertags; j++)
3969 taskpointerarray[i+OFFSET]=parameter;
3970 } // line 2824: for(i=0; i<numparams; i++)
3972 for(; i<numtotal; i++) {
3973 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
3978 /* Actually call task */
3980 ((int *)taskpointerarray)[0]=currtpd->numParameters;
3981 taskpointerarray[1]=NULL;
3984 #ifdef ACCURATEPROFILE
3985 // check finish, set the end of the checkTaskInfo
3988 profileTaskStart(currtpd->task->name);
3992 //clock4 = BAMBOO_GET_EXE_TIME();
3993 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3996 BAMBOO_DEBUGPRINT(0xe997);
3998 ((void (*)(void **))currtpd->task->taskptr)(taskpointerarray);
4001 //clock5 = BAMBOO_GET_EXE_TIME();
4002 // tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
4005 #ifdef ACCURATEPROFILE
4006 // task finish, set the end of the checkTaskInfo
4008 // new a PostTaskInfo for the post-task execution
4009 profileTaskStart("post task execution");
4013 BAMBOO_DEBUGPRINT(0xe998);
4014 BAMBOO_DEBUGPRINT_REG(islock);
4019 BAMBOO_DEBUGPRINT(0xe999);
4021 for(i = 0; i < runtime_locklen; ++i) {
4022 void * ptr = (void *)(runtime_locks[i].redirectlock);
4023 int * lock = (int *)(runtime_locks[i].value);
4025 BAMBOO_DEBUGPRINT_REG((int)ptr);
4026 BAMBOO_DEBUGPRINT_REG((int)lock);
4027 BAMBOO_DEBUGPRINT_REG(*((int*)lock+5));
4029 #ifndef MULTICORE_GC
4030 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
4032 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
4033 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
4034 releasewritelock_r(lock, (int *)redirectlock);
4039 releasewritelock(ptr);
4042 } // line 3015: if(islock)
4045 //clock6 = BAMBOO_GET_EXE_TIME();
4046 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
4049 // post task execution finish, set the end of the postTaskInfo
4053 // Free up task parameter descriptor
4054 RUNFREE(currtpd->parameterArray);
4058 BAMBOO_DEBUGPRINT(0xe99a);
4061 //clock7 = BAMBOO_GET_EXE_TIME();
4062 //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));
4065 //} // if (hashsize(activetasks)>0)
4066 } // while(hashsize(activetasks)>0)
4068 BAMBOO_DEBUGPRINT(0xe99b);
4072 /* This function processes an objects tags */
4073 void processtags(struct parameterdescriptor *pd,
4075 struct parameterwrapper *parameter,
4076 int * iteratorcount,
4081 for(i=0; i<pd->numbertags; i++) {
4082 int slotid=pd->tagarray[2*i];
4083 int tagid=pd->tagarray[2*i+1];
4085 if (statusarray[slotid+numparams]==0) {
4086 parameter->iterators[*iteratorcount].istag=1;
4087 parameter->iterators[*iteratorcount].tagid=tagid;
4088 parameter->iterators[*iteratorcount].slot=slotid+numparams;
4089 parameter->iterators[*iteratorcount].tagobjectslot=index;
4090 statusarray[slotid+numparams]=1;
4097 void processobject(struct parameterwrapper *parameter,
4099 struct parameterdescriptor *pd,
4105 struct ObjectHash * objectset=
4106 ((struct parameterwrapper *)pd->queue)->objectset;
4108 parameter->iterators[*iteratorcount].istag=0;
4109 parameter->iterators[*iteratorcount].slot=index;
4110 parameter->iterators[*iteratorcount].objectset=objectset;
4111 statusarray[index]=1;
4113 for(i=0; i<pd->numbertags; i++) {
4114 int slotid=pd->tagarray[2*i];
4115 //int tagid=pd->tagarray[2*i+1];
4116 if (statusarray[slotid+numparams]!=0) {
4117 /* This tag has already been enqueued, use it to narrow search */
4118 parameter->iterators[*iteratorcount].tagbindings[tagcount]=
4123 parameter->iterators[*iteratorcount].numtags=tagcount;
4128 /* This function builds the iterators for a task & parameter */
4130 void builditerators(struct taskdescriptor * task,
4132 struct parameterwrapper * parameter) {
4133 int statusarray[MAXTASKPARAMS];
4135 int numparams=task->numParameters;
4136 int iteratorcount=0;
4137 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
4139 statusarray[index]=1; /* Initial parameter */
4140 /* Process tags for initial iterator */
4142 processtags(task->descriptorarray[index], index, parameter,
4143 &iteratorcount, statusarray, numparams);
4147 /* Check for objects with existing tags */
4148 for(i=0; i<numparams; i++) {
4149 if (statusarray[i]==0) {
4150 struct parameterdescriptor *pd=task->descriptorarray[i];
4152 for(j=0; j<pd->numbertags; j++) {
4153 int slotid=pd->tagarray[2*j];
4154 if(statusarray[slotid+numparams]!=0) {
4155 processobject(parameter,i,pd,&iteratorcount,
4156 statusarray,numparams);
4157 processtags(pd,i,parameter,&iteratorcount,statusarray,numparams);
4164 /* Next do objects w/ unbound tags*/
4166 for(i=0; i<numparams; i++) {
4167 if (statusarray[i]==0) {
4168 struct parameterdescriptor *pd=task->descriptorarray[i];
4169 if (pd->numbertags>0) {
4170 processobject(parameter,i,pd,&iteratorcount,statusarray,numparams);
4171 processtags(pd,i,parameter,&iteratorcount,statusarray,numparams);
4177 /* Nothing with a tag enqueued */
4179 for(i=0; i<numparams; i++) {
4180 if (statusarray[i]==0) {
4181 struct parameterdescriptor *pd=task->descriptorarray[i];
4182 processobject(parameter,i,pd,&iteratorcount,statusarray,numparams);
4183 processtags(pd,i,parameter,&iteratorcount,statusarray,numparams);
4196 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
4199 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
4200 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
4202 printf("%s\n", task->name);
4204 for(j=0; j<task->numParameters; j++) {
4205 struct parameterdescriptor *param=task->descriptorarray[j];
4206 struct parameterwrapper *parameter=param->queue;
4207 struct ObjectHash * set=parameter->objectset;
4208 struct ObjectIterator objit;
4210 printf(" Parameter %d\n", j);
4212 ObjectHashiterator(set, &objit);
4213 while(ObjhasNext(&objit)) {
4214 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
4215 struct ___Object___ * tagptr=obj->___tags___;
4216 int nonfailed=Objdata4(&objit);
4217 int numflags=Objdata3(&objit);
4218 int flags=Objdata2(&objit);
4221 printf(" Contains %lx\n", obj);
4222 printf(" flag=%d\n", obj->flag);
4225 } else if (tagptr->type==TAGTYPE) {
4227 printf(" tag=%lx\n",tagptr);
4233 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
4234 for(; tagindex<ao->___cachedCode___; tagindex++) {
4236 printf(" tag=%lx\n",ARRAYGET(ao,struct ___TagDescriptor___*,
4249 /* This function processes the task information to create queues for
4250 each parameter type. */
4252 void processtasks() {
4254 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
4257 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
4258 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
4261 /* Build objectsets */
4262 for(j=0; j<task->numParameters; j++) {
4263 struct parameterdescriptor *param=task->descriptorarray[j];
4264 struct parameterwrapper *parameter=param->queue;
4265 parameter->objectset=allocateObjectHash(10);
4266 parameter->task=task;
4269 /* Build iterators for parameters */
4270 for(j=0; j<task->numParameters; j++) {
4271 struct parameterdescriptor *param=task->descriptorarray[j];
4272 struct parameterwrapper *parameter=param->queue;
4273 builditerators(task, j, parameter);
4278 void toiReset(struct tagobjectiterator * it) {
4281 } else if (it->numtags>0) {
4284 ObjectHashiterator(it->objectset, &it->it);
4288 int toiHasNext(struct tagobjectiterator *it,
4289 void ** objectarray OPTARG(int * failed)) {
4292 /* Get object with tags */
4293 struct ___Object___ *obj=objectarray[it->tagobjectslot];
4294 struct ___Object___ *tagptr=obj->___tags___;
4295 if (tagptr->type==TAGTYPE) {
4296 if ((it->tagobjindex==0)&& /* First object */
4297 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
4302 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
4303 int tagindex=it->tagobjindex;
4304 for(; tagindex<ao->___cachedCode___; tagindex++) {
4305 struct ___TagDescriptor___ *td=
4306 ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
4307 if (td->flag==it->tagid) {
4308 it->tagobjindex=tagindex; /* Found right type of tag */
4314 } else if (it->numtags>0) {
4315 /* Use tags to locate appropriate objects */
4316 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
4317 struct ___Object___ *objptr=tag->flagptr;
4319 if (objptr->type!=OBJECTARRAYTYPE) {
4320 if (it->tagobjindex>0)
4322 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
4324 for(i=1; i<it->numtags; i++) {
4325 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
4326 if (!containstag(objptr,tag2))
4331 struct ArrayObject *ao=(struct ArrayObject *) objptr;
4334 for(tagindex=it->tagobjindex;tagindex<ao->___cachedCode___;tagindex++){
4335 struct ___Object___ *objptr=
4336 ARRAYGET(ao,struct ___Object___*,tagindex);
4337 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
4339 for(i=1; i<it->numtags; i++) {
4340 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
4341 if (!containstag(objptr,tag2))
4344 it->tagobjindex=tagindex;
4349 it->tagobjindex=tagindex;
4353 return ObjhasNext(&it->it);
4357 int containstag(struct ___Object___ *ptr,
4358 struct ___TagDescriptor___ *tag) {
4360 struct ___Object___ * objptr=tag->flagptr;
4361 if (objptr->type==OBJECTARRAYTYPE) {
4362 struct ArrayObject *ao=(struct ArrayObject *)objptr;
4363 for(j=0; j<ao->___cachedCode___; j++) {
4364 if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
4374 void toiNext(struct tagobjectiterator *it,
4375 void ** objectarray OPTARG(int * failed)) {
4376 /* hasNext has all of the intelligence */
4379 /* Get object with tags */
4380 struct ___Object___ *obj=objectarray[it->tagobjectslot];
4381 struct ___Object___ *tagptr=obj->___tags___;
4382 if (tagptr->type==TAGTYPE) {
4384 objectarray[it->slot]=tagptr;
4386 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
4387 objectarray[it->slot]=
4388 ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
4390 } else if (it->numtags>0) {
4391 /* Use tags to locate appropriate objects */
4392 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
4393 struct ___Object___ *objptr=tag->flagptr;
4394 if (objptr->type!=OBJECTARRAYTYPE) {
4396 objectarray[it->slot]=objptr;
4398 struct ArrayObject *ao=(struct ArrayObject *) objptr;
4399 objectarray[it->slot]=
4400 ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
4403 /* Iterate object */
4404 objectarray[it->slot]=(void *)Objkey(&it->it);
4410 inline void profileTaskStart(char * taskname) {
4411 if(!taskInfoOverflow) {
4412 TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
4413 taskInfoArray[taskInfoIndex] = taskInfo;
4414 taskInfo->taskName = taskname;
4415 taskInfo->startTime = BAMBOO_GET_EXE_TIME();
4416 taskInfo->endTime = -1;
4417 taskInfo->exitIndex = -1;
4418 taskInfo->newObjs = NULL;
4422 inline void profileTaskEnd() {
4423 if(!taskInfoOverflow) {
4424 taskInfoArray[taskInfoIndex]->endTime = BAMBOO_GET_EXE_TIME();
4426 if(taskInfoIndex == TASKINFOLENGTH) {
4427 taskInfoOverflow = true;
4428 //taskInfoIndex = 0;
4433 // output the profiling data
4434 void outputProfileData() {
4437 unsigned long long totaltasktime = 0;
4438 unsigned long long preprocessingtime = 0;
4439 unsigned long long objqueuecheckingtime = 0;
4440 unsigned long long postprocessingtime = 0;
4441 //int interruptiontime = 0;
4442 unsigned long long other = 0;
4443 unsigned long long averagetasktime = 0;
4446 printf("Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
4447 // output task related info
4448 for(i = 0; i < taskInfoIndex; i++) {
4449 TaskInfo* tmpTInfo = taskInfoArray[i];
4450 unsigned long long duration = tmpTInfo->endTime - tmpTInfo->startTime;
4451 printf("%s, %lld, %lld, %lld, %lld",
4452 tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime,
4453 duration, tmpTInfo->exitIndex);
4454 // summarize new obj info
4455 if(tmpTInfo->newObjs != NULL) {
4456 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
4457 struct RuntimeIterator * iter = NULL;
4458 while(0 == isEmpty(tmpTInfo->newObjs)) {
4459 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
4460 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
4462 RuntimeHashget(nobjtbl, (int)objtype, &num);
4463 RuntimeHashremovekey(nobjtbl, (int)objtype);
4465 RuntimeHashadd(nobjtbl, (int)objtype, num);
4467 RuntimeHashadd(nobjtbl, (int)objtype, 1);
4469 //printf(stderr, "new obj!\n");
4472 // output all new obj info
4473 iter = RuntimeHashcreateiterator(nobjtbl);
4474 while(RunhasNext(iter)) {
4475 char * objtype = (char *)Runkey(iter);
4476 int num = Runnext(iter);
4477 printf(", %s, %d", objtype, num);
4481 if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
4482 preprocessingtime += duration;
4483 } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
4484 postprocessingtime += duration;
4485 } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
4486 objqueuecheckingtime += duration;
4488 totaltasktime += duration;
4489 averagetasktime += duration;
4494 if(taskInfoOverflow) {
4495 printf("Caution: task info overflow!\n");
4498 other = totalexetime-totaltasktime-preprocessingtime-postprocessingtime;
4499 averagetasktime /= tasknum;
4501 printf("\nTotal time: %lld\n", totalexetime);
4502 printf("Total task execution time: %lld (%d%%)\n", totaltasktime,
4503 (int)(((double)totaltasktime/(double)totalexetime)*100));
4504 printf("Total objqueue checking time: %lld (%d%%)\n",
4505 objqueuecheckingtime,
4506 (int)(((double)objqueuecheckingtime/(double)totalexetime)*100));
4507 printf("Total pre-processing time: %lld (%d%%)\n", preprocessingtime,
4508 (int)(((double)preprocessingtime/(double)totalexetime)*100));
4509 printf("Total post-processing time: %lld (%d%%)\n", postprocessingtime,
4510 (int)(((double)postprocessingtime/(double)totalexetime)*100));
4511 printf("Other time: %lld (%d%%)\n", other,
4512 (int)(((double)other/(double)totalexetime)*100));
4515 printf("\nAverage task execution time: %lld\n", averagetasktime);
4517 //printf("\nTotal time spent for interruptions: %lld\n", interrupttime);
4522 BAMBOO_DEBUGPRINT(0xdddd);
4523 // output task related info
4524 for(i= 0; i < taskInfoIndex; i++) {
4525 TaskInfo* tmpTInfo = taskInfoArray[i];
4526 char* tmpName = tmpTInfo->taskName;
4527 int nameLen = strlen(tmpName);
4528 BAMBOO_DEBUGPRINT(0xddda);
4529 for(j = 0; j < nameLen; j++) {
4530 BAMBOO_DEBUGPRINT_REG(tmpName[j]);
4532 BAMBOO_DEBUGPRINT(0xdddb);
4533 BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
4534 BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
4535 BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
4536 if(tmpTInfo->newObjs != NULL) {
4537 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
4538 struct RuntimeIterator * iter = NULL;
4539 while(0 == isEmpty(tmpTInfo->newObjs)) {
4540 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
4541 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
4543 RuntimeHashget(nobjtbl, (int)objtype, &num);
4544 RuntimeHashremovekey(nobjtbl, (int)objtype);
4546 RuntimeHashadd(nobjtbl, (int)objtype, num);
4548 RuntimeHashadd(nobjtbl, (int)objtype, 1);
4552 // ouput all new obj info
4553 iter = RuntimeHashcreateiterator(nobjtbl);
4554 while(RunhasNext(iter)) {
4555 char * objtype = (char *)Runkey(iter);
4556 int num = Runnext(iter);
4557 int nameLen = strlen(objtype);
4558 BAMBOO_DEBUGPRINT(0xddda);
4559 for(j = 0; j < nameLen; j++) {
4560 BAMBOO_DEBUGPRINT_REG(objtype[j]);
4562 BAMBOO_DEBUGPRINT(0xdddb);
4563 BAMBOO_DEBUGPRINT_REG(num);
4566 BAMBOO_DEBUGPRINT(0xdddc);
4569 if(taskInfoOverflow) {
4570 BAMBOO_DEBUGPRINT(0xefee);
4573 #ifdef PROFILE_INTERRUPT
4574 // output interrupt related info
4575 for(i = 0; i < interruptInfoIndex; i++) {
4576 InterruptInfo* tmpIInfo = interruptInfoArray[i];
4577 BAMBOO_DEBUGPRINT(0xddde);
4578 BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
4579 BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
4580 BAMBOO_DEBUGPRINT(0xdddf);
4583 if(interruptInfoOverflow) {
4584 BAMBOO_DEBUGPRINT(0xefef);
4586 #endif // PROFILE_INTERRUPT
4588 BAMBOO_DEBUGPRINT(0xeeee);
4591 #endif // #ifdef PROFILE