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;
243 } // void setupsmemmode(void)
246 inline __attribute__((always_inline))
247 void initruntimedata() {
249 // initialize the arrays
250 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
251 // startup core to initialize corestatus[]
252 for(i = 0; i < NUMCORESACTIVE; ++i) {
255 numreceiveobjs[i] = 0;
257 // initialize the profile data arrays
258 profilestatus[i] = 1;
262 gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
263 gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
265 } // for(i = 0; i < NUMCORESACTIVE; ++i)
267 for(i = 0; i < NUMCORES4GC; ++i) {
269 gcrequiredmems[i] = 0;
271 gcfilledblocks[i] = 0;
272 } // for(i = 0; i < NUMCORES4GC; ++i)
275 gc_infoOverflow = false;
276 gc_num_livespace = 0;
277 gc_num_freespace = 0;
288 self_numsendobjs = 0;
289 self_numreceiveobjs = 0;
291 for(i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
296 msglength = BAMBOO_MSG_BUF_LENGTH;
298 for(i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
304 isMsgHanging = false;
307 bamboo_cur_msp = NULL;
308 bamboo_smem_size = 0;
309 totransobjqueue = createQueue_I();
312 bamboo_smem_zero_top = NULL;
314 gcprocessing = false;
315 gcphase = FINISHPHASE;
318 gcself_numsendobjs = 0;
319 gcself_numreceiveobjs = 0;
320 gcmarkedptrbound = 0;
321 #ifdef LOCALHASHTBL_TEST
322 gcpointertbl = allocateRuntimeHash_I(20);
324 gcpointertbl = mgchashCreate_I(2000, 0.75);
326 gcforwardobjtbl = allocateMGCHash_I(20, 3);
337 gcsbstarttbl = BAMBOO_BASE_VA;
338 bamboo_smemtbl = (void *)gcsbstarttbl
339 + (BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE)*sizeof(INTPTR);
340 if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
341 int t_size = ((BAMBOO_RMSP_SIZE)-sizeof(mgcsharedhashtbl_t)*2
342 -128*sizeof(size_t))/sizeof(mgcsharedhashlistnode_t)-2;
344 unsigned int tmp_k = 1 << (sizeof(int)*8 -1);
345 while(((t_size & tmp_k) == 0) && (kk < sizeof(int)*8)) {
346 t_size = t_size << 1;
349 t_size = tmp_k >> kk;
350 gcsharedptbl = mgcsharedhashCreate_I(t_size,0.30);
354 BAMBOO_MEMSET_WH(gcrpointertbls, 0,
355 sizeof(mgcsharedhashtbl_t *)*NUMCORES4GC);
357 gcmem_mixed_threshold = (unsigned int)((BAMBOO_SHARED_MEM_SIZE
358 -bamboo_reserved_smem*BAMBOO_SMEM_SIZE)*0.8);
359 gcmem_mixed_usedmem = 0;
364 gc_num_forwardobj = 0;
365 gc_num_profiles = NUMCORESACTIVE - 1;
368 gc_num_flush_dtlb = 0;
370 gc_localheap_s = false;
371 #ifdef GC_CACHE_ADAPT
372 gccachestage = false;
373 #endif // GC_CACHE_ADAPT
375 // create the lock table, lockresult table and obj queue
378 (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
379 /* Set allocation blocks*/
380 locktable.listhead=NULL;
381 locktable.listtail=NULL;
383 locktable.numelements = 0;
388 lockRedirectTbl = allocateRuntimeHash_I(20);
389 objRedirectLockTbl = allocateRuntimeHash_I(20);
394 objqueue.head = NULL;
395 objqueue.tail = NULL;
403 taskInfoOverflow = false;
404 #ifdef PROFILE_INTERRUPT
405 interruptInfoIndex = 0;
406 interruptInfoOverflow = false;
407 #endif // PROFILE_INTERRUPT
410 for(i = 0; i < MAXTASKPARAMS; i++) {
411 runtime_locks[i].redirectlock = 0;
412 runtime_locks[i].value = 0;
417 inline __attribute__((always_inline))
418 void disruntimedata() {
420 #ifdef LOCALHASHTBL_TEST
421 freeRuntimeHash(gcpointertbl);
423 mgchashDelete(gcpointertbl);
425 freeMGCHash(gcforwardobjtbl);
427 freeRuntimeHash(lockRedirectTbl);
428 freeRuntimeHash(objRedirectLockTbl);
429 RUNFREE(locktable.bucket);
431 if(activetasks != NULL) {
432 genfreehashtable(activetasks);
434 if(currtpd != NULL) {
435 RUNFREE(currtpd->parameterArray);
439 BAMBOO_LOCAL_MEM_CLOSE();
440 BAMBOO_SHARE_MEM_CLOSE();
443 inline __attribute__((always_inline))
444 bool checkObjQueue() {
446 struct transObjInfo * objInfo = NULL;
450 #ifdef ACCURATEPROFILE
451 bool isChecking = false;
452 if(!isEmpty(&objqueue)) {
453 profileTaskStart("objqueue checking");
455 } // if(!isEmpty(&objqueue))
459 while(!isEmpty(&objqueue)) {
461 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
462 BAMBOO_DEBUGPRINT(0xf001);
463 BAMBOO_DEBUGPRINT(0xeee1);
465 objInfo = (struct transObjInfo *)getItem(&objqueue);
466 obj = objInfo->objptr;
467 BAMBOO_DEBUGPRINT_REG((int)obj);
468 // grab lock and flush the obj
470 struct ___Object___ * tmpobj = (struct ___Object___ *)obj;
471 while(tmpobj->lock != NULL) {
472 tmpobj = (struct ___Object___ *)(tmpobj->lock);
474 getwritelock_I(tmpobj);
476 BAMBOO_WAITING_FOR_LOCK(0);
477 } // while(!lockflag)
479 BAMBOO_DEBUGPRINT_REG(grount);
493 BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
494 BAMBOO_CACHE_FLUSH_RANGE((int)obj,
495 classsize[((struct ___Object___ *)obj)->type]);
497 // enqueue the object
498 for(k = 0; k < objInfo->length; ++k) {
499 int taskindex = objInfo->queues[2 * k];
500 int paramindex = objInfo->queues[2 * k + 1];
501 struct parameterwrapper ** queues =
502 &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
503 BAMBOO_DEBUGPRINT_REG(taskindex);
504 BAMBOO_DEBUGPRINT_REG(paramindex);
505 enqueueObject_I(obj, queues, 1);
506 BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
507 } // for(k = 0; k < objInfo->length; ++k)
508 releasewritelock_I(tmpobj);
509 RUNFREE(objInfo->queues);
513 // put it at the end of the queue if no update version in the queue
514 struct QueueItem * qitem = getHead(&objqueue);
515 struct QueueItem * prev = NULL;
516 while(qitem != NULL) {
517 struct transObjInfo * tmpinfo =
518 (struct transObjInfo *)(qitem->objectptr);
519 if(tmpinfo->objptr == obj) {
520 // the same object in the queue, which should be enqueued
521 // recently. Current one is outdate, do not re-enqueue it
522 RUNFREE(objInfo->queues);
527 } // if(tmpinfo->objptr == obj)
528 qitem = getNextQueueItem(prev);
529 } // while(qitem != NULL)
530 // try to execute active tasks already enqueued first
531 addNewItem_I(&objqueue, objInfo);
533 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
534 BAMBOO_DEBUGPRINT(0xf000);
537 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
538 BAMBOO_DEBUGPRINT(0xf000);
539 } // while(!isEmpty(&objqueue))
542 #ifdef ACCURATEPROFILE
549 BAMBOO_DEBUGPRINT(0xee02);
553 inline __attribute__((always_inline))
554 void checkCoreStatus() {
555 bool allStall = false;
559 (waitconfirm && (numconfirm == 0))) {
560 BAMBOO_DEBUGPRINT(0xee04);
561 BAMBOO_DEBUGPRINT_REG(waitconfirm);
562 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
563 BAMBOO_DEBUGPRINT(0xf001);
564 corestatus[BAMBOO_NUM_OF_CORE] = 0;
565 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
566 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
567 // check the status of all cores
569 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
570 for(i = 0; i < NUMCORESACTIVE; ++i) {
571 BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
572 if(corestatus[i] != 0) {
576 } // for(i = 0; i < NUMCORESACTIVE; ++i)
578 // check if the sum of send objs and receive obj are the same
579 // yes->check if the info is the latest; no->go on executing
581 for(i = 0; i < NUMCORESACTIVE; ++i) {
582 sumsendobj += numsendobjs[i];
583 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
584 } // for(i = 0; i < NUMCORESACTIVE; ++i)
585 for(i = 0; i < NUMCORESACTIVE; ++i) {
586 sumsendobj -= numreceiveobjs[i];
587 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
588 } // for(i = 0; i < NUMCORESACTIVE; ++i)
589 if(0 == sumsendobj) {
591 // the first time found all cores stall
592 // send out status confirm msg to all other cores
593 // reset the corestatus array too
594 BAMBOO_DEBUGPRINT(0xee05);
595 corestatus[BAMBOO_NUM_OF_CORE] = 1;
597 numconfirm = NUMCORESACTIVE - 1;
598 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
599 for(i = 1; i < NUMCORESACTIVE; ++i) {
601 // send status confirm msg to core i
602 send_msg_1(i, STATUSCONFIRM, false);
603 } // for(i = 1; i < NUMCORESACTIVE; ++i)
606 // all the core status info are the latest
607 // terminate; for profiling mode, send request to all
608 // other cores to pour out profiling data
609 BAMBOO_DEBUGPRINT(0xee06);
612 totalexetime = BAMBOO_GET_EXE_TIME() - bamboo_start_time;
615 BAMBOO_PRINT(BAMBOO_GET_EXE_TIME() - bamboo_start_time);
616 //BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
618 BAMBOO_PRINT_REG(gc_num_flush_dtlb);
620 #ifndef BAMBOO_MEMPROF
621 BAMBOO_PRINT(0xbbbbbbbb);
624 // profile mode, send msgs to other cores to request pouring
625 // out progiling data
627 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
628 BAMBOO_DEBUGPRINT(0xf000);
629 for(i = 1; i < NUMCORESACTIVE; ++i) {
630 // send profile request msg to core i
631 send_msg_2(i, PROFILEOUTPUT, totalexetime, false);
632 } // for(i = 1; i < NUMCORESACTIVE; ++i)
634 // pour profiling data on startup core
638 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
639 BAMBOO_DEBUGPRINT(0xf001);
640 profilestatus[BAMBOO_NUM_OF_CORE] = 0;
641 // check the status of all cores
643 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
644 for(i = 0; i < NUMCORESACTIVE; ++i) {
645 BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
646 if(profilestatus[i] != 0) {
650 } // for(i = 0; i < NUMCORESACTIVE; ++i)
653 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
654 BAMBOO_DEBUGPRINT(0xf000);
658 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
664 // gc_profile mode, output gc prfiling data
666 #ifdef GC_CACHE_ADAPT
667 bamboo_mask_timer_intr(); // disable the TILE_TIMER interrupt
668 #endif // GC_CACHE_ADAPT
670 gc_outputProfileData();
671 #endif // #ifdef GC_PROFILE
672 #endif // #ifdef MULTICORE_GC
674 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
675 terminate(); // All done.
676 } // if(!waitconfirm)
678 // still some objects on the fly on the network
679 // reset the waitconfirm and numconfirm
680 BAMBOO_DEBUGPRINT(0xee07);
683 } // if(0 == sumsendobj)
685 // not all cores are stall, keep on waiting
686 BAMBOO_DEBUGPRINT(0xee08);
690 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
691 BAMBOO_DEBUGPRINT(0xf000);
692 } // if((!waitconfirm) ||
695 // main function for each core
696 inline void run(void * arg) {
700 bool sendStall = false;
702 bool tocontinue = false;
704 corenum = BAMBOO_GET_NUM_OF_CORE();
705 BAMBOO_DEBUGPRINT(0xeeee);
706 BAMBOO_DEBUGPRINT_REG(corenum);
707 BAMBOO_DEBUGPRINT(STARTUPCORE);
709 // initialize runtime data structures
712 // other architecture related initialization
716 #ifdef GC_CACHE_ADAPT
717 // enable the timer interrupt
718 #ifdef GC_CACHE_SAMPLING
719 bamboo_tile_timer_set_next_event(GC_TILE_TIMER_EVENT_SETTING); // TODO
720 bamboo_unmask_timer_intr();
721 bamboo_dtlb_sampling_process();
722 #endif // GC_CACHE_SAMPLING
723 #endif // GC_CACHE_ADAPT
725 initializeexithandler();
727 // main process of the execution module
728 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
729 // non-executing cores, only processing communications
733 /* Create queue of active tasks */
735 genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
736 (int (*)(void *,void *)) &comparetpd);
738 /* Process task information */
741 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
742 /* Create startup object */
743 createstartupobject(argc, argv);
746 BAMBOO_DEBUGPRINT(0xee00);
751 // check if need to do GC
755 #endif // MULTICORE_GC
757 // check if there are new active tasks can be executed
764 while(receiveObject() != -1) {
768 BAMBOO_DEBUGPRINT(0xee01);
770 // check if there are some pending objects,
771 // if yes, enqueue them and executetasks again
772 tocontinue = checkObjQueue();
776 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
778 BAMBOO_DEBUGPRINT(0xee03);
784 BAMBOO_DEBUGPRINT(0xee09);
789 // wait for some time
791 BAMBOO_DEBUGPRINT(0xee0a);
796 // send StallMsg to startup core
797 BAMBOO_DEBUGPRINT(0xee0b);
799 send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
800 self_numsendobjs, self_numreceiveobjs, false);
811 BAMBOO_DEBUGPRINT(0xee0c);
813 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
816 } // if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)
820 struct ___createstartupobject____I_locals {
823 struct ___StartupObject___ * ___startupobject___;
824 struct ArrayObject * ___stringarray___;
825 }; // struct ___createstartupobject____I_locals
827 void createstartupobject(int argc,
831 /* Allocate startup object */
833 struct ___createstartupobject____I_locals ___locals___ =
834 {2, NULL, NULL, NULL};
835 struct ___StartupObject___ *startupobject=
836 (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
837 ___locals___.___startupobject___ = startupobject;
838 struct ArrayObject * stringarray=
839 allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
840 ___locals___.___stringarray___ = stringarray;
842 struct ___StartupObject___ *startupobject=
843 (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
844 struct ArrayObject * stringarray=
845 allocate_newarray(STRINGARRAYTYPE, argc-1);
847 /* Build array of strings */
848 startupobject->___parameters___=stringarray;
849 for(i=1; i<argc; i++) {
850 int length=strlen(argv[i]);
852 struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
854 struct ___String___ *newstring=NewString(argv[i],length);
856 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
860 startupobject->version = 0;
861 startupobject->lock = NULL;
863 /* Set initialized flag for startup object */
864 flagorandinit(startupobject,1,0xFFFFFFFF);
865 enqueueObject(startupobject, NULL, 0);
867 BAMBOO_CACHE_FLUSH_ALL();
871 int hashCodetpd(struct taskparamdescriptor *ftd) {
872 int hash=(int)ftd->task;
874 for(i=0; i<ftd->numParameters; i++) {
875 hash^=(int)ftd->parameterArray[i];
880 int comparetpd(struct taskparamdescriptor *ftd1,
881 struct taskparamdescriptor *ftd2) {
883 if (ftd1->task!=ftd2->task)
885 for(i=0; i<ftd1->numParameters; i++)
886 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
891 /* This function sets a tag. */
893 void tagset(void *ptr,
894 struct ___Object___ * obj,
895 struct ___TagDescriptor___ * tagd) {
897 void tagset(struct ___Object___ * obj,
898 struct ___TagDescriptor___ * tagd) {
900 struct ArrayObject * ao=NULL;
901 struct ___Object___ * tagptr=obj->___tags___;
903 obj->___tags___=(struct ___Object___ *)tagd;
905 /* Have to check if it is already set */
906 if (tagptr->type==TAGTYPE) {
907 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
912 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
913 struct ArrayObject * ao=
914 allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
915 obj=(struct ___Object___ *)ptrarray[2];
916 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
917 td=(struct ___TagDescriptor___ *) obj->___tags___;
919 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
922 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
923 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
924 obj->___tags___=(struct ___Object___ *) ao;
925 ao->___cachedCode___=2;
929 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
930 for(i=0; i<ao->___cachedCode___; i++) {
931 struct ___TagDescriptor___ * td=
932 ARRAYGET(ao, struct ___TagDescriptor___*, i);
937 if (ao->___cachedCode___<ao->___length___) {
938 ARRAYSET(ao, struct ___TagDescriptor___ *,ao->___cachedCode___,tagd);
939 ao->___cachedCode___++;
942 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
943 struct ArrayObject * aonew=
944 allocate_newarray(&ptrarray,TAGARRAYTYPE,
945 TAGARRAYINTERVAL+ao->___length___);
946 obj=(struct ___Object___ *)ptrarray[2];
947 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
948 ao=(struct ArrayObject *)obj->___tags___;
950 struct ArrayObject * aonew=
951 allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
954 aonew->___cachedCode___=ao->___length___+1;
955 for(i=0; i<ao->___length___; i++) {
956 ARRAYSET(aonew, struct ___TagDescriptor___*, i,
957 ARRAYGET(ao, struct ___TagDescriptor___*, i));
959 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___,tagd);
965 struct ___Object___ * tagset=tagd->flagptr;
968 } else if (tagset->type!=OBJECTARRAYTYPE) {
970 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
971 struct ArrayObject * ao=
972 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
973 obj=(struct ___Object___ *)ptrarray[2];
974 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
976 struct ArrayObject * ao=
977 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
979 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
980 ARRAYSET(ao, struct ___Object___ *, 1, obj);
981 ao->___cachedCode___=2;
982 tagd->flagptr=(struct ___Object___ *)ao;
984 struct ArrayObject *ao=(struct ArrayObject *) tagset;
985 if (ao->___cachedCode___<ao->___length___) {
986 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
990 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
991 struct ArrayObject * aonew=
992 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
993 OBJECTARRAYINTERVAL+ao->___length___);
994 obj=(struct ___Object___ *)ptrarray[2];
995 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
996 ao=(struct ArrayObject *)tagd->flagptr;
998 struct ArrayObject * aonew=allocate_newarray(OBJECTARRAYTYPE,
999 OBJECTARRAYINTERVAL+ao->___length___);
1001 aonew->___cachedCode___=ao->___cachedCode___+1;
1002 for(i=0; i<ao->___length___; i++) {
1003 ARRAYSET(aonew, struct ___Object___*, i,
1004 ARRAYGET(ao, struct ___Object___*, i));
1006 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
1007 tagd->flagptr=(struct ___Object___ *) aonew;
1013 /* This function clears a tag. */
1015 void tagclear(void *ptr,
1016 struct ___Object___ * obj,
1017 struct ___TagDescriptor___ * tagd) {
1019 void tagclear(struct ___Object___ * obj,
1020 struct ___TagDescriptor___ * tagd) {
1022 /* We'll assume that tag is alway there.
1023 Need to statically check for this of course. */
1024 struct ___Object___ * tagptr=obj->___tags___;
1026 if (tagptr->type==TAGTYPE) {
1027 if ((struct ___TagDescriptor___ *)tagptr==tagd)
1028 obj->___tags___=NULL;
1030 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
1032 for(i=0; i<ao->___cachedCode___; i++) {
1033 struct ___TagDescriptor___ * td=
1034 ARRAYGET(ao, struct ___TagDescriptor___ *, i);
1036 ao->___cachedCode___--;
1037 if (i<ao->___cachedCode___)
1038 ARRAYSET(ao, struct ___TagDescriptor___ *, i,
1039 ARRAYGET(ao,struct ___TagDescriptor___*,ao->___cachedCode___));
1040 ARRAYSET(ao,struct ___TagDescriptor___ *,ao->___cachedCode___, NULL);
1041 if (ao->___cachedCode___==0)
1042 obj->___tags___=NULL;
1049 struct ___Object___ *tagset=tagd->flagptr;
1050 if (tagset->type!=OBJECTARRAYTYPE) {
1054 struct ArrayObject *ao=(struct ArrayObject *) tagset;
1056 for(i=0; i<ao->___cachedCode___; i++) {
1057 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
1059 ao->___cachedCode___--;
1060 if (i<ao->___cachedCode___)
1061 ARRAYSET(ao, struct ___Object___ *, i,
1062 ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
1063 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
1064 if (ao->___cachedCode___==0)
1075 /* This function allocates a new tag. */
1077 struct ___TagDescriptor___ * allocate_tag(void *ptr,
1079 struct ___TagDescriptor___ * v=
1080 (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
1081 classsize[TAGTYPE]);
1083 struct ___TagDescriptor___ * allocate_tag(int index) {
1084 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
1091 /* This function updates the flag for object ptr. It or's the flag
1092 with the or mask and and's it with the andmask. */
1094 void flagbody(struct ___Object___ *ptr,
1096 struct parameterwrapper ** queues,
1100 int flagcomp(const int *val1, const int *val2) {
1101 return (*val1)-(*val2);
1104 void flagorand(void * ptr,
1107 struct parameterwrapper ** queues,
1110 int oldflag=((int *)ptr)[1];
1111 int flag=ormask|oldflag;
1113 flagbody(ptr, flag, queues, length, false);
1117 bool intflagorand(void * ptr,
1121 int oldflag=((int *)ptr)[1];
1122 int flag=ormask|oldflag;
1124 if (flag==oldflag) /* Don't do anything */
1127 flagbody(ptr, flag, NULL, 0, false);
1133 void flagorandinit(void * ptr,
1136 int oldflag=((int *)ptr)[1];
1137 int flag=ormask|oldflag;
1139 flagbody(ptr,flag,NULL,0,true);
1142 void flagbody(struct ___Object___ *ptr,
1144 struct parameterwrapper ** vqueues,
1147 struct parameterwrapper * flagptr = NULL;
1149 struct parameterwrapper ** queues = vqueues;
1150 int length = vlength;
1152 int UNUSED, UNUSED2;
1153 int * enterflags = NULL;
1154 if((!isnew) && (queues == NULL)) {
1155 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
1156 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1157 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1164 /*Remove object from all queues */
1165 for(i = 0; i < length; ++i) {
1166 flagptr = queues[i];
1167 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
1168 (int *) &enterflags, &UNUSED, &UNUSED2);
1169 ObjectHashremove(flagptr->objectset, (int)ptr);
1170 if (enterflags!=NULL)
1171 RUNFREE(enterflags);
1175 void enqueueObject(void * vptr,
1176 struct parameterwrapper ** vqueues,
1178 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1181 struct parameterwrapper * parameter=NULL;
1184 struct parameterwrapper * prevptr=NULL;
1185 struct ___Object___ *tagptr=NULL;
1186 struct parameterwrapper ** queues = vqueues;
1187 int length = vlength;
1188 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1191 if(queues == NULL) {
1192 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1193 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1195 tagptr=ptr->___tags___;
1197 /* Outer loop iterates through all parameter queues an object of
1198 this type could be in. */
1199 for(j = 0; j < length; ++j) {
1200 parameter = queues[j];
1202 if (parameter->numbertags>0) {
1204 goto nextloop; //that means the object has no tag
1205 //but that param needs tag
1206 else if(tagptr->type==TAGTYPE) { //one tag
1207 for(i=0; i<parameter->numbertags; i++) {
1208 //slotid is parameter->tagarray[2*i];
1209 int tagid=parameter->tagarray[2*i+1];
1210 if (tagid!=tagptr->flag)
1211 goto nextloop; /*We don't have this tag */
1213 } else { //multiple tags
1214 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1215 for(i=0; i<parameter->numbertags; i++) {
1216 //slotid is parameter->tagarray[2*i];
1217 int tagid=parameter->tagarray[2*i+1];
1219 for(j=0; j<ao->___cachedCode___; j++) {
1220 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1231 for(i=0; i<parameter->numberofterms; i++) {
1232 int andmask=parameter->intarray[i*2];
1233 int checkmask=parameter->intarray[i*2+1];
1234 if ((ptr->flag&andmask)==checkmask) {
1235 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
1246 void enqueueObject_I(void * vptr,
1247 struct parameterwrapper ** vqueues,
1249 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1252 struct parameterwrapper * parameter=NULL;
1255 struct parameterwrapper * prevptr=NULL;
1256 struct ___Object___ *tagptr=NULL;
1257 struct parameterwrapper ** queues = vqueues;
1258 int length = vlength;
1259 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1262 if(queues == NULL) {
1263 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1264 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1266 tagptr=ptr->___tags___;
1268 /* Outer loop iterates through all parameter queues an object of
1269 this type could be in. */
1270 for(j = 0; j < length; ++j) {
1271 parameter = queues[j];
1273 if (parameter->numbertags>0) {
1275 goto nextloop; //that means the object has no tag
1276 //but that param needs tag
1277 else if(tagptr->type==TAGTYPE) { //one tag
1278 for(i=0; i<parameter->numbertags; i++) {
1279 //slotid is parameter->tagarray[2*i];
1280 int tagid=parameter->tagarray[2*i+1];
1281 if (tagid!=tagptr->flag)
1282 goto nextloop; /*We don't have this tag */
1284 } else { //multiple tags
1285 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1286 for(i=0; i<parameter->numbertags; i++) {
1287 //slotid is parameter->tagarray[2*i];
1288 int tagid=parameter->tagarray[2*i+1];
1290 for(j=0; j<ao->___cachedCode___; j++) {
1291 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1302 for(i=0; i<parameter->numberofterms; i++) {
1303 int andmask=parameter->intarray[i*2];
1304 int checkmask=parameter->intarray[i*2+1];
1305 if ((ptr->flag&andmask)==checkmask) {
1306 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1318 int * getAliasLock(void ** ptrs,
1320 struct RuntimeHash * tbl) {
1325 // sort all the locks required by the objs in the aliased set
1326 for(; i < length; i++) {
1327 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1330 if(ptr->lock == NULL) {
1333 lock = (int)(ptr->lock);
1336 for(j = 0; j < locklen; j++) {
1337 if(locks[j] == lock) {
1340 } else if(locks[j] > lock) {
1347 locks[h] = locks[h-1];
1353 // use the smallest lock as the shared lock for the whole set
1354 return (int *)(locks[0]);
1356 // TODO possible bug here!!!
1358 return (int*)(RUNMALLOC(sizeof(int)));
1363 bool redirect = false;
1364 int redirectlock = 0;
1365 for(; i < length; i++) {
1366 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1369 if(ptr->lock == NULL) {
1372 lock = (int)(ptr->lock);
1375 if(lock != redirectlock) {
1376 RuntimeHashadd(tbl, lock, redirectlock);
1379 if(RuntimeHashcontainskey(tbl, lock)) {
1380 // already redirected
1382 RuntimeHashget(tbl, lock, &redirectlock);
1383 for(; j < locklen; j++) {
1384 if(locks[j] != redirectlock) {
1385 RuntimeHashadd(tbl, locks[j], redirectlock);
1390 for(j = 0; j < locklen; j++) {
1391 if(locks[j] == lock) {
1394 } else if(locks[j] > lock) {
1401 locks[h] = locks[h-1];
1410 return (int *)redirectlock;
1412 // use the first lock as the shared lock
1413 for(j = 1; j < locklen; j++) {
1414 if(locks[j] != locks[0]) {
1415 RuntimeHashadd(tbl, locks[j], locks[0]);
1418 return (int *)(locks[0]);
1421 #endif // TILERA_BME
1424 void addAliasLock(void * ptr,
1426 struct ___Object___ * obj = (struct ___Object___ *)ptr;
1427 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1428 // originally no alias lock associated or have a different alias lock
1429 // flush it as the new one
1431 while(obj->lock != NULL) {
1432 // previously have alias lock, trace the 'root' obj and redirect it
1433 obj = (struct ___Object___ *)(obj->lock);
1435 #endif // TILERA_BME
1436 obj->lock = (int *)lock;
1441 inline void setTaskExitIndex(int index) {
1442 taskInfoArray[taskInfoIndex]->exitIndex = index;
1445 inline void addNewObjInfo(void * nobj) {
1446 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1447 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1449 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1454 // Only allocate local mem chunks to each core.
1455 // If a core has used up its local shared memory, start gc.
1456 void * localmalloc_I(int coren,
1460 int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
1463 int tofindb = gc_core2block[2*gccorenum+i]+(NUMCORES4GC*2)*j;
1464 int totest = tofindb;
1465 int bound = BAMBOO_SMEM_SIZE_L;
1469 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1470 int nsize = bamboo_smemtbl[totest];
1471 bool islocal = true;
1473 bool tocheck = true;
1474 // have some space in the block
1475 if(totest == tofindb) {
1476 // the first partition
1477 size = bound - nsize;
1478 } else if(nsize == 0) {
1479 // an empty partition, can be appended
1482 // not an empty partition, can not be appended
1483 // the last continuous block is not big enough, go to check the next
1487 } // if(totest == tofindb) else if(nsize == 0) else ...
1490 // have enough space in the block, malloc
1494 // no enough space yet, try to append next continuous block
1496 } // if(size > isize) else ...
1498 } // if(nsize < bound)
1500 // no space in the block, go to check the next block
1506 tofindb = totest = gc_core2block[2*gccorenum+i]+(NUMCORES4GC*2)*j;
1509 } // if(islocal) else ...
1510 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1511 // no more local mem, do not find suitable block
1514 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1517 if(foundsmem == 1) {
1518 // find suitable block
1519 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1520 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1521 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1523 // set bamboo_smemtbl
1524 for(i = tofindb; i <= totest; i++) {
1525 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1527 } else if(foundsmem == 2) {
1528 // no suitable block
1533 } // void * localmalloc_I(int, int, int *)
1536 // Allocate the local shared memory to each core with the highest priority,
1537 // if a core has used up its local shared memory, try to allocate the
1538 // shared memory that belong to its neighbours, if also failed, start gc.
1539 void * fixedmalloc_I(int coren,
1546 int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
1547 int coords_x = bamboo_cpu2coords[gccorenum*2];
1548 int coords_y = bamboo_cpu2coords[gccorenum*2+1];
1550 int tofindb = gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1551 int totest = tofindb;
1552 int bound = BAMBOO_SMEM_SIZE_L;
1556 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1557 int nsize = bamboo_smemtbl[totest];
1558 bool islocal = true;
1560 bool tocheck = true;
1561 // have some space in the block
1562 if(totest == tofindb) {
1563 // the first partition
1564 size = bound - nsize;
1565 } else if(nsize == 0) {
1566 // an empty partition, can be appended
1569 // not an empty partition, can not be appended
1570 // the last continuous block is not big enough, go to check the next
1574 } // if(totest == tofindb) else if(nsize == 0) else ...
1577 // have enough space in the block, malloc
1581 // no enough space yet, try to append next continuous block
1582 // TODO may consider to go to next local block?
1584 } // if(size > isize) else ...
1586 } // if(nsize < bound)
1588 // no space in the block, go to check the next block
1595 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1598 } // if(islocal) else ...
1599 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1600 // no more local mem, do not find suitable block on local mem
1601 // try to malloc shared memory assigned to the neighbour cores
1604 if(k >= NUM_CORES2TEST) {
1605 // no more memory available on either coren or its neighbour cores
1607 goto memsearchresult;
1609 } while(core2test[gccorenum][k] == -1);
1613 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1614 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1618 if(foundsmem == 1) {
1619 // find suitable block
1620 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1621 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1622 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1624 // set bamboo_smemtbl
1625 for(i = tofindb; i <= totest; i++) {
1626 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1628 } else if(foundsmem == 2) {
1629 // no suitable block
1634 } // void * fixedmalloc_I(int, int, int *)
1635 #endif // #ifdef SMEMF
1638 // Allocate the local shared memory to each core with the highest priority,
1639 // if a core has used up its local shared memory, try to allocate the
1640 // shared memory that belong to its neighbours first, if failed, check
1641 // current memory allocation rate, if it has already reached the threshold,
1642 // start gc, otherwise, allocate the shared memory globally. If all the
1643 // shared memory has been used up, start gc.
1644 void * mixedmalloc_I(int coren,
1651 int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
1653 int tofindb = gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1654 int totest = tofindb;
1655 int bound = BAMBOO_SMEM_SIZE_L;
1659 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1660 int nsize = bamboo_smemtbl[totest];
1661 bool islocal = true;
1663 bool tocheck = true;
1664 // have some space in the block
1665 if(totest == tofindb) {
1666 // the first partition
1667 size = bound - nsize;
1668 } else if(nsize == 0) {
1669 // an empty partition, can be appended
1672 // not an empty partition, can not be appended
1673 // the last continuous block is not big enough, go to check the next
1677 } // if(totest == tofindb) else if(nsize == 0) else ...
1680 // have enough space in the block, malloc
1684 // no enough space yet, try to append next continuous block
1685 // TODO may consider to go to next local block?
1687 } // if(size > isize) else ...
1689 } // if(nsize < bound)
1691 // no space in the block, go to check the next block
1698 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1701 } // if(islocal) else ...
1702 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1703 // no more local mem, do not find suitable block on local mem
1704 // try to malloc shared memory assigned to the neighbour cores
1707 if(k >= NUM_CORES2TEST) {
1708 if(gcmem_mixed_usedmem >= gcmem_mixed_threshold) {
1709 // no more memory available on either coren or its neighbour cores
1711 goto memmixedsearchresult;
1713 // try allocate globally
1714 mem = globalmalloc_I(coren, isize, allocsize);
1718 } while(core2test[gccorenum][k] == -1);
1722 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1723 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1726 memmixedsearchresult:
1727 if(foundsmem == 1) {
1728 // find suitable block
1729 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1730 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1731 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1733 // set bamboo_smemtbl
1734 for(i = tofindb; i <= totest; i++) {
1735 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1737 gcmem_mixed_usedmem += size;
1738 if(tofindb == bamboo_free_block) {
1739 bamboo_free_block = totest+1;
1741 } else if(foundsmem == 2) {
1742 // no suitable block
1747 } // void * mixedmalloc_I(int, int, int *)
1748 #endif // #ifdef SMEMM
1750 // Allocate all the memory chunks globally, do not consider the host cores
1751 // When all the shared memory are used up, start gc.
1752 void * globalmalloc_I(int coren,
1756 int tofindb = bamboo_free_block; //0;
1757 int totest = tofindb;
1758 int bound = BAMBOO_SMEM_SIZE_L;
1761 if(tofindb > gcnumblock-1-bamboo_reserved_smem) {
1762 // Out of shared memory
1767 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1768 int nsize = bamboo_smemtbl[totest];
1769 bool isnext = false;
1771 bool tocheck = true;
1772 // have some space in the block
1773 if(totest == tofindb) {
1774 // the first partition
1775 size = bound - nsize;
1776 } else if(nsize == 0) {
1777 // an empty partition, can be appended
1780 // not an empty partition, can not be appended
1781 // the last continuous block is not big enough, start another block
1784 } // if(totest == tofindb) else if(nsize == 0) else ...
1787 // have enough space in the block, malloc
1790 } // if(size > isize)
1794 } // if(nsize < bound) else ...
1796 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1797 // no more local mem, do not find suitable block
1800 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1802 // start another block
1807 if(foundsmem == 1) {
1808 // find suitable block
1809 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1810 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1811 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1813 // set bamboo_smemtbl
1814 for(int i = tofindb; i <= totest; i++) {
1815 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1817 if(tofindb == bamboo_free_block) {
1818 bamboo_free_block = totest+1;
1820 } else if(foundsmem == 2) {
1821 // no suitable block
1827 } // void * globalmalloc_I(int, int, int *)
1828 #endif // #ifdef MULTICORE_GC
1830 // malloc from the shared memory
1831 void * smemalloc_I(int coren,
1836 int isize = size+(BAMBOO_CACHE_LINE_SIZE);
1838 // go through the bamboo_smemtbl for suitable partitions
1839 switch(bamboo_smem_mode) {
1841 mem = localmalloc_I(coren, isize, allocsize);
1847 mem = fixedmalloc_I(coren, isize, allocsize);
1849 // not supported yet
1850 BAMBOO_EXIT(0xe001);
1857 mem = mixedmalloc_I(coren, isize, allocsize);
1859 // not supported yet
1860 BAMBOO_EXIT(0xe002);
1866 mem = globalmalloc_I(coren, isize, allocsize);
1876 int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size) : (BAMBOO_SMEM_SIZE);
1877 if(toallocate > bamboo_free_smem_size) {
1881 mem = (void *)bamboo_free_smemp;
1882 bamboo_free_smemp = ((void*)bamboo_free_smemp) + toallocate;
1883 bamboo_free_smem_size -= toallocate;
1885 *allocsize = toallocate;
1887 #endif // MULTICORE_GC
1888 // no enough shared global memory
1893 // inform other cores to stop and wait for gc
1895 for(int i = 0; i < NUMCORESACTIVE; i++) {
1896 // reuse the gcnumsendobjs & gcnumreceiveobjs
1897 gccorestatus[i] = 1;
1898 gcnumsendobjs[0][i] = 0;
1899 gcnumreceiveobjs[0][i] = 0;
1901 for(int i = 0; i < NUMCORESACTIVE; i++) {
1902 if(i != BAMBOO_NUM_OF_CORE) {
1903 if(BAMBOO_CHECK_SEND_MODE()) {
1904 cache_msg_1(i, GCSTARTPRE);
1906 send_msg_1(i, GCSTARTPRE, true);
1913 BAMBOO_DEBUGPRINT(0xe003);
1914 BAMBOO_EXIT(0xe003);
1918 } // void * smemalloc_I(int, int, int)
1920 INLINE int checkMsgLength_I(int size) {
1922 BAMBOO_DEBUGPRINT(0xcccc);
1924 int type = msgdata[msgdataindex];
1932 case GCSTARTMAPINFO:
1937 #ifdef GC_CACHE_ADAPT
1939 #endif // GC_CACHE_ADAPT
1940 #endif // MULTICORE_GC
1949 case GCSTARTCOMPACT:
1952 case GCFINISHMAPINFO:
1954 #ifdef GC_CACHE_ADAPT
1956 #endif // GC_CACHE_ADAPT
1957 #endif // MULTICORE_GC
1980 case REDIRECTGROUNT:
1982 case REDIRECTRELEASE:
1999 case GCFINISHCOMPACT:
2013 case TRANSOBJ: // nonfixed size
2019 msglength = msgdata[(msgdataindex+1)&(BAMBOO_MSG_BUF_MASK)];
2028 BAMBOO_DEBUGPRINT_REG(type);
2029 BAMBOO_DEBUGPRINT_REG(size);
2030 BAMBOO_DEBUGPRINT_REG(msgdataindex);
2031 BAMBOO_DEBUGPRINT_REG(msgdatalast);
2032 BAMBOO_DEBUGPRINT_REG(msgdatafull);
2035 BAMBOO_DEBUGPRINT(msgdata[msgdataindex+i]);
2037 BAMBOO_EXIT(0xe004);
2042 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
2043 BAMBOO_DEBUGPRINT(0xffff);
2048 INLINE void processmsg_transobj_I() {
2050 struct transObjInfo * transObj=RUNMALLOC_I(sizeof(struct transObjInfo));
2053 BAMBOO_DEBUGPRINT(0xe880);
2055 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2057 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
2059 BAMBOO_EXIT(0xe005);
2061 // store the object and its corresponding queue info, enqueue it later
2062 transObj->objptr = (void *)msgdata[msgdataindex]; //[2]
2064 transObj->length = (msglength - 3) / 2;
2065 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
2066 for(k = 0; k < transObj->length; ++k) {
2067 transObj->queues[2*k] = msgdata[msgdataindex]; //[3+2*k];
2069 transObj->queues[2*k+1] = msgdata[msgdataindex]; //[3+2*k+1];
2072 // check if there is an existing duplicate item
2074 struct QueueItem * qitem = getHead(&objqueue);
2075 struct QueueItem * prev = NULL;
2076 while(qitem != NULL) {
2077 struct transObjInfo * tmpinfo =
2078 (struct transObjInfo *)(qitem->objectptr);
2079 if(tmpinfo->objptr == transObj->objptr) {
2080 // the same object, remove outdate one
2081 RUNFREE(tmpinfo->queues);
2083 removeItem(&objqueue, qitem);
2089 qitem = getHead(&objqueue);
2091 qitem = getNextQueueItem(prev);
2094 addNewItem_I(&objqueue, (void *)transObj);
2096 ++(self_numreceiveobjs);
2099 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
2100 // set the gcprecheck to enable checking again
2103 // send a update pregc information msg to the master core
2104 if(BAMBOO_CHECK_SEND_MODE()) {
2105 cache_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
2106 self_numsendobjs, self_numreceiveobjs);
2108 send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
2109 self_numsendobjs, self_numreceiveobjs, true);
2116 INLINE void processmsg_transtall_I() {
2117 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2118 // non startup core can not receive stall msg
2120 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
2122 BAMBOO_EXIT(0xe006);
2124 int num_core = msgdata[msgdataindex]; //[1]
2126 int data2 = msgdata[msgdataindex]; //[2];
2128 int data3 = msgdata[msgdataindex]; //[3];
2130 if(num_core < NUMCORESACTIVE) {
2132 BAMBOO_DEBUGPRINT(0xe881);
2134 corestatus[num_core] = 0;
2135 numsendobjs[num_core] = data2; //[2];
2136 numreceiveobjs[num_core] = data3; //[3];
2140 #ifndef MULTICORE_GC
2141 INLINE void processmsg_lockrequest_I() {
2142 // check to see if there is a lock exist for the required obj
2143 // msgdata[1] -> lock type
2144 int locktype = msgdata[msgdataindex]; //[1];
2146 int data2 = msgdata[msgdataindex]; // obj pointer
2148 int data3 = msgdata[msgdataindex]; // lock
2150 int data4 = msgdata[msgdataindex]; // request core
2152 // -1: redirected, 0: approved, 1: denied
2153 int deny=processlockrequest(locktype, data3, data2, data4, data4, true);
2155 // this lock request is redirected
2158 // send response msg
2159 // for 32 bit machine, the size is always 4 words, cache the msg first
2160 int tmp = deny==1 ? LOCKDENY : LOCKGROUNT;
2161 if(BAMBOO_CHECK_SEND_MODE()) {
2162 cache_msg_4(data4, tmp, locktype, data2, data3);
2164 send_msg_4(data4, tmp, locktype, data2, data3, true);
2169 INLINE void processmsg_lockgrount_I() {
2171 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2173 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
2175 BAMBOO_EXIT(0xe007);
2177 int data2 = msgdata[msgdataindex];
2179 int data3 = msgdata[msgdataindex];
2181 if((lockobj == data2) && (lock2require == data3)) {
2183 BAMBOO_DEBUGPRINT(0xe882);
2191 // conflicts on lockresults
2193 BAMBOO_DEBUGPRINT_REG(data2);
2195 BAMBOO_EXIT(0xe008);
2199 INLINE void processmsg_lockdeny_I() {
2201 int data2 = msgdata[msgdataindex];
2203 int data3 = msgdata[msgdataindex];
2205 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2207 BAMBOO_DEBUGPRINT_REG(data2);
2209 BAMBOO_EXIT(0xe009);
2211 if((lockobj == data2) && (lock2require == data3)) {
2213 BAMBOO_DEBUGPRINT(0xe883);
2221 // conflicts on lockresults
2223 BAMBOO_DEBUGPRINT_REG(data2);
2225 BAMBOO_EXIT(0xe00a);
2229 INLINE void processmsg_lockrelease_I() {
2230 int data1 = msgdata[msgdataindex];
2232 int data2 = msgdata[msgdataindex];
2234 int data3 = msgdata[msgdataindex];
2236 // receive lock release msg
2237 processlockrelease(data1, data2, 0, false);
2240 INLINE void processmsg_redirectlock_I() {
2241 // check to see if there is a lock exist for the required obj
2242 int data1 = msgdata[msgdataindex];
2243 MSG_INDEXINC_I(); //msgdata[1]; // lock type
2244 int data2 = msgdata[msgdataindex];
2245 MSG_INDEXINC_I(); //msgdata[2]; // obj pointer
2246 int data3 = msgdata[msgdataindex];
2247 MSG_INDEXINC_I(); //msgdata[3]; // redirect lock
2248 int data4 = msgdata[msgdataindex];
2249 MSG_INDEXINC_I(); //msgdata[4]; // root request core
2250 int data5 = msgdata[msgdataindex];
2251 MSG_INDEXINC_I(); //msgdata[5]; // request core
2252 int deny = processlockrequest(data1, data3, data2, data5, data4, true);
2254 // this lock request is redirected
2257 // send response msg
2258 // for 32 bit machine, the size is always 4 words, cache the msg first
2259 if(BAMBOO_CHECK_SEND_MODE()) {
2260 cache_msg_4(data4, deny==1 ? REDIRECTDENY : REDIRECTGROUNT,
2261 data1, data2, data3);
2263 send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
2264 data1, data2, data3, true);
2269 INLINE void processmsg_redirectgrount_I() {
2271 int data2 = msgdata[msgdataindex];
2273 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2275 BAMBOO_DEBUGPRINT_REG(data2);
2277 BAMBOO_EXIT(0xe00b);
2279 if(lockobj == data2) {
2281 BAMBOO_DEBUGPRINT(0xe891);
2283 int data3 = msgdata[msgdataindex];
2287 RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
2292 // conflicts on lockresults
2294 BAMBOO_DEBUGPRINT_REG(data2);
2296 BAMBOO_EXIT(0xe00c);
2300 INLINE void processmsg_redirectdeny_I() {
2302 int data2 = msgdata[msgdataindex];
2304 int data3 = msgdata[msgdataindex];
2306 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2308 BAMBOO_DEBUGPRINT_REG(data2);
2310 BAMBOO_EXIT(0xe00d);
2312 if(lockobj == data2) {
2314 BAMBOO_DEBUGPRINT(0xe892);
2322 // conflicts on lockresults
2324 BAMBOO_DEBUGPRINT_REG(data2);
2326 BAMBOO_EXIT(0xe00e);
2330 INLINE void processmsg_redirectrelease_I() {
2331 int data1 = msgdata[msgdataindex];
2333 int data2 = msgdata[msgdataindex];
2335 int data3 = msgdata[msgdataindex];
2337 processlockrelease(data1, data2, data3, true);
2339 #endif // #ifndef MULTICORE_GC
2342 INLINE void processmsg_profileoutput_I() {
2343 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
2344 // startup core can not receive profile output finish msg
2345 BAMBOO_EXIT(0xe00f);
2348 BAMBOO_DEBUGPRINT(0xe885);
2351 totalexetime = msgdata[msgdataindex]; //[1]
2354 BAMBOO_DEBUGPRINT_REG(dot_num);
2356 outputProfileData();
2358 // cache the msg first
2359 if(BAMBOO_CHECK_SEND_MODE()) {
2360 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
2362 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE, true);
2366 INLINE void processmsg_profilefinish_I() {
2367 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2368 // non startup core can not receive profile output finish msg
2370 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex /*1*/]);
2372 BAMBOO_EXIT(0xe010);
2375 BAMBOO_DEBUGPRINT(0xe886);
2377 int data1 = msgdata[msgdataindex];
2379 profilestatus[data1] = 0;
2381 #endif // #ifdef PROFILE
2383 INLINE void processmsg_statusconfirm_I() {
2384 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2385 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2386 // wrong core to receive such msg
2387 BAMBOO_EXIT(0xe011);
2389 // send response msg
2391 BAMBOO_DEBUGPRINT(0xe887);
2393 // cache the msg first
2394 if(BAMBOO_CHECK_SEND_MODE()) {
2395 cache_msg_5(STARTUPCORE, STATUSREPORT,
2396 busystatus ? 1 : 0, BAMBOO_NUM_OF_CORE,
2397 self_numsendobjs, self_numreceiveobjs);
2399 send_msg_5(STARTUPCORE, STATUSREPORT, busystatus?1:0,
2400 BAMBOO_NUM_OF_CORE, self_numsendobjs,
2401 self_numreceiveobjs, true);
2406 INLINE void processmsg_statusreport_I() {
2407 int data1 = msgdata[msgdataindex];
2409 int data2 = msgdata[msgdataindex];
2411 int data3 = msgdata[msgdataindex];
2413 int data4 = msgdata[msgdataindex];
2415 // receive a status confirm info
2416 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2417 // wrong core to receive such msg
2419 BAMBOO_DEBUGPRINT_REG(data2);
2421 BAMBOO_EXIT(0xe012);
2424 BAMBOO_DEBUGPRINT(0xe888);
2429 corestatus[data2] = data1;
2430 numsendobjs[data2] = data3;
2431 numreceiveobjs[data2] = data4;
2435 INLINE void processmsg_terminate_I() {
2437 BAMBOO_DEBUGPRINT(0xe889);
2441 #ifdef GC_CACHE_ADAPT
2442 bamboo_mask_timer_intr(); // disable the TILE_TIMER interrupt
2443 #endif // GC_CACHE_ADAPT
2444 #endif // MULTICORE_GC
2448 INLINE void processmsg_memrequest_I() {
2449 int data1 = msgdata[msgdataindex];
2451 int data2 = msgdata[msgdataindex];
2453 // receive a shared memory request msg
2454 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2455 // wrong core to receive such msg
2457 BAMBOO_DEBUGPRINT_REG(data2);
2459 BAMBOO_EXIT(0xe013);
2462 BAMBOO_DEBUGPRINT(0xe88a);
2468 // is currently doing gc, dump this msg
2469 if(INITPHASE == gcphase) {
2470 // if still in the initphase of gc, send a startinit msg again,
2471 // cache the msg first
2472 if(BAMBOO_CHECK_SEND_MODE()) {
2473 cache_msg_1(data2, GCSTARTINIT);
2475 send_msg_1(data2, GCSTARTINIT, true);
2480 mem = smemalloc_I(data2, data1, &allocsize);
2482 // send the start_va to request core, cache the msg first
2483 if(BAMBOO_CHECK_SEND_MODE()) {
2484 cache_msg_3(data2, MEMRESPONSE, mem, allocsize);
2486 send_msg_3(data2, MEMRESPONSE, mem, allocsize, true);
2489 // if mem == NULL, the gcflag of the startup core has been set
2490 // and all the other cores have been informed to start gc
2497 INLINE void processmsg_memresponse_I() {
2498 int data1 = msgdata[msgdataindex];
2500 int data2 = msgdata[msgdataindex];
2502 // receive a shared memory response msg
2504 BAMBOO_DEBUGPRINT(0xe88b);
2507 // if is currently doing gc, dump this msg
2511 bamboo_smem_size = 0;
2514 bamboo_smem_zero_top = 0;
2518 // fill header to store the size of this mem block
2519 BAMBOO_MEMSET_WH(data1, '\0', BAMBOO_CACHE_LINE_SIZE);
2520 (*((int*)data1)) = data2;
2521 bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
2522 bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
2523 bamboo_smem_zero_top = bamboo_cur_msp;
2525 bamboo_smem_size = data2;
2526 bamboo_cur_msp =(void*)(data1);
2536 INLINE void processmsg_gcstartpre_I() {
2538 // already stall for gc
2539 // send a update pregc information msg to the master core
2540 if(BAMBOO_CHECK_SEND_MODE()) {
2541 cache_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
2542 self_numsendobjs, self_numreceiveobjs);
2544 send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
2545 self_numsendobjs, self_numreceiveobjs, true);
2548 // the first time to be informed to start gc
2551 // is waiting for response of mem request
2552 // let it return NULL and start gc
2553 bamboo_smem_size = 0;
2554 bamboo_cur_msp = NULL;
2556 bamboo_smem_zero_top = NULL;
2561 INLINE void processmsg_gcstartinit_I() {
2562 gcphase = INITPHASE;
2565 INLINE void processmsg_gcstart_I() {
2567 BAMBOO_DEBUGPRINT(0xe88c);
2570 gcphase = MARKPHASE;
2573 INLINE void processmsg_gcstartcompact_I() {
2574 gcblock2fill = msgdata[msgdataindex];
2575 MSG_INDEXINC_I(); //msgdata[1];
2576 gcphase = COMPACTPHASE;
2579 INLINE void processmsg_gcstartmapinfo_I() {
2583 INLINE void processmsg_gcstartflush_I() {
2584 gcphase = FLUSHPHASE;
2587 INLINE void processmsg_gcfinishpre_I() {
2588 int data1 = msgdata[msgdataindex];
2590 int data2 = msgdata[msgdataindex];
2592 int data3 = msgdata[msgdataindex];
2594 // received a init phase finish msg
2595 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2596 // non startup core can not receive this msg
2598 BAMBOO_DEBUGPRINT_REG(data1);
2600 BAMBOO_EXIT(0xe014);
2602 // All cores should do init GC
2606 gccorestatus[data1] = 0;
2607 gcnumsendobjs[0][data1] = data2;
2608 gcnumreceiveobjs[0][data1] = data3;
2611 INLINE void processmsg_gcfinishinit_I() {
2612 int data1 = msgdata[msgdataindex];
2614 // received a init phase finish msg
2615 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2616 // non startup core can not receive this msg
2618 BAMBOO_DEBUGPRINT_REG(data1);
2620 BAMBOO_EXIT(0xe015);
2623 BAMBOO_DEBUGPRINT(0xe88c);
2624 BAMBOO_DEBUGPRINT_REG(data1);
2626 // All cores should do init GC
2627 if(data1 < NUMCORESACTIVE) {
2628 gccorestatus[data1] = 0;
2632 INLINE void processmsg_gcfinishmark_I() {
2633 int data1 = msgdata[msgdataindex];
2635 int data2 = msgdata[msgdataindex];
2637 int data3 = msgdata[msgdataindex];
2639 // received a mark phase finish msg
2640 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2641 // non startup core can not receive this msg
2643 BAMBOO_DEBUGPRINT_REG(data1);
2645 BAMBOO_EXIT(0xe016);
2647 // all cores should do mark
2648 if(data1 < NUMCORESACTIVE) {
2649 gccorestatus[data1] = 0;
2650 int entry_index = 0;
2653 entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
2656 entry_index = gcnumsrobjs_index;
2658 gcnumsendobjs[entry_index][data1] = data2;
2659 gcnumreceiveobjs[entry_index][data1] = data3;
2663 INLINE void processmsg_gcfinishcompact_I() {
2664 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2665 // non startup core can not receive this msg
2668 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
2670 BAMBOO_EXIT(0xe017);
2672 int cnum = msgdata[msgdataindex];
2673 MSG_INDEXINC_I(); //msgdata[1];
2674 int filledblocks = msgdata[msgdataindex];
2675 MSG_INDEXINC_I(); //msgdata[2];
2676 int heaptop = msgdata[msgdataindex];
2677 MSG_INDEXINC_I(); //msgdata[3];
2678 int data4 = msgdata[msgdataindex];
2679 MSG_INDEXINC_I(); //msgdata[4];
2680 // only gc cores need to do compact
2681 if(cnum < NUMCORES4GC) {
2682 if(COMPACTPHASE == gcphase) {
2683 gcfilledblocks[cnum] = filledblocks;
2684 gcloads[cnum] = heaptop;
2691 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
2692 // cache the msg first
2693 if(BAMBOO_CHECK_SEND_MODE()) {
2694 cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
2696 send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove, true);
2700 gccorestatus[cnum] = 0;
2702 } // if(cnum < NUMCORES4GC)
2705 INLINE void processmsg_gcfinishmapinfo_I() {
2706 int data1 = msgdata[msgdataindex];
2708 // received a map phase finish msg
2709 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2710 // non startup core can not receive this msg
2712 BAMBOO_DEBUGPRINT_REG(data1);
2714 BAMBOO_EXIT(0xe018);
2716 // all cores should do flush
2717 if(data1 < NUMCORES4GC) {
2718 gccorestatus[data1] = 0;
2723 INLINE void processmsg_gcfinishflush_I() {
2724 int data1 = msgdata[msgdataindex];
2726 // received a flush phase finish msg
2727 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2728 // non startup core can not receive this msg
2730 BAMBOO_DEBUGPRINT_REG(data1);
2732 BAMBOO_EXIT(0xe019);
2734 // all cores should do flush
2735 if(data1 < NUMCORESACTIVE) {
2736 gccorestatus[data1] = 0;
2740 INLINE void processmsg_gcmarkconfirm_I() {
2741 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2742 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2743 // wrong core to receive such msg
2744 BAMBOO_EXIT(0xe01a);
2746 // send response msg, cahce the msg first
2747 if(BAMBOO_CHECK_SEND_MODE()) {
2748 cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2749 gcbusystatus, gcself_numsendobjs,
2750 gcself_numreceiveobjs);
2752 send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2753 gcbusystatus, gcself_numsendobjs,
2754 gcself_numreceiveobjs, true);
2759 INLINE void processmsg_gcmarkreport_I() {
2760 int data1 = msgdata[msgdataindex];
2762 int data2 = msgdata[msgdataindex];
2764 int data3 = msgdata[msgdataindex];
2766 int data4 = msgdata[msgdataindex];
2768 // received a marked phase finish confirm response msg
2769 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2770 // wrong core to receive such msg
2772 BAMBOO_DEBUGPRINT_REG(data2);
2774 BAMBOO_EXIT(0xe01b);
2776 int entry_index = 0;
2780 entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
2782 // can never reach here
2784 entry_index = gcnumsrobjs_index;
2786 gccorestatus[data1] = data2;
2787 gcnumsendobjs[entry_index][data1] = data3;
2788 gcnumreceiveobjs[entry_index][data1] = data4;
2792 INLINE void processmsg_gcmarkedobj_I() {
2793 int data1 = msgdata[msgdataindex];
2795 // received a markedObj msg
2796 if(((int *)data1)[6] == INIT) {
2797 // this is the first time that this object is discovered,
2798 // set the flag as DISCOVERED
2799 ((int *)data1)[6] = DISCOVERED;
2800 gc_enqueue_I(data1);
2802 // set the remote flag
2803 ((int *)data1)[6] |= REMOTEM;
2804 gcself_numreceiveobjs++;
2805 gcbusystatus = true;
2808 INLINE void processmsg_gcmovestart_I() {
2810 gcdstcore = msgdata[msgdataindex];
2811 MSG_INDEXINC_I(); //msgdata[1];
2812 gcmovestartaddr = msgdata[msgdataindex];
2813 MSG_INDEXINC_I(); //msgdata[2];
2814 gcblock2fill = msgdata[msgdataindex];
2815 MSG_INDEXINC_I(); //msgdata[3];
2818 INLINE void processmsg_gcmaprequest_I() {
2819 void * dstptr = NULL;
2820 int data1 = msgdata[msgdataindex];
2822 int data2 = msgdata[msgdataindex];
2824 #ifdef LOCALHASHTBL_TEST
2825 RuntimeHashget(gcpointertbl, data1, &dstptr);
2827 dstptr = mgchashSearch(gcpointertbl, data1);
2829 if(NULL == dstptr) {
2830 // no such pointer in this core, something is wrong
2832 BAMBOO_DEBUGPRINT_REG(data1);
2833 BAMBOO_DEBUGPRINT_REG(data2);
2835 BAMBOO_EXIT(0xe01c);
2837 // send back the mapping info, cache the msg first
2838 if(BAMBOO_CHECK_SEND_MODE()) {
2839 cache_msg_3(data2, GCMAPINFO, data1, (int)dstptr);
2841 send_msg_3(data2, GCMAPINFO, data1, (int)dstptr, true);
2846 INLINE void processmsg_gcmapinfo_I() {
2847 int data1 = msgdata[msgdataindex];
2849 gcmappedobj = msgdata[msgdataindex]; // [2]
2851 #ifdef LOCALHASHTBL_TEST
2852 RuntimeHashadd_I(gcpointertbl, data1, gcmappedobj);
2854 mgchashInsert_I(gcpointertbl, data1, gcmappedobj);
2856 if(data1 == gcobj2map) {
2861 INLINE void processmsg_gcmaptbl_I() {
2862 int data1 = msgdata[msgdataindex];
2864 int data2 = msgdata[msgdataindex];
2866 gcrpointertbls[data2] = (mgcsharedhashtbl_t *)data1;
2869 INLINE void processmsg_gclobjinfo_I() {
2872 int data1 = msgdata[msgdataindex];
2874 int data2 = msgdata[msgdataindex];
2876 if(BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1) {
2878 BAMBOO_DEBUGPRINT_REG(data2);
2880 BAMBOO_EXIT(0xe01d);
2882 // store the mark result info
2884 gcloads[cnum] = msgdata[msgdataindex];
2885 MSG_INDEXINC_I(); // msgdata[3];
2886 int data4 = msgdata[msgdataindex];
2888 if(gcheaptop < data4) {
2891 // large obj info here
2892 for(int k = 5; k < data1; k+=2) {
2893 int lobj = msgdata[msgdataindex];
2894 MSG_INDEXINC_I(); //msgdata[k++];
2895 int length = msgdata[msgdataindex];
2896 MSG_INDEXINC_I(); //msgdata[k++];
2897 gc_lobjenqueue_I(lobj, length, cnum);
2899 } // for(int k = 5; k < msgdata[1];)
2902 INLINE void processmsg_gclobjmapping_I() {
2903 int data1 = msgdata[msgdataindex];
2905 int data2 = msgdata[msgdataindex];
2907 #ifdef LOCALHASHTBL_TEST
2908 RuntimeHashadd_I(gcpointertbl, data1, data2);
2910 mgchashInsert_I(gcpointertbl, data1, data2);
2912 mgcsharedhashInsert_I(gcsharedptbl, data1, data2);
2916 INLINE void processmsg_gcprofiles_I() {
2917 int data1 = msgdata[msgdataindex];
2919 int data2 = msgdata[msgdataindex];
2921 int data3 = msgdata[msgdataindex];
2923 gc_num_obj += data1;
2924 gc_num_liveobj += data2;
2925 gc_num_forwardobj += data3;
2928 #endif // GC_PROFILE
2930 #ifdef GC_CACHE_ADAPT
2931 INLINE void processmsg_gcstartpref_I() {
2932 gcphase = PREFINISHPHASE;
2935 INLINE void processmsg_gcfinishpref_I() {
2936 int data1 = msgdata[msgdataindex];
2938 // received a flush phase finish msg
2939 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2940 // non startup core can not receive this msg
2942 BAMBOO_DEBUGPRINT_REG(data1);
2944 BAMBOO_EXIT(0xe01e);
2946 // all cores should do flush
2947 if(data1 < NUMCORESACTIVE) {
2948 gccorestatus[data1] = 0;
2951 #endif // GC_CACHE_ADAPT
2952 #endif // #ifdef MULTICORE_GC
2954 // receive object transferred from other cores
2955 // or the terminate message from other cores
2956 // Should be invoked in critical sections!!
2957 // NOTICE: following format is for threadsimulate version only
2958 // RAW version please see previous description
2959 // format: type + object
2960 // type: -1--stall msg
2962 // return value: 0--received an object
2963 // 1--received nothing
2964 // 2--received a Stall Msg
2965 // 3--received a lock Msg
2966 // RAW version: -1 -- received nothing
2967 // otherwise -- received msg type
2968 int receiveObject(int send_port_pending) {
2969 #ifdef PROFILE_INTERRUPT
2970 if(!interruptInfoOverflow) {
2971 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
2972 interruptInfoArray[interruptInfoIndex] = intInfo;
2973 intInfo->startTime = BAMBOO_GET_EXE_TIME();
2974 intInfo->endTime = -1;
2978 // get the incoming msgs
2979 if(receiveMsg(send_port_pending) == -1) {
2983 // processing received msgs
2985 MSG_REMAINSIZE_I(&size);
2986 if((size == 0) || (checkMsgLength_I(size) == -1)) {
2988 // have new coming msg
2989 if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
2996 if(msglength <= size) {
2997 // have some whole msg
2999 type = msgdata[msgdataindex]; //[0]
3001 msgdatafull = false;
3004 // receive a object transfer msg
3005 processmsg_transobj_I();
3010 // receive a stall msg
3011 processmsg_transtall_I();
3015 // GC version have no lock msgs
3016 #ifndef MULTICORE_GC
3018 // receive lock request msg, handle it right now
3019 processmsg_lockrequest_I();
3021 } // case LOCKREQUEST
3024 // receive lock grount msg
3025 processmsg_lockgrount_I();
3027 } // case LOCKGROUNT
3030 // receive lock deny msg
3031 processmsg_lockdeny_I();
3036 processmsg_lockrelease_I();
3038 } // case LOCKRELEASE
3039 #endif // #ifndef MULTICORE_GC
3042 case PROFILEOUTPUT: {
3043 // receive an output profile data request msg
3044 processmsg_profileoutput_I();
3046 } // case PROFILEOUTPUT
3048 case PROFILEFINISH: {
3049 // receive a profile output finish msg
3050 processmsg_profilefinish_I();
3052 } // case PROFILEFINISH
3053 #endif // #ifdef PROFILE
3055 // GC version has no lock msgs
3056 #ifndef MULTICORE_GC
3057 case REDIRECTLOCK: {
3058 // receive a redirect lock request msg, handle it right now
3059 processmsg_redirectlock_I();
3061 } // case REDIRECTLOCK
3063 case REDIRECTGROUNT: {
3064 // receive a lock grant msg with redirect info
3065 processmsg_redirectgrount_I();
3067 } // case REDIRECTGROUNT
3069 case REDIRECTDENY: {
3070 // receive a lock deny msg with redirect info
3071 processmsg_redirectdeny_I();
3073 } // case REDIRECTDENY
3075 case REDIRECTRELEASE: {
3076 // receive a lock release msg with redirect info
3077 processmsg_redirectrelease_I();
3079 } // case REDIRECTRELEASE
3080 #endif // #ifndef MULTICORE_GC
3082 case STATUSCONFIRM: {
3083 // receive a status confirm info
3084 processmsg_statusconfirm_I();
3086 } // case STATUSCONFIRM
3088 case STATUSREPORT: {
3089 processmsg_statusreport_I();
3091 } // case STATUSREPORT
3094 // receive a terminate msg
3095 processmsg_terminate_I();
3100 processmsg_memrequest_I();
3102 } // case MEMREQUEST
3105 processmsg_memresponse_I();
3107 } // case MEMRESPONSE
3112 processmsg_gcstartpre_I();
3114 } // case GCSTARTPRE
3117 processmsg_gcstartinit_I();
3119 } // case GCSTARTINIT
3122 // receive a start GC msg
3123 processmsg_gcstart_I();
3127 case GCSTARTCOMPACT: {
3128 // a compact phase start msg
3129 processmsg_gcstartcompact_I();
3131 } // case GCSTARTCOMPACT
3133 case GCSTARTMAPINFO: {
3134 // received a flush phase start msg
3135 processmsg_gcstartmapinfo_I();
3137 } // case GCSTARTFLUSH
3139 case GCSTARTFLUSH: {
3140 // received a flush phase start msg
3141 processmsg_gcstartflush_I();
3143 } // case GCSTARTFLUSH
3146 processmsg_gcfinishpre_I();
3148 } // case GCFINISHPRE
3150 case GCFINISHINIT: {
3151 processmsg_gcfinishinit_I();
3153 } // case GCFINISHINIT
3155 case GCFINISHMARK: {
3156 processmsg_gcfinishmark_I();
3158 } // case GCFINISHMARK
3160 case GCFINISHCOMPACT: {
3161 // received a compact phase finish msg
3162 processmsg_gcfinishcompact_I();
3164 } // case GCFINISHCOMPACT
3166 case GCFINISHMAPINFO: {
3167 processmsg_gcfinishmapinfo_I();
3169 } // case GCFINISHMAPINFO
3171 case GCFINISHFLUSH: {
3172 processmsg_gcfinishflush_I();
3174 } // case GCFINISHFLUSH
3177 // received a GC finish msg
3178 gcphase = FINISHPHASE;
3182 case GCMARKCONFIRM: {
3183 // received a marked phase finish confirm request msg
3184 // all cores should do mark
3185 processmsg_gcmarkconfirm_I();
3187 } // case GCMARKCONFIRM
3189 case GCMARKREPORT: {
3190 processmsg_gcmarkreport_I();
3192 } // case GCMARKREPORT
3195 processmsg_gcmarkedobj_I();
3197 } // case GCMARKEDOBJ
3200 // received a start moving objs msg
3201 processmsg_gcmovestart_I();
3203 } // case GCMOVESTART
3205 case GCMAPREQUEST: {
3206 // received a mapping info request msg
3207 processmsg_gcmaprequest_I();
3209 } // case GCMAPREQUEST
3212 // received a mapping info response msg
3213 processmsg_gcmapinfo_I();
3218 // received a mapping tbl response msg
3219 processmsg_gcmaptbl_I();
3223 case GCLOBJREQUEST: {
3224 // received a large objs info request msg
3225 transferMarkResults_I();
3227 } // case GCLOBJREQUEST
3230 // received a large objs info response msg
3231 processmsg_gclobjinfo_I();
3233 } // case GCLOBJINFO
3235 case GCLOBJMAPPING: {
3236 // received a large obj mapping info msg
3237 processmsg_gclobjmapping_I();
3239 } // case GCLOBJMAPPING
3243 // received a gcprofiles msg
3244 processmsg_gcprofiles_I();
3247 #endif // GC_PROFILE
3249 #ifdef GC_CACHE_ADAPT
3251 // received a gcstartpref msg
3252 processmsg_gcstartpref_I();
3256 case GCFINISHPREF: {
3257 // received a gcfinishpref msg
3258 processmsg_gcfinishpref_I();
3261 #endif // GC_CACHE_ADAPT
3262 #endif // #ifdef MULTICORE_GC
3267 msglength = BAMBOO_MSG_BUF_LENGTH;
3269 if((msgdataindex != msgdatalast) || (msgdatafull)) {
3270 // still have available msg
3274 BAMBOO_DEBUGPRINT(0xe88d);
3277 // have new coming msg
3278 if(BAMBOO_MSG_AVAIL() != 0) {
3282 #ifdef PROFILE_INTERRUPT
3283 if(!interruptInfoOverflow) {
3284 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
3285 interruptInfoIndex++;
3286 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
3287 interruptInfoOverflow = true;
3295 BAMBOO_DEBUGPRINT(0xe88e);
3301 int enqueuetasks(struct parameterwrapper *parameter,
3302 struct parameterwrapper *prevptr,
3303 struct ___Object___ *ptr,
3305 int numenterflags) {
3306 void * taskpointerarray[MAXTASKPARAMS];
3308 int numiterators=parameter->task->numTotal-1;
3311 struct taskdescriptor * task=parameter->task;
3313 //this add the object to parameterwrapper
3314 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
3315 numenterflags, enterflags==NULL);
3317 /* Add enqueued object to parameter vector */
3318 taskpointerarray[parameter->slot]=ptr;
3320 /* Reset iterators */
3321 for(j=0; j<numiterators; j++) {
3322 toiReset(¶meter->iterators[j]);
3325 /* Find initial state */
3326 for(j=0; j<numiterators; j++) {
3328 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3329 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3331 /* Need to backtrack */
3332 toiReset(¶meter->iterators[j]);
3336 /* Nothing to enqueue */
3342 /* Enqueue current state */
3344 struct taskparamdescriptor *tpd=
3345 RUNMALLOC(sizeof(struct taskparamdescriptor));
3347 tpd->numParameters=numiterators+1;
3348 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
3350 for(j=0; j<=numiterators; j++) {
3351 //store the actual parameters
3352 tpd->parameterArray[j]=taskpointerarray[j];
3355 if (!gencontains(activetasks,tpd)) {
3356 genputtable(activetasks, tpd, tpd);
3358 RUNFREE(tpd->parameterArray);
3362 /* This loop iterates to the next parameter combination */
3363 if (numiterators==0)
3366 for(j=numiterators-1; j<numiterators; j++) {
3369 ¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3370 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3372 /* Need to backtrack */
3373 toiReset(¶meter->iterators[j]);
3377 /* Nothing more to enqueue */
3385 int enqueuetasks_I(struct parameterwrapper *parameter,
3386 struct parameterwrapper *prevptr,
3387 struct ___Object___ *ptr,
3389 int numenterflags) {
3390 void * taskpointerarray[MAXTASKPARAMS];
3392 int numiterators=parameter->task->numTotal-1;
3395 struct taskdescriptor * task=parameter->task;
3397 //this add the object to parameterwrapper
3398 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
3399 numenterflags, enterflags==NULL);
3401 /* Add enqueued object to parameter vector */
3402 taskpointerarray[parameter->slot]=ptr;
3404 /* Reset iterators */
3405 for(j=0; j<numiterators; j++) {
3406 toiReset(¶meter->iterators[j]);
3409 /* Find initial state */
3410 for(j=0; j<numiterators; j++) {
3412 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3413 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3415 /* Need to backtrack */
3416 toiReset(¶meter->iterators[j]);
3420 /* Nothing to enqueue */
3426 /* Enqueue current state */
3428 struct taskparamdescriptor *tpd=
3429 RUNMALLOC_I(sizeof(struct taskparamdescriptor));
3431 tpd->numParameters=numiterators+1;
3432 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
3434 for(j=0; j<=numiterators; j++) {
3435 //store the actual parameters
3436 tpd->parameterArray[j]=taskpointerarray[j];
3439 if (!gencontains(activetasks,tpd)) {
3440 genputtable_I(activetasks, tpd, tpd);
3442 RUNFREE(tpd->parameterArray);
3446 /* This loop iterates to the next parameter combination */
3447 if (numiterators==0)
3450 for(j=numiterators-1; j<numiterators; j++) {
3453 ¶meter->iterators[j], taskpointerarray OPTARG(failed)))
3454 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3456 /* Need to backtrack */
3457 toiReset(¶meter->iterators[j]);
3461 /* Nothing more to enqueue */
3475 int containstag(struct ___Object___ *ptr,
3476 struct ___TagDescriptor___ *tag);
3478 #ifndef MULTICORE_GC
3479 void releasewritelock_r(void * lock, void * redirectlock) {
3481 int reallock = (int)lock;
3482 targetcore = (reallock >> 5) % NUMCORES;
3484 BAMBOO_DEBUGPRINT(0xe671);
3485 BAMBOO_DEBUGPRINT_REG((int)lock);
3486 BAMBOO_DEBUGPRINT_REG(reallock);
3487 BAMBOO_DEBUGPRINT_REG(targetcore);
3489 if(targetcore == BAMBOO_NUM_OF_CORE) {
3490 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3491 BAMBOO_DEBUGPRINT(0xf001);
3492 // reside on this core
3493 if(!RuntimeHashcontainskey(locktbl, reallock)) {
3494 // no locks for this object, something is wrong
3495 BAMBOO_EXIT(0xe01f);
3498 struct LockValue * lockvalue = NULL;
3499 BAMBOO_DEBUGPRINT(0xe672);
3500 RuntimeHashget(locktbl, reallock, &rwlock_obj);
3501 lockvalue = (struct LockValue *)rwlock_obj;
3502 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
3504 lockvalue->redirectlock = (int)redirectlock;
3505 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
3507 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3508 BAMBOO_DEBUGPRINT(0xf000);
3511 // send lock release with redirect info msg
3512 // for 32 bit machine, the size is always 4 words
3513 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock,
3514 (int)redirectlock, false);
3519 void executetasks() {
3520 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
3523 struct ___Object___ * tmpparam = NULL;
3524 struct parameterdescriptor * pd=NULL;
3525 struct parameterwrapper *pw=NULL;
3535 while(hashsize(activetasks)>0) {
3537 if(gcflag) gc(NULL);
3539 BAMBOO_DEBUGPRINT(0xe990);
3541 /* See if there are any active tasks */
3544 #ifdef ACCURATEPROFILE
3545 profileTaskStart("tpd checking");
3550 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
3551 genfreekey(activetasks, currtpd);
3553 numparams=currtpd->task->numParameters;
3554 numtotal=currtpd->task->numTotal;
3556 // (TODO, this table should be empty after all locks are released)
3558 // get all required locks
3559 runtime_locklen = 0;
3560 // check which locks are needed
3561 for(i = 0; i < numparams; i++) {
3562 void * param = currtpd->parameterArray[i];
3566 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
3568 taskpointerarray[i+OFFSET]=param;
3571 /*if(((struct ___Object___ *)param)->lock == NULL) {
3572 tmplock = (int)param;
3574 struct ___Object___ * obj = (struct ___Object___ *)param;
3575 while(obj->lock != NULL) {
3576 obj = (struct ___Object___ *)(obj->lock);
3578 tmplock = (int)(obj);
3580 struct ___Object___ * obj = (struct ___Object___ *)param;
3581 while(obj->lock != NULL) {
3582 obj = (struct ___Object___ *)(obj->lock);
3584 tmplock = (int)(obj);
3585 // insert into the locks array
3586 for(j = 0; j < runtime_locklen; j++) {
3587 if(runtime_locks[j].value == tmplock) {
3590 } else if(runtime_locks[j].value > tmplock) {
3595 int h = runtime_locklen;
3597 runtime_locks[h].redirectlock = runtime_locks[h-1].redirectlock;
3598 runtime_locks[h].value = runtime_locks[h-1].value;
3600 runtime_locks[j].value = tmplock;
3601 runtime_locks[j].redirectlock = (int)param;
3604 } // line 2713: for(i = 0; i < numparams; i++)
3605 // grab these required locks
3606 BAMBOO_DEBUGPRINT(0xe991);
3608 for(i = 0; i < runtime_locklen; i++) {
3609 int * lock = (int *)(runtime_locks[i].value);//(runtime_locks[i].redirectlock);
3611 // require locks for this parameter if it is not a startup object
3612 BAMBOO_DEBUGPRINT_REG((int)lock);
3613 BAMBOO_DEBUGPRINT_REG((int)(runtime_locks[i].value));
3615 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3616 BAMBOO_DEBUGPRINT(0xf001);
3618 BAMBOO_WAITING_FOR_LOCK(0);
3622 while(BAMBOO_WAITING_FOR_LOCK(0) != -1) {
3626 grount = lockresult;
3635 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3636 BAMBOO_DEBUGPRINT(0xf000);
3639 BAMBOO_DEBUGPRINT(0xe992);
3640 BAMBOO_DEBUGPRINT_REG(lock);
3641 // check if has the lock already
3642 // can not get the lock, try later
3643 // release all grabbed locks for previous parameters
3644 for(j = 0; j < i; ++j) {
3645 lock = (int*)(runtime_locks[j].value/*redirectlock*/);
3646 releasewritelock(lock);
3648 genputtable(activetasks, currtpd, currtpd);
3649 if(hashsize(activetasks) == 1) {
3650 // only one task right now, wait a little while before next try
3656 #ifdef ACCURATEPROFILE
3657 // fail, set the end of the checkTaskInfo
3663 } // line 2752: for(i = 0; i < runtime_locklen; i++)
3665 BAMBOO_DEBUGPRINT(0xe993);
3666 /* Make sure that the parameters are still in the queues */
3667 for(i=0; i<numparams; i++) {
3668 void * parameter=currtpd->parameterArray[i];
3672 BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
3673 classsize[((struct ___Object___ *)parameter)->type]);
3675 tmpparam = (struct ___Object___ *)parameter;
3676 pd=currtpd->task->descriptorarray[i];
3677 pw=(struct parameterwrapper *) pd->queue;
3678 /* Check that object is still in queue */
3680 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
3681 BAMBOO_DEBUGPRINT(0xe994);
3682 BAMBOO_DEBUGPRINT_REG(parameter);
3683 // release grabbed locks
3684 for(j = 0; j < runtime_locklen; ++j) {
3685 int * lock = (int *)(runtime_locks[j].value/*redirectlock*/);
3686 releasewritelock(lock);
3688 RUNFREE(currtpd->parameterArray);
3694 /* Check if the object's flags still meets requirements */
3698 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
3699 andmask=pw->intarray[tmpi*2];
3700 checkmask=pw->intarray[tmpi*2+1];
3701 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
3707 // flags are never suitable
3708 // remove this obj from the queue
3710 int UNUSED, UNUSED2;
3712 BAMBOO_DEBUGPRINT(0xe995);
3713 BAMBOO_DEBUGPRINT_REG(parameter);
3714 ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
3715 (int *) &enterflags, &UNUSED, &UNUSED2);
3716 ObjectHashremove(pw->objectset, (int)parameter);
3717 if (enterflags!=NULL)
3718 RUNFREE(enterflags);
3719 // release grabbed locks
3720 for(j = 0; j < runtime_locklen; ++j) {
3721 int * lock = (int *)(runtime_locks[j].value/*redirectlock*/);
3722 releasewritelock(lock);
3724 RUNFREE(currtpd->parameterArray);
3728 #ifdef ACCURATEPROFILE
3729 // fail, set the end of the checkTaskInfo
3734 } // line 2878: if (!ismet)
3738 /* Check that object still has necessary tags */
3739 for(j=0; j<pd->numbertags; j++) {
3740 int slotid=pd->tagarray[2*j]+numparams;
3741 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
3742 if (!containstag(parameter, tagd)) {
3743 BAMBOO_DEBUGPRINT(0xe996);
3745 // release grabbed locks
3747 for(tmpj = 0; tmpj < runtime_locklen; ++tmpj) {
3748 int * lock = (int *)(runtime_locks[tmpj].value/*redirectlock*/);
3749 releasewritelock(lock);
3752 RUNFREE(currtpd->parameterArray);
3756 } // line2911: if (!containstag(parameter, tagd))
3757 } // line 2808: for(j=0; j<pd->numbertags; j++)
3759 taskpointerarray[i+OFFSET]=parameter;
3760 } // line 2824: for(i=0; i<numparams; i++)
3762 for(; i<numtotal; i++) {
3763 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
3768 /* Actually call task */
3770 ((int *)taskpointerarray)[0]=currtpd->numParameters;
3771 taskpointerarray[1]=NULL;
3774 #ifdef ACCURATEPROFILE
3775 // check finish, set the end of the checkTaskInfo
3778 profileTaskStart(currtpd->task->name);
3781 BAMBOO_DEBUGPRINT(0xe997);
3782 ((void (*)(void **))currtpd->task->taskptr)(taskpointerarray);
3785 #ifdef ACCURATEPROFILE
3786 // task finish, set the end of the checkTaskInfo
3788 // new a PostTaskInfo for the post-task execution
3789 profileTaskStart("post task execution");
3792 BAMBOO_DEBUGPRINT(0xe998);
3793 BAMBOO_DEBUGPRINT_REG(islock);
3796 BAMBOO_DEBUGPRINT(0xe999);
3797 for(i = runtime_locklen; i>0; i--) {
3798 void * ptr = (void *)(runtime_locks[i-1].redirectlock);
3799 int * lock = (int *)(runtime_locks[i-1].value);
3800 BAMBOO_DEBUGPRINT_REG((int)ptr);
3801 BAMBOO_DEBUGPRINT_REG((int)lock);
3802 BAMBOO_DEBUGPRINT_REG(*((int*)lock+5));
3803 #ifndef MULTICORE_GC
3805 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
3807 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
3808 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
3809 releasewritelock_r(lock, (int *)redirectlock);
3817 releasewritelock(lock); // ptr
3820 } // line 3015: if(islock)
3823 // post task execution finish, set the end of the postTaskInfo
3827 // Free up task parameter descriptor
3828 RUNFREE(currtpd->parameterArray);
3831 BAMBOO_DEBUGPRINT(0xe99a);
3833 //} // if (hashsize(activetasks)>0)
3834 } // while(hashsize(activetasks)>0)
3835 BAMBOO_DEBUGPRINT(0xe99b);
3838 /* This function processes an objects tags */
3839 void processtags(struct parameterdescriptor *pd,
3841 struct parameterwrapper *parameter,
3842 int * iteratorcount,
3847 for(i=0; i<pd->numbertags; i++) {
3848 int slotid=pd->tagarray[2*i];
3849 int tagid=pd->tagarray[2*i+1];
3851 if (statusarray[slotid+numparams]==0) {
3852 parameter->iterators[*iteratorcount].istag=1;
3853 parameter->iterators[*iteratorcount].tagid=tagid;
3854 parameter->iterators[*iteratorcount].slot=slotid+numparams;
3855 parameter->iterators[*iteratorcount].tagobjectslot=index;
3856 statusarray[slotid+numparams]=1;
3863 void processobject(struct parameterwrapper *parameter,
3865 struct parameterdescriptor *pd,
3871 struct ObjectHash * objectset=
3872 ((struct parameterwrapper *)pd->queue)->objectset;
3874 parameter->iterators[*iteratorcount].istag=0;
3875 parameter->iterators[*iteratorcount].slot=index;
3876 parameter->iterators[*iteratorcount].objectset=objectset;
3877 statusarray[index]=1;
3879 for(i=0; i<pd->numbertags; i++) {
3880 int slotid=pd->tagarray[2*i];
3881 if (statusarray[slotid+numparams]!=0) {
3882 /* This tag has already been enqueued, use it to narrow search */
3883 parameter->iterators[*iteratorcount].tagbindings[tagcount]=
3888 parameter->iterators[*iteratorcount].numtags=tagcount;
3893 /* This function builds the iterators for a task & parameter */
3895 void builditerators(struct taskdescriptor * task,
3897 struct parameterwrapper * parameter) {
3898 int statusarray[MAXTASKPARAMS];
3900 int numparams=task->numParameters;
3901 int iteratorcount=0;
3902 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
3904 statusarray[index]=1; /* Initial parameter */
3905 /* Process tags for initial iterator */
3907 processtags(task->descriptorarray[index], index, parameter,
3908 &iteratorcount, statusarray, numparams);
3912 /* Check for objects with existing tags */
3913 for(i=0; i<numparams; i++) {
3914 if (statusarray[i]==0) {
3915 struct parameterdescriptor *pd=task->descriptorarray[i];
3917 for(j=0; j<pd->numbertags; j++) {
3918 int slotid=pd->tagarray[2*j];
3919 if(statusarray[slotid+numparams]!=0) {
3920 processobject(parameter,i,pd,&iteratorcount,
3921 statusarray,numparams);
3922 processtags(pd,i,parameter,&iteratorcount,statusarray,numparams);
3929 /* Next do objects w/ unbound tags*/
3931 for(i=0; i<numparams; i++) {
3932 if (statusarray[i]==0) {
3933 struct parameterdescriptor *pd=task->descriptorarray[i];
3934 if (pd->numbertags>0) {
3935 processobject(parameter,i,pd,&iteratorcount,statusarray,numparams);
3936 processtags(pd,i,parameter,&iteratorcount,statusarray,numparams);
3942 /* Nothing with a tag enqueued */
3944 for(i=0; i<numparams; i++) {
3945 if (statusarray[i]==0) {
3946 struct parameterdescriptor *pd=task->descriptorarray[i];
3947 processobject(parameter,i,pd,&iteratorcount,statusarray,numparams);
3948 processtags(pd,i,parameter,&iteratorcount,statusarray,numparams);
3961 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3964 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3965 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3967 printf("%s\n", task->name);
3969 for(j=0; j<task->numParameters; j++) {
3970 struct parameterdescriptor *param=task->descriptorarray[j];
3971 struct parameterwrapper *parameter=param->queue;
3972 struct ObjectHash * set=parameter->objectset;
3973 struct ObjectIterator objit;
3975 printf(" Parameter %d\n", j);
3977 ObjectHashiterator(set, &objit);
3978 while(ObjhasNext(&objit)) {
3979 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
3980 struct ___Object___ * tagptr=obj->___tags___;
3981 int nonfailed=Objdata4(&objit);
3982 int numflags=Objdata3(&objit);
3983 int flags=Objdata2(&objit);
3986 printf(" Contains %lx\n", obj);
3987 printf(" flag=%d\n", obj->flag);
3990 } else if (tagptr->type==TAGTYPE) {
3992 printf(" tag=%lx\n",tagptr);
3998 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
3999 for(; tagindex<ao->___cachedCode___; tagindex++) {
4001 printf(" tag=%lx\n",ARRAYGET(ao,struct ___TagDescriptor___*,
4014 /* This function processes the task information to create queues for
4015 each parameter type. */
4017 void processtasks() {
4019 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
4022 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
4023 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
4026 /* Build objectsets */
4027 for(j=0; j<task->numParameters; j++) {
4028 struct parameterdescriptor *param=task->descriptorarray[j];
4029 struct parameterwrapper *parameter=param->queue;
4030 parameter->objectset=allocateObjectHash(10);
4031 parameter->task=task;
4034 /* Build iterators for parameters */
4035 for(j=0; j<task->numParameters; j++) {
4036 struct parameterdescriptor *param=task->descriptorarray[j];
4037 struct parameterwrapper *parameter=param->queue;
4038 builditerators(task, j, parameter);
4043 void toiReset(struct tagobjectiterator * it) {
4046 } else if (it->numtags>0) {
4049 ObjectHashiterator(it->objectset, &it->it);
4053 int toiHasNext(struct tagobjectiterator *it,
4054 void ** objectarray OPTARG(int * failed)) {
4057 /* Get object with tags */
4058 struct ___Object___ *obj=objectarray[it->tagobjectslot];
4059 struct ___Object___ *tagptr=obj->___tags___;
4060 if (tagptr->type==TAGTYPE) {
4061 if ((it->tagobjindex==0)&& /* First object */
4062 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
4067 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
4068 int tagindex=it->tagobjindex;
4069 for(; tagindex<ao->___cachedCode___; tagindex++) {
4070 struct ___TagDescriptor___ *td=
4071 ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
4072 if (td->flag==it->tagid) {
4073 it->tagobjindex=tagindex; /* Found right type of tag */
4079 } else if (it->numtags>0) {
4080 /* Use tags to locate appropriate objects */
4081 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
4082 struct ___Object___ *objptr=tag->flagptr;
4084 if (objptr->type!=OBJECTARRAYTYPE) {
4085 if (it->tagobjindex>0)
4087 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
4089 for(i=1; i<it->numtags; i++) {
4090 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
4091 if (!containstag(objptr,tag2))
4096 struct ArrayObject *ao=(struct ArrayObject *) objptr;
4099 for(tagindex=it->tagobjindex;tagindex<ao->___cachedCode___;tagindex++){
4100 struct ___Object___ *objptr=
4101 ARRAYGET(ao,struct ___Object___*,tagindex);
4102 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
4104 for(i=1; i<it->numtags; i++) {
4105 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
4106 if (!containstag(objptr,tag2))
4109 it->tagobjindex=tagindex;
4114 it->tagobjindex=tagindex;
4118 return ObjhasNext(&it->it);
4122 int containstag(struct ___Object___ *ptr,
4123 struct ___TagDescriptor___ *tag) {
4125 struct ___Object___ * objptr=tag->flagptr;
4126 if (objptr->type==OBJECTARRAYTYPE) {
4127 struct ArrayObject *ao=(struct ArrayObject *)objptr;
4128 for(j=0; j<ao->___cachedCode___; j++) {
4129 if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
4139 void toiNext(struct tagobjectiterator *it,
4140 void ** objectarray OPTARG(int * failed)) {
4141 /* hasNext has all of the intelligence */
4144 /* Get object with tags */
4145 struct ___Object___ *obj=objectarray[it->tagobjectslot];
4146 struct ___Object___ *tagptr=obj->___tags___;
4147 if (tagptr->type==TAGTYPE) {
4149 objectarray[it->slot]=tagptr;
4151 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
4152 objectarray[it->slot]=
4153 ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
4155 } else if (it->numtags>0) {
4156 /* Use tags to locate appropriate objects */
4157 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
4158 struct ___Object___ *objptr=tag->flagptr;
4159 if (objptr->type!=OBJECTARRAYTYPE) {
4161 objectarray[it->slot]=objptr;
4163 struct ArrayObject *ao=(struct ArrayObject *) objptr;
4164 objectarray[it->slot]=
4165 ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
4168 /* Iterate object */
4169 objectarray[it->slot]=(void *)Objkey(&it->it);
4175 inline void profileTaskStart(char * taskname) {
4176 if(!taskInfoOverflow) {
4177 TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
4178 taskInfoArray[taskInfoIndex] = taskInfo;
4179 taskInfo->taskName = taskname;
4180 taskInfo->startTime = BAMBOO_GET_EXE_TIME();
4181 taskInfo->endTime = -1;
4182 taskInfo->exitIndex = -1;
4183 taskInfo->newObjs = NULL;
4187 inline void profileTaskEnd() {
4188 if(!taskInfoOverflow) {
4189 taskInfoArray[taskInfoIndex]->endTime = BAMBOO_GET_EXE_TIME();
4191 if(taskInfoIndex == TASKINFOLENGTH) {
4192 taskInfoOverflow = true;
4197 // output the profiling data
4198 void outputProfileData() {
4201 unsigned long long totaltasktime = 0;
4202 unsigned long long preprocessingtime = 0;
4203 unsigned long long objqueuecheckingtime = 0;
4204 unsigned long long postprocessingtime = 0;
4205 unsigned long long other = 0;
4206 unsigned long long averagetasktime = 0;
4209 printf("Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
4210 // output task related info
4211 for(i = 0; i < taskInfoIndex; i++) {
4212 TaskInfo* tmpTInfo = taskInfoArray[i];
4213 unsigned long long duration = tmpTInfo->endTime - tmpTInfo->startTime;
4214 printf("%s, %lld, %lld, %lld, %lld",
4215 tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime,
4216 duration, tmpTInfo->exitIndex);
4217 // summarize new obj info
4218 if(tmpTInfo->newObjs != NULL) {
4219 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
4220 struct RuntimeIterator * iter = NULL;
4221 while(0 == isEmpty(tmpTInfo->newObjs)) {
4222 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
4223 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
4225 RuntimeHashget(nobjtbl, (int)objtype, &num);
4226 RuntimeHashremovekey(nobjtbl, (int)objtype);
4228 RuntimeHashadd(nobjtbl, (int)objtype, num);
4230 RuntimeHashadd(nobjtbl, (int)objtype, 1);
4232 //printf(stderr, "new obj!\n");
4235 // output all new obj info
4236 iter = RuntimeHashcreateiterator(nobjtbl);
4237 while(RunhasNext(iter)) {
4238 char * objtype = (char *)Runkey(iter);
4239 int num = Runnext(iter);
4240 printf(", %s, %d", objtype, num);
4244 if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
4245 preprocessingtime += duration;
4246 } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
4247 postprocessingtime += duration;
4248 } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
4249 objqueuecheckingtime += duration;
4251 totaltasktime += duration;
4252 averagetasktime += duration;
4257 if(taskInfoOverflow) {
4258 printf("Caution: task info overflow!\n");
4261 other = totalexetime-totaltasktime-preprocessingtime-postprocessingtime;
4262 averagetasktime /= tasknum;
4264 printf("\nTotal time: %lld\n", totalexetime);
4265 printf("Total task execution time: %lld (%d%%)\n", totaltasktime,
4266 (int)(((double)totaltasktime/(double)totalexetime)*100));
4267 printf("Total objqueue checking time: %lld (%d%%)\n",
4268 objqueuecheckingtime,
4269 (int)(((double)objqueuecheckingtime/(double)totalexetime)*100));
4270 printf("Total pre-processing time: %lld (%d%%)\n", preprocessingtime,
4271 (int)(((double)preprocessingtime/(double)totalexetime)*100));
4272 printf("Total post-processing time: %lld (%d%%)\n", postprocessingtime,
4273 (int)(((double)postprocessingtime/(double)totalexetime)*100));
4274 printf("Other time: %lld (%d%%)\n", other,
4275 (int)(((double)other/(double)totalexetime)*100));
4278 printf("\nAverage task execution time: %lld\n", averagetasktime);
4284 BAMBOO_PRINT(0xdddd);
4285 // output task related info
4286 for(i= 0; i < taskInfoIndex; i++) {
4287 TaskInfo* tmpTInfo = taskInfoArray[i];
4288 char* tmpName = tmpTInfo->taskName;
4289 int nameLen = strlen(tmpName);
4290 BAMBOO_PRINT(0xddda);
4291 for(j = 0; j < nameLen; j++) {
4292 BAMBOO_PRINT_REG(tmpName[j]);
4294 BAMBOO_PRINT(0xdddb);
4295 BAMBOO_PRINT_REG(tmpTInfo->startTime);
4296 BAMBOO_PRINT_REG(tmpTInfo->endTime);
4297 BAMBOO_PRINT_REG(tmpTInfo->exitIndex);
4298 if(tmpTInfo->newObjs != NULL) {
4299 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
4300 struct RuntimeIterator * iter = NULL;
4301 while(0 == isEmpty(tmpTInfo->newObjs)) {
4302 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
4303 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
4305 RuntimeHashget(nobjtbl, (int)objtype, &num);
4306 RuntimeHashremovekey(nobjtbl, (int)objtype);
4308 RuntimeHashadd(nobjtbl, (int)objtype, num);
4310 RuntimeHashadd(nobjtbl, (int)objtype, 1);
4314 // ouput all new obj info
4315 iter = RuntimeHashcreateiterator(nobjtbl);
4316 while(RunhasNext(iter)) {
4317 char * objtype = (char *)Runkey(iter);
4318 int num = Runnext(iter);
4319 int nameLen = strlen(objtype);
4320 BAMBOO_PRINT(0xddda);
4321 for(j = 0; j < nameLen; j++) {
4322 BAMBOO_PRINT_REG(objtype[j]);
4324 BAMBOO_PRINT(0xdddb);
4325 BAMBOO_PRINT_REG(num);
4328 BAMBOO_PRINT(0xdddc);
4331 if(taskInfoOverflow) {
4332 BAMBOO_PRINT(0xefee);
4335 #ifdef PROFILE_INTERRUPT
4336 // output interrupt related info
4337 for(i = 0; i < interruptInfoIndex; i++) {
4338 InterruptInfo* tmpIInfo = interruptInfoArray[i];
4339 BAMBOO_PRINT(0xddde);
4340 BAMBOO_PRINT_REG(tmpIInfo->startTime);
4341 BAMBOO_PRINT_REG(tmpIInfo->endTime);
4342 BAMBOO_PRINT(0xdddf);
4345 if(interruptInfoOverflow) {
4346 BAMBOO_PRINT(0xefef);
4348 #endif // PROFILE_INTERRUPT
4350 BAMBOO_PRINT(0xeeee);
4353 #endif // #ifdef PROFILE