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 bamboo_tile_timer_set_next_event(500000000); // TODO
382 bamboo_unmask_timer_intr();
383 //BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME());
384 bamboo_dtlb_sampling_process();
385 #endif // GC_CACHE_ADAPT
387 // create the lock table, lockresult table and obj queue
390 (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
391 /* Set allocation blocks*/
392 locktable.listhead=NULL;
393 locktable.listtail=NULL;
395 locktable.numelements = 0;
400 lockRedirectTbl = allocateRuntimeHash_I(20);
401 objRedirectLockTbl = allocateRuntimeHash_I(20);
406 objqueue.head = NULL;
407 objqueue.tail = NULL;
413 //isInterrupt = true;
417 taskInfoOverflow = false;
418 #ifdef PROFILE_INTERRUPT
419 interruptInfoIndex = 0;
420 interruptInfoOverflow = false;
421 #endif // PROFILE_INTERRUPT
424 for(i = 0; i < MAXTASKPARAMS; i++) {
425 runtime_locks[i].redirectlock = 0;
426 runtime_locks[i].value = 0;
431 inline __attribute__((always_inline))
432 void disruntimedata() {
434 #ifdef LOCALHASHTBL_TEST
435 freeRuntimeHash(gcpointertbl);
437 mgchashDelete(gcpointertbl);
439 //freeMGCHash(gcpointertbl);
440 freeMGCHash(gcforwardobjtbl);
441 // for mapping info structures
442 //freeRuntimeHash(gcrcoretbl);
444 freeRuntimeHash(lockRedirectTbl);
445 freeRuntimeHash(objRedirectLockTbl);
446 RUNFREE(locktable.bucket);
448 if(activetasks != NULL) {
449 genfreehashtable(activetasks);
451 if(currtpd != NULL) {
452 RUNFREE(currtpd->parameterArray);
456 BAMBOO_LOCAL_MEM_CLOSE();
457 BAMBOO_SHARE_MEM_CLOSE();
460 inline __attribute__((always_inline))
461 bool checkObjQueue() {
463 struct transObjInfo * objInfo = NULL;
467 #ifdef ACCURATEPROFILE
468 bool isChecking = false;
469 if(!isEmpty(&objqueue)) {
470 profileTaskStart("objqueue checking");
472 } // if(!isEmpty(&objqueue))
476 while(!isEmpty(&objqueue)) {
478 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
480 BAMBOO_DEBUGPRINT(0xf001);
483 //isInterrupt = false;
486 BAMBOO_DEBUGPRINT(0xeee1);
489 objInfo = (struct transObjInfo *)getItem(&objqueue);
490 obj = objInfo->objptr;
492 BAMBOO_DEBUGPRINT_REG((int)obj);
494 // grab lock and flush the obj
498 BAMBOO_WAITING_FOR_LOCK(0);
499 } // while(!lockflag)
502 BAMBOO_DEBUGPRINT_REG(grount);
517 BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
518 BAMBOO_CACHE_FLUSH_RANGE((int)obj,
519 classsize[((struct ___Object___ *)obj)->type]);
521 // enqueue the object
522 for(k = 0; k < objInfo->length; ++k) {
523 int taskindex = objInfo->queues[2 * k];
524 int paramindex = objInfo->queues[2 * k + 1];
525 struct parameterwrapper ** queues =
526 &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
528 BAMBOO_DEBUGPRINT_REG(taskindex);
529 BAMBOO_DEBUGPRINT_REG(paramindex);
530 struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
531 tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n",
532 BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj,
533 (long)obj, tmpptr->flag);
535 enqueueObject_I(obj, queues, 1);
537 BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
539 } // for(k = 0; k < objInfo->length; ++k)
540 releasewritelock_I(obj);
541 RUNFREE(objInfo->queues);
545 // put it at the end of the queue if no update version in the queue
546 struct QueueItem * qitem = getHead(&objqueue);
547 struct QueueItem * prev = NULL;
548 while(qitem != NULL) {
549 struct transObjInfo * tmpinfo =
550 (struct transObjInfo *)(qitem->objectptr);
551 if(tmpinfo->objptr == obj) {
552 // the same object in the queue, which should be enqueued
553 // recently. Current one is outdate, do not re-enqueue it
554 RUNFREE(objInfo->queues);
559 } // if(tmpinfo->objptr == obj)
560 qitem = getNextQueueItem(prev);
561 } // while(qitem != NULL)
562 // try to execute active tasks already enqueued first
563 addNewItem_I(&objqueue, objInfo);
565 //isInterrupt = true;
568 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
570 BAMBOO_DEBUGPRINT(0xf000);
574 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
576 BAMBOO_DEBUGPRINT(0xf000);
578 } // while(!isEmpty(&objqueue))
581 #ifdef ACCURATEPROFILE
589 BAMBOO_DEBUGPRINT(0xee02);
594 inline __attribute__((always_inline))
595 void checkCoreStatus() {
596 bool allStall = false;
600 (waitconfirm && (numconfirm == 0))) {
602 BAMBOO_DEBUGPRINT(0xee04);
603 BAMBOO_DEBUGPRINT_REG(waitconfirm);
605 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
607 BAMBOO_DEBUGPRINT(0xf001);
609 corestatus[BAMBOO_NUM_OF_CORE] = 0;
610 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
611 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
612 // check the status of all cores
615 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
617 for(i = 0; i < NUMCORESACTIVE; ++i) {
619 BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
621 if(corestatus[i] != 0) {
625 } // for(i = 0; i < NUMCORESACTIVE; ++i)
627 // check if the sum of send objs and receive obj are the same
628 // yes->check if the info is the latest; no->go on executing
630 for(i = 0; i < NUMCORESACTIVE; ++i) {
631 sumsendobj += numsendobjs[i];
633 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
635 } // for(i = 0; i < NUMCORESACTIVE; ++i)
636 for(i = 0; i < NUMCORESACTIVE; ++i) {
637 sumsendobj -= numreceiveobjs[i];
639 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
641 } // for(i = 0; i < NUMCORESACTIVE; ++i)
642 if(0 == sumsendobj) {
644 // the first time found all cores stall
645 // send out status confirm msg to all other cores
646 // reset the corestatus array too
648 BAMBOO_DEBUGPRINT(0xee05);
650 corestatus[BAMBOO_NUM_OF_CORE] = 1;
652 numconfirm = NUMCORESACTIVE - 1;
653 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
654 for(i = 1; i < NUMCORESACTIVE; ++i) {
656 // send status confirm msg to core i
657 send_msg_1(i, STATUSCONFIRM, false);
658 } // for(i = 1; i < NUMCORESACTIVE; ++i)
661 // all the core status info are the latest
662 // terminate; for profiling mode, send request to all
663 // other cores to pour out profiling data
665 BAMBOO_DEBUGPRINT(0xee06);
669 totalexetime = BAMBOO_GET_EXE_TIME() - bamboo_start_time;
672 //BAMBOO_DEBUGPRINT_REG(interrupttime);
675 BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME() - bamboo_start_time);
676 //BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
678 BAMBOO_DEBUGPRINT_REG(gc_num_flush_dtlb);
680 #ifndef BAMBOO_MEMPROF
681 BAMBOO_DEBUGPRINT(0xbbbbbbbb);
684 // profile mode, send msgs to other cores to request pouring
685 // out progiling data
687 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
689 BAMBOO_DEBUGPRINT(0xf000);
691 for(i = 1; i < NUMCORESACTIVE; ++i) {
692 // send profile request msg to core i
693 send_msg_2(i, PROFILEOUTPUT, totalexetime, false);
694 } // for(i = 1; i < NUMCORESACTIVE; ++i)
696 // pour profiling data on startup core
700 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
702 BAMBOO_DEBUGPRINT(0xf001);
704 profilestatus[BAMBOO_NUM_OF_CORE] = 0;
705 // check the status of all cores
708 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
710 for(i = 0; i < NUMCORESACTIVE; ++i) {
712 BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
714 if(profilestatus[i] != 0) {
718 } // for(i = 0; i < NUMCORESACTIVE; ++i)
721 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
723 BAMBOO_DEBUGPRINT(0xf000);
728 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
734 // gc_profile mode, output gc prfiling data
736 #ifdef GC_CACHE_ADAPT
737 bamboo_mask_timer_intr(); // disable the TILE_TIMER interrupt
738 #endif // GC_CACHE_ADAPT
740 gc_outputProfileData();
741 #endif // #ifdef GC_PROFILE
742 #endif // #ifdef MULTICORE_GC
744 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
745 terminate(); // All done.
746 } // if(!waitconfirm)
748 // still some objects on the fly on the network
749 // reset the waitconfirm and numconfirm
751 BAMBOO_DEBUGPRINT(0xee07);
755 } // if(0 == sumsendobj)
757 // not all cores are stall, keep on waiting
759 BAMBOO_DEBUGPRINT(0xee08);
764 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
766 BAMBOO_DEBUGPRINT(0xf000);
768 } // if((!waitconfirm) ||
771 // main function for each core
772 inline void run(void * arg) {
776 bool sendStall = false;
778 bool tocontinue = false;
780 corenum = BAMBOO_GET_NUM_OF_CORE();
782 BAMBOO_DEBUGPRINT(0xeeee);
783 BAMBOO_DEBUGPRINT_REG(corenum);
784 BAMBOO_DEBUGPRINT(STARTUPCORE);
786 //BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME()); // TODO
788 // initialize runtime data structures
791 // other architecture related initialization
795 initializeexithandler();
797 // main process of the execution module
798 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
799 // non-executing cores, only processing communications
802 //isInterrupt = false;
806 /* Create queue of active tasks */
808 genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
809 (int (*)(void *,void *)) &comparetpd);
811 /* Process task information */
814 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
815 /* Create startup object */
816 createstartupobject(argc, argv);
820 BAMBOO_DEBUGPRINT(0xee00);
826 //#ifdef GC_CACHE_ADAPT
827 // do dtlb sampling if necessary
828 // bamboo_dtlb_sampling_process();
829 //#endif // GC_CACHE_ADAPT
830 // check if need to do GC
834 #endif // MULTICORE_GC
836 // check if there are new active tasks can be executed
843 while(receiveObject() != -1) {
848 BAMBOO_DEBUGPRINT(0xee01);
851 // check if there are some pending objects,
852 // if yes, enqueue them and executetasks again
853 tocontinue = checkObjQueue();
857 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
860 BAMBOO_DEBUGPRINT(0xee03);
868 BAMBOO_DEBUGPRINT(0xee09);
874 // wait for some time
877 BAMBOO_DEBUGPRINT(0xee0a);
883 // send StallMsg to startup core
885 BAMBOO_DEBUGPRINT(0xee0b);
888 send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
889 self_numsendobjs, self_numreceiveobjs, false);
901 BAMBOO_DEBUGPRINT(0xee0c);
904 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
907 } // if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)
911 struct ___createstartupobject____I_locals {
914 struct ___StartupObject___ * ___startupobject___;
915 struct ArrayObject * ___stringarray___;
916 }; // struct ___createstartupobject____I_locals
918 void createstartupobject(int argc,
922 /* Allocate startup object */
924 struct ___createstartupobject____I_locals ___locals___ =
925 {2, NULL, NULL, NULL};
926 struct ___StartupObject___ *startupobject=
927 (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
928 ___locals___.___startupobject___ = startupobject;
929 struct ArrayObject * stringarray=
930 allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
931 ___locals___.___stringarray___ = stringarray;
933 struct ___StartupObject___ *startupobject=
934 (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
935 struct ArrayObject * stringarray=
936 allocate_newarray(STRINGARRAYTYPE, argc-1);
938 /* Build array of strings */
939 startupobject->___parameters___=stringarray;
940 for(i=1; i<argc; i++) {
941 int length=strlen(argv[i]);
943 struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
945 struct ___String___ *newstring=NewString(argv[i],length);
947 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
951 startupobject->version = 0;
952 startupobject->lock = NULL;
954 /* Set initialized flag for startup object */
955 flagorandinit(startupobject,1,0xFFFFFFFF);
956 enqueueObject(startupobject, NULL, 0);
958 BAMBOO_CACHE_FLUSH_ALL();
962 int hashCodetpd(struct taskparamdescriptor *ftd) {
963 int hash=(int)ftd->task;
965 for(i=0; i<ftd->numParameters; i++) {
966 hash^=(int)ftd->parameterArray[i];
971 int comparetpd(struct taskparamdescriptor *ftd1,
972 struct taskparamdescriptor *ftd2) {
974 if (ftd1->task!=ftd2->task)
976 for(i=0; i<ftd1->numParameters; i++)
977 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
982 /* This function sets a tag. */
984 void tagset(void *ptr,
985 struct ___Object___ * obj,
986 struct ___TagDescriptor___ * tagd) {
988 void tagset(struct ___Object___ * obj,
989 struct ___TagDescriptor___ * tagd) {
991 struct ArrayObject * ao=NULL;
992 struct ___Object___ * tagptr=obj->___tags___;
994 obj->___tags___=(struct ___Object___ *)tagd;
996 /* Have to check if it is already set */
997 if (tagptr->type==TAGTYPE) {
998 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
1003 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
1004 struct ArrayObject * ao=
1005 allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
1006 obj=(struct ___Object___ *)ptrarray[2];
1007 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
1008 td=(struct ___TagDescriptor___ *) obj->___tags___;
1010 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
1013 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
1014 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
1015 obj->___tags___=(struct ___Object___ *) ao;
1016 ao->___cachedCode___=2;
1020 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
1021 for(i=0; i<ao->___cachedCode___; i++) {
1022 struct ___TagDescriptor___ * td=
1023 ARRAYGET(ao, struct ___TagDescriptor___*, i);
1028 if (ao->___cachedCode___<ao->___length___) {
1029 ARRAYSET(ao, struct ___TagDescriptor___ *,ao->___cachedCode___,tagd);
1030 ao->___cachedCode___++;
1033 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
1034 struct ArrayObject * aonew=
1035 allocate_newarray(&ptrarray,TAGARRAYTYPE,
1036 TAGARRAYINTERVAL+ao->___length___);
1037 obj=(struct ___Object___ *)ptrarray[2];
1038 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
1039 ao=(struct ArrayObject *)obj->___tags___;
1041 struct ArrayObject * aonew=
1042 allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
1045 aonew->___cachedCode___=ao->___length___+1;
1046 for(i=0; i<ao->___length___; i++) {
1047 ARRAYSET(aonew, struct ___TagDescriptor___*, i,
1048 ARRAYGET(ao, struct ___TagDescriptor___*, i));
1050 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___,tagd);
1056 struct ___Object___ * tagset=tagd->flagptr;
1059 } else if (tagset->type!=OBJECTARRAYTYPE) {
1061 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
1062 struct ArrayObject * ao=
1063 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
1064 obj=(struct ___Object___ *)ptrarray[2];
1065 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
1067 struct ArrayObject * ao=
1068 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
1070 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
1071 ARRAYSET(ao, struct ___Object___ *, 1, obj);
1072 ao->___cachedCode___=2;
1073 tagd->flagptr=(struct ___Object___ *)ao;
1075 struct ArrayObject *ao=(struct ArrayObject *) tagset;
1076 if (ao->___cachedCode___<ao->___length___) {
1077 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
1081 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
1082 struct ArrayObject * aonew=
1083 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
1084 OBJECTARRAYINTERVAL+ao->___length___);
1085 obj=(struct ___Object___ *)ptrarray[2];
1086 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
1087 ao=(struct ArrayObject *)tagd->flagptr;
1089 struct ArrayObject * aonew=allocate_newarray(OBJECTARRAYTYPE,
1090 OBJECTARRAYINTERVAL+ao->___length___);
1092 aonew->___cachedCode___=ao->___cachedCode___+1;
1093 for(i=0; i<ao->___length___; i++) {
1094 ARRAYSET(aonew, struct ___Object___*, i,
1095 ARRAYGET(ao, struct ___Object___*, i));
1097 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
1098 tagd->flagptr=(struct ___Object___ *) aonew;
1104 /* This function clears a tag. */
1106 void tagclear(void *ptr,
1107 struct ___Object___ * obj,
1108 struct ___TagDescriptor___ * tagd) {
1110 void tagclear(struct ___Object___ * obj,
1111 struct ___TagDescriptor___ * tagd) {
1113 /* We'll assume that tag is alway there.
1114 Need to statically check for this of course. */
1115 struct ___Object___ * tagptr=obj->___tags___;
1117 if (tagptr->type==TAGTYPE) {
1118 if ((struct ___TagDescriptor___ *)tagptr==tagd)
1119 obj->___tags___=NULL;
1121 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
1123 for(i=0; i<ao->___cachedCode___; i++) {
1124 struct ___TagDescriptor___ * td=
1125 ARRAYGET(ao, struct ___TagDescriptor___ *, i);
1127 ao->___cachedCode___--;
1128 if (i<ao->___cachedCode___)
1129 ARRAYSET(ao, struct ___TagDescriptor___ *, i,
1130 ARRAYGET(ao,struct ___TagDescriptor___*,ao->___cachedCode___));
1131 ARRAYSET(ao,struct ___TagDescriptor___ *,ao->___cachedCode___, NULL);
1132 if (ao->___cachedCode___==0)
1133 obj->___tags___=NULL;
1140 struct ___Object___ *tagset=tagd->flagptr;
1141 if (tagset->type!=OBJECTARRAYTYPE) {
1145 struct ArrayObject *ao=(struct ArrayObject *) tagset;
1147 for(i=0; i<ao->___cachedCode___; i++) {
1148 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
1150 ao->___cachedCode___--;
1151 if (i<ao->___cachedCode___)
1152 ARRAYSET(ao, struct ___Object___ *, i,
1153 ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
1154 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
1155 if (ao->___cachedCode___==0)
1166 /* This function allocates a new tag. */
1168 struct ___TagDescriptor___ * allocate_tag(void *ptr,
1170 struct ___TagDescriptor___ * v=
1171 (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
1172 classsize[TAGTYPE]);
1174 struct ___TagDescriptor___ * allocate_tag(int index) {
1175 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
1184 /* This function updates the flag for object ptr. It or's the flag
1185 with the or mask and and's it with the andmask. */
1187 void flagbody(struct ___Object___ *ptr,
1189 struct parameterwrapper ** queues,
1193 int flagcomp(const int *val1, const int *val2) {
1194 return (*val1)-(*val2);
1197 void flagorand(void * ptr,
1200 struct parameterwrapper ** queues,
1203 int oldflag=((int *)ptr)[1];
1204 int flag=ormask|oldflag;
1206 flagbody(ptr, flag, queues, length, false);
1210 bool intflagorand(void * ptr,
1214 int oldflag=((int *)ptr)[1];
1215 int flag=ormask|oldflag;
1217 if (flag==oldflag) /* Don't do anything */
1220 flagbody(ptr, flag, NULL, 0, false);
1226 void flagorandinit(void * ptr,
1229 int oldflag=((int *)ptr)[1];
1230 int flag=ormask|oldflag;
1232 flagbody(ptr,flag,NULL,0,true);
1235 void flagbody(struct ___Object___ *ptr,
1237 struct parameterwrapper ** vqueues,
1240 struct parameterwrapper * flagptr = NULL;
1242 struct parameterwrapper ** queues = vqueues;
1243 int length = vlength;
1245 int UNUSED, UNUSED2;
1246 int * enterflags = NULL;
1247 if((!isnew) && (queues == NULL)) {
1248 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
1249 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1250 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1257 /*Remove object from all queues */
1258 for(i = 0; i < length; ++i) {
1259 flagptr = queues[i];
1260 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
1261 (int *) &enterflags, &UNUSED, &UNUSED2);
1262 ObjectHashremove(flagptr->objectset, (int)ptr);
1263 if (enterflags!=NULL)
1264 RUNFREE(enterflags);
1268 void enqueueObject(void * vptr,
1269 struct parameterwrapper ** vqueues,
1271 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1274 //struct QueueItem *tmpptr;
1275 struct parameterwrapper * parameter=NULL;
1278 struct parameterwrapper * prevptr=NULL;
1279 struct ___Object___ *tagptr=NULL;
1280 struct parameterwrapper ** queues = vqueues;
1281 int length = vlength;
1282 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1285 if(queues == NULL) {
1286 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1287 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1289 tagptr=ptr->___tags___;
1291 /* Outer loop iterates through all parameter queues an object of
1292 this type could be in. */
1293 for(j = 0; j < length; ++j) {
1294 parameter = queues[j];
1296 if (parameter->numbertags>0) {
1298 goto nextloop; //that means the object has no tag
1299 //but that param needs tag
1300 else if(tagptr->type==TAGTYPE) { //one tag
1301 //struct ___TagDescriptor___ * tag=
1302 //(struct ___TagDescriptor___*) tagptr;
1303 for(i=0; i<parameter->numbertags; i++) {
1304 //slotid is parameter->tagarray[2*i];
1305 int tagid=parameter->tagarray[2*i+1];
1306 if (tagid!=tagptr->flag)
1307 goto nextloop; /*We don't have this tag */
1309 } else { //multiple tags
1310 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1311 for(i=0; i<parameter->numbertags; i++) {
1312 //slotid is parameter->tagarray[2*i];
1313 int tagid=parameter->tagarray[2*i+1];
1315 for(j=0; j<ao->___cachedCode___; j++) {
1316 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1327 for(i=0; i<parameter->numberofterms; i++) {
1328 int andmask=parameter->intarray[i*2];
1329 int checkmask=parameter->intarray[i*2+1];
1330 if ((ptr->flag&andmask)==checkmask) {
1331 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
1342 void enqueueObject_I(void * vptr,
1343 struct parameterwrapper ** vqueues,
1345 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1348 //struct QueueItem *tmpptr;
1349 struct parameterwrapper * parameter=NULL;
1352 struct parameterwrapper * prevptr=NULL;
1353 struct ___Object___ *tagptr=NULL;
1354 struct parameterwrapper ** queues = vqueues;
1355 int length = vlength;
1356 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1359 if(queues == NULL) {
1360 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1361 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1363 tagptr=ptr->___tags___;
1365 /* Outer loop iterates through all parameter queues an object of
1366 this type could be in. */
1367 for(j = 0; j < length; ++j) {
1368 parameter = queues[j];
1370 if (parameter->numbertags>0) {
1372 goto nextloop; //that means the object has no tag
1373 //but that param needs tag
1374 else if(tagptr->type==TAGTYPE) { //one tag
1375 //struct ___TagDescriptor___*tag=(struct ___TagDescriptor___*)tagptr;
1376 for(i=0; i<parameter->numbertags; i++) {
1377 //slotid is parameter->tagarray[2*i];
1378 int tagid=parameter->tagarray[2*i+1];
1379 if (tagid!=tagptr->flag)
1380 goto nextloop; /*We don't have this tag */
1382 } else { //multiple tags
1383 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1384 for(i=0; i<parameter->numbertags; i++) {
1385 //slotid is parameter->tagarray[2*i];
1386 int tagid=parameter->tagarray[2*i+1];
1388 for(j=0; j<ao->___cachedCode___; j++) {
1389 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1400 for(i=0; i<parameter->numberofterms; i++) {
1401 int andmask=parameter->intarray[i*2];
1402 int checkmask=parameter->intarray[i*2+1];
1403 if ((ptr->flag&andmask)==checkmask) {
1404 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1416 int * getAliasLock(void ** ptrs,
1418 struct RuntimeHash * tbl) {
1420 return (int*)(RUNMALLOC(sizeof(int)));
1425 bool redirect = false;
1426 int redirectlock = 0;
1427 for(; i < length; i++) {
1428 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1431 if(ptr->lock == NULL) {
1434 lock = (int)(ptr->lock);
1437 if(lock != redirectlock) {
1438 RuntimeHashadd(tbl, lock, redirectlock);
1441 if(RuntimeHashcontainskey(tbl, lock)) {
1442 // already redirected
1444 RuntimeHashget(tbl, lock, &redirectlock);
1445 for(; j < locklen; j++) {
1446 if(locks[j] != redirectlock) {
1447 RuntimeHashadd(tbl, locks[j], redirectlock);
1452 for(j = 0; j < locklen; j++) {
1453 if(locks[j] == lock) {
1456 } else if(locks[j] > lock) {
1463 locks[h] = locks[h-1];
1472 return (int *)redirectlock;
1474 return (int *)(locks[0]);
1479 void addAliasLock(void * ptr,
1481 struct ___Object___ * obj = (struct ___Object___ *)ptr;
1482 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1483 // originally no alias lock associated or have a different alias lock
1484 // flush it as the new one
1485 obj->lock = (int *)lock;
1490 inline void setTaskExitIndex(int index) {
1491 taskInfoArray[taskInfoIndex]->exitIndex = index;
1494 inline void addNewObjInfo(void * nobj) {
1495 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1496 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1498 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1503 // Only allocate local mem chunks to each core.
1504 // If a core has used up its local shared memory, start gc.
1505 void * localmalloc_I(int coren,
1509 int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
1512 int tofindb = gc_core2block[2*gccorenum+i]+(NUMCORES4GC*2)*j;
1513 int totest = tofindb;
1514 int bound = BAMBOO_SMEM_SIZE_L;
1518 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1519 int nsize = bamboo_smemtbl[totest];
1520 bool islocal = true;
1522 bool tocheck = true;
1523 // have some space in the block
1524 if(totest == tofindb) {
1525 // the first partition
1526 size = bound - nsize;
1527 } else if(nsize == 0) {
1528 // an empty partition, can be appended
1531 // not an empty partition, can not be appended
1532 // the last continuous block is not big enough, go to check the next
1536 } // if(totest == tofindb) else if(nsize == 0) else ...
1539 // have enough space in the block, malloc
1543 // no enough space yet, try to append next continuous block
1545 } // if(size > isize) else ...
1547 } // if(nsize < bound)
1549 // no space in the block, go to check the next block
1555 tofindb = totest = gc_core2block[2*gccorenum+i]+(NUMCORES4GC*2)*j;
1558 } // if(islocal) else ...
1559 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1560 // no more local mem, do not find suitable block
1563 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1566 if(foundsmem == 1) {
1567 // find suitable block
1568 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1569 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1570 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1572 // set bamboo_smemtbl
1573 for(i = tofindb; i <= totest; i++) {
1574 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1576 } else if(foundsmem == 2) {
1577 // no suitable block
1582 } // void * localmalloc_I(int, int, int *)
1585 // Allocate the local shared memory to each core with the highest priority,
1586 // if a core has used up its local shared memory, try to allocate the
1587 // shared memory that belong to its neighbours, if also failed, start gc.
1588 void * fixedmalloc_I(int coren,
1595 int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
1596 int coords_x = bamboo_cpu2coords[gccorenum*2];
1597 int coords_y = bamboo_cpu2coords[gccorenum*2+1];
1599 int tofindb = gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1600 int totest = tofindb;
1601 int bound = BAMBOO_SMEM_SIZE_L;
1605 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1606 int nsize = bamboo_smemtbl[totest];
1607 bool islocal = true;
1609 bool tocheck = true;
1610 // have some space in the block
1611 if(totest == tofindb) {
1612 // the first partition
1613 size = bound - nsize;
1614 } else if(nsize == 0) {
1615 // an empty partition, can be appended
1618 // not an empty partition, can not be appended
1619 // the last continuous block is not big enough, go to check the next
1623 } // if(totest == tofindb) else if(nsize == 0) else ...
1626 // have enough space in the block, malloc
1630 // no enough space yet, try to append next continuous block
1631 // TODO may consider to go to next local block?
1633 } // if(size > isize) else ...
1635 } // if(nsize < bound)
1637 // no space in the block, go to check the next block
1644 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1647 } // if(islocal) else ...
1648 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1649 // no more local mem, do not find suitable block on local mem
1650 // try to malloc shared memory assigned to the neighbour cores
1653 if(k >= NUM_CORES2TEST) {
1654 // no more memory available on either coren or its neighbour cores
1656 goto memsearchresult;
1658 } while(core2test[gccorenum][k] == -1);
1662 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1663 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1667 if(foundsmem == 1) {
1668 // find suitable block
1669 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1670 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1671 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1673 // set bamboo_smemtbl
1674 for(i = tofindb; i <= totest; i++) {
1675 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1677 } else if(foundsmem == 2) {
1678 // no suitable block
1683 } // void * fixedmalloc_I(int, int, int *)
1684 #endif // #ifdef SMEMF
1687 // Allocate the local shared memory to each core with the highest priority,
1688 // if a core has used up its local shared memory, try to allocate the
1689 // shared memory that belong to its neighbours first, if failed, check
1690 // current memory allocation rate, if it has already reached the threshold,
1691 // start gc, otherwise, allocate the shared memory globally. If all the
1692 // shared memory has been used up, start gc.
1693 void * mixedmalloc_I(int coren,
1700 int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
1702 int tofindb = gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1703 int totest = tofindb;
1704 int bound = BAMBOO_SMEM_SIZE_L;
1708 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1709 int nsize = bamboo_smemtbl[totest];
1710 bool islocal = true;
1712 bool tocheck = true;
1713 // have some space in the block
1714 if(totest == tofindb) {
1715 // the first partition
1716 size = bound - nsize;
1717 } else if(nsize == 0) {
1718 // an empty partition, can be appended
1721 // not an empty partition, can not be appended
1722 // the last continuous block is not big enough, go to check the next
1726 } // if(totest == tofindb) else if(nsize == 0) else ...
1729 // have enough space in the block, malloc
1733 // no enough space yet, try to append next continuous block
1734 // TODO may consider to go to next local block?
1736 } // if(size > isize) else ...
1738 } // if(nsize < bound)
1740 // no space in the block, go to check the next block
1747 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1750 } // if(islocal) else ...
1751 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1752 // no more local mem, do not find suitable block on local mem
1753 // try to malloc shared memory assigned to the neighbour cores
1756 if(k >= NUM_CORES2TEST) {
1757 if(gcmem_mixed_usedmem >= gcmem_mixed_threshold) {
1758 // no more memory available on either coren or its neighbour cores
1760 goto memmixedsearchresult;
1762 // try allocate globally
1763 mem = globalmalloc_I(coren, isize, allocsize);
1767 } while(core2test[gccorenum][k] == -1);
1771 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1772 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1775 memmixedsearchresult:
1776 if(foundsmem == 1) {
1777 // find suitable block
1778 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1779 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1780 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1782 // set bamboo_smemtbl
1783 for(i = tofindb; i <= totest; i++) {
1784 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1786 gcmem_mixed_usedmem += size;
1787 if(tofindb == bamboo_free_block) {
1788 bamboo_free_block = totest+1;
1790 } else if(foundsmem == 2) {
1791 // no suitable block
1796 } // void * mixedmalloc_I(int, int, int *)
1797 #endif // #ifdef SMEMM
1799 // Allocate all the memory chunks globally, do not consider the host cores
1800 // When all the shared memory are used up, start gc.
1801 void * globalmalloc_I(int coren,
1805 int tofindb = bamboo_free_block; //0;
1806 int totest = tofindb;
1807 int bound = BAMBOO_SMEM_SIZE_L;
1810 if(tofindb > gcnumblock-1-bamboo_reserved_smem) {
1811 // Out of shared memory
1816 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1817 int nsize = bamboo_smemtbl[totest];
1818 bool isnext = false;
1820 bool tocheck = true;
1821 // have some space in the block
1822 if(totest == tofindb) {
1823 // the first partition
1824 size = bound - nsize;
1825 } else if(nsize == 0) {
1826 // an empty partition, can be appended
1829 // not an empty partition, can not be appended
1830 // the last continuous block is not big enough, start another block
1833 } // if(totest == tofindb) else if(nsize == 0) else ...
1836 // have enough space in the block, malloc
1839 } // if(size > isize)
1843 } // if(nsize < bound) else ...
1845 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1846 // no more local mem, do not find suitable block
1849 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1851 // start another block
1856 if(foundsmem == 1) {
1857 // find suitable block
1858 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1859 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1860 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1862 // set bamboo_smemtbl
1863 for(int i = tofindb; i <= totest; i++) {
1864 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1866 if(tofindb == bamboo_free_block) {
1867 bamboo_free_block = totest+1;
1869 } else if(foundsmem == 2) {
1870 // no suitable block
1876 } // void * globalmalloc_I(int, int, int *)
1877 #endif // #ifdef MULTICORE_GC
1879 // malloc from the shared memory
1880 void * smemalloc_I(int coren,
1885 int isize = size+(BAMBOO_CACHE_LINE_SIZE);
1887 // go through the bamboo_smemtbl for suitable partitions
1888 switch(bamboo_smem_mode) {
1890 mem = localmalloc_I(coren, isize, allocsize);
1896 mem = fixedmalloc_I(coren, isize, allocsize);
1898 // not supported yet
1899 BAMBOO_EXIT(0xe001);
1906 mem = mixedmalloc_I(coren, isize, allocsize);
1908 // not supported yet
1909 BAMBOO_EXIT(0xe002);
1915 mem = globalmalloc_I(coren, isize, allocsize);
1925 int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size) : (BAMBOO_SMEM_SIZE);
1926 if(toallocate > bamboo_free_smem_size) {
1930 mem = (void *)bamboo_free_smemp;
1931 bamboo_free_smemp = ((void*)bamboo_free_smemp) + toallocate;
1932 bamboo_free_smem_size -= toallocate;
1934 *allocsize = toallocate;
1936 #endif // MULTICORE_GC
1937 // no enough shared global memory
1942 // inform other cores to stop and wait for gc
1944 for(int i = 0; i < NUMCORESACTIVE; i++) {
1945 // reuse the gcnumsendobjs & gcnumreceiveobjs
1946 gccorestatus[i] = 1;
1947 gcnumsendobjs[0][i] = 0;
1948 gcnumreceiveobjs[0][i] = 0;
1950 for(int i = 0; i < NUMCORESACTIVE; i++) {
1951 if(i != BAMBOO_NUM_OF_CORE) {
1952 if(BAMBOO_CHECK_SEND_MODE()) {
1953 cache_msg_1(i, GCSTARTPRE);
1955 send_msg_1(i, GCSTARTPRE, true);
1962 BAMBOO_DEBUGPRINT(0xa001);
1963 BAMBOO_EXIT(0xa001);
1967 } // void * smemalloc_I(int, int, int)
1969 INLINE int checkMsgLength_I(int size) {
1972 BAMBOO_DEBUGPRINT(0xcccc);
1975 int type = msgdata[msgdataindex];
1983 case GCSTARTMAPINFO:
1988 #ifdef GC_CACHE_ADAPT
1990 #endif // GC_CACHE_ADAPT
1991 #endif // MULTICORE_GC
2000 case GCSTARTCOMPACT:
2003 case GCFINISHMAPINFO:
2005 #ifdef GC_CACHE_ADAPT
2007 #endif // GC_CACHE_ADAPT
2008 #endif // MULTICORE_GC
2031 case REDIRECTGROUNT:
2033 case REDIRECTRELEASE:
2050 case GCFINISHCOMPACT:
2064 case TRANSOBJ: // nonfixed size
2070 msglength = msgdata[msgdataindex+1];
2079 BAMBOO_DEBUGPRINT_REG(type);
2080 BAMBOO_DEBUGPRINT_REG(size);
2081 BAMBOO_DEBUGPRINT_REG(msgdataindex);
2082 BAMBOO_DEBUGPRINT_REG(msgdatalast);
2083 BAMBOO_DEBUGPRINT_REG(msgdatafull);
2086 BAMBOO_DEBUGPRINT(msgdata[msgdataindex+i]);
2088 BAMBOO_EXIT(0xd005);
2094 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
2099 BAMBOO_DEBUGPRINT(0xffff);
2105 INLINE void processmsg_transobj_I() {
2106 #ifdef PROFILE_INTERRUPT
2107 /*if(!interruptInfoOverflow) {
2108 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
2109 interruptInfoArray[interruptInfoIndex] = intInfo;
2110 intInfo->startTime = BAMBOO_GET_EXE_TIME();
2111 intInfo->endTime = -1;
2115 struct transObjInfo * transObj=RUNMALLOC_I(sizeof(struct transObjInfo));
2119 BAMBOO_DEBUGPRINT(0xe880);
2122 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2124 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
2126 BAMBOO_EXIT(0xa002);
2128 // store the object and its corresponding queue info, enqueue it later
2129 transObj->objptr = (void *)msgdata[msgdataindex]; //[2]
2131 transObj->length = (msglength - 3) / 2;
2132 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
2133 for(k = 0; k < transObj->length; ++k) {
2134 transObj->queues[2*k] = msgdata[msgdataindex]; //[3+2*k];
2138 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
2141 transObj->queues[2*k+1] = msgdata[msgdataindex]; //[3+2*k+1];
2145 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
2149 // check if there is an existing duplicate item
2151 struct QueueItem * qitem = getHead(&objqueue);
2152 struct QueueItem * prev = NULL;
2153 while(qitem != NULL) {
2154 struct transObjInfo * tmpinfo =
2155 (struct transObjInfo *)(qitem->objectptr);
2156 if(tmpinfo->objptr == transObj->objptr) {
2157 // the same object, remove outdate one
2158 RUNFREE(tmpinfo->queues);
2160 removeItem(&objqueue, qitem);
2166 qitem = getHead(&objqueue);
2168 qitem = getNextQueueItem(prev);
2171 addNewItem_I(&objqueue, (void *)transObj);
2173 ++(self_numreceiveobjs);
2176 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
2177 // set the gcprecheck to enable checking again
2180 // send a update pregc information msg to the master core
2181 if(BAMBOO_CHECK_SEND_MODE()) {
2182 cache_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
2183 self_numsendobjs, self_numreceiveobjs);
2185 send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
2186 self_numsendobjs, self_numreceiveobjs, true);
2191 #ifdef PROFILE_INTERRUPT
2192 /*if(!interruptInfoOverflow) {
2193 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
2194 interruptInfoIndex++;
2195 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
2196 interruptInfoOverflow = true;
2202 INLINE void processmsg_transtall_I() {
2203 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2204 // non startup core can not receive stall msg
2206 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
2208 BAMBOO_EXIT(0xa003);
2210 int num_core = msgdata[msgdataindex]; //[1]
2212 if(num_core < NUMCORESACTIVE) {
2215 BAMBOO_DEBUGPRINT(0xe881);
2218 corestatus[num_core] = 0;
2219 numsendobjs[num_core] = msgdata[msgdataindex]; //[2];
2221 numreceiveobjs[num_core] = msgdata[msgdataindex]; //[3];
2226 #ifndef MULTICORE_GC
2227 INLINE void processmsg_lockrequest_I() {
2228 // check to see if there is a lock exist for the required obj
2229 // msgdata[1] -> lock type
2230 int locktype = msgdata[msgdataindex]; //[1];
2232 int data2 = msgdata[msgdataindex]; // obj pointer
2234 int data3 = msgdata[msgdataindex]; // lock
2236 int data4 = msgdata[msgdataindex]; // request core
2238 // -1: redirected, 0: approved, 1: denied
2239 int deny=processlockrequest(locktype, data3, data2, data4, data4, true);
2241 // this lock request is redirected
2244 // send response msg
2245 // for 32 bit machine, the size is always 4 words, cache the msg first
2246 int tmp = deny==1 ? LOCKDENY : LOCKGROUNT;
2247 if(BAMBOO_CHECK_SEND_MODE()) {
2248 cache_msg_4(data4, tmp, locktype, data2, data3);
2250 send_msg_4(data4, tmp, locktype, data2, data3, true);
2255 INLINE void processmsg_lockgrount_I() {
2257 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2259 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
2261 BAMBOO_EXIT(0xa004);
2263 int data2 = msgdata[msgdataindex];
2265 int data3 = msgdata[msgdataindex];
2267 if((lockobj == data2) && (lock2require == data3)) {
2270 BAMBOO_DEBUGPRINT(0xe882);
2279 // conflicts on lockresults
2281 BAMBOO_DEBUGPRINT_REG(data2);
2283 BAMBOO_EXIT(0xa005);
2287 INLINE void processmsg_lockdeny_I() {
2289 int data2 = msgdata[msgdataindex];
2291 int data3 = msgdata[msgdataindex];
2293 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2295 BAMBOO_DEBUGPRINT_REG(data2);
2297 BAMBOO_EXIT(0xa006);
2299 if((lockobj == data2) && (lock2require == data3)) {
2302 BAMBOO_DEBUGPRINT(0xe883);
2311 // conflicts on lockresults
2313 BAMBOO_DEBUGPRINT_REG(data2);
2315 BAMBOO_EXIT(0xa007);
2319 INLINE void processmsg_lockrelease_I() {
2320 int data1 = msgdata[msgdataindex];
2322 int data2 = msgdata[msgdataindex];
2324 // receive lock release msg
2325 processlockrelease(data1, data2, 0, false);
2328 INLINE void processmsg_redirectlock_I() {
2329 // check to see if there is a lock exist for the required obj
2330 int data1 = msgdata[msgdataindex];
2331 MSG_INDEXINC_I(); //msgdata[1]; // lock type
2332 int data2 = msgdata[msgdataindex];
2333 MSG_INDEXINC_I(); //msgdata[2]; // obj pointer
2334 int data3 = msgdata[msgdataindex];
2335 MSG_INDEXINC_I(); //msgdata[3]; // redirect lock
2336 int data4 = msgdata[msgdataindex];
2337 MSG_INDEXINC_I(); //msgdata[4]; // root request core
2338 int data5 = msgdata[msgdataindex];
2339 MSG_INDEXINC_I(); //msgdata[5]; // request core
2340 int deny = processlockrequest(data1, data3, data2, data5, data4, true);
2342 // this lock request is redirected
2345 // send response msg
2346 // for 32 bit machine, the size is always 4 words, cache the msg first
2347 if(BAMBOO_CHECK_SEND_MODE()) {
2348 cache_msg_4(data4, deny==1 ? REDIRECTDENY : REDIRECTGROUNT,
2349 data1, data2, data3);
2351 send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
2352 data1, data2, data3, true);
2357 INLINE void processmsg_redirectgrount_I() {
2359 int data2 = msgdata[msgdataindex];
2361 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2363 BAMBOO_DEBUGPRINT_REG(data2);
2365 BAMBOO_EXIT(0xa00a);
2367 if(lockobj == data2) {
2370 BAMBOO_DEBUGPRINT(0xe891);
2373 int data3 = msgdata[msgdataindex];
2377 RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
2382 // conflicts on lockresults
2384 BAMBOO_DEBUGPRINT_REG(data2);
2386 BAMBOO_EXIT(0xa00b);
2390 INLINE void processmsg_redirectdeny_I() {
2392 int data2 = msgdata[msgdataindex];
2394 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2396 BAMBOO_DEBUGPRINT_REG(data2);
2398 BAMBOO_EXIT(0xa00c);
2400 if(lockobj == data2) {
2403 BAMBOO_DEBUGPRINT(0xe892);
2412 // conflicts on lockresults
2414 BAMBOO_DEBUGPRINT_REG(data2);
2416 BAMBOO_EXIT(0xa00d);
2420 INLINE void processmsg_redirectrelease_I() {
2421 int data1 = msgdata[msgdataindex];
2423 int data2 = msgdata[msgdataindex];
2425 int data3 = msgdata[msgdataindex];
2427 processlockrelease(data1, data2, data3, true);
2429 #endif // #ifndef MULTICORE_GC
2432 INLINE void processmsg_profileoutput_I() {
2433 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
2434 // startup core can not receive profile output finish msg
2435 BAMBOO_EXIT(0xa008);
2439 BAMBOO_DEBUGPRINT(0xe885);
2443 totalexetime = msgdata[msgdataindex]; //[1]
2446 BAMBOO_DEBUGPRINT_REG(dot_num);
2448 outputProfileData();
2450 // cache the msg first
2451 if(BAMBOO_CHECK_SEND_MODE()) {
2452 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
2454 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE, true);
2458 INLINE void processmsg_profilefinish_I() {
2459 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2460 // non startup core can not receive profile output finish msg
2462 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex /*1*/]);
2464 BAMBOO_EXIT(0xa009);
2468 BAMBOO_DEBUGPRINT(0xe886);
2471 int data1 = msgdata[msgdataindex];
2473 profilestatus[data1] = 0;
2475 #endif // #ifdef PROFILE
2477 INLINE void processmsg_statusconfirm_I() {
2478 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2479 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2480 // wrong core to receive such msg
2481 BAMBOO_EXIT(0xa00e);
2483 // send response msg
2486 BAMBOO_DEBUGPRINT(0xe887);
2489 // cache the msg first
2490 if(BAMBOO_CHECK_SEND_MODE()) {
2491 cache_msg_5(STARTUPCORE, STATUSREPORT,
2492 busystatus ? 1 : 0, BAMBOO_NUM_OF_CORE,
2493 self_numsendobjs, self_numreceiveobjs);
2495 send_msg_5(STARTUPCORE, STATUSREPORT, busystatus?1:0,
2496 BAMBOO_NUM_OF_CORE, self_numsendobjs,
2497 self_numreceiveobjs, true);
2502 INLINE void processmsg_statusreport_I() {
2503 int data1 = msgdata[msgdataindex];
2505 int data2 = msgdata[msgdataindex];
2507 int data3 = msgdata[msgdataindex];
2509 int data4 = msgdata[msgdataindex];
2511 // receive a status confirm info
2512 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2513 // wrong core to receive such msg
2515 BAMBOO_DEBUGPRINT_REG(data2);
2517 BAMBOO_EXIT(0xa00f);
2521 BAMBOO_DEBUGPRINT(0xe888);
2527 corestatus[data2] = data1;
2528 numsendobjs[data2] = data3;
2529 numreceiveobjs[data2] = data4;
2533 INLINE void processmsg_terminate_I() {
2536 BAMBOO_DEBUGPRINT(0xe889);
2541 #ifdef GC_CACHE_ADAPT
2542 bamboo_mask_timer_intr(); // disable the TILE_TIMER interrupt
2543 #endif // GC_CACHE_ADAPT
2544 #endif // MULTICORE_GC
2548 INLINE void processmsg_memrequest_I() {
2549 #ifdef PROFILE_INTERRUPT
2550 /*if(!interruptInfoOverflow) {
2551 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
2552 interruptInfoArray[interruptInfoIndex] = intInfo;
2553 intInfo->startTime = BAMBOO_GET_EXE_TIME();
2554 intInfo->endTime = -1;
2557 int data1 = msgdata[msgdataindex];
2559 int data2 = msgdata[msgdataindex];
2561 // receive a shared memory request msg
2562 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2563 // wrong core to receive such msg
2565 BAMBOO_DEBUGPRINT_REG(data2);
2567 BAMBOO_EXIT(0xa010);
2571 BAMBOO_DEBUGPRINT(0xe88a);
2578 // is currently doing gc, dump this msg
2579 if(INITPHASE == gcphase) {
2580 // if still in the initphase of gc, send a startinit msg again,
2581 // cache the msg first
2582 if(BAMBOO_CHECK_SEND_MODE()) {
2583 cache_msg_1(data2, GCSTARTINIT);
2585 send_msg_1(data2, GCSTARTINIT, true);
2590 mem = smemalloc_I(data2, data1, &allocsize);
2592 // send the start_va to request core, cache the msg first
2593 if(BAMBOO_CHECK_SEND_MODE()) {
2594 cache_msg_3(data2, MEMRESPONSE, mem, allocsize);
2596 send_msg_3(data2, MEMRESPONSE, mem, allocsize, true);
2599 // if mem == NULL, the gcflag of the startup core has been set
2600 // and all the other cores have been informed to start gc
2605 #ifdef PROFILE_INTERRUPT
2606 /*if(!interruptInfoOverflow) {
2607 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
2608 interruptInfoIndex++;
2609 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
2610 interruptInfoOverflow = true;
2616 INLINE void processmsg_memresponse_I() {
2617 int data1 = msgdata[msgdataindex];
2619 int data2 = msgdata[msgdataindex];
2621 // receive a shared memory response msg
2624 BAMBOO_DEBUGPRINT(0xe88b);
2628 // if is currently doing gc, dump this msg
2632 bamboo_smem_size = 0;
2635 bamboo_smem_zero_top = 0;
2639 // fill header to store the size of this mem block
2640 BAMBOO_MEMSET_WH(data1, '\0', BAMBOO_CACHE_LINE_SIZE);
2641 //memset(data1, 0, BAMBOO_CACHE_LINE_SIZE);
2642 (*((int*)data1)) = data2;
2643 bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
2644 bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
2645 bamboo_smem_zero_top = bamboo_cur_msp;
2647 bamboo_smem_size = data2;
2648 bamboo_cur_msp =(void*)(data1);
2658 INLINE void processmsg_gcstartpre_I() {
2660 // already stall for gc
2661 // send a update pregc information msg to the master core
2662 if(BAMBOO_CHECK_SEND_MODE()) {
2663 cache_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
2664 self_numsendobjs, self_numreceiveobjs);
2666 send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
2667 self_numsendobjs, self_numreceiveobjs, true);
2670 // the first time to be informed to start gc
2673 // is waiting for response of mem request
2674 // let it return NULL and start gc
2675 bamboo_smem_size = 0;
2676 bamboo_cur_msp = NULL;
2678 bamboo_smem_zero_top = NULL;
2683 INLINE void processmsg_gcstartinit_I() {
2684 gcphase = INITPHASE;
2687 INLINE void processmsg_gcstart_I() {
2690 BAMBOO_DEBUGPRINT(0xe88c);
2694 gcphase = MARKPHASE;
2697 INLINE void processmsg_gcstartcompact_I() {
2698 gcblock2fill = msgdata[msgdataindex];
2699 MSG_INDEXINC_I(); //msgdata[1];
2700 gcphase = COMPACTPHASE;
2703 INLINE void processmsg_gcstartmapinfo_I() {
2707 INLINE void processmsg_gcstartflush_I() {
2708 gcphase = FLUSHPHASE;
2711 INLINE void processmsg_gcfinishpre_I() {
2712 int data1 = msgdata[msgdataindex];
2714 int data2 = msgdata[msgdataindex];
2716 int data3 = msgdata[msgdataindex];
2718 // received a init phase finish msg
2719 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2720 // non startup core can not receive this msg
2722 BAMBOO_DEBUGPRINT_REG(data1);
2724 BAMBOO_EXIT(0xb000);
2726 // All cores should do init GC
2730 gccorestatus[data1] = 0;
2731 gcnumsendobjs[0][data1] = data2;
2732 gcnumreceiveobjs[0][data1] = data3;
2735 INLINE void processmsg_gcfinishinit_I() {
2736 int data1 = msgdata[msgdataindex];
2738 // received a init phase finish msg
2739 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2740 // non startup core can not receive this msg
2742 BAMBOO_DEBUGPRINT_REG(data1);
2744 BAMBOO_EXIT(0xb001);
2747 BAMBOO_DEBUGPRINT(0xe88c);
2748 BAMBOO_DEBUGPRINT_REG(data1);
2750 // All cores should do init GC
2751 if(data1 < NUMCORESACTIVE) {
2752 gccorestatus[data1] = 0;
2756 INLINE void processmsg_gcfinishmark_I() {
2757 int data1 = msgdata[msgdataindex];
2759 int data2 = msgdata[msgdataindex];
2761 int data3 = msgdata[msgdataindex];
2763 // received a mark phase finish msg
2764 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2765 // non startup core can not receive this msg
2767 BAMBOO_DEBUGPRINT_REG(data1);
2769 BAMBOO_EXIT(0xb002);
2771 // all cores should do mark
2772 if(data1 < NUMCORESACTIVE) {
2773 gccorestatus[data1] = 0;
2774 int entry_index = 0;
2777 entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
2780 entry_index = gcnumsrobjs_index;
2782 gcnumsendobjs[entry_index][data1] = data2;
2783 gcnumreceiveobjs[entry_index][data1] = data3;
2787 INLINE void processmsg_gcfinishcompact_I() {
2788 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2789 // non startup core can not receive this msg
2792 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
2794 BAMBOO_EXIT(0xb003);
2796 int cnum = msgdata[msgdataindex];
2797 MSG_INDEXINC_I(); //msgdata[1];
2798 int filledblocks = msgdata[msgdataindex];
2799 MSG_INDEXINC_I(); //msgdata[2];
2800 int heaptop = msgdata[msgdataindex];
2801 MSG_INDEXINC_I(); //msgdata[3];
2802 int data4 = msgdata[msgdataindex];
2803 MSG_INDEXINC_I(); //msgdata[4];
2804 // only gc cores need to do compact
2805 if(cnum < NUMCORES4GC) {
2806 if(COMPACTPHASE == gcphase) {
2807 gcfilledblocks[cnum] = filledblocks;
2808 gcloads[cnum] = heaptop;
2815 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
2816 // cache the msg first
2817 if(BAMBOO_CHECK_SEND_MODE()) {
2818 cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
2820 send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove, true);
2824 gccorestatus[cnum] = 0;
2826 } // if(cnum < NUMCORES4GC)
2829 INLINE void processmsg_gcfinishmapinfo_I() {
2830 int data1 = msgdata[msgdataindex];
2832 // received a map phase finish msg
2833 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2834 // non startup core can not receive this msg
2836 BAMBOO_DEBUGPRINT_REG(data1);
2838 BAMBOO_EXIT(0xb004);
2840 // all cores should do flush
2841 if(data1 < NUMCORES4GC) {
2842 gccorestatus[data1] = 0;
2847 INLINE void processmsg_gcfinishflush_I() {
2848 int data1 = msgdata[msgdataindex];
2850 // received a flush phase finish msg
2851 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2852 // non startup core can not receive this msg
2854 BAMBOO_DEBUGPRINT_REG(data1);
2856 BAMBOO_EXIT(0xb005);
2858 // all cores should do flush
2859 if(data1 < NUMCORESACTIVE) {
2860 gccorestatus[data1] = 0;
2864 INLINE void processmsg_gcmarkconfirm_I() {
2865 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2866 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2867 // wrong core to receive such msg
2868 BAMBOO_EXIT(0xb006);
2870 // send response msg, cahce the msg first
2871 if(BAMBOO_CHECK_SEND_MODE()) {
2872 cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2873 gcbusystatus, gcself_numsendobjs,
2874 gcself_numreceiveobjs);
2876 send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2877 gcbusystatus, gcself_numsendobjs,
2878 gcself_numreceiveobjs, true);
2883 INLINE void processmsg_gcmarkreport_I() {
2884 int data1 = msgdata[msgdataindex];
2886 int data2 = msgdata[msgdataindex];
2888 int data3 = msgdata[msgdataindex];
2890 int data4 = msgdata[msgdataindex];
2892 // received a marked phase finish confirm response msg
2893 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2894 // wrong core to receive such msg
2896 BAMBOO_DEBUGPRINT_REG(data2);
2898 BAMBOO_EXIT(0xb007);
2900 int entry_index = 0;
2904 entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
2906 // can never reach here
2908 entry_index = gcnumsrobjs_index;
2910 gccorestatus[data1] = data2;
2911 gcnumsendobjs[entry_index][data1] = data3;
2912 gcnumreceiveobjs[entry_index][data1] = data4;
2916 INLINE void processmsg_gcmarkedobj_I() {
2917 int data1 = msgdata[msgdataindex];
2919 // received a markedObj msg
2920 if(((int *)data1)[6] == INIT) {
2921 // this is the first time that this object is discovered,
2922 // set the flag as DISCOVERED
2923 ((int *)data1)[6] = DISCOVERED;
2924 gc_enqueue_I(data1);
2926 // set the remote flag
2927 ((int *)data1)[6] |= REMOTEM;
2928 gcself_numreceiveobjs++;
2929 gcbusystatus = true;
2932 INLINE void processmsg_gcmovestart_I() {
2934 gcdstcore = msgdata[msgdataindex];
2935 MSG_INDEXINC_I(); //msgdata[1];
2936 gcmovestartaddr = msgdata[msgdataindex];
2937 MSG_INDEXINC_I(); //msgdata[2];
2938 gcblock2fill = msgdata[msgdataindex];
2939 MSG_INDEXINC_I(); //msgdata[3];
2942 INLINE void processmsg_gcmaprequest_I() {
2944 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2946 void * dstptr = NULL;
2947 int data1 = msgdata[msgdataindex];
2950 // TODO unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2952 #ifdef LOCALHASHTBL_TEST
2953 RuntimeHashget(gcpointertbl, data1, &dstptr);
2955 dstptr = mgchashSearch(gcpointertbl, data1);
2957 //MGCHashget(gcpointertbl, data1, &dstptr);
2959 // TODO flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2961 int data2 = msgdata[msgdataindex];
2964 // TODO unsigned long long ttimei = BAMBOO_GET_EXE_TIME();
2966 if(NULL == dstptr) {
2967 // no such pointer in this core, something is wrong
2969 BAMBOO_DEBUGPRINT_REG(data1);
2970 BAMBOO_DEBUGPRINT_REG(data2);
2972 BAMBOO_EXIT(0xb008);
2973 //assume that the object was not moved, use the original address
2974 /*if(isMsgSending) {
2975 cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2977 send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2980 // send back the mapping info, cache the msg first
2981 if(BAMBOO_CHECK_SEND_MODE()) {
2982 cache_msg_3(data2, GCMAPINFO, data1, (int)dstptr);
2984 send_msg_3(data2, GCMAPINFO, data1, (int)dstptr, true);
2988 // TODO flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimei;
2989 //num_mapinforequest_i++;
2993 INLINE void processmsg_gcmapinfo_I() {
2995 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2997 int data1 = msgdata[msgdataindex];
2999 gcmappedobj = msgdata[msgdataindex]; // [2]
3001 #ifdef LOCALHASHTBL_TEST
3002 RuntimeHashadd_I(gcpointertbl, data1, gcmappedobj);
3004 mgchashInsert_I(gcpointertbl, data1, gcmappedobj);
3006 //MGCHashadd_I(gcpointertbl, data1, gcmappedobj);
3007 if(data1 == gcobj2map) {
3011 //flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
3015 INLINE void processmsg_gcmaptbl_I() {
3016 int data1 = msgdata[msgdataindex];
3018 int data2 = msgdata[msgdataindex];
3020 gcrpointertbls[data2] = (mgcsharedhashtbl_t *)data1; //(struct GCSharedHash *)data1;
3023 INLINE void processmsg_gclobjinfo_I() {
3026 int data1 = msgdata[msgdataindex];
3028 int data2 = msgdata[msgdataindex];
3030 if(BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1) {
3032 BAMBOO_DEBUGPRINT_REG(data2);
3034 BAMBOO_EXIT(0xb009);
3036 // store the mark result info
3038 gcloads[cnum] = msgdata[msgdataindex];
3039 MSG_INDEXINC_I(); // msgdata[3];
3040 int data4 = msgdata[msgdataindex];
3042 if(gcheaptop < data4) {
3045 // large obj info here
3046 for(int k = 5; k < data1; ) {
3047 int lobj = msgdata[msgdataindex];
3048 MSG_INDEXINC_I(); //msgdata[k++];
3049 int length = msgdata[msgdataindex];
3050 MSG_INDEXINC_I(); //msgdata[k++];
3051 gc_lobjenqueue_I(lobj, length, cnum);
3053 } // for(int k = 5; k < msgdata[1];)
3056 INLINE void processmsg_gclobjmapping_I() {
3057 int data1 = msgdata[msgdataindex];
3059 int data2 = msgdata[msgdataindex];
3061 #ifdef LOCALHASHTBL_TEST
3062 RuntimeHashadd_I(gcpointertbl, data1, data2);
3064 mgchashInsert_I(gcpointertbl, data1, data2);
3066 //MGCHashadd_I(gcpointertbl, data1, data2);
3067 mgcsharedhashInsert_I(gcsharedptbl, data1, data2);
3071 INLINE void processmsg_gcprofiles_I() {
3072 int data1 = msgdata[msgdataindex];
3074 int data2 = msgdata[msgdataindex];
3076 int data3 = msgdata[msgdataindex];
3078 gc_num_obj += data1;
3079 gc_num_liveobj += data2;
3080 gc_num_forwardobj += data3;
3083 #endif // GC_PROFILE
3085 #ifdef GC_CACHE_ADAPT
3086 INLINE void processmsg_gcstartpref_I() {
3087 gcphase = PREFINISHPHASE;
3090 INLINE void processmsg_gcfinishpref_I() {
3091 int data1 = msgdata[msgdataindex];
3093 // received a flush phase finish msg
3094 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
3095 // non startup core can not receive this msg
3097 BAMBOO_DEBUGPRINT_REG(data1);
3099 BAMBOO_EXIT(0xb00a);
3101 // all cores should do flush
3102 if(data1 < NUMCORESACTIVE) {
3103 gccorestatus[data1] = 0;
3106 #endif // GC_CACHE_ADAPT
3107 #endif // #ifdef MULTICORE_GC
3109 // receive object transferred from other cores
3110 // or the terminate message from other cores
3111 // Should be invoked in critical sections!!
3112 // NOTICE: following format is for threadsimulate version only
3113 // RAW version please see previous description
3114 // format: type + object
3115 // type: -1--stall msg
3117 // return value: 0--received an object
3118 // 1--received nothing
3119 // 2--received a Stall Msg
3120 // 3--received a lock Msg
3121 // RAW version: -1 -- received nothing
3122 // otherwise -- received msg type
3123 int receiveObject(int send_port_pending) {
3124 #ifdef PROFILE_INTERRUPT
3125 if(!interruptInfoOverflow) {
3126 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
3127 interruptInfoArray[interruptInfoIndex] = intInfo;
3128 intInfo->startTime = BAMBOO_GET_EXE_TIME();
3129 intInfo->endTime = -1;
3133 // get the incoming msgs
3134 if(receiveMsg(send_port_pending) == -1) {
3138 // processing received msgs
3140 MSG_REMAINSIZE_I(&size);
3141 if((size == 0) || (checkMsgLength_I(size) == -1)) {
3143 // have new coming msg
3144 if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
3151 if(msglength <= size) {
3152 // have some whole msg
3154 type = msgdata[msgdataindex]; //[0]
3156 msgdatafull = false;
3158 //tprintf("msg type: %x\n", type);
3161 // receive a object transfer msg
3162 processmsg_transobj_I();
3167 // receive a stall msg
3168 processmsg_transtall_I();
3172 // GC version have no lock msgs
3173 #ifndef MULTICORE_GC
3175 // receive lock request msg, handle it right now
3176 processmsg_lockrequest_I();
3178 } // case LOCKREQUEST
3181 // receive lock grount msg
3182 processmsg_lockgrount_I();
3184 } // case LOCKGROUNT
3187 // receive lock deny msg
3188 processmsg_lockdeny_I();
3193 processmsg_lockrelease_I();
3195 } // case LOCKRELEASE
3196 #endif // #ifndef MULTICORE_GC
3199 case PROFILEOUTPUT: {
3200 // receive an output profile data request msg
3201 processmsg_profileoutput_I();
3203 } // case PROFILEOUTPUT
3205 case PROFILEFINISH: {
3206 // receive a profile output finish msg
3207 processmsg_profilefinish_I();
3209 } // case PROFILEFINISH
3210 #endif // #ifdef PROFILE
3212 // GC version has no lock msgs
3213 #ifndef MULTICORE_GC
3214 case REDIRECTLOCK: {
3215 // receive a redirect lock request msg, handle it right now
3216 processmsg_redirectlock_I();
3218 } // case REDIRECTLOCK
3220 case REDIRECTGROUNT: {
3221 // receive a lock grant msg with redirect info
3222 processmsg_redirectgrount_I();
3224 } // case REDIRECTGROUNT
3226 case REDIRECTDENY: {
3227 // receive a lock deny msg with redirect info
3228 processmsg_redirectdeny_I();
3230 } // case REDIRECTDENY
3232 case REDIRECTRELEASE: {
3233 // receive a lock release msg with redirect info
3234 processmsg_redirectrelease_I();
3236 } // case REDIRECTRELEASE
3237 #endif // #ifndef MULTICORE_GC
3239 case STATUSCONFIRM: {
3240 // receive a status confirm info
3241 processmsg_statusconfirm_I();
3243 } // case STATUSCONFIRM
3245 case STATUSREPORT: {
3246 processmsg_statusreport_I();
3248 } // case STATUSREPORT
3251 // receive a terminate msg
3252 processmsg_terminate_I();
3257 processmsg_memrequest_I();
3259 } // case MEMREQUEST
3262 processmsg_memresponse_I();
3264 } // case MEMRESPONSE
3269 processmsg_gcstartpre_I();
3271 } // case GCSTARTPRE
3274 processmsg_gcstartinit_I();
3276 } // case GCSTARTINIT
3279 // receive a start GC msg
3280 processmsg_gcstart_I();
3284 case GCSTARTCOMPACT: {
3285 // a compact phase start msg
3286 processmsg_gcstartcompact_I();
3288 } // case GCSTARTCOMPACT
3290 case GCSTARTMAPINFO: {
3291 // received a flush phase start msg
3292 processmsg_gcstartmapinfo_I();
3294 } // case GCSTARTFLUSH
3296 case GCSTARTFLUSH: {
3297 // received a flush phase start msg
3298 processmsg_gcstartflush_I();
3300 } // case GCSTARTFLUSH
3303 processmsg_gcfinishpre_I();
3305 } // case GCFINISHPRE
3307 case GCFINISHINIT: {
3308 processmsg_gcfinishinit_I();
3310 } // case GCFINISHINIT
3312 case GCFINISHMARK: {
3313 processmsg_gcfinishmark_I();
3315 } // case GCFINISHMARK
3317 case GCFINISHCOMPACT: {
3318 // received a compact phase finish msg
3319 processmsg_gcfinishcompact_I();
3321 } // case GCFINISHCOMPACT
3323 case GCFINISHMAPINFO: {
3324 processmsg_gcfinishmapinfo_I();
3326 } // case GCFINISHMAPINFO
3328 case GCFINISHFLUSH: {
3329 processmsg_gcfinishflush_I();
3331 } // case GCFINISHFLUSH
3334 // received a GC finish msg
3335 gcphase = FINISHPHASE;
3339 case GCMARKCONFIRM: {
3340 // received a marked phase finish confirm request msg
3341 // all cores should do mark
3342 processmsg_gcmarkconfirm_I();
3344 } // case GCMARKCONFIRM
3346 case GCMARKREPORT: {
3347 processmsg_gcmarkreport_I();
3349 } // case GCMARKREPORT
3352 processmsg_gcmarkedobj_I();
3354 } // case GCMARKEDOBJ
3357 // received a start moving objs msg
3358 processmsg_gcmovestart_I();
3360 } // case GCMOVESTART
3362 case GCMAPREQUEST: {
3363 // received a mapping info request msg
3364 processmsg_gcmaprequest_I();
3366 } // case GCMAPREQUEST
3369 // received a mapping info response msg
3370 processmsg_gcmapinfo_I();
3375 // received a mapping tbl response msg
3376 processmsg_gcmaptbl_I();
3380 case GCLOBJREQUEST: {
3381 // received a large objs info request msg
3382 transferMarkResults_I();
3384 } // case GCLOBJREQUEST
3387 // received a large objs info response msg
3388 processmsg_gclobjinfo_I();
3390 } // case GCLOBJINFO
3392 case GCLOBJMAPPING: {
3393 // received a large obj mapping info msg
3394 processmsg_gclobjmapping_I();
3396 } // case GCLOBJMAPPING
3400 // received a gcprofiles msg
3401 processmsg_gcprofiles_I();
3404 #endif // GC_PROFILE
3406 #ifdef GC_CACHE_ADAPT
3408 // received a gcstartpref msg
3409 processmsg_gcstartpref_I();
3413 case GCFINISHPREF: {
3414 // received a gcfinishpref msg
3415 processmsg_gcfinishpref_I();
3418 #endif // GC_CACHE_ADAPT
3419 #endif // #ifdef MULTICORE_GC
3424 msglength = BAMBOO_MSG_BUF_LENGTH;
3426 //printf("++ msg: %x \n", type);
3428 if(msgdataindex != msgdatalast) {
3429 // still have available msg
3434 BAMBOO_DEBUGPRINT(0xe88d);
3438 // have new coming msg
3439 if(BAMBOO_MSG_AVAIL() != 0) {
3443 #ifdef PROFILE_INTERRUPT
3444 if(!interruptInfoOverflow) {
3445 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
3446 interruptInfoIndex++;
3447 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
3448 interruptInfoOverflow = true;
3457 BAMBOO_DEBUGPRINT(0xe88e);
3464 int enqueuetasks(struct parameterwrapper *parameter,
3465 struct parameterwrapper *prevptr,
3466 struct ___Object___ *ptr,
3468 int numenterflags) {
3469 void * taskpointerarray[MAXTASKPARAMS];
3471 //int numparams=parameter->task->numParameters;
3472 int numiterators=parameter->task->numTotal-1;
3475 struct taskdescriptor * task=parameter->task;
3477 //this add the object to parameterwrapper
3478 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
3479 numenterflags, enterflags==NULL);
3481 /* Add enqueued object to parameter vector */
3482 taskpointerarray[parameter->slot]=ptr;
3484 /* Reset iterators */
3485 for(j=0; j<numiterators; j++) {
3486 toiReset(¶meter->iterators[j]);
3489 /* Find initial state */
3490 for(j=0; j<numiterators; j++) {
3492 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3493 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3495 /* Need to backtrack */
3496 toiReset(¶meter->iterators[j]);
3500 /* Nothing to enqueue */
3506 /* Enqueue current state */
3508 struct taskparamdescriptor *tpd=
3509 RUNMALLOC(sizeof(struct taskparamdescriptor));
3511 tpd->numParameters=numiterators+1;
3512 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
3514 for(j=0; j<=numiterators; j++) {
3515 //store the actual parameters
3516 tpd->parameterArray[j]=taskpointerarray[j];
3519 if (( /*!gencontains(failedtasks, tpd)&&*/
3520 !gencontains(activetasks,tpd))) {
3521 genputtable(activetasks, tpd, tpd);
3523 RUNFREE(tpd->parameterArray);
3527 /* This loop iterates to the next parameter combination */
3528 if (numiterators==0)
3531 for(j=numiterators-1; j<numiterators; j++) {
3534 ¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3535 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3537 /* Need to backtrack */
3538 toiReset(¶meter->iterators[j]);
3542 /* Nothing more to enqueue */
3550 int enqueuetasks_I(struct parameterwrapper *parameter,
3551 struct parameterwrapper *prevptr,
3552 struct ___Object___ *ptr,
3554 int numenterflags) {
3555 void * taskpointerarray[MAXTASKPARAMS];
3557 //int numparams=parameter->task->numParameters;
3558 int numiterators=parameter->task->numTotal-1;
3563 struct taskdescriptor * task=parameter->task;
3565 //this add the object to parameterwrapper
3566 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
3567 numenterflags, enterflags==NULL);
3569 /* Add enqueued object to parameter vector */
3570 taskpointerarray[parameter->slot]=ptr;
3572 /* Reset iterators */
3573 for(j=0; j<numiterators; j++) {
3574 toiReset(¶meter->iterators[j]);
3577 /* Find initial state */
3578 for(j=0; j<numiterators; j++) {
3580 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3581 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3583 /* Need to backtrack */
3584 toiReset(¶meter->iterators[j]);
3588 /* Nothing to enqueue */
3594 /* Enqueue current state */
3596 struct taskparamdescriptor *tpd=
3597 RUNMALLOC_I(sizeof(struct taskparamdescriptor));
3599 tpd->numParameters=numiterators+1;
3600 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
3602 for(j=0; j<=numiterators; j++) {
3603 //store the actual parameters
3604 tpd->parameterArray[j]=taskpointerarray[j];
3607 if (( /*!gencontains(failedtasks, tpd)&&*/
3608 !gencontains(activetasks,tpd))) {
3609 genputtable_I(activetasks, tpd, tpd);
3611 RUNFREE(tpd->parameterArray);
3615 /* This loop iterates to the next parameter combination */
3616 if (numiterators==0)
3619 for(j=numiterators-1; j<numiterators; j++) {
3622 ¶meter->iterators[j], taskpointerarray OPTARG(failed)))
3623 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3625 /* Need to backtrack */
3626 toiReset(¶meter->iterators[j]);
3630 /* Nothing more to enqueue */
3644 int containstag(struct ___Object___ *ptr,
3645 struct ___TagDescriptor___ *tag);
3647 #ifndef MULTICORE_GC
3648 void releasewritelock_r(void * lock, void * redirectlock) {
3650 int reallock = (int)lock;
3651 targetcore = (reallock >> 5) % NUMCORES;
3654 BAMBOO_DEBUGPRINT(0xe671);
3655 BAMBOO_DEBUGPRINT_REG((int)lock);
3656 BAMBOO_DEBUGPRINT_REG(reallock);
3657 BAMBOO_DEBUGPRINT_REG(targetcore);
3660 if(targetcore == BAMBOO_NUM_OF_CORE) {
3661 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3663 BAMBOO_DEBUGPRINT(0xf001);
3665 // reside on this core
3666 if(!RuntimeHashcontainskey(locktbl, reallock)) {
3667 // no locks for this object, something is wrong
3668 BAMBOO_EXIT(0xa00b);
3671 struct LockValue * lockvalue = NULL;
3673 BAMBOO_DEBUGPRINT(0xe672);
3675 RuntimeHashget(locktbl, reallock, &rwlock_obj);
3676 lockvalue = (struct LockValue *)rwlock_obj;
3678 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
3681 lockvalue->redirectlock = (int)redirectlock;
3683 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
3686 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3688 BAMBOO_DEBUGPRINT(0xf000);
3692 // send lock release with redirect info msg
3693 // for 32 bit machine, the size is always 4 words
3694 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock,
3695 (int)redirectlock, false);
3700 void executetasks() {
3701 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
3704 struct ___Object___ * tmpparam = NULL;
3705 struct parameterdescriptor * pd=NULL;
3706 struct parameterwrapper *pw=NULL;
3716 while(hashsize(activetasks)>0) {
3718 //#ifdef GC_CACHE_ADAPT
3719 // do dtlb sampling if necessary
3720 // bamboo_dtlb_sampling_process();
3721 //#endif // GC_CACHE_ADAPT
3722 if(gcflag) gc(NULL);
3725 BAMBOO_DEBUGPRINT(0xe990);
3728 /* See if there are any active tasks */
3729 //if (hashsize(activetasks)>0) {
3732 #ifdef ACCURATEPROFILE
3733 profileTaskStart("tpd checking");
3737 //clock1 = BAMBOO_GET_EXE_TIME();
3740 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
3741 genfreekey(activetasks, currtpd);
3743 numparams=currtpd->task->numParameters;
3744 numtotal=currtpd->task->numTotal;
3746 // clear the lockRedirectTbl
3747 // (TODO, this table should be empty after all locks are released)
3749 /*for(j = 0; j < MAXTASKPARAMS; j++) {
3750 runtime_locks[j].redirectlock = 0;
3751 runtime_locks[j].value = 0;
3753 // get all required locks
3754 runtime_locklen = 0;
3755 // check which locks are needed
3756 for(i = 0; i < numparams; i++) {
3757 void * param = currtpd->parameterArray[i];
3761 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
3763 taskpointerarray[i+OFFSET]=param;
3766 if(((struct ___Object___ *)param)->lock == NULL) {
3767 tmplock = (int)param;
3769 tmplock = (int)(((struct ___Object___ *)param)->lock);
3771 // insert into the locks array
3772 for(j = 0; j < runtime_locklen; j++) {
3773 if(runtime_locks[j].value == tmplock) {
3776 } else if(runtime_locks[j].value > tmplock) {
3781 int h = runtime_locklen;
3783 runtime_locks[h].redirectlock = runtime_locks[h-1].redirectlock;
3784 runtime_locks[h].value = runtime_locks[h-1].value;
3786 runtime_locks[j].value = tmplock;
3787 runtime_locks[j].redirectlock = (int)param;
3790 } // line 2713: for(i = 0; i < numparams; i++)
3791 // grab these required locks
3793 BAMBOO_DEBUGPRINT(0xe991);
3796 //clock2 = BAMBOO_GET_EXE_TIME();
3798 for(i = 0; i < runtime_locklen; i++) {
3799 int * lock = (int *)(runtime_locks[i].redirectlock);
3801 // require locks for this parameter if it is not a startup object
3803 BAMBOO_DEBUGPRINT_REG((int)lock);
3804 BAMBOO_DEBUGPRINT_REG((int)(runtime_locks[i].value));
3807 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3809 BAMBOO_DEBUGPRINT(0xf001);
3812 //isInterrupt = false;
3815 BAMBOO_WAITING_FOR_LOCK(0);
3819 while(BAMBOO_WAITING_FOR_LOCK(0) != -1) {
3823 grount = lockresult;
3833 //isInterrupt = true;
3835 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3837 BAMBOO_DEBUGPRINT(0xf000);
3842 BAMBOO_DEBUGPRINT(0xe992);
3843 BAMBOO_DEBUGPRINT_REG(lock);
3845 // check if has the lock already
3846 // can not get the lock, try later
3847 // release all grabbed locks for previous parameters
3848 for(j = 0; j < i; ++j) {
3849 lock = (int*)(runtime_locks[j].redirectlock);
3850 releasewritelock(lock);
3852 genputtable(activetasks, currtpd, currtpd);
3853 if(hashsize(activetasks) == 1) {
3854 // only one task right now, wait a little while before next try
3860 #ifdef ACCURATEPROFILE
3861 // fail, set the end of the checkTaskInfo
3868 } // line 2752: for(i = 0; i < runtime_locklen; i++)
3871 clock3 = BAMBOO_GET_EXE_TIME();
3872 //tprintf("sort: %d, grab: %d \n", clock2-clock1, clock3-clock2);*/
3875 BAMBOO_DEBUGPRINT(0xe993);
3877 /* Make sure that the parameters are still in the queues */
3878 for(i=0; i<numparams; i++) {
3879 void * parameter=currtpd->parameterArray[i];
3883 BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
3884 classsize[((struct ___Object___ *)parameter)->type]);
3886 tmpparam = (struct ___Object___ *)parameter;
3887 pd=currtpd->task->descriptorarray[i];
3888 pw=(struct parameterwrapper *) pd->queue;
3889 /* Check that object is still in queue */
3891 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
3893 BAMBOO_DEBUGPRINT(0xe994);
3894 BAMBOO_DEBUGPRINT_REG(parameter);
3896 // release grabbed locks
3897 for(j = 0; j < runtime_locklen; ++j) {
3898 int * lock = (int *)(runtime_locks[j].redirectlock);
3899 releasewritelock(lock);
3901 RUNFREE(currtpd->parameterArray);
3907 /* Check if the object's flags still meets requirements */
3911 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
3912 andmask=pw->intarray[tmpi*2];
3913 checkmask=pw->intarray[tmpi*2+1];
3914 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
3920 // flags are never suitable
3921 // remove this obj from the queue
3923 int UNUSED, UNUSED2;
3926 BAMBOO_DEBUGPRINT(0xe995);
3927 BAMBOO_DEBUGPRINT_REG(parameter);
3929 ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
3930 (int *) &enterflags, &UNUSED, &UNUSED2);
3931 ObjectHashremove(pw->objectset, (int)parameter);
3932 if (enterflags!=NULL)
3933 RUNFREE(enterflags);
3934 // release grabbed locks
3935 for(j = 0; j < runtime_locklen; ++j) {
3936 int * lock = (int *)(runtime_locks[j].redirectlock);
3937 releasewritelock(lock);
3939 RUNFREE(currtpd->parameterArray);
3943 #ifdef ACCURATEPROFILE
3944 // fail, set the end of the checkTaskInfo
3949 } // line 2878: if (!ismet)
3953 /* Check that object still has necessary tags */
3954 for(j=0; j<pd->numbertags; j++) {
3955 int slotid=pd->tagarray[2*j]+numparams;
3956 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
3957 if (!containstag(parameter, tagd)) {
3959 BAMBOO_DEBUGPRINT(0xe996);
3962 // release grabbed locks
3964 for(tmpj = 0; tmpj < runtime_locklen; ++tmpj) {
3965 int * lock = (int *)(runtime_locks[tmpj].redirectlock);
3966 releasewritelock(lock);
3969 RUNFREE(currtpd->parameterArray);
3973 } // line2911: if (!containstag(parameter, tagd))
3974 } // line 2808: for(j=0; j<pd->numbertags; j++)
3976 taskpointerarray[i+OFFSET]=parameter;
3977 } // line 2824: for(i=0; i<numparams; i++)
3979 for(; i<numtotal; i++) {
3980 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
3985 /* Actually call task */
3987 ((int *)taskpointerarray)[0]=currtpd->numParameters;
3988 taskpointerarray[1]=NULL;
3991 #ifdef ACCURATEPROFILE
3992 // check finish, set the end of the checkTaskInfo
3995 profileTaskStart(currtpd->task->name);
3999 //clock4 = BAMBOO_GET_EXE_TIME();
4000 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
4003 BAMBOO_DEBUGPRINT(0xe997);
4005 ((void (*)(void **))currtpd->task->taskptr)(taskpointerarray);
4008 //clock5 = BAMBOO_GET_EXE_TIME();
4009 // tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
4012 #ifdef ACCURATEPROFILE
4013 // task finish, set the end of the checkTaskInfo
4015 // new a PostTaskInfo for the post-task execution
4016 profileTaskStart("post task execution");
4020 BAMBOO_DEBUGPRINT(0xe998);
4021 BAMBOO_DEBUGPRINT_REG(islock);
4026 BAMBOO_DEBUGPRINT(0xe999);
4028 for(i = 0; i < runtime_locklen; ++i) {
4029 void * ptr = (void *)(runtime_locks[i].redirectlock);
4030 int * lock = (int *)(runtime_locks[i].value);
4032 BAMBOO_DEBUGPRINT_REG((int)ptr);
4033 BAMBOO_DEBUGPRINT_REG((int)lock);
4034 BAMBOO_DEBUGPRINT_REG(*((int*)lock+5));
4036 #ifndef MULTICORE_GC
4037 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
4039 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
4040 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
4041 releasewritelock_r(lock, (int *)redirectlock);
4046 releasewritelock(ptr);
4049 } // line 3015: if(islock)
4052 //clock6 = BAMBOO_GET_EXE_TIME();
4053 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
4056 // post task execution finish, set the end of the postTaskInfo
4060 // Free up task parameter descriptor
4061 RUNFREE(currtpd->parameterArray);
4065 BAMBOO_DEBUGPRINT(0xe99a);
4068 //clock7 = BAMBOO_GET_EXE_TIME();
4069 //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));
4072 //} // if (hashsize(activetasks)>0)
4073 } // while(hashsize(activetasks)>0)
4075 BAMBOO_DEBUGPRINT(0xe99b);
4079 /* This function processes an objects tags */
4080 void processtags(struct parameterdescriptor *pd,
4082 struct parameterwrapper *parameter,
4083 int * iteratorcount,
4088 for(i=0; i<pd->numbertags; i++) {
4089 int slotid=pd->tagarray[2*i];
4090 int tagid=pd->tagarray[2*i+1];
4092 if (statusarray[slotid+numparams]==0) {
4093 parameter->iterators[*iteratorcount].istag=1;
4094 parameter->iterators[*iteratorcount].tagid=tagid;
4095 parameter->iterators[*iteratorcount].slot=slotid+numparams;
4096 parameter->iterators[*iteratorcount].tagobjectslot=index;
4097 statusarray[slotid+numparams]=1;
4104 void processobject(struct parameterwrapper *parameter,
4106 struct parameterdescriptor *pd,
4112 struct ObjectHash * objectset=
4113 ((struct parameterwrapper *)pd->queue)->objectset;
4115 parameter->iterators[*iteratorcount].istag=0;
4116 parameter->iterators[*iteratorcount].slot=index;
4117 parameter->iterators[*iteratorcount].objectset=objectset;
4118 statusarray[index]=1;
4120 for(i=0; i<pd->numbertags; i++) {
4121 int slotid=pd->tagarray[2*i];
4122 //int tagid=pd->tagarray[2*i+1];
4123 if (statusarray[slotid+numparams]!=0) {
4124 /* This tag has already been enqueued, use it to narrow search */
4125 parameter->iterators[*iteratorcount].tagbindings[tagcount]=
4130 parameter->iterators[*iteratorcount].numtags=tagcount;
4135 /* This function builds the iterators for a task & parameter */
4137 void builditerators(struct taskdescriptor * task,
4139 struct parameterwrapper * parameter) {
4140 int statusarray[MAXTASKPARAMS];
4142 int numparams=task->numParameters;
4143 int iteratorcount=0;
4144 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
4146 statusarray[index]=1; /* Initial parameter */
4147 /* Process tags for initial iterator */
4149 processtags(task->descriptorarray[index], index, parameter,
4150 &iteratorcount, statusarray, numparams);
4154 /* Check for objects with existing tags */
4155 for(i=0; i<numparams; i++) {
4156 if (statusarray[i]==0) {
4157 struct parameterdescriptor *pd=task->descriptorarray[i];
4159 for(j=0; j<pd->numbertags; j++) {
4160 int slotid=pd->tagarray[2*j];
4161 if(statusarray[slotid+numparams]!=0) {
4162 processobject(parameter,i,pd,&iteratorcount,
4163 statusarray,numparams);
4164 processtags(pd,i,parameter,&iteratorcount,statusarray,numparams);
4171 /* Next do objects w/ unbound tags*/
4173 for(i=0; i<numparams; i++) {
4174 if (statusarray[i]==0) {
4175 struct parameterdescriptor *pd=task->descriptorarray[i];
4176 if (pd->numbertags>0) {
4177 processobject(parameter,i,pd,&iteratorcount,statusarray,numparams);
4178 processtags(pd,i,parameter,&iteratorcount,statusarray,numparams);
4184 /* Nothing with a tag enqueued */
4186 for(i=0; i<numparams; i++) {
4187 if (statusarray[i]==0) {
4188 struct parameterdescriptor *pd=task->descriptorarray[i];
4189 processobject(parameter,i,pd,&iteratorcount,statusarray,numparams);
4190 processtags(pd,i,parameter,&iteratorcount,statusarray,numparams);
4203 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
4206 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
4207 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
4209 printf("%s\n", task->name);
4211 for(j=0; j<task->numParameters; j++) {
4212 struct parameterdescriptor *param=task->descriptorarray[j];
4213 struct parameterwrapper *parameter=param->queue;
4214 struct ObjectHash * set=parameter->objectset;
4215 struct ObjectIterator objit;
4217 printf(" Parameter %d\n", j);
4219 ObjectHashiterator(set, &objit);
4220 while(ObjhasNext(&objit)) {
4221 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
4222 struct ___Object___ * tagptr=obj->___tags___;
4223 int nonfailed=Objdata4(&objit);
4224 int numflags=Objdata3(&objit);
4225 int flags=Objdata2(&objit);
4228 printf(" Contains %lx\n", obj);
4229 printf(" flag=%d\n", obj->flag);
4232 } else if (tagptr->type==TAGTYPE) {
4234 printf(" tag=%lx\n",tagptr);
4240 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
4241 for(; tagindex<ao->___cachedCode___; tagindex++) {
4243 printf(" tag=%lx\n",ARRAYGET(ao,struct ___TagDescriptor___*,
4256 /* This function processes the task information to create queues for
4257 each parameter type. */
4259 void processtasks() {
4261 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
4264 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
4265 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
4268 /* Build objectsets */
4269 for(j=0; j<task->numParameters; j++) {
4270 struct parameterdescriptor *param=task->descriptorarray[j];
4271 struct parameterwrapper *parameter=param->queue;
4272 parameter->objectset=allocateObjectHash(10);
4273 parameter->task=task;
4276 /* Build iterators for parameters */
4277 for(j=0; j<task->numParameters; j++) {
4278 struct parameterdescriptor *param=task->descriptorarray[j];
4279 struct parameterwrapper *parameter=param->queue;
4280 builditerators(task, j, parameter);
4285 void toiReset(struct tagobjectiterator * it) {
4288 } else if (it->numtags>0) {
4291 ObjectHashiterator(it->objectset, &it->it);
4295 int toiHasNext(struct tagobjectiterator *it,
4296 void ** objectarray OPTARG(int * failed)) {
4299 /* Get object with tags */
4300 struct ___Object___ *obj=objectarray[it->tagobjectslot];
4301 struct ___Object___ *tagptr=obj->___tags___;
4302 if (tagptr->type==TAGTYPE) {
4303 if ((it->tagobjindex==0)&& /* First object */
4304 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
4309 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
4310 int tagindex=it->tagobjindex;
4311 for(; tagindex<ao->___cachedCode___; tagindex++) {
4312 struct ___TagDescriptor___ *td=
4313 ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
4314 if (td->flag==it->tagid) {
4315 it->tagobjindex=tagindex; /* Found right type of tag */
4321 } else if (it->numtags>0) {
4322 /* Use tags to locate appropriate objects */
4323 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
4324 struct ___Object___ *objptr=tag->flagptr;
4326 if (objptr->type!=OBJECTARRAYTYPE) {
4327 if (it->tagobjindex>0)
4329 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
4331 for(i=1; i<it->numtags; i++) {
4332 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
4333 if (!containstag(objptr,tag2))
4338 struct ArrayObject *ao=(struct ArrayObject *) objptr;
4341 for(tagindex=it->tagobjindex;tagindex<ao->___cachedCode___;tagindex++){
4342 struct ___Object___ *objptr=
4343 ARRAYGET(ao,struct ___Object___*,tagindex);
4344 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
4346 for(i=1; i<it->numtags; i++) {
4347 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
4348 if (!containstag(objptr,tag2))
4351 it->tagobjindex=tagindex;
4356 it->tagobjindex=tagindex;
4360 return ObjhasNext(&it->it);
4364 int containstag(struct ___Object___ *ptr,
4365 struct ___TagDescriptor___ *tag) {
4367 struct ___Object___ * objptr=tag->flagptr;
4368 if (objptr->type==OBJECTARRAYTYPE) {
4369 struct ArrayObject *ao=(struct ArrayObject *)objptr;
4370 for(j=0; j<ao->___cachedCode___; j++) {
4371 if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
4381 void toiNext(struct tagobjectiterator *it,
4382 void ** objectarray OPTARG(int * failed)) {
4383 /* hasNext has all of the intelligence */
4386 /* Get object with tags */
4387 struct ___Object___ *obj=objectarray[it->tagobjectslot];
4388 struct ___Object___ *tagptr=obj->___tags___;
4389 if (tagptr->type==TAGTYPE) {
4391 objectarray[it->slot]=tagptr;
4393 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
4394 objectarray[it->slot]=
4395 ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
4397 } else if (it->numtags>0) {
4398 /* Use tags to locate appropriate objects */
4399 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
4400 struct ___Object___ *objptr=tag->flagptr;
4401 if (objptr->type!=OBJECTARRAYTYPE) {
4403 objectarray[it->slot]=objptr;
4405 struct ArrayObject *ao=(struct ArrayObject *) objptr;
4406 objectarray[it->slot]=
4407 ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
4410 /* Iterate object */
4411 objectarray[it->slot]=(void *)Objkey(&it->it);
4417 inline void profileTaskStart(char * taskname) {
4418 if(!taskInfoOverflow) {
4419 TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
4420 taskInfoArray[taskInfoIndex] = taskInfo;
4421 taskInfo->taskName = taskname;
4422 taskInfo->startTime = BAMBOO_GET_EXE_TIME();
4423 taskInfo->endTime = -1;
4424 taskInfo->exitIndex = -1;
4425 taskInfo->newObjs = NULL;
4429 inline void profileTaskEnd() {
4430 if(!taskInfoOverflow) {
4431 taskInfoArray[taskInfoIndex]->endTime = BAMBOO_GET_EXE_TIME();
4433 if(taskInfoIndex == TASKINFOLENGTH) {
4434 taskInfoOverflow = true;
4435 //taskInfoIndex = 0;
4440 // output the profiling data
4441 void outputProfileData() {
4444 unsigned long long totaltasktime = 0;
4445 unsigned long long preprocessingtime = 0;
4446 unsigned long long objqueuecheckingtime = 0;
4447 unsigned long long postprocessingtime = 0;
4448 //int interruptiontime = 0;
4449 unsigned long long other = 0;
4450 unsigned long long averagetasktime = 0;
4453 printf("Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
4454 // output task related info
4455 for(i = 0; i < taskInfoIndex; i++) {
4456 TaskInfo* tmpTInfo = taskInfoArray[i];
4457 unsigned long long duration = tmpTInfo->endTime - tmpTInfo->startTime;
4458 printf("%s, %lld, %lld, %lld, %lld",
4459 tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime,
4460 duration, tmpTInfo->exitIndex);
4461 // summarize new obj info
4462 if(tmpTInfo->newObjs != NULL) {
4463 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
4464 struct RuntimeIterator * iter = NULL;
4465 while(0 == isEmpty(tmpTInfo->newObjs)) {
4466 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
4467 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
4469 RuntimeHashget(nobjtbl, (int)objtype, &num);
4470 RuntimeHashremovekey(nobjtbl, (int)objtype);
4472 RuntimeHashadd(nobjtbl, (int)objtype, num);
4474 RuntimeHashadd(nobjtbl, (int)objtype, 1);
4476 //printf(stderr, "new obj!\n");
4479 // output all new obj info
4480 iter = RuntimeHashcreateiterator(nobjtbl);
4481 while(RunhasNext(iter)) {
4482 char * objtype = (char *)Runkey(iter);
4483 int num = Runnext(iter);
4484 printf(", %s, %d", objtype, num);
4488 if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
4489 preprocessingtime += duration;
4490 } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
4491 postprocessingtime += duration;
4492 } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
4493 objqueuecheckingtime += duration;
4495 totaltasktime += duration;
4496 averagetasktime += duration;
4501 if(taskInfoOverflow) {
4502 printf("Caution: task info overflow!\n");
4505 other = totalexetime-totaltasktime-preprocessingtime-postprocessingtime;
4506 averagetasktime /= tasknum;
4508 printf("\nTotal time: %lld\n", totalexetime);
4509 printf("Total task execution time: %lld (%d%%)\n", totaltasktime,
4510 (int)(((double)totaltasktime/(double)totalexetime)*100));
4511 printf("Total objqueue checking time: %lld (%d%%)\n",
4512 objqueuecheckingtime,
4513 (int)(((double)objqueuecheckingtime/(double)totalexetime)*100));
4514 printf("Total pre-processing time: %lld (%d%%)\n", preprocessingtime,
4515 (int)(((double)preprocessingtime/(double)totalexetime)*100));
4516 printf("Total post-processing time: %lld (%d%%)\n", postprocessingtime,
4517 (int)(((double)postprocessingtime/(double)totalexetime)*100));
4518 printf("Other time: %lld (%d%%)\n", other,
4519 (int)(((double)other/(double)totalexetime)*100));
4522 printf("\nAverage task execution time: %lld\n", averagetasktime);
4524 //printf("\nTotal time spent for interruptions: %lld\n", interrupttime);
4529 BAMBOO_DEBUGPRINT(0xdddd);
4530 // output task related info
4531 for(i= 0; i < taskInfoIndex; i++) {
4532 TaskInfo* tmpTInfo = taskInfoArray[i];
4533 char* tmpName = tmpTInfo->taskName;
4534 int nameLen = strlen(tmpName);
4535 BAMBOO_DEBUGPRINT(0xddda);
4536 for(j = 0; j < nameLen; j++) {
4537 BAMBOO_DEBUGPRINT_REG(tmpName[j]);
4539 BAMBOO_DEBUGPRINT(0xdddb);
4540 BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
4541 BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
4542 BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
4543 if(tmpTInfo->newObjs != NULL) {
4544 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
4545 struct RuntimeIterator * iter = NULL;
4546 while(0 == isEmpty(tmpTInfo->newObjs)) {
4547 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
4548 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
4550 RuntimeHashget(nobjtbl, (int)objtype, &num);
4551 RuntimeHashremovekey(nobjtbl, (int)objtype);
4553 RuntimeHashadd(nobjtbl, (int)objtype, num);
4555 RuntimeHashadd(nobjtbl, (int)objtype, 1);
4559 // ouput all new obj info
4560 iter = RuntimeHashcreateiterator(nobjtbl);
4561 while(RunhasNext(iter)) {
4562 char * objtype = (char *)Runkey(iter);
4563 int num = Runnext(iter);
4564 int nameLen = strlen(objtype);
4565 BAMBOO_DEBUGPRINT(0xddda);
4566 for(j = 0; j < nameLen; j++) {
4567 BAMBOO_DEBUGPRINT_REG(objtype[j]);
4569 BAMBOO_DEBUGPRINT(0xdddb);
4570 BAMBOO_DEBUGPRINT_REG(num);
4573 BAMBOO_DEBUGPRINT(0xdddc);
4576 if(taskInfoOverflow) {
4577 BAMBOO_DEBUGPRINT(0xefee);
4580 #ifdef PROFILE_INTERRUPT
4581 // output interrupt related info
4582 for(i = 0; i < interruptInfoIndex; i++) {
4583 InterruptInfo* tmpIInfo = interruptInfoArray[i];
4584 BAMBOO_DEBUGPRINT(0xddde);
4585 BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
4586 BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
4587 BAMBOO_DEBUGPRINT(0xdddf);
4590 if(interruptInfoOverflow) {
4591 BAMBOO_DEBUGPRINT(0xefef);
4593 #endif // PROFILE_INTERRUPT
4595 BAMBOO_DEBUGPRINT(0xeeee);
4598 #endif // #ifdef PROFILE