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
472 BAMBOO_WAITING_FOR_LOCK(0);
473 } // while(!lockflag)
475 BAMBOO_DEBUGPRINT_REG(grount);
489 BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
490 BAMBOO_CACHE_FLUSH_RANGE((int)obj,
491 classsize[((struct ___Object___ *)obj)->type]);
493 // enqueue the object
494 for(k = 0; k < objInfo->length; ++k) {
495 int taskindex = objInfo->queues[2 * k];
496 int paramindex = objInfo->queues[2 * k + 1];
497 struct parameterwrapper ** queues =
498 &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
499 BAMBOO_DEBUGPRINT_REG(taskindex);
500 BAMBOO_DEBUGPRINT_REG(paramindex);
501 enqueueObject_I(obj, queues, 1);
502 BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
503 } // for(k = 0; k < objInfo->length; ++k)
504 releasewritelock_I(obj);
505 RUNFREE(objInfo->queues);
509 // put it at the end of the queue if no update version in the queue
510 struct QueueItem * qitem = getHead(&objqueue);
511 struct QueueItem * prev = NULL;
512 while(qitem != NULL) {
513 struct transObjInfo * tmpinfo =
514 (struct transObjInfo *)(qitem->objectptr);
515 if(tmpinfo->objptr == obj) {
516 // the same object in the queue, which should be enqueued
517 // recently. Current one is outdate, do not re-enqueue it
518 RUNFREE(objInfo->queues);
523 } // if(tmpinfo->objptr == obj)
524 qitem = getNextQueueItem(prev);
525 } // while(qitem != NULL)
526 // try to execute active tasks already enqueued first
527 addNewItem_I(&objqueue, objInfo);
529 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
530 BAMBOO_DEBUGPRINT(0xf000);
533 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
534 BAMBOO_DEBUGPRINT(0xf000);
535 } // while(!isEmpty(&objqueue))
538 #ifdef ACCURATEPROFILE
545 BAMBOO_DEBUGPRINT(0xee02);
549 inline __attribute__((always_inline))
550 void checkCoreStatus() {
551 bool allStall = false;
555 (waitconfirm && (numconfirm == 0))) {
556 BAMBOO_DEBUGPRINT(0xee04);
557 BAMBOO_DEBUGPRINT_REG(waitconfirm);
558 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
559 BAMBOO_DEBUGPRINT(0xf001);
560 corestatus[BAMBOO_NUM_OF_CORE] = 0;
561 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
562 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
563 // check the status of all cores
565 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
566 for(i = 0; i < NUMCORESACTIVE; ++i) {
567 BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
568 if(corestatus[i] != 0) {
572 } // for(i = 0; i < NUMCORESACTIVE; ++i)
574 // check if the sum of send objs and receive obj are the same
575 // yes->check if the info is the latest; no->go on executing
577 for(i = 0; i < NUMCORESACTIVE; ++i) {
578 sumsendobj += numsendobjs[i];
579 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
580 } // for(i = 0; i < NUMCORESACTIVE; ++i)
581 for(i = 0; i < NUMCORESACTIVE; ++i) {
582 sumsendobj -= numreceiveobjs[i];
583 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
584 } // for(i = 0; i < NUMCORESACTIVE; ++i)
585 if(0 == sumsendobj) {
587 // the first time found all cores stall
588 // send out status confirm msg to all other cores
589 // reset the corestatus array too
590 BAMBOO_DEBUGPRINT(0xee05);
591 corestatus[BAMBOO_NUM_OF_CORE] = 1;
593 numconfirm = NUMCORESACTIVE - 1;
594 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
595 for(i = 1; i < NUMCORESACTIVE; ++i) {
597 // send status confirm msg to core i
598 send_msg_1(i, STATUSCONFIRM, false);
599 } // for(i = 1; i < NUMCORESACTIVE; ++i)
602 // all the core status info are the latest
603 // terminate; for profiling mode, send request to all
604 // other cores to pour out profiling data
605 BAMBOO_DEBUGPRINT(0xee06);
608 totalexetime = BAMBOO_GET_EXE_TIME() - bamboo_start_time;
611 BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME() - bamboo_start_time);
612 //BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
614 BAMBOO_DEBUGPRINT_REG(gc_num_flush_dtlb);
616 #ifndef BAMBOO_MEMPROF
617 BAMBOO_DEBUGPRINT(0xbbbbbbbb);
620 // profile mode, send msgs to other cores to request pouring
621 // out progiling data
623 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
624 BAMBOO_DEBUGPRINT(0xf000);
625 for(i = 1; i < NUMCORESACTIVE; ++i) {
626 // send profile request msg to core i
627 send_msg_2(i, PROFILEOUTPUT, totalexetime, false);
628 } // for(i = 1; i < NUMCORESACTIVE; ++i)
630 // pour profiling data on startup core
634 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
635 BAMBOO_DEBUGPRINT(0xf001);
636 profilestatus[BAMBOO_NUM_OF_CORE] = 0;
637 // check the status of all cores
639 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
640 for(i = 0; i < NUMCORESACTIVE; ++i) {
641 BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
642 if(profilestatus[i] != 0) {
646 } // for(i = 0; i < NUMCORESACTIVE; ++i)
649 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
650 BAMBOO_DEBUGPRINT(0xf000);
654 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
660 // gc_profile mode, output gc prfiling data
662 #ifdef GC_CACHE_ADAPT
663 bamboo_mask_timer_intr(); // disable the TILE_TIMER interrupt
664 #endif // GC_CACHE_ADAPT
666 gc_outputProfileData();
667 #endif // #ifdef GC_PROFILE
668 #endif // #ifdef MULTICORE_GC
670 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
671 terminate(); // All done.
672 } // if(!waitconfirm)
674 // still some objects on the fly on the network
675 // reset the waitconfirm and numconfirm
676 BAMBOO_DEBUGPRINT(0xee07);
679 } // if(0 == sumsendobj)
681 // not all cores are stall, keep on waiting
682 BAMBOO_DEBUGPRINT(0xee08);
686 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
687 BAMBOO_DEBUGPRINT(0xf000);
688 } // if((!waitconfirm) ||
691 // main function for each core
692 inline void run(void * arg) {
696 bool sendStall = false;
698 bool tocontinue = false;
700 corenum = BAMBOO_GET_NUM_OF_CORE();
701 BAMBOO_DEBUGPRINT(0xeeee);
702 BAMBOO_DEBUGPRINT_REG(corenum);
703 BAMBOO_DEBUGPRINT(STARTUPCORE);
705 // initialize runtime data structures
708 // other architecture related initialization
712 #ifdef GC_CACHE_ADAPT
713 // enable the timer interrupt
714 #ifdef GC_CACHE_SAMPLING
715 bamboo_tile_timer_set_next_event(GC_TILE_TIMER_EVENT_SETTING); // TODO
716 bamboo_unmask_timer_intr();
717 bamboo_dtlb_sampling_process();
718 #endif // GC_CACHE_SAMPLING
719 #endif // GC_CACHE_ADAPT
721 initializeexithandler();
723 // main process of the execution module
724 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
725 // non-executing cores, only processing communications
729 /* Create queue of active tasks */
731 genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
732 (int (*)(void *,void *)) &comparetpd);
734 /* Process task information */
737 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
738 /* Create startup object */
739 createstartupobject(argc, argv);
742 BAMBOO_DEBUGPRINT(0xee00);
747 // check if need to do GC
751 #endif // MULTICORE_GC
753 // check if there are new active tasks can be executed
760 while(receiveObject() != -1) {
764 BAMBOO_DEBUGPRINT(0xee01);
766 // check if there are some pending objects,
767 // if yes, enqueue them and executetasks again
768 tocontinue = checkObjQueue();
772 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
774 BAMBOO_DEBUGPRINT(0xee03);
780 BAMBOO_DEBUGPRINT(0xee09);
785 // wait for some time
787 BAMBOO_DEBUGPRINT(0xee0a);
792 // send StallMsg to startup core
793 BAMBOO_DEBUGPRINT(0xee0b);
795 send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
796 self_numsendobjs, self_numreceiveobjs, false);
807 BAMBOO_DEBUGPRINT(0xee0c);
809 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
812 } // if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)
816 struct ___createstartupobject____I_locals {
819 struct ___StartupObject___ * ___startupobject___;
820 struct ArrayObject * ___stringarray___;
821 }; // struct ___createstartupobject____I_locals
823 void createstartupobject(int argc,
827 /* Allocate startup object */
829 struct ___createstartupobject____I_locals ___locals___ =
830 {2, NULL, NULL, NULL};
831 struct ___StartupObject___ *startupobject=
832 (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
833 ___locals___.___startupobject___ = startupobject;
834 struct ArrayObject * stringarray=
835 allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
836 ___locals___.___stringarray___ = stringarray;
838 struct ___StartupObject___ *startupobject=
839 (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
840 struct ArrayObject * stringarray=
841 allocate_newarray(STRINGARRAYTYPE, argc-1);
843 /* Build array of strings */
844 startupobject->___parameters___=stringarray;
845 for(i=1; i<argc; i++) {
846 int length=strlen(argv[i]);
848 struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
850 struct ___String___ *newstring=NewString(argv[i],length);
852 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
856 startupobject->version = 0;
857 startupobject->lock = NULL;
859 /* Set initialized flag for startup object */
860 flagorandinit(startupobject,1,0xFFFFFFFF);
861 enqueueObject(startupobject, NULL, 0);
863 BAMBOO_CACHE_FLUSH_ALL();
867 int hashCodetpd(struct taskparamdescriptor *ftd) {
868 int hash=(int)ftd->task;
870 for(i=0; i<ftd->numParameters; i++) {
871 hash^=(int)ftd->parameterArray[i];
876 int comparetpd(struct taskparamdescriptor *ftd1,
877 struct taskparamdescriptor *ftd2) {
879 if (ftd1->task!=ftd2->task)
881 for(i=0; i<ftd1->numParameters; i++)
882 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
887 /* This function sets a tag. */
889 void tagset(void *ptr,
890 struct ___Object___ * obj,
891 struct ___TagDescriptor___ * tagd) {
893 void tagset(struct ___Object___ * obj,
894 struct ___TagDescriptor___ * tagd) {
896 struct ArrayObject * ao=NULL;
897 struct ___Object___ * tagptr=obj->___tags___;
899 obj->___tags___=(struct ___Object___ *)tagd;
901 /* Have to check if it is already set */
902 if (tagptr->type==TAGTYPE) {
903 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
908 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
909 struct ArrayObject * ao=
910 allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
911 obj=(struct ___Object___ *)ptrarray[2];
912 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
913 td=(struct ___TagDescriptor___ *) obj->___tags___;
915 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
918 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
919 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
920 obj->___tags___=(struct ___Object___ *) ao;
921 ao->___cachedCode___=2;
925 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
926 for(i=0; i<ao->___cachedCode___; i++) {
927 struct ___TagDescriptor___ * td=
928 ARRAYGET(ao, struct ___TagDescriptor___*, i);
933 if (ao->___cachedCode___<ao->___length___) {
934 ARRAYSET(ao, struct ___TagDescriptor___ *,ao->___cachedCode___,tagd);
935 ao->___cachedCode___++;
938 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
939 struct ArrayObject * aonew=
940 allocate_newarray(&ptrarray,TAGARRAYTYPE,
941 TAGARRAYINTERVAL+ao->___length___);
942 obj=(struct ___Object___ *)ptrarray[2];
943 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
944 ao=(struct ArrayObject *)obj->___tags___;
946 struct ArrayObject * aonew=
947 allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
950 aonew->___cachedCode___=ao->___length___+1;
951 for(i=0; i<ao->___length___; i++) {
952 ARRAYSET(aonew, struct ___TagDescriptor___*, i,
953 ARRAYGET(ao, struct ___TagDescriptor___*, i));
955 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___,tagd);
961 struct ___Object___ * tagset=tagd->flagptr;
964 } else if (tagset->type!=OBJECTARRAYTYPE) {
966 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
967 struct ArrayObject * ao=
968 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
969 obj=(struct ___Object___ *)ptrarray[2];
970 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
972 struct ArrayObject * ao=
973 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
975 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
976 ARRAYSET(ao, struct ___Object___ *, 1, obj);
977 ao->___cachedCode___=2;
978 tagd->flagptr=(struct ___Object___ *)ao;
980 struct ArrayObject *ao=(struct ArrayObject *) tagset;
981 if (ao->___cachedCode___<ao->___length___) {
982 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
986 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
987 struct ArrayObject * aonew=
988 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
989 OBJECTARRAYINTERVAL+ao->___length___);
990 obj=(struct ___Object___ *)ptrarray[2];
991 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
992 ao=(struct ArrayObject *)tagd->flagptr;
994 struct ArrayObject * aonew=allocate_newarray(OBJECTARRAYTYPE,
995 OBJECTARRAYINTERVAL+ao->___length___);
997 aonew->___cachedCode___=ao->___cachedCode___+1;
998 for(i=0; i<ao->___length___; i++) {
999 ARRAYSET(aonew, struct ___Object___*, i,
1000 ARRAYGET(ao, struct ___Object___*, i));
1002 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
1003 tagd->flagptr=(struct ___Object___ *) aonew;
1009 /* This function clears a tag. */
1011 void tagclear(void *ptr,
1012 struct ___Object___ * obj,
1013 struct ___TagDescriptor___ * tagd) {
1015 void tagclear(struct ___Object___ * obj,
1016 struct ___TagDescriptor___ * tagd) {
1018 /* We'll assume that tag is alway there.
1019 Need to statically check for this of course. */
1020 struct ___Object___ * tagptr=obj->___tags___;
1022 if (tagptr->type==TAGTYPE) {
1023 if ((struct ___TagDescriptor___ *)tagptr==tagd)
1024 obj->___tags___=NULL;
1026 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
1028 for(i=0; i<ao->___cachedCode___; i++) {
1029 struct ___TagDescriptor___ * td=
1030 ARRAYGET(ao, struct ___TagDescriptor___ *, i);
1032 ao->___cachedCode___--;
1033 if (i<ao->___cachedCode___)
1034 ARRAYSET(ao, struct ___TagDescriptor___ *, i,
1035 ARRAYGET(ao,struct ___TagDescriptor___*,ao->___cachedCode___));
1036 ARRAYSET(ao,struct ___TagDescriptor___ *,ao->___cachedCode___, NULL);
1037 if (ao->___cachedCode___==0)
1038 obj->___tags___=NULL;
1045 struct ___Object___ *tagset=tagd->flagptr;
1046 if (tagset->type!=OBJECTARRAYTYPE) {
1050 struct ArrayObject *ao=(struct ArrayObject *) tagset;
1052 for(i=0; i<ao->___cachedCode___; i++) {
1053 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
1055 ao->___cachedCode___--;
1056 if (i<ao->___cachedCode___)
1057 ARRAYSET(ao, struct ___Object___ *, i,
1058 ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
1059 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
1060 if (ao->___cachedCode___==0)
1071 /* This function allocates a new tag. */
1073 struct ___TagDescriptor___ * allocate_tag(void *ptr,
1075 struct ___TagDescriptor___ * v=
1076 (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
1077 classsize[TAGTYPE]);
1079 struct ___TagDescriptor___ * allocate_tag(int index) {
1080 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
1087 /* This function updates the flag for object ptr. It or's the flag
1088 with the or mask and and's it with the andmask. */
1090 void flagbody(struct ___Object___ *ptr,
1092 struct parameterwrapper ** queues,
1096 int flagcomp(const int *val1, const int *val2) {
1097 return (*val1)-(*val2);
1100 void flagorand(void * ptr,
1103 struct parameterwrapper ** queues,
1106 int oldflag=((int *)ptr)[1];
1107 int flag=ormask|oldflag;
1109 flagbody(ptr, flag, queues, length, false);
1113 bool intflagorand(void * ptr,
1117 int oldflag=((int *)ptr)[1];
1118 int flag=ormask|oldflag;
1120 if (flag==oldflag) /* Don't do anything */
1123 flagbody(ptr, flag, NULL, 0, false);
1129 void flagorandinit(void * ptr,
1132 int oldflag=((int *)ptr)[1];
1133 int flag=ormask|oldflag;
1135 flagbody(ptr,flag,NULL,0,true);
1138 void flagbody(struct ___Object___ *ptr,
1140 struct parameterwrapper ** vqueues,
1143 struct parameterwrapper * flagptr = NULL;
1145 struct parameterwrapper ** queues = vqueues;
1146 int length = vlength;
1148 int UNUSED, UNUSED2;
1149 int * enterflags = NULL;
1150 if((!isnew) && (queues == NULL)) {
1151 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
1152 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1153 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1160 /*Remove object from all queues */
1161 for(i = 0; i < length; ++i) {
1162 flagptr = queues[i];
1163 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
1164 (int *) &enterflags, &UNUSED, &UNUSED2);
1165 ObjectHashremove(flagptr->objectset, (int)ptr);
1166 if (enterflags!=NULL)
1167 RUNFREE(enterflags);
1171 void enqueueObject(void * vptr,
1172 struct parameterwrapper ** vqueues,
1174 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1177 struct parameterwrapper * parameter=NULL;
1180 struct parameterwrapper * prevptr=NULL;
1181 struct ___Object___ *tagptr=NULL;
1182 struct parameterwrapper ** queues = vqueues;
1183 int length = vlength;
1184 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1187 if(queues == NULL) {
1188 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1189 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1191 tagptr=ptr->___tags___;
1193 /* Outer loop iterates through all parameter queues an object of
1194 this type could be in. */
1195 for(j = 0; j < length; ++j) {
1196 parameter = queues[j];
1198 if (parameter->numbertags>0) {
1200 goto nextloop; //that means the object has no tag
1201 //but that param needs tag
1202 else if(tagptr->type==TAGTYPE) { //one tag
1203 for(i=0; i<parameter->numbertags; i++) {
1204 //slotid is parameter->tagarray[2*i];
1205 int tagid=parameter->tagarray[2*i+1];
1206 if (tagid!=tagptr->flag)
1207 goto nextloop; /*We don't have this tag */
1209 } else { //multiple tags
1210 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1211 for(i=0; i<parameter->numbertags; i++) {
1212 //slotid is parameter->tagarray[2*i];
1213 int tagid=parameter->tagarray[2*i+1];
1215 for(j=0; j<ao->___cachedCode___; j++) {
1216 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1227 for(i=0; i<parameter->numberofterms; i++) {
1228 int andmask=parameter->intarray[i*2];
1229 int checkmask=parameter->intarray[i*2+1];
1230 if ((ptr->flag&andmask)==checkmask) {
1231 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
1242 void enqueueObject_I(void * vptr,
1243 struct parameterwrapper ** vqueues,
1245 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1248 struct parameterwrapper * parameter=NULL;
1251 struct parameterwrapper * prevptr=NULL;
1252 struct ___Object___ *tagptr=NULL;
1253 struct parameterwrapper ** queues = vqueues;
1254 int length = vlength;
1255 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1258 if(queues == NULL) {
1259 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1260 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1262 tagptr=ptr->___tags___;
1264 /* Outer loop iterates through all parameter queues an object of
1265 this type could be in. */
1266 for(j = 0; j < length; ++j) {
1267 parameter = queues[j];
1269 if (parameter->numbertags>0) {
1271 goto nextloop; //that means the object has no tag
1272 //but that param needs tag
1273 else if(tagptr->type==TAGTYPE) { //one tag
1274 for(i=0; i<parameter->numbertags; i++) {
1275 //slotid is parameter->tagarray[2*i];
1276 int tagid=parameter->tagarray[2*i+1];
1277 if (tagid!=tagptr->flag)
1278 goto nextloop; /*We don't have this tag */
1280 } else { //multiple tags
1281 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1282 for(i=0; i<parameter->numbertags; i++) {
1283 //slotid is parameter->tagarray[2*i];
1284 int tagid=parameter->tagarray[2*i+1];
1286 for(j=0; j<ao->___cachedCode___; j++) {
1287 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1298 for(i=0; i<parameter->numberofterms; i++) {
1299 int andmask=parameter->intarray[i*2];
1300 int checkmask=parameter->intarray[i*2+1];
1301 if ((ptr->flag&andmask)==checkmask) {
1302 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1314 int * getAliasLock(void ** ptrs,
1316 struct RuntimeHash * tbl) {
1318 return (int*)(RUNMALLOC(sizeof(int)));
1323 bool redirect = false;
1324 int redirectlock = 0;
1325 for(; i < length; i++) {
1326 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1329 if(ptr->lock == NULL) {
1332 lock = (int)(ptr->lock);
1335 if(lock != redirectlock) {
1336 RuntimeHashadd(tbl, lock, redirectlock);
1339 if(RuntimeHashcontainskey(tbl, lock)) {
1340 // already redirected
1342 RuntimeHashget(tbl, lock, &redirectlock);
1343 for(; j < locklen; j++) {
1344 if(locks[j] != redirectlock) {
1345 RuntimeHashadd(tbl, locks[j], redirectlock);
1350 for(j = 0; j < locklen; j++) {
1351 if(locks[j] == lock) {
1354 } else if(locks[j] > lock) {
1361 locks[h] = locks[h-1];
1370 return (int *)redirectlock;
1372 return (int *)(locks[0]);
1377 void addAliasLock(void * ptr,
1379 struct ___Object___ * obj = (struct ___Object___ *)ptr;
1380 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1381 // originally no alias lock associated or have a different alias lock
1382 // flush it as the new one
1383 obj->lock = (int *)lock;
1388 inline void setTaskExitIndex(int index) {
1389 taskInfoArray[taskInfoIndex]->exitIndex = index;
1392 inline void addNewObjInfo(void * nobj) {
1393 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1394 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1396 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1401 // Only allocate local mem chunks to each core.
1402 // If a core has used up its local shared memory, start gc.
1403 void * localmalloc_I(int coren,
1407 int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
1410 int tofindb = gc_core2block[2*gccorenum+i]+(NUMCORES4GC*2)*j;
1411 int totest = tofindb;
1412 int bound = BAMBOO_SMEM_SIZE_L;
1416 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1417 int nsize = bamboo_smemtbl[totest];
1418 bool islocal = true;
1420 bool tocheck = true;
1421 // have some space in the block
1422 if(totest == tofindb) {
1423 // the first partition
1424 size = bound - nsize;
1425 } else if(nsize == 0) {
1426 // an empty partition, can be appended
1429 // not an empty partition, can not be appended
1430 // the last continuous block is not big enough, go to check the next
1434 } // if(totest == tofindb) else if(nsize == 0) else ...
1437 // have enough space in the block, malloc
1441 // no enough space yet, try to append next continuous block
1443 } // if(size > isize) else ...
1445 } // if(nsize < bound)
1447 // no space in the block, go to check the next block
1453 tofindb = totest = gc_core2block[2*gccorenum+i]+(NUMCORES4GC*2)*j;
1456 } // if(islocal) else ...
1457 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1458 // no more local mem, do not find suitable block
1461 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1464 if(foundsmem == 1) {
1465 // find suitable block
1466 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1467 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1468 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1470 // set bamboo_smemtbl
1471 for(i = tofindb; i <= totest; i++) {
1472 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1474 } else if(foundsmem == 2) {
1475 // no suitable block
1480 } // void * localmalloc_I(int, int, int *)
1483 // Allocate the local shared memory to each core with the highest priority,
1484 // if a core has used up its local shared memory, try to allocate the
1485 // shared memory that belong to its neighbours, if also failed, start gc.
1486 void * fixedmalloc_I(int coren,
1493 int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
1494 int coords_x = bamboo_cpu2coords[gccorenum*2];
1495 int coords_y = bamboo_cpu2coords[gccorenum*2+1];
1497 int tofindb = gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1498 int totest = tofindb;
1499 int bound = BAMBOO_SMEM_SIZE_L;
1503 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1504 int nsize = bamboo_smemtbl[totest];
1505 bool islocal = true;
1507 bool tocheck = true;
1508 // have some space in the block
1509 if(totest == tofindb) {
1510 // the first partition
1511 size = bound - nsize;
1512 } else if(nsize == 0) {
1513 // an empty partition, can be appended
1516 // not an empty partition, can not be appended
1517 // the last continuous block is not big enough, go to check the next
1521 } // if(totest == tofindb) else if(nsize == 0) else ...
1524 // have enough space in the block, malloc
1528 // no enough space yet, try to append next continuous block
1529 // TODO may consider to go to next local block?
1531 } // if(size > isize) else ...
1533 } // if(nsize < bound)
1535 // no space in the block, go to check the next block
1542 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1545 } // if(islocal) else ...
1546 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1547 // no more local mem, do not find suitable block on local mem
1548 // try to malloc shared memory assigned to the neighbour cores
1551 if(k >= NUM_CORES2TEST) {
1552 // no more memory available on either coren or its neighbour cores
1554 goto memsearchresult;
1556 } while(core2test[gccorenum][k] == -1);
1560 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1561 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1565 if(foundsmem == 1) {
1566 // find suitable block
1567 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1568 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1569 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1571 // set bamboo_smemtbl
1572 for(i = tofindb; i <= totest; i++) {
1573 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1575 } else if(foundsmem == 2) {
1576 // no suitable block
1581 } // void * fixedmalloc_I(int, int, int *)
1582 #endif // #ifdef SMEMF
1585 // Allocate the local shared memory to each core with the highest priority,
1586 // if a core has used up its local shared memory, try to allocate the
1587 // shared memory that belong to its neighbours first, if failed, check
1588 // current memory allocation rate, if it has already reached the threshold,
1589 // start gc, otherwise, allocate the shared memory globally. If all the
1590 // shared memory has been used up, start gc.
1591 void * mixedmalloc_I(int coren,
1598 int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
1600 int tofindb = gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1601 int totest = tofindb;
1602 int bound = BAMBOO_SMEM_SIZE_L;
1606 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1607 int nsize = bamboo_smemtbl[totest];
1608 bool islocal = true;
1610 bool tocheck = true;
1611 // have some space in the block
1612 if(totest == tofindb) {
1613 // the first partition
1614 size = bound - nsize;
1615 } else if(nsize == 0) {
1616 // an empty partition, can be appended
1619 // not an empty partition, can not be appended
1620 // the last continuous block is not big enough, go to check the next
1624 } // if(totest == tofindb) else if(nsize == 0) else ...
1627 // have enough space in the block, malloc
1631 // no enough space yet, try to append next continuous block
1632 // TODO may consider to go to next local block?
1634 } // if(size > isize) else ...
1636 } // if(nsize < bound)
1638 // no space in the block, go to check the next block
1645 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1648 } // if(islocal) else ...
1649 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1650 // no more local mem, do not find suitable block on local mem
1651 // try to malloc shared memory assigned to the neighbour cores
1654 if(k >= NUM_CORES2TEST) {
1655 if(gcmem_mixed_usedmem >= gcmem_mixed_threshold) {
1656 // no more memory available on either coren or its neighbour cores
1658 goto memmixedsearchresult;
1660 // try allocate globally
1661 mem = globalmalloc_I(coren, isize, allocsize);
1665 } while(core2test[gccorenum][k] == -1);
1669 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1670 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1673 memmixedsearchresult:
1674 if(foundsmem == 1) {
1675 // find suitable block
1676 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1677 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1678 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1680 // set bamboo_smemtbl
1681 for(i = tofindb; i <= totest; i++) {
1682 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1684 gcmem_mixed_usedmem += size;
1685 if(tofindb == bamboo_free_block) {
1686 bamboo_free_block = totest+1;
1688 } else if(foundsmem == 2) {
1689 // no suitable block
1694 } // void * mixedmalloc_I(int, int, int *)
1695 #endif // #ifdef SMEMM
1697 // Allocate all the memory chunks globally, do not consider the host cores
1698 // When all the shared memory are used up, start gc.
1699 void * globalmalloc_I(int coren,
1703 int tofindb = bamboo_free_block; //0;
1704 int totest = tofindb;
1705 int bound = BAMBOO_SMEM_SIZE_L;
1708 if(tofindb > gcnumblock-1-bamboo_reserved_smem) {
1709 // Out of shared memory
1714 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1715 int nsize = bamboo_smemtbl[totest];
1716 bool isnext = false;
1718 bool tocheck = true;
1719 // have some space in the block
1720 if(totest == tofindb) {
1721 // the first partition
1722 size = bound - nsize;
1723 } else if(nsize == 0) {
1724 // an empty partition, can be appended
1727 // not an empty partition, can not be appended
1728 // the last continuous block is not big enough, start another block
1731 } // if(totest == tofindb) else if(nsize == 0) else ...
1734 // have enough space in the block, malloc
1737 } // if(size > isize)
1741 } // if(nsize < bound) else ...
1743 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1744 // no more local mem, do not find suitable block
1747 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1749 // start another block
1754 if(foundsmem == 1) {
1755 // find suitable block
1756 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1757 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1758 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1760 // set bamboo_smemtbl
1761 for(int i = tofindb; i <= totest; i++) {
1762 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1764 if(tofindb == bamboo_free_block) {
1765 bamboo_free_block = totest+1;
1767 } else if(foundsmem == 2) {
1768 // no suitable block
1774 } // void * globalmalloc_I(int, int, int *)
1775 #endif // #ifdef MULTICORE_GC
1777 // malloc from the shared memory
1778 void * smemalloc_I(int coren,
1783 int isize = size+(BAMBOO_CACHE_LINE_SIZE);
1785 // go through the bamboo_smemtbl for suitable partitions
1786 switch(bamboo_smem_mode) {
1788 mem = localmalloc_I(coren, isize, allocsize);
1794 mem = fixedmalloc_I(coren, isize, allocsize);
1796 // not supported yet
1797 BAMBOO_EXIT(0xe001);
1804 mem = mixedmalloc_I(coren, isize, allocsize);
1806 // not supported yet
1807 BAMBOO_EXIT(0xe002);
1813 mem = globalmalloc_I(coren, isize, allocsize);
1823 int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size) : (BAMBOO_SMEM_SIZE);
1824 if(toallocate > bamboo_free_smem_size) {
1828 mem = (void *)bamboo_free_smemp;
1829 bamboo_free_smemp = ((void*)bamboo_free_smemp) + toallocate;
1830 bamboo_free_smem_size -= toallocate;
1832 *allocsize = toallocate;
1834 #endif // MULTICORE_GC
1835 // no enough shared global memory
1840 // inform other cores to stop and wait for gc
1842 for(int i = 0; i < NUMCORESACTIVE; i++) {
1843 // reuse the gcnumsendobjs & gcnumreceiveobjs
1844 gccorestatus[i] = 1;
1845 gcnumsendobjs[0][i] = 0;
1846 gcnumreceiveobjs[0][i] = 0;
1848 for(int i = 0; i < NUMCORESACTIVE; i++) {
1849 if(i != BAMBOO_NUM_OF_CORE) {
1850 if(BAMBOO_CHECK_SEND_MODE()) {
1851 cache_msg_1(i, GCSTARTPRE);
1853 send_msg_1(i, GCSTARTPRE, true);
1860 BAMBOO_DEBUGPRINT(0xe003);
1861 BAMBOO_EXIT(0xe003);
1865 } // void * smemalloc_I(int, int, int)
1867 INLINE int checkMsgLength_I(int size) {
1869 BAMBOO_DEBUGPRINT(0xcccc);
1871 int type = msgdata[msgdataindex];
1879 case GCSTARTMAPINFO:
1884 #ifdef GC_CACHE_ADAPT
1886 #endif // GC_CACHE_ADAPT
1887 #endif // MULTICORE_GC
1896 case GCSTARTCOMPACT:
1899 case GCFINISHMAPINFO:
1901 #ifdef GC_CACHE_ADAPT
1903 #endif // GC_CACHE_ADAPT
1904 #endif // MULTICORE_GC
1927 case REDIRECTGROUNT:
1929 case REDIRECTRELEASE:
1946 case GCFINISHCOMPACT:
1960 case TRANSOBJ: // nonfixed size
1966 msglength = msgdata[(msgdataindex+1)&(BAMBOO_MSG_BUF_MASK)];
1975 BAMBOO_DEBUGPRINT_REG(type);
1976 BAMBOO_DEBUGPRINT_REG(size);
1977 BAMBOO_DEBUGPRINT_REG(msgdataindex);
1978 BAMBOO_DEBUGPRINT_REG(msgdatalast);
1979 BAMBOO_DEBUGPRINT_REG(msgdatafull);
1982 BAMBOO_DEBUGPRINT(msgdata[msgdataindex+i]);
1984 BAMBOO_EXIT(0xe004);
1989 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
1990 BAMBOO_DEBUGPRINT(0xffff);
1995 INLINE void processmsg_transobj_I() {
1997 struct transObjInfo * transObj=RUNMALLOC_I(sizeof(struct transObjInfo));
2000 BAMBOO_DEBUGPRINT(0xe880);
2002 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2004 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
2006 BAMBOO_EXIT(0xe005);
2008 // store the object and its corresponding queue info, enqueue it later
2009 transObj->objptr = (void *)msgdata[msgdataindex]; //[2]
2011 transObj->length = (msglength - 3) / 2;
2012 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
2013 for(k = 0; k < transObj->length; ++k) {
2014 transObj->queues[2*k] = msgdata[msgdataindex]; //[3+2*k];
2016 transObj->queues[2*k+1] = msgdata[msgdataindex]; //[3+2*k+1];
2019 // check if there is an existing duplicate item
2021 struct QueueItem * qitem = getHead(&objqueue);
2022 struct QueueItem * prev = NULL;
2023 while(qitem != NULL) {
2024 struct transObjInfo * tmpinfo =
2025 (struct transObjInfo *)(qitem->objectptr);
2026 if(tmpinfo->objptr == transObj->objptr) {
2027 // the same object, remove outdate one
2028 RUNFREE(tmpinfo->queues);
2030 removeItem(&objqueue, qitem);
2036 qitem = getHead(&objqueue);
2038 qitem = getNextQueueItem(prev);
2041 addNewItem_I(&objqueue, (void *)transObj);
2043 ++(self_numreceiveobjs);
2046 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
2047 // set the gcprecheck to enable checking again
2050 // send a update pregc information msg to the master core
2051 if(BAMBOO_CHECK_SEND_MODE()) {
2052 cache_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
2053 self_numsendobjs, self_numreceiveobjs);
2055 send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
2056 self_numsendobjs, self_numreceiveobjs, true);
2063 INLINE void processmsg_transtall_I() {
2064 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2065 // non startup core can not receive stall msg
2067 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
2069 BAMBOO_EXIT(0xe006);
2071 int num_core = msgdata[msgdataindex]; //[1]
2073 int data2 = msgdata[msgdataindex]; //[2];
2075 int data3 = msgdata[msgdataindex]; //[3];
2077 if(num_core < NUMCORESACTIVE) {
2079 BAMBOO_DEBUGPRINT(0xe881);
2081 corestatus[num_core] = 0;
2082 numsendobjs[num_core] = data2; //[2];
2083 numreceiveobjs[num_core] = data3; //[3];
2087 #ifndef MULTICORE_GC
2088 INLINE void processmsg_lockrequest_I() {
2089 // check to see if there is a lock exist for the required obj
2090 // msgdata[1] -> lock type
2091 int locktype = msgdata[msgdataindex]; //[1];
2093 int data2 = msgdata[msgdataindex]; // obj pointer
2095 int data3 = msgdata[msgdataindex]; // lock
2097 int data4 = msgdata[msgdataindex]; // request core
2099 // -1: redirected, 0: approved, 1: denied
2100 int deny=processlockrequest(locktype, data3, data2, data4, data4, true);
2102 // this lock request is redirected
2105 // send response msg
2106 // for 32 bit machine, the size is always 4 words, cache the msg first
2107 int tmp = deny==1 ? LOCKDENY : LOCKGROUNT;
2108 if(BAMBOO_CHECK_SEND_MODE()) {
2109 cache_msg_4(data4, tmp, locktype, data2, data3);
2111 send_msg_4(data4, tmp, locktype, data2, data3, true);
2116 INLINE void processmsg_lockgrount_I() {
2118 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2120 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
2122 BAMBOO_EXIT(0xe007);
2124 int data2 = msgdata[msgdataindex];
2126 int data3 = msgdata[msgdataindex];
2128 if((lockobj == data2) && (lock2require == data3)) {
2130 BAMBOO_DEBUGPRINT(0xe882);
2138 // conflicts on lockresults
2140 BAMBOO_DEBUGPRINT_REG(data2);
2142 BAMBOO_EXIT(0xe008);
2146 INLINE void processmsg_lockdeny_I() {
2148 int data2 = msgdata[msgdataindex];
2150 int data3 = msgdata[msgdataindex];
2152 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2154 BAMBOO_DEBUGPRINT_REG(data2);
2156 BAMBOO_EXIT(0xe009);
2158 if((lockobj == data2) && (lock2require == data3)) {
2160 BAMBOO_DEBUGPRINT(0xe883);
2168 // conflicts on lockresults
2170 BAMBOO_DEBUGPRINT_REG(data2);
2172 BAMBOO_EXIT(0xe00a);
2176 INLINE void processmsg_lockrelease_I() {
2177 int data1 = msgdata[msgdataindex];
2179 int data2 = msgdata[msgdataindex];
2181 int data3 = msgdata[msgdataindex];
2183 // receive lock release msg
2184 processlockrelease(data1, data2, 0, false);
2187 INLINE void processmsg_redirectlock_I() {
2188 // check to see if there is a lock exist for the required obj
2189 int data1 = msgdata[msgdataindex];
2190 MSG_INDEXINC_I(); //msgdata[1]; // lock type
2191 int data2 = msgdata[msgdataindex];
2192 MSG_INDEXINC_I(); //msgdata[2]; // obj pointer
2193 int data3 = msgdata[msgdataindex];
2194 MSG_INDEXINC_I(); //msgdata[3]; // redirect lock
2195 int data4 = msgdata[msgdataindex];
2196 MSG_INDEXINC_I(); //msgdata[4]; // root request core
2197 int data5 = msgdata[msgdataindex];
2198 MSG_INDEXINC_I(); //msgdata[5]; // request core
2199 int deny = processlockrequest(data1, data3, data2, data5, data4, true);
2201 // this lock request is redirected
2204 // send response msg
2205 // for 32 bit machine, the size is always 4 words, cache the msg first
2206 if(BAMBOO_CHECK_SEND_MODE()) {
2207 cache_msg_4(data4, deny==1 ? REDIRECTDENY : REDIRECTGROUNT,
2208 data1, data2, data3);
2210 send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
2211 data1, data2, data3, true);
2216 INLINE void processmsg_redirectgrount_I() {
2218 int data2 = msgdata[msgdataindex];
2220 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2222 BAMBOO_DEBUGPRINT_REG(data2);
2224 BAMBOO_EXIT(0xe00b);
2226 if(lockobj == data2) {
2228 BAMBOO_DEBUGPRINT(0xe891);
2230 int data3 = msgdata[msgdataindex];
2234 RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
2239 // conflicts on lockresults
2241 BAMBOO_DEBUGPRINT_REG(data2);
2243 BAMBOO_EXIT(0xe00c);
2247 INLINE void processmsg_redirectdeny_I() {
2249 int data2 = msgdata[msgdataindex];
2251 int data3 = msgdata[msgdataindex];
2253 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2255 BAMBOO_DEBUGPRINT_REG(data2);
2257 BAMBOO_EXIT(0xe00d);
2259 if(lockobj == data2) {
2261 BAMBOO_DEBUGPRINT(0xe892);
2269 // conflicts on lockresults
2271 BAMBOO_DEBUGPRINT_REG(data2);
2273 BAMBOO_EXIT(0xe00e);
2277 INLINE void processmsg_redirectrelease_I() {
2278 int data1 = msgdata[msgdataindex];
2280 int data2 = msgdata[msgdataindex];
2282 int data3 = msgdata[msgdataindex];
2284 processlockrelease(data1, data2, data3, true);
2286 #endif // #ifndef MULTICORE_GC
2289 INLINE void processmsg_profileoutput_I() {
2290 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
2291 // startup core can not receive profile output finish msg
2292 BAMBOO_EXIT(0xe00f);
2295 BAMBOO_DEBUGPRINT(0xe885);
2298 totalexetime = msgdata[msgdataindex]; //[1]
2301 BAMBOO_DEBUGPRINT_REG(dot_num);
2303 outputProfileData();
2305 // cache the msg first
2306 if(BAMBOO_CHECK_SEND_MODE()) {
2307 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
2309 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE, true);
2313 INLINE void processmsg_profilefinish_I() {
2314 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2315 // non startup core can not receive profile output finish msg
2317 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex /*1*/]);
2319 BAMBOO_EXIT(0xe010);
2322 BAMBOO_DEBUGPRINT(0xe886);
2324 int data1 = msgdata[msgdataindex];
2326 profilestatus[data1] = 0;
2328 #endif // #ifdef PROFILE
2330 INLINE void processmsg_statusconfirm_I() {
2331 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2332 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2333 // wrong core to receive such msg
2334 BAMBOO_EXIT(0xe011);
2336 // send response msg
2338 BAMBOO_DEBUGPRINT(0xe887);
2340 // cache the msg first
2341 if(BAMBOO_CHECK_SEND_MODE()) {
2342 cache_msg_5(STARTUPCORE, STATUSREPORT,
2343 busystatus ? 1 : 0, BAMBOO_NUM_OF_CORE,
2344 self_numsendobjs, self_numreceiveobjs);
2346 send_msg_5(STARTUPCORE, STATUSREPORT, busystatus?1:0,
2347 BAMBOO_NUM_OF_CORE, self_numsendobjs,
2348 self_numreceiveobjs, true);
2353 INLINE void processmsg_statusreport_I() {
2354 int data1 = msgdata[msgdataindex];
2356 int data2 = msgdata[msgdataindex];
2358 int data3 = msgdata[msgdataindex];
2360 int data4 = msgdata[msgdataindex];
2362 // receive a status confirm info
2363 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2364 // wrong core to receive such msg
2366 BAMBOO_DEBUGPRINT_REG(data2);
2368 BAMBOO_EXIT(0xe012);
2371 BAMBOO_DEBUGPRINT(0xe888);
2376 corestatus[data2] = data1;
2377 numsendobjs[data2] = data3;
2378 numreceiveobjs[data2] = data4;
2382 INLINE void processmsg_terminate_I() {
2384 BAMBOO_DEBUGPRINT(0xe889);
2388 #ifdef GC_CACHE_ADAPT
2389 bamboo_mask_timer_intr(); // disable the TILE_TIMER interrupt
2390 #endif // GC_CACHE_ADAPT
2391 #endif // MULTICORE_GC
2395 INLINE void processmsg_memrequest_I() {
2396 int data1 = msgdata[msgdataindex];
2398 int data2 = msgdata[msgdataindex];
2400 // receive a shared memory request msg
2401 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2402 // wrong core to receive such msg
2404 BAMBOO_DEBUGPRINT_REG(data2);
2406 BAMBOO_EXIT(0xe013);
2409 BAMBOO_DEBUGPRINT(0xe88a);
2415 // is currently doing gc, dump this msg
2416 if(INITPHASE == gcphase) {
2417 // if still in the initphase of gc, send a startinit msg again,
2418 // cache the msg first
2419 if(BAMBOO_CHECK_SEND_MODE()) {
2420 cache_msg_1(data2, GCSTARTINIT);
2422 send_msg_1(data2, GCSTARTINIT, true);
2427 mem = smemalloc_I(data2, data1, &allocsize);
2429 // send the start_va to request core, cache the msg first
2430 if(BAMBOO_CHECK_SEND_MODE()) {
2431 cache_msg_3(data2, MEMRESPONSE, mem, allocsize);
2433 send_msg_3(data2, MEMRESPONSE, mem, allocsize, true);
2436 // if mem == NULL, the gcflag of the startup core has been set
2437 // and all the other cores have been informed to start gc
2444 INLINE void processmsg_memresponse_I() {
2445 int data1 = msgdata[msgdataindex];
2447 int data2 = msgdata[msgdataindex];
2449 // receive a shared memory response msg
2451 BAMBOO_DEBUGPRINT(0xe88b);
2454 // if is currently doing gc, dump this msg
2458 bamboo_smem_size = 0;
2461 bamboo_smem_zero_top = 0;
2465 // fill header to store the size of this mem block
2466 BAMBOO_MEMSET_WH(data1, '\0', BAMBOO_CACHE_LINE_SIZE);
2467 (*((int*)data1)) = data2;
2468 bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
2469 bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
2470 bamboo_smem_zero_top = bamboo_cur_msp;
2472 bamboo_smem_size = data2;
2473 bamboo_cur_msp =(void*)(data1);
2483 INLINE void processmsg_gcstartpre_I() {
2485 // already stall for gc
2486 // send a update pregc information msg to the master core
2487 if(BAMBOO_CHECK_SEND_MODE()) {
2488 cache_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
2489 self_numsendobjs, self_numreceiveobjs);
2491 send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
2492 self_numsendobjs, self_numreceiveobjs, true);
2495 // the first time to be informed to start gc
2498 // is waiting for response of mem request
2499 // let it return NULL and start gc
2500 bamboo_smem_size = 0;
2501 bamboo_cur_msp = NULL;
2503 bamboo_smem_zero_top = NULL;
2508 INLINE void processmsg_gcstartinit_I() {
2509 gcphase = INITPHASE;
2512 INLINE void processmsg_gcstart_I() {
2514 BAMBOO_DEBUGPRINT(0xe88c);
2517 gcphase = MARKPHASE;
2520 INLINE void processmsg_gcstartcompact_I() {
2521 gcblock2fill = msgdata[msgdataindex];
2522 MSG_INDEXINC_I(); //msgdata[1];
2523 gcphase = COMPACTPHASE;
2526 INLINE void processmsg_gcstartmapinfo_I() {
2530 INLINE void processmsg_gcstartflush_I() {
2531 gcphase = FLUSHPHASE;
2534 INLINE void processmsg_gcfinishpre_I() {
2535 int data1 = msgdata[msgdataindex];
2537 int data2 = msgdata[msgdataindex];
2539 int data3 = msgdata[msgdataindex];
2541 // received a init phase finish msg
2542 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2543 // non startup core can not receive this msg
2545 BAMBOO_DEBUGPRINT_REG(data1);
2547 BAMBOO_EXIT(0xe014);
2549 // All cores should do init GC
2553 gccorestatus[data1] = 0;
2554 gcnumsendobjs[0][data1] = data2;
2555 gcnumreceiveobjs[0][data1] = data3;
2558 INLINE void processmsg_gcfinishinit_I() {
2559 int data1 = msgdata[msgdataindex];
2561 // received a init phase finish msg
2562 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2563 // non startup core can not receive this msg
2565 BAMBOO_DEBUGPRINT_REG(data1);
2567 BAMBOO_EXIT(0xe015);
2570 BAMBOO_DEBUGPRINT(0xe88c);
2571 BAMBOO_DEBUGPRINT_REG(data1);
2573 // All cores should do init GC
2574 if(data1 < NUMCORESACTIVE) {
2575 gccorestatus[data1] = 0;
2579 INLINE void processmsg_gcfinishmark_I() {
2580 int data1 = msgdata[msgdataindex];
2582 int data2 = msgdata[msgdataindex];
2584 int data3 = msgdata[msgdataindex];
2586 // received a mark phase finish msg
2587 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2588 // non startup core can not receive this msg
2590 BAMBOO_DEBUGPRINT_REG(data1);
2592 BAMBOO_EXIT(0xe016);
2594 // all cores should do mark
2595 if(data1 < NUMCORESACTIVE) {
2596 gccorestatus[data1] = 0;
2597 int entry_index = 0;
2600 entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
2603 entry_index = gcnumsrobjs_index;
2605 gcnumsendobjs[entry_index][data1] = data2;
2606 gcnumreceiveobjs[entry_index][data1] = data3;
2610 INLINE void processmsg_gcfinishcompact_I() {
2611 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2612 // non startup core can not receive this msg
2615 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
2617 BAMBOO_EXIT(0xe017);
2619 int cnum = msgdata[msgdataindex];
2620 MSG_INDEXINC_I(); //msgdata[1];
2621 int filledblocks = msgdata[msgdataindex];
2622 MSG_INDEXINC_I(); //msgdata[2];
2623 int heaptop = msgdata[msgdataindex];
2624 MSG_INDEXINC_I(); //msgdata[3];
2625 int data4 = msgdata[msgdataindex];
2626 MSG_INDEXINC_I(); //msgdata[4];
2627 // only gc cores need to do compact
2628 if(cnum < NUMCORES4GC) {
2629 if(COMPACTPHASE == gcphase) {
2630 gcfilledblocks[cnum] = filledblocks;
2631 gcloads[cnum] = heaptop;
2638 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
2639 // cache the msg first
2640 if(BAMBOO_CHECK_SEND_MODE()) {
2641 cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
2643 send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove, true);
2647 gccorestatus[cnum] = 0;
2649 } // if(cnum < NUMCORES4GC)
2652 INLINE void processmsg_gcfinishmapinfo_I() {
2653 int data1 = msgdata[msgdataindex];
2655 // received a map phase finish msg
2656 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2657 // non startup core can not receive this msg
2659 BAMBOO_DEBUGPRINT_REG(data1);
2661 BAMBOO_EXIT(0xe018);
2663 // all cores should do flush
2664 if(data1 < NUMCORES4GC) {
2665 gccorestatus[data1] = 0;
2670 INLINE void processmsg_gcfinishflush_I() {
2671 int data1 = msgdata[msgdataindex];
2673 // received a flush phase finish msg
2674 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2675 // non startup core can not receive this msg
2677 BAMBOO_DEBUGPRINT_REG(data1);
2679 BAMBOO_EXIT(0xe019);
2681 // all cores should do flush
2682 if(data1 < NUMCORESACTIVE) {
2683 gccorestatus[data1] = 0;
2687 INLINE void processmsg_gcmarkconfirm_I() {
2688 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2689 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2690 // wrong core to receive such msg
2691 BAMBOO_EXIT(0xe01a);
2693 // send response msg, cahce the msg first
2694 if(BAMBOO_CHECK_SEND_MODE()) {
2695 cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2696 gcbusystatus, gcself_numsendobjs,
2697 gcself_numreceiveobjs);
2699 send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2700 gcbusystatus, gcself_numsendobjs,
2701 gcself_numreceiveobjs, true);
2706 INLINE void processmsg_gcmarkreport_I() {
2707 int data1 = msgdata[msgdataindex];
2709 int data2 = msgdata[msgdataindex];
2711 int data3 = msgdata[msgdataindex];
2713 int data4 = msgdata[msgdataindex];
2715 // received a marked phase finish confirm response msg
2716 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2717 // wrong core to receive such msg
2719 BAMBOO_DEBUGPRINT_REG(data2);
2721 BAMBOO_EXIT(0xe01b);
2723 int entry_index = 0;
2727 entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
2729 // can never reach here
2731 entry_index = gcnumsrobjs_index;
2733 gccorestatus[data1] = data2;
2734 gcnumsendobjs[entry_index][data1] = data3;
2735 gcnumreceiveobjs[entry_index][data1] = data4;
2739 INLINE void processmsg_gcmarkedobj_I() {
2740 int data1 = msgdata[msgdataindex];
2742 // received a markedObj msg
2743 if(((int *)data1)[6] == INIT) {
2744 // this is the first time that this object is discovered,
2745 // set the flag as DISCOVERED
2746 ((int *)data1)[6] = DISCOVERED;
2747 gc_enqueue_I(data1);
2749 // set the remote flag
2750 ((int *)data1)[6] |= REMOTEM;
2751 gcself_numreceiveobjs++;
2752 gcbusystatus = true;
2755 INLINE void processmsg_gcmovestart_I() {
2757 gcdstcore = msgdata[msgdataindex];
2758 MSG_INDEXINC_I(); //msgdata[1];
2759 gcmovestartaddr = msgdata[msgdataindex];
2760 MSG_INDEXINC_I(); //msgdata[2];
2761 gcblock2fill = msgdata[msgdataindex];
2762 MSG_INDEXINC_I(); //msgdata[3];
2765 INLINE void processmsg_gcmaprequest_I() {
2766 void * dstptr = NULL;
2767 int data1 = msgdata[msgdataindex];
2769 int data2 = msgdata[msgdataindex];
2771 #ifdef LOCALHASHTBL_TEST
2772 RuntimeHashget(gcpointertbl, data1, &dstptr);
2774 dstptr = mgchashSearch(gcpointertbl, data1);
2776 if(NULL == dstptr) {
2777 // no such pointer in this core, something is wrong
2779 BAMBOO_DEBUGPRINT_REG(data1);
2780 BAMBOO_DEBUGPRINT_REG(data2);
2782 BAMBOO_EXIT(0xe01c);
2784 // send back the mapping info, cache the msg first
2785 if(BAMBOO_CHECK_SEND_MODE()) {
2786 cache_msg_3(data2, GCMAPINFO, data1, (int)dstptr);
2788 send_msg_3(data2, GCMAPINFO, data1, (int)dstptr, true);
2793 INLINE void processmsg_gcmapinfo_I() {
2794 int data1 = msgdata[msgdataindex];
2796 gcmappedobj = msgdata[msgdataindex]; // [2]
2798 #ifdef LOCALHASHTBL_TEST
2799 RuntimeHashadd_I(gcpointertbl, data1, gcmappedobj);
2801 mgchashInsert_I(gcpointertbl, data1, gcmappedobj);
2803 if(data1 == gcobj2map) {
2808 INLINE void processmsg_gcmaptbl_I() {
2809 int data1 = msgdata[msgdataindex];
2811 int data2 = msgdata[msgdataindex];
2813 gcrpointertbls[data2] = (mgcsharedhashtbl_t *)data1;
2816 INLINE void processmsg_gclobjinfo_I() {
2819 int data1 = msgdata[msgdataindex];
2821 int data2 = msgdata[msgdataindex];
2823 if(BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1) {
2825 BAMBOO_DEBUGPRINT_REG(data2);
2827 BAMBOO_EXIT(0xe01d);
2829 // store the mark result info
2831 gcloads[cnum] = msgdata[msgdataindex];
2832 MSG_INDEXINC_I(); // msgdata[3];
2833 int data4 = msgdata[msgdataindex];
2835 if(gcheaptop < data4) {
2838 // large obj info here
2839 for(int k = 5; k < data1; k+=2) {
2840 int lobj = msgdata[msgdataindex];
2841 MSG_INDEXINC_I(); //msgdata[k++];
2842 int length = msgdata[msgdataindex];
2843 MSG_INDEXINC_I(); //msgdata[k++];
2844 gc_lobjenqueue_I(lobj, length, cnum);
2846 } // for(int k = 5; k < msgdata[1];)
2849 INLINE void processmsg_gclobjmapping_I() {
2850 int data1 = msgdata[msgdataindex];
2852 int data2 = msgdata[msgdataindex];
2854 #ifdef LOCALHASHTBL_TEST
2855 RuntimeHashadd_I(gcpointertbl, data1, data2);
2857 mgchashInsert_I(gcpointertbl, data1, data2);
2859 mgcsharedhashInsert_I(gcsharedptbl, data1, data2);
2863 INLINE void processmsg_gcprofiles_I() {
2864 int data1 = msgdata[msgdataindex];
2866 int data2 = msgdata[msgdataindex];
2868 int data3 = msgdata[msgdataindex];
2870 gc_num_obj += data1;
2871 gc_num_liveobj += data2;
2872 gc_num_forwardobj += data3;
2875 #endif // GC_PROFILE
2877 #ifdef GC_CACHE_ADAPT
2878 INLINE void processmsg_gcstartpref_I() {
2879 gcphase = PREFINISHPHASE;
2882 INLINE void processmsg_gcfinishpref_I() {
2883 int data1 = msgdata[msgdataindex];
2885 // received a flush phase finish msg
2886 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2887 // non startup core can not receive this msg
2889 BAMBOO_DEBUGPRINT_REG(data1);
2891 BAMBOO_EXIT(0xe01e);
2893 // all cores should do flush
2894 if(data1 < NUMCORESACTIVE) {
2895 gccorestatus[data1] = 0;
2898 #endif // GC_CACHE_ADAPT
2899 #endif // #ifdef MULTICORE_GC
2901 // receive object transferred from other cores
2902 // or the terminate message from other cores
2903 // Should be invoked in critical sections!!
2904 // NOTICE: following format is for threadsimulate version only
2905 // RAW version please see previous description
2906 // format: type + object
2907 // type: -1--stall msg
2909 // return value: 0--received an object
2910 // 1--received nothing
2911 // 2--received a Stall Msg
2912 // 3--received a lock Msg
2913 // RAW version: -1 -- received nothing
2914 // otherwise -- received msg type
2915 int receiveObject(int send_port_pending) {
2916 #ifdef PROFILE_INTERRUPT
2917 if(!interruptInfoOverflow) {
2918 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
2919 interruptInfoArray[interruptInfoIndex] = intInfo;
2920 intInfo->startTime = BAMBOO_GET_EXE_TIME();
2921 intInfo->endTime = -1;
2925 // get the incoming msgs
2926 if(receiveMsg(send_port_pending) == -1) {
2930 // processing received msgs
2932 MSG_REMAINSIZE_I(&size);
2933 if((size == 0) || (checkMsgLength_I(size) == -1)) {
2935 // have new coming msg
2936 if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
2943 if(msglength <= size) {
2944 // have some whole msg
2946 type = msgdata[msgdataindex]; //[0]
2948 msgdatafull = false;
2951 // receive a object transfer msg
2952 processmsg_transobj_I();
2957 // receive a stall msg
2958 processmsg_transtall_I();
2962 // GC version have no lock msgs
2963 #ifndef MULTICORE_GC
2965 // receive lock request msg, handle it right now
2966 processmsg_lockrequest_I();
2968 } // case LOCKREQUEST
2971 // receive lock grount msg
2972 processmsg_lockgrount_I();
2974 } // case LOCKGROUNT
2977 // receive lock deny msg
2978 processmsg_lockdeny_I();
2983 processmsg_lockrelease_I();
2985 } // case LOCKRELEASE
2986 #endif // #ifndef MULTICORE_GC
2989 case PROFILEOUTPUT: {
2990 // receive an output profile data request msg
2991 processmsg_profileoutput_I();
2993 } // case PROFILEOUTPUT
2995 case PROFILEFINISH: {
2996 // receive a profile output finish msg
2997 processmsg_profilefinish_I();
2999 } // case PROFILEFINISH
3000 #endif // #ifdef PROFILE
3002 // GC version has no lock msgs
3003 #ifndef MULTICORE_GC
3004 case REDIRECTLOCK: {
3005 // receive a redirect lock request msg, handle it right now
3006 processmsg_redirectlock_I();
3008 } // case REDIRECTLOCK
3010 case REDIRECTGROUNT: {
3011 // receive a lock grant msg with redirect info
3012 processmsg_redirectgrount_I();
3014 } // case REDIRECTGROUNT
3016 case REDIRECTDENY: {
3017 // receive a lock deny msg with redirect info
3018 processmsg_redirectdeny_I();
3020 } // case REDIRECTDENY
3022 case REDIRECTRELEASE: {
3023 // receive a lock release msg with redirect info
3024 processmsg_redirectrelease_I();
3026 } // case REDIRECTRELEASE
3027 #endif // #ifndef MULTICORE_GC
3029 case STATUSCONFIRM: {
3030 // receive a status confirm info
3031 processmsg_statusconfirm_I();
3033 } // case STATUSCONFIRM
3035 case STATUSREPORT: {
3036 processmsg_statusreport_I();
3038 } // case STATUSREPORT
3041 // receive a terminate msg
3042 processmsg_terminate_I();
3047 processmsg_memrequest_I();
3049 } // case MEMREQUEST
3052 processmsg_memresponse_I();
3054 } // case MEMRESPONSE
3059 processmsg_gcstartpre_I();
3061 } // case GCSTARTPRE
3064 processmsg_gcstartinit_I();
3066 } // case GCSTARTINIT
3069 // receive a start GC msg
3070 processmsg_gcstart_I();
3074 case GCSTARTCOMPACT: {
3075 // a compact phase start msg
3076 processmsg_gcstartcompact_I();
3078 } // case GCSTARTCOMPACT
3080 case GCSTARTMAPINFO: {
3081 // received a flush phase start msg
3082 processmsg_gcstartmapinfo_I();
3084 } // case GCSTARTFLUSH
3086 case GCSTARTFLUSH: {
3087 // received a flush phase start msg
3088 processmsg_gcstartflush_I();
3090 } // case GCSTARTFLUSH
3093 processmsg_gcfinishpre_I();
3095 } // case GCFINISHPRE
3097 case GCFINISHINIT: {
3098 processmsg_gcfinishinit_I();
3100 } // case GCFINISHINIT
3102 case GCFINISHMARK: {
3103 processmsg_gcfinishmark_I();
3105 } // case GCFINISHMARK
3107 case GCFINISHCOMPACT: {
3108 // received a compact phase finish msg
3109 processmsg_gcfinishcompact_I();
3111 } // case GCFINISHCOMPACT
3113 case GCFINISHMAPINFO: {
3114 processmsg_gcfinishmapinfo_I();
3116 } // case GCFINISHMAPINFO
3118 case GCFINISHFLUSH: {
3119 processmsg_gcfinishflush_I();
3121 } // case GCFINISHFLUSH
3124 // received a GC finish msg
3125 gcphase = FINISHPHASE;
3129 case GCMARKCONFIRM: {
3130 // received a marked phase finish confirm request msg
3131 // all cores should do mark
3132 processmsg_gcmarkconfirm_I();
3134 } // case GCMARKCONFIRM
3136 case GCMARKREPORT: {
3137 processmsg_gcmarkreport_I();
3139 } // case GCMARKREPORT
3142 processmsg_gcmarkedobj_I();
3144 } // case GCMARKEDOBJ
3147 // received a start moving objs msg
3148 processmsg_gcmovestart_I();
3150 } // case GCMOVESTART
3152 case GCMAPREQUEST: {
3153 // received a mapping info request msg
3154 processmsg_gcmaprequest_I();
3156 } // case GCMAPREQUEST
3159 // received a mapping info response msg
3160 processmsg_gcmapinfo_I();
3165 // received a mapping tbl response msg
3166 processmsg_gcmaptbl_I();
3170 case GCLOBJREQUEST: {
3171 // received a large objs info request msg
3172 transferMarkResults_I();
3174 } // case GCLOBJREQUEST
3177 // received a large objs info response msg
3178 processmsg_gclobjinfo_I();
3180 } // case GCLOBJINFO
3182 case GCLOBJMAPPING: {
3183 // received a large obj mapping info msg
3184 processmsg_gclobjmapping_I();
3186 } // case GCLOBJMAPPING
3190 // received a gcprofiles msg
3191 processmsg_gcprofiles_I();
3194 #endif // GC_PROFILE
3196 #ifdef GC_CACHE_ADAPT
3198 // received a gcstartpref msg
3199 processmsg_gcstartpref_I();
3203 case GCFINISHPREF: {
3204 // received a gcfinishpref msg
3205 processmsg_gcfinishpref_I();
3208 #endif // GC_CACHE_ADAPT
3209 #endif // #ifdef MULTICORE_GC
3214 msglength = BAMBOO_MSG_BUF_LENGTH;
3216 if((msgdataindex != msgdatalast) || (msgdatafull)) {
3217 // still have available msg
3221 BAMBOO_DEBUGPRINT(0xe88d);
3224 // have new coming msg
3225 if(BAMBOO_MSG_AVAIL() != 0) {
3229 #ifdef PROFILE_INTERRUPT
3230 if(!interruptInfoOverflow) {
3231 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
3232 interruptInfoIndex++;
3233 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
3234 interruptInfoOverflow = true;
3242 BAMBOO_DEBUGPRINT(0xe88e);
3248 int enqueuetasks(struct parameterwrapper *parameter,
3249 struct parameterwrapper *prevptr,
3250 struct ___Object___ *ptr,
3252 int numenterflags) {
3253 void * taskpointerarray[MAXTASKPARAMS];
3255 int numiterators=parameter->task->numTotal-1;
3258 struct taskdescriptor * task=parameter->task;
3260 //this add the object to parameterwrapper
3261 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
3262 numenterflags, enterflags==NULL);
3264 /* Add enqueued object to parameter vector */
3265 taskpointerarray[parameter->slot]=ptr;
3267 /* Reset iterators */
3268 for(j=0; j<numiterators; j++) {
3269 toiReset(¶meter->iterators[j]);
3272 /* Find initial state */
3273 for(j=0; j<numiterators; j++) {
3275 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3276 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3278 /* Need to backtrack */
3279 toiReset(¶meter->iterators[j]);
3283 /* Nothing to enqueue */
3289 /* Enqueue current state */
3291 struct taskparamdescriptor *tpd=
3292 RUNMALLOC(sizeof(struct taskparamdescriptor));
3294 tpd->numParameters=numiterators+1;
3295 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
3297 for(j=0; j<=numiterators; j++) {
3298 //store the actual parameters
3299 tpd->parameterArray[j]=taskpointerarray[j];
3302 if (!gencontains(activetasks,tpd)) {
3303 genputtable(activetasks, tpd, tpd);
3305 RUNFREE(tpd->parameterArray);
3309 /* This loop iterates to the next parameter combination */
3310 if (numiterators==0)
3313 for(j=numiterators-1; j<numiterators; j++) {
3316 ¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3317 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3319 /* Need to backtrack */
3320 toiReset(¶meter->iterators[j]);
3324 /* Nothing more to enqueue */
3332 int enqueuetasks_I(struct parameterwrapper *parameter,
3333 struct parameterwrapper *prevptr,
3334 struct ___Object___ *ptr,
3336 int numenterflags) {
3337 void * taskpointerarray[MAXTASKPARAMS];
3339 int numiterators=parameter->task->numTotal-1;
3342 struct taskdescriptor * task=parameter->task;
3344 //this add the object to parameterwrapper
3345 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
3346 numenterflags, enterflags==NULL);
3348 /* Add enqueued object to parameter vector */
3349 taskpointerarray[parameter->slot]=ptr;
3351 /* Reset iterators */
3352 for(j=0; j<numiterators; j++) {
3353 toiReset(¶meter->iterators[j]);
3356 /* Find initial state */
3357 for(j=0; j<numiterators; j++) {
3359 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3360 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3362 /* Need to backtrack */
3363 toiReset(¶meter->iterators[j]);
3367 /* Nothing to enqueue */
3373 /* Enqueue current state */
3375 struct taskparamdescriptor *tpd=
3376 RUNMALLOC_I(sizeof(struct taskparamdescriptor));
3378 tpd->numParameters=numiterators+1;
3379 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
3381 for(j=0; j<=numiterators; j++) {
3382 //store the actual parameters
3383 tpd->parameterArray[j]=taskpointerarray[j];
3386 if (!gencontains(activetasks,tpd)) {
3387 genputtable_I(activetasks, tpd, tpd);
3389 RUNFREE(tpd->parameterArray);
3393 /* This loop iterates to the next parameter combination */
3394 if (numiterators==0)
3397 for(j=numiterators-1; j<numiterators; j++) {
3400 ¶meter->iterators[j], taskpointerarray OPTARG(failed)))
3401 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3403 /* Need to backtrack */
3404 toiReset(¶meter->iterators[j]);
3408 /* Nothing more to enqueue */
3422 int containstag(struct ___Object___ *ptr,
3423 struct ___TagDescriptor___ *tag);
3425 #ifndef MULTICORE_GC
3426 void releasewritelock_r(void * lock, void * redirectlock) {
3428 int reallock = (int)lock;
3429 targetcore = (reallock >> 5) % NUMCORES;
3431 BAMBOO_DEBUGPRINT(0xe671);
3432 BAMBOO_DEBUGPRINT_REG((int)lock);
3433 BAMBOO_DEBUGPRINT_REG(reallock);
3434 BAMBOO_DEBUGPRINT_REG(targetcore);
3436 if(targetcore == BAMBOO_NUM_OF_CORE) {
3437 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3438 BAMBOO_DEBUGPRINT(0xf001);
3439 // reside on this core
3440 if(!RuntimeHashcontainskey(locktbl, reallock)) {
3441 // no locks for this object, something is wrong
3442 BAMBOO_EXIT(0xe01f);
3445 struct LockValue * lockvalue = NULL;
3446 BAMBOO_DEBUGPRINT(0xe672);
3447 RuntimeHashget(locktbl, reallock, &rwlock_obj);
3448 lockvalue = (struct LockValue *)rwlock_obj;
3449 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
3451 lockvalue->redirectlock = (int)redirectlock;
3452 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
3454 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3455 BAMBOO_DEBUGPRINT(0xf000);
3458 // send lock release with redirect info msg
3459 // for 32 bit machine, the size is always 4 words
3460 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock,
3461 (int)redirectlock, false);
3466 void executetasks() {
3467 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
3470 struct ___Object___ * tmpparam = NULL;
3471 struct parameterdescriptor * pd=NULL;
3472 struct parameterwrapper *pw=NULL;
3482 while(hashsize(activetasks)>0) {
3484 if(gcflag) gc(NULL);
3486 BAMBOO_DEBUGPRINT(0xe990);
3488 /* See if there are any active tasks */
3491 #ifdef ACCURATEPROFILE
3492 profileTaskStart("tpd checking");
3497 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
3498 genfreekey(activetasks, currtpd);
3500 numparams=currtpd->task->numParameters;
3501 numtotal=currtpd->task->numTotal;
3503 // (TODO, this table should be empty after all locks are released)
3505 // get all required locks
3506 runtime_locklen = 0;
3507 // check which locks are needed
3508 for(i = 0; i < numparams; i++) {
3509 void * param = currtpd->parameterArray[i];
3513 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
3515 taskpointerarray[i+OFFSET]=param;
3518 if(((struct ___Object___ *)param)->lock == NULL) {
3519 tmplock = (int)param;
3521 tmplock = (int)(((struct ___Object___ *)param)->lock);
3523 // insert into the locks array
3524 for(j = 0; j < runtime_locklen; j++) {
3525 if(runtime_locks[j].value == tmplock) {
3528 } else if(runtime_locks[j].value > tmplock) {
3533 int h = runtime_locklen;
3535 runtime_locks[h].redirectlock = runtime_locks[h-1].redirectlock;
3536 runtime_locks[h].value = runtime_locks[h-1].value;
3538 runtime_locks[j].value = tmplock;
3539 runtime_locks[j].redirectlock = (int)param;
3542 } // line 2713: for(i = 0; i < numparams; i++)
3543 // grab these required locks
3544 BAMBOO_DEBUGPRINT(0xe991);
3546 for(i = 0; i < runtime_locklen; i++) {
3547 int * lock = (int *)(runtime_locks[i].redirectlock);
3549 // require locks for this parameter if it is not a startup object
3550 BAMBOO_DEBUGPRINT_REG((int)lock);
3551 BAMBOO_DEBUGPRINT_REG((int)(runtime_locks[i].value));
3553 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3554 BAMBOO_DEBUGPRINT(0xf001);
3556 BAMBOO_WAITING_FOR_LOCK(0);
3560 while(BAMBOO_WAITING_FOR_LOCK(0) != -1) {
3564 grount = lockresult;
3573 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3574 BAMBOO_DEBUGPRINT(0xf000);
3577 BAMBOO_DEBUGPRINT(0xe992);
3578 BAMBOO_DEBUGPRINT_REG(lock);
3579 // check if has the lock already
3580 // can not get the lock, try later
3581 // release all grabbed locks for previous parameters
3582 for(j = 0; j < i; ++j) {
3583 lock = (int*)(runtime_locks[j].redirectlock);
3584 releasewritelock(lock);
3586 genputtable(activetasks, currtpd, currtpd);
3587 if(hashsize(activetasks) == 1) {
3588 // only one task right now, wait a little while before next try
3594 #ifdef ACCURATEPROFILE
3595 // fail, set the end of the checkTaskInfo
3601 } // line 2752: for(i = 0; i < runtime_locklen; i++)
3603 BAMBOO_DEBUGPRINT(0xe993);
3604 /* Make sure that the parameters are still in the queues */
3605 for(i=0; i<numparams; i++) {
3606 void * parameter=currtpd->parameterArray[i];
3610 BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
3611 classsize[((struct ___Object___ *)parameter)->type]);
3613 tmpparam = (struct ___Object___ *)parameter;
3614 pd=currtpd->task->descriptorarray[i];
3615 pw=(struct parameterwrapper *) pd->queue;
3616 /* Check that object is still in queue */
3618 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
3619 BAMBOO_DEBUGPRINT(0xe994);
3620 BAMBOO_DEBUGPRINT_REG(parameter);
3621 // release grabbed locks
3622 for(j = 0; j < runtime_locklen; ++j) {
3623 int * lock = (int *)(runtime_locks[j].redirectlock);
3624 releasewritelock(lock);
3626 RUNFREE(currtpd->parameterArray);
3632 /* Check if the object's flags still meets requirements */
3636 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
3637 andmask=pw->intarray[tmpi*2];
3638 checkmask=pw->intarray[tmpi*2+1];
3639 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
3645 // flags are never suitable
3646 // remove this obj from the queue
3648 int UNUSED, UNUSED2;
3650 BAMBOO_DEBUGPRINT(0xe995);
3651 BAMBOO_DEBUGPRINT_REG(parameter);
3652 ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
3653 (int *) &enterflags, &UNUSED, &UNUSED2);
3654 ObjectHashremove(pw->objectset, (int)parameter);
3655 if (enterflags!=NULL)
3656 RUNFREE(enterflags);
3657 // release grabbed locks
3658 for(j = 0; j < runtime_locklen; ++j) {
3659 int * lock = (int *)(runtime_locks[j].redirectlock);
3660 releasewritelock(lock);
3662 RUNFREE(currtpd->parameterArray);
3666 #ifdef ACCURATEPROFILE
3667 // fail, set the end of the checkTaskInfo
3672 } // line 2878: if (!ismet)
3676 /* Check that object still has necessary tags */
3677 for(j=0; j<pd->numbertags; j++) {
3678 int slotid=pd->tagarray[2*j]+numparams;
3679 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
3680 if (!containstag(parameter, tagd)) {
3681 BAMBOO_DEBUGPRINT(0xe996);
3683 // release grabbed locks
3685 for(tmpj = 0; tmpj < runtime_locklen; ++tmpj) {
3686 int * lock = (int *)(runtime_locks[tmpj].redirectlock);
3687 releasewritelock(lock);
3690 RUNFREE(currtpd->parameterArray);
3694 } // line2911: if (!containstag(parameter, tagd))
3695 } // line 2808: for(j=0; j<pd->numbertags; j++)
3697 taskpointerarray[i+OFFSET]=parameter;
3698 } // line 2824: for(i=0; i<numparams; i++)
3700 for(; i<numtotal; i++) {
3701 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
3706 /* Actually call task */
3708 ((int *)taskpointerarray)[0]=currtpd->numParameters;
3709 taskpointerarray[1]=NULL;
3712 #ifdef ACCURATEPROFILE
3713 // check finish, set the end of the checkTaskInfo
3716 profileTaskStart(currtpd->task->name);
3719 BAMBOO_DEBUGPRINT(0xe997);
3720 ((void (*)(void **))currtpd->task->taskptr)(taskpointerarray);
3723 #ifdef ACCURATEPROFILE
3724 // task finish, set the end of the checkTaskInfo
3726 // new a PostTaskInfo for the post-task execution
3727 profileTaskStart("post task execution");
3730 BAMBOO_DEBUGPRINT(0xe998);
3731 BAMBOO_DEBUGPRINT_REG(islock);
3734 BAMBOO_DEBUGPRINT(0xe999);
3735 for(i = 0; i < runtime_locklen; ++i) {
3736 void * ptr = (void *)(runtime_locks[i].redirectlock);
3737 int * lock = (int *)(runtime_locks[i].value);
3738 BAMBOO_DEBUGPRINT_REG((int)ptr);
3739 BAMBOO_DEBUGPRINT_REG((int)lock);
3740 BAMBOO_DEBUGPRINT_REG(*((int*)lock+5));
3741 #ifndef MULTICORE_GC
3742 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
3744 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
3745 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
3746 releasewritelock_r(lock, (int *)redirectlock);
3751 releasewritelock(ptr);
3754 } // line 3015: if(islock)
3757 // post task execution finish, set the end of the postTaskInfo
3761 // Free up task parameter descriptor
3762 RUNFREE(currtpd->parameterArray);
3765 BAMBOO_DEBUGPRINT(0xe99a);
3767 //} // if (hashsize(activetasks)>0)
3768 } // while(hashsize(activetasks)>0)
3769 BAMBOO_DEBUGPRINT(0xe99b);
3772 /* This function processes an objects tags */
3773 void processtags(struct parameterdescriptor *pd,
3775 struct parameterwrapper *parameter,
3776 int * iteratorcount,
3781 for(i=0; i<pd->numbertags; i++) {
3782 int slotid=pd->tagarray[2*i];
3783 int tagid=pd->tagarray[2*i+1];
3785 if (statusarray[slotid+numparams]==0) {
3786 parameter->iterators[*iteratorcount].istag=1;
3787 parameter->iterators[*iteratorcount].tagid=tagid;
3788 parameter->iterators[*iteratorcount].slot=slotid+numparams;
3789 parameter->iterators[*iteratorcount].tagobjectslot=index;
3790 statusarray[slotid+numparams]=1;
3797 void processobject(struct parameterwrapper *parameter,
3799 struct parameterdescriptor *pd,
3805 struct ObjectHash * objectset=
3806 ((struct parameterwrapper *)pd->queue)->objectset;
3808 parameter->iterators[*iteratorcount].istag=0;
3809 parameter->iterators[*iteratorcount].slot=index;
3810 parameter->iterators[*iteratorcount].objectset=objectset;
3811 statusarray[index]=1;
3813 for(i=0; i<pd->numbertags; i++) {
3814 int slotid=pd->tagarray[2*i];
3815 if (statusarray[slotid+numparams]!=0) {
3816 /* This tag has already been enqueued, use it to narrow search */
3817 parameter->iterators[*iteratorcount].tagbindings[tagcount]=
3822 parameter->iterators[*iteratorcount].numtags=tagcount;
3827 /* This function builds the iterators for a task & parameter */
3829 void builditerators(struct taskdescriptor * task,
3831 struct parameterwrapper * parameter) {
3832 int statusarray[MAXTASKPARAMS];
3834 int numparams=task->numParameters;
3835 int iteratorcount=0;
3836 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
3838 statusarray[index]=1; /* Initial parameter */
3839 /* Process tags for initial iterator */
3841 processtags(task->descriptorarray[index], index, parameter,
3842 &iteratorcount, statusarray, numparams);
3846 /* Check for objects with existing tags */
3847 for(i=0; i<numparams; i++) {
3848 if (statusarray[i]==0) {
3849 struct parameterdescriptor *pd=task->descriptorarray[i];
3851 for(j=0; j<pd->numbertags; j++) {
3852 int slotid=pd->tagarray[2*j];
3853 if(statusarray[slotid+numparams]!=0) {
3854 processobject(parameter,i,pd,&iteratorcount,
3855 statusarray,numparams);
3856 processtags(pd,i,parameter,&iteratorcount,statusarray,numparams);
3863 /* Next do objects w/ unbound tags*/
3865 for(i=0; i<numparams; i++) {
3866 if (statusarray[i]==0) {
3867 struct parameterdescriptor *pd=task->descriptorarray[i];
3868 if (pd->numbertags>0) {
3869 processobject(parameter,i,pd,&iteratorcount,statusarray,numparams);
3870 processtags(pd,i,parameter,&iteratorcount,statusarray,numparams);
3876 /* Nothing with a tag enqueued */
3878 for(i=0; i<numparams; i++) {
3879 if (statusarray[i]==0) {
3880 struct parameterdescriptor *pd=task->descriptorarray[i];
3881 processobject(parameter,i,pd,&iteratorcount,statusarray,numparams);
3882 processtags(pd,i,parameter,&iteratorcount,statusarray,numparams);
3895 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3898 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3899 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3901 printf("%s\n", task->name);
3903 for(j=0; j<task->numParameters; j++) {
3904 struct parameterdescriptor *param=task->descriptorarray[j];
3905 struct parameterwrapper *parameter=param->queue;
3906 struct ObjectHash * set=parameter->objectset;
3907 struct ObjectIterator objit;
3909 printf(" Parameter %d\n", j);
3911 ObjectHashiterator(set, &objit);
3912 while(ObjhasNext(&objit)) {
3913 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
3914 struct ___Object___ * tagptr=obj->___tags___;
3915 int nonfailed=Objdata4(&objit);
3916 int numflags=Objdata3(&objit);
3917 int flags=Objdata2(&objit);
3920 printf(" Contains %lx\n", obj);
3921 printf(" flag=%d\n", obj->flag);
3924 } else if (tagptr->type==TAGTYPE) {
3926 printf(" tag=%lx\n",tagptr);
3932 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
3933 for(; tagindex<ao->___cachedCode___; tagindex++) {
3935 printf(" tag=%lx\n",ARRAYGET(ao,struct ___TagDescriptor___*,
3948 /* This function processes the task information to create queues for
3949 each parameter type. */
3951 void processtasks() {
3953 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3956 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3957 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3960 /* Build objectsets */
3961 for(j=0; j<task->numParameters; j++) {
3962 struct parameterdescriptor *param=task->descriptorarray[j];
3963 struct parameterwrapper *parameter=param->queue;
3964 parameter->objectset=allocateObjectHash(10);
3965 parameter->task=task;
3968 /* Build iterators for parameters */
3969 for(j=0; j<task->numParameters; j++) {
3970 struct parameterdescriptor *param=task->descriptorarray[j];
3971 struct parameterwrapper *parameter=param->queue;
3972 builditerators(task, j, parameter);
3977 void toiReset(struct tagobjectiterator * it) {
3980 } else if (it->numtags>0) {
3983 ObjectHashiterator(it->objectset, &it->it);
3987 int toiHasNext(struct tagobjectiterator *it,
3988 void ** objectarray OPTARG(int * failed)) {
3991 /* Get object with tags */
3992 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3993 struct ___Object___ *tagptr=obj->___tags___;
3994 if (tagptr->type==TAGTYPE) {
3995 if ((it->tagobjindex==0)&& /* First object */
3996 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
4001 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
4002 int tagindex=it->tagobjindex;
4003 for(; tagindex<ao->___cachedCode___; tagindex++) {
4004 struct ___TagDescriptor___ *td=
4005 ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
4006 if (td->flag==it->tagid) {
4007 it->tagobjindex=tagindex; /* Found right type of tag */
4013 } else if (it->numtags>0) {
4014 /* Use tags to locate appropriate objects */
4015 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
4016 struct ___Object___ *objptr=tag->flagptr;
4018 if (objptr->type!=OBJECTARRAYTYPE) {
4019 if (it->tagobjindex>0)
4021 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
4023 for(i=1; i<it->numtags; i++) {
4024 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
4025 if (!containstag(objptr,tag2))
4030 struct ArrayObject *ao=(struct ArrayObject *) objptr;
4033 for(tagindex=it->tagobjindex;tagindex<ao->___cachedCode___;tagindex++){
4034 struct ___Object___ *objptr=
4035 ARRAYGET(ao,struct ___Object___*,tagindex);
4036 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
4038 for(i=1; i<it->numtags; i++) {
4039 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
4040 if (!containstag(objptr,tag2))
4043 it->tagobjindex=tagindex;
4048 it->tagobjindex=tagindex;
4052 return ObjhasNext(&it->it);
4056 int containstag(struct ___Object___ *ptr,
4057 struct ___TagDescriptor___ *tag) {
4059 struct ___Object___ * objptr=tag->flagptr;
4060 if (objptr->type==OBJECTARRAYTYPE) {
4061 struct ArrayObject *ao=(struct ArrayObject *)objptr;
4062 for(j=0; j<ao->___cachedCode___; j++) {
4063 if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
4073 void toiNext(struct tagobjectiterator *it,
4074 void ** objectarray OPTARG(int * failed)) {
4075 /* hasNext has all of the intelligence */
4078 /* Get object with tags */
4079 struct ___Object___ *obj=objectarray[it->tagobjectslot];
4080 struct ___Object___ *tagptr=obj->___tags___;
4081 if (tagptr->type==TAGTYPE) {
4083 objectarray[it->slot]=tagptr;
4085 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
4086 objectarray[it->slot]=
4087 ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
4089 } else if (it->numtags>0) {
4090 /* Use tags to locate appropriate objects */
4091 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
4092 struct ___Object___ *objptr=tag->flagptr;
4093 if (objptr->type!=OBJECTARRAYTYPE) {
4095 objectarray[it->slot]=objptr;
4097 struct ArrayObject *ao=(struct ArrayObject *) objptr;
4098 objectarray[it->slot]=
4099 ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
4102 /* Iterate object */
4103 objectarray[it->slot]=(void *)Objkey(&it->it);
4109 inline void profileTaskStart(char * taskname) {
4110 if(!taskInfoOverflow) {
4111 TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
4112 taskInfoArray[taskInfoIndex] = taskInfo;
4113 taskInfo->taskName = taskname;
4114 taskInfo->startTime = BAMBOO_GET_EXE_TIME();
4115 taskInfo->endTime = -1;
4116 taskInfo->exitIndex = -1;
4117 taskInfo->newObjs = NULL;
4121 inline void profileTaskEnd() {
4122 if(!taskInfoOverflow) {
4123 taskInfoArray[taskInfoIndex]->endTime = BAMBOO_GET_EXE_TIME();
4125 if(taskInfoIndex == TASKINFOLENGTH) {
4126 taskInfoOverflow = true;
4131 // output the profiling data
4132 void outputProfileData() {
4135 unsigned long long totaltasktime = 0;
4136 unsigned long long preprocessingtime = 0;
4137 unsigned long long objqueuecheckingtime = 0;
4138 unsigned long long postprocessingtime = 0;
4139 unsigned long long other = 0;
4140 unsigned long long averagetasktime = 0;
4143 printf("Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
4144 // output task related info
4145 for(i = 0; i < taskInfoIndex; i++) {
4146 TaskInfo* tmpTInfo = taskInfoArray[i];
4147 unsigned long long duration = tmpTInfo->endTime - tmpTInfo->startTime;
4148 printf("%s, %lld, %lld, %lld, %lld",
4149 tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime,
4150 duration, tmpTInfo->exitIndex);
4151 // summarize new obj info
4152 if(tmpTInfo->newObjs != NULL) {
4153 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
4154 struct RuntimeIterator * iter = NULL;
4155 while(0 == isEmpty(tmpTInfo->newObjs)) {
4156 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
4157 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
4159 RuntimeHashget(nobjtbl, (int)objtype, &num);
4160 RuntimeHashremovekey(nobjtbl, (int)objtype);
4162 RuntimeHashadd(nobjtbl, (int)objtype, num);
4164 RuntimeHashadd(nobjtbl, (int)objtype, 1);
4166 //printf(stderr, "new obj!\n");
4169 // output all new obj info
4170 iter = RuntimeHashcreateiterator(nobjtbl);
4171 while(RunhasNext(iter)) {
4172 char * objtype = (char *)Runkey(iter);
4173 int num = Runnext(iter);
4174 printf(", %s, %d", objtype, num);
4178 if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
4179 preprocessingtime += duration;
4180 } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
4181 postprocessingtime += duration;
4182 } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
4183 objqueuecheckingtime += duration;
4185 totaltasktime += duration;
4186 averagetasktime += duration;
4191 if(taskInfoOverflow) {
4192 printf("Caution: task info overflow!\n");
4195 other = totalexetime-totaltasktime-preprocessingtime-postprocessingtime;
4196 averagetasktime /= tasknum;
4198 printf("\nTotal time: %lld\n", totalexetime);
4199 printf("Total task execution time: %lld (%d%%)\n", totaltasktime,
4200 (int)(((double)totaltasktime/(double)totalexetime)*100));
4201 printf("Total objqueue checking time: %lld (%d%%)\n",
4202 objqueuecheckingtime,
4203 (int)(((double)objqueuecheckingtime/(double)totalexetime)*100));
4204 printf("Total pre-processing time: %lld (%d%%)\n", preprocessingtime,
4205 (int)(((double)preprocessingtime/(double)totalexetime)*100));
4206 printf("Total post-processing time: %lld (%d%%)\n", postprocessingtime,
4207 (int)(((double)postprocessingtime/(double)totalexetime)*100));
4208 printf("Other time: %lld (%d%%)\n", other,
4209 (int)(((double)other/(double)totalexetime)*100));
4212 printf("\nAverage task execution time: %lld\n", averagetasktime);
4218 BAMBOO_PRINT(0xdddd);
4219 // output task related info
4220 for(i= 0; i < taskInfoIndex; i++) {
4221 TaskInfo* tmpTInfo = taskInfoArray[i];
4222 char* tmpName = tmpTInfo->taskName;
4223 int nameLen = strlen(tmpName);
4224 BAMBOO_PRINT(0xddda);
4225 for(j = 0; j < nameLen; j++) {
4226 BAMBOO_PRINT_REG(tmpName[j]);
4228 BAMBOO_PRINT(0xdddb);
4229 BAMBOO_PRINT_REG(tmpTInfo->startTime);
4230 BAMBOO_PRINT_REG(tmpTInfo->endTime);
4231 BAMBOO_PRINT_REG(tmpTInfo->exitIndex);
4232 if(tmpTInfo->newObjs != NULL) {
4233 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
4234 struct RuntimeIterator * iter = NULL;
4235 while(0 == isEmpty(tmpTInfo->newObjs)) {
4236 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
4237 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
4239 RuntimeHashget(nobjtbl, (int)objtype, &num);
4240 RuntimeHashremovekey(nobjtbl, (int)objtype);
4242 RuntimeHashadd(nobjtbl, (int)objtype, num);
4244 RuntimeHashadd(nobjtbl, (int)objtype, 1);
4248 // ouput all new obj info
4249 iter = RuntimeHashcreateiterator(nobjtbl);
4250 while(RunhasNext(iter)) {
4251 char * objtype = (char *)Runkey(iter);
4252 int num = Runnext(iter);
4253 int nameLen = strlen(objtype);
4254 BAMBOO_PRINT(0xddda);
4255 for(j = 0; j < nameLen; j++) {
4256 BAMBOO_PRINT_REG(objtype[j]);
4258 BAMBOO_PRINT(0xdddb);
4259 BAMBOO_PRINT_REG(num);
4262 BAMBOO_PRINT(0xdddc);
4265 if(taskInfoOverflow) {
4266 BAMBOO_PRINT(0xefee);
4269 #ifdef PROFILE_INTERRUPT
4270 // output interrupt related info
4271 for(i = 0; i < interruptInfoIndex; i++) {
4272 InterruptInfo* tmpIInfo = interruptInfoArray[i];
4273 BAMBOO_PRINT(0xddde);
4274 BAMBOO_PRINT_REG(tmpIInfo->startTime);
4275 BAMBOO_PRINT_REG(tmpIInfo->endTime);
4276 BAMBOO_PRINT(0xdddf);
4279 if(interruptInfoOverflow) {
4280 BAMBOO_PRINT(0xefef);
4282 #endif // PROFILE_INTERRUPT
4284 BAMBOO_PRINT(0xeeee);
4287 #endif // #ifdef PROFILE