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}, { 1, -1, 8, 0, 2, -1, 15, -1, 3},
92 { 2, -1, 9, 1, 3, -1, 16, 0, 4}, { 3, -1, 10, 2, 4, -1, 17, 1, 5},
93 { 4, -1, 11, 3, 5, -1, 18, 2, 6}, { 5, -1, 12, 4, 6, -1, 19, 3, -1},
94 { 6, -1, 13, 5, -1, -1, 20, 4, -1}, { 7, 0, 14, -1, 8, -1, 21, -1, 9},
95 { 8, 1, 15, 7, 9, -1, 22, -1, 10}, { 9, 2, 16, 8, 10, -1, 23, 7, 11},
96 {10, 3, 17, 9, 11, -1, 24, 8, 12}, {11, 4, 18, 10, 12, -1, 25, 9, 13},
97 {12, 5, 19, 11, 13, -1, 26, 10, -1}, {13, 6, 20, 12, -1, -1, 27, 11, -1},
98 {14, 7, 21, -1, 15, 0, 28, -1, 16}, {15, 8, 22, 14, 16, 1, 29, -1, 17},
99 {16, 9, 23, 15, 17, 2, 30, 14, 18}, {17, 10, 24, 16, 18, 3, 31, 15, 19},
100 {18, 11, 25, 17, 19, 4, 32, 16, 20}, {19, 12, 26, 18, 20, 5, 33, 17, -1},
101 {20, 13, 27, 19, -1, 6, 34, 18, -1}, {21, 14, 28, -1, 22, 7, 35, -1, 23},
102 {22, 15, 29, 21, 23, 8, 36, -1, 24}, {23, 16, 30, 22, 24, 9, 37, 21, 25},
103 {24, 17, 31, 23, 25, 10, 38, 22, 26}, {25, 18, 32, 24, 26, 11, 39, 23, 27},
104 {26, 19, 33, 25, 27, 12, 40, 24, -1}, {27, 20, 34, 26, -1, 13, 41, 25, -1},
105 {28, 21, 35, -1, 29, 14, 42, -1, 30}, {29, 22, 36, 28, 30, 15, 43, -1, 31},
106 {30, 23, 37, 29, 31, 16, 44, 28, 32}, {31, 24, 38, 30, 32, 17, 45, 29, 33},
107 {32, 25, 39, 31, 33, 18, 46, 30, 34}, {33, 26, 40, 32, 34, 19, 47, 31, -1},
108 {34, 27, 41, 33, -1, 20, 48, 32, -1}, {35, 28, 42, -1, 36, 21, 49, -1, 37},
109 {36, 29, 43, 35, 37, 22, 50, -1, 38}, {37, 30, 44, 36, 38, 23, 51, 35, 39},
110 {38, 31, 45, 37, 39, 24, 52, 36, 40}, {39, 32, 46, 38, 40, 25, 53, 37, 41},
111 {40, 33, 47, 39, 41, 26, 54, 38, -1}, {41, 34, 48, 40, -1, 27, 55, 39, -1},
112 {42, 35, 49, -1, 43, 28, -1, -1, 44}, {43, 36, 50, 42, 44, 29, -1, -1, 45},
113 {44, 37, 51, 43, 45, 30, -1, 42, 46}, {45, 38, 52, 44, 46, 31, -1, 43, 47},
114 {46, 39, 53, 45, 47, 32, -1, 44, 48}, {47, 40, 54, 46, 48, 33, -1, 45, -1},
115 {48, 41, 55, 47, -1, 34, -1, 46, -1}, {49, 42, -1, -1, 50, 35, -1, -1, 51},
116 {50, 43, -1, 49, 51, 36, -1, -1, 52}, {51, 44, -1, 50, 52, 37, -1, 49, 53},
117 {52, 45, -1, 51, 53, 38, -1, 50, 54}, {53, 46, -1, 52, 54, 39, -1, 51, 55},
118 {54, 47, -1, 53, 55, 40, -1, 52, -1}, {55, 48, -1, 54, -1, 41, -1, 53, -1}
121 int core2test[62][NUM_CORES2TEST] = {
122 { 0, -1, 6, -1, 1, -1, 14, -1, 2}, { 1, -1, 7, 0, 2, -1, 15, -1, 3},
123 { 2, -1, 8, 1, 3, -1, 16, 0, 4}, { 3, -1, 9, 2, 4, -1, 17, 1, 5},
124 { 4, -1, 10, 3, 5, -1, 18, 2, -1}, { 5, -1, 11, 4, -1, -1, 19, 3, -1},
125 { 6, 0, 14, -1, 7, -1, 22, -1, 8}, { 7, 1, 15, 6, 8, -1, 23, -1, 9},
126 { 8, 2, 16, 7, 9, -1, 24, 6, 10}, { 9, 3, 17, 8, 10, -1, 25, 7, 11},
127 {10, 4, 18, 9, 11, -1, 26, 8, 12}, {11, 5, 19, 10, 12, -1, 27, 9, 13},
128 {12, -1, 20, 11, 13, -1, 28, 10, -1}, {13, -1, 21, 12, -1, -1, 29, 11, -1},
129 {14, 6, 22, -1, 15, 0, 30, -1, 16}, {15, 7, 23, 14, 16, 1, 31, -1, 17},
130 {16, 8, 24, 15, 17, 2, 32, 14, 18}, {17, 9, 25, 16, 18, 3, 33, 15, 19},
131 {18, 10, 26, 17, 19, 4, 34, 16, 20}, {19, 11, 27, 18, 20, 5, 35, 17, 21},
132 {20, 12, 28, 19, 21, -1, 36, 18, -1}, {21, 13, 29, 28, -1, -1, 37, 19, -1},
133 {22, 14, 30, -1, 23, 6, 38, -1, 24}, {23, 15, 31, 22, 24, 7, 39, -1, 25},
134 {24, 16, 32, 23, 25, 8, 40, 22, 26}, {25, 17, 33, 24, 26, 9, 41, 23, 27},
135 {26, 18, 34, 25, 27, 10, 42, 24, 28}, {27, 19, 35, 26, 28, 11, 43, 25, 29},
136 {28, 20, 36, 27, 29, 12, 44, 26, -1}, {29, 21, 37, 28, -1, 13, 45, 27, -1},
137 {30, 22, 38, -1, 31, 22, 46, -1, 32}, {31, 23, 39, 30, 32, 15, 47, -1, 33},
138 {32, 24, 40, 31, 33, 16, 48, 30, 34}, {33, 25, 41, 32, 34, 17, 49, 31, 35},
139 {34, 26, 42, 33, 35, 18, 50, 32, 36}, {35, 27, 43, 34, 36, 19, 51, 33, 37},
140 {36, 28, 44, 35, 37, 20, 52, 34, -1}, {37, 29, 45, 36, -1, 21, 53, 35, -1},
141 {38, 30, 46, -1, 39, 22, 54, -1, 40}, {39, 31, 47, 38, 40, 23, 55, -1, 41},
142 {40, 32, 48, 39, 41, 24, 56, 38, 42}, {41, 33, 49, 40, 42, 25, 57, 39, 43},
143 {42, 34, 50, 41, 43, 26, 58, 40, 44}, {43, 35, 51, 42, 44, 27, 59, 41, 45},
144 {44, 36, 52, 43, 45, 28, 60, 42, -1}, {45, 37, 53, 44, -1, 29, 61, 43, -1},
145 {46, 38, 54, -1, 47, 30, -1, -1, 48}, {47, 39, 55, 46, 48, 31, -1, -1, 49},
146 {48, 40, 56, 47, 49, 32, -1, 46, 50}, {49, 41, 57, 48, 50, 33, -1, 47, 51},
147 {50, 42, 58, 49, 51, 34, -1, 48, 52}, {51, 43, 59, 50, 52, 35, -1, 49, 53},
148 {52, 44, 60, 51, 53, 36, -1, 50, -1}, {53, 45, 61, 52, -1, 37, -1, 51, -1},
149 {54, 46, -1, -1, 55, 38, -1, -1, 56}, {55, 47, -1, 54, 56, 39, -1, -1, 57},
150 {56, 48, -1, 55, 57, 40, -1, 54, 58}, {57, 49, -1, 56, 59, 41, -1, 55, 59},
151 {58, 50, -1, 57, 59, 42, -1, 56, 60}, {59, 51, -1, 58, 60, 43, -1, 57, 61},
152 {60, 52, -1, 59, 61, 44, -1, 58, -1}, {61, 53, -1, 60, -1, 45, -1, 59, -1}
157 inline __attribute__((always_inline))
158 void setupsmemmode(void) {
160 // Only allocate local mem chunks to each core.
161 // If a core has used up its local shared memory, start gc.
162 bamboo_smem_mode = SMEMLOCAL;
164 // Allocate the local shared memory to each core with the highest priority,
165 // if a core has used up its local shared memory, try to allocate the
166 // shared memory that belong to its neighbours, if also failed, start gc.
167 bamboo_smem_mode = SMEMFIXED;
169 // Allocate the local shared memory to each core with the highest priority,
170 // if a core has used up its local shared memory, try to allocate the
171 // shared memory that belong to its neighbours first, if failed, check
172 // current memory allocation rate, if it has already reached the threshold,
173 // start gc, otherwise, allocate the shared memory globally. If all the
174 // shared memory has been used up, start gc.
175 bamboo_smem_mode = SMEMMIXED;
177 // Allocate all the memory chunks globally, do not consider the host cores
178 // When all the shared memory are used up, start gc.
179 bamboo_smem_mode = SMEMGLOBAL;
181 // defaultly using local mode
182 bamboo_smem_mode = SMEMLOCAL;
183 //bamboo_smem_mode = SMEMGLOBAL;
184 //bamboo_smem_mode = SMEMFIXED;
186 } // void setupsmemmode(void)
189 inline __attribute__((always_inline))
190 void initruntimedata() {
192 // initialize the arrays
193 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
194 // startup core to initialize corestatus[]
195 for(i = 0; i < NUMCORESACTIVE; ++i) {
198 numreceiveobjs[i] = 0;
200 // initialize the profile data arrays
201 profilestatus[i] = 1;
205 gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
206 gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
208 } // for(i = 0; i < NUMCORESACTIVE; ++i)
210 for(i = 0; i < NUMCORES4GC; ++i) {
212 gcrequiredmems[i] = 0;
214 gcfilledblocks[i] = 0;
215 } // for(i = 0; i < NUMCORES4GC; ++i)
218 gc_infoOverflow = false;
219 gc_num_livespace = 0;
220 gc_num_freespace = 0;
231 self_numsendobjs = 0;
232 self_numreceiveobjs = 0;
234 for(i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
239 msglength = BAMBOO_MSG_BUF_LENGTH;
241 for(i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
247 isMsgHanging = false;
248 //isMsgSending = false;
251 bamboo_cur_msp = NULL;
252 bamboo_smem_size = 0;
253 totransobjqueue = createQueue_I();
256 bamboo_smem_zero_top = NULL;
258 gcprocessing = false;
259 gcphase = FINISHPHASE;
263 gcself_numsendobjs = 0;
264 gcself_numreceiveobjs = 0;
265 gcmarkedptrbound = 0;
266 #ifdef LOCALHASHTBL_TEST
267 gcpointertbl = allocateRuntimeHash_I(20);
269 gcpointertbl = mgchashCreate_I(2000, 0.75);
271 //gcpointertbl = allocateMGCHash_I(20);
272 gcforwardobjtbl = allocateMGCHash_I(20, 3);
275 //gcismapped = false;
284 gcsbstarttbl = BAMBOO_BASE_VA;
285 bamboo_smemtbl = (void *)gcsbstarttbl
286 + (BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE)*sizeof(INTPTR);
287 if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
288 int t_size = ((BAMBOO_RMSP_SIZE)-sizeof(mgcsharedhashtbl_t)*2
289 -128*sizeof(size_t))/sizeof(mgcsharedhashlistnode_t)-2;
291 unsigned int tmp_k = 1 << (sizeof(int)*8 -1);
292 while(((t_size & tmp_k) == 0) && (kk < sizeof(int)*8)) {
293 t_size = t_size << 1;
296 t_size = tmp_k >> kk;
297 gcsharedptbl = mgcsharedhashCreate_I(t_size,0.30);//allocateGCSharedHash_I(20);
301 BAMBOO_MEMSET_WH(gcrpointertbls,0,sizeof(mgcsharedhashtbl_t *)*NUMCORES4GC);
302 //sizeof(struct RuntimeHash *)*NUMCORES4GC);
304 gcmem_mixed_threshold = (unsigned int)((BAMBOO_SHARED_MEM_SIZE
305 -bamboo_reserved_smem*BAMBOO_SMEM_SIZE)*0.8);
306 gcmem_mixed_usedmem = 0;
311 gc_num_forwardobj = 0;
312 gc_num_profiles = NUMCORESACTIVE - 1;
315 gc_num_flush_dtlb = 0;
317 gc_localheap_s = false;
319 // create the lock table, lockresult table and obj queue
322 (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
323 /* Set allocation blocks*/
324 locktable.listhead=NULL;
325 locktable.listtail=NULL;
327 locktable.numelements = 0;
332 lockRedirectTbl = allocateRuntimeHash_I(20);
333 objRedirectLockTbl = allocateRuntimeHash_I(20);
338 objqueue.head = NULL;
339 objqueue.tail = NULL;
345 //isInterrupt = true;
349 taskInfoOverflow = false;
350 #ifdef PROFILE_INTERRUPT
351 interruptInfoIndex = 0;
352 interruptInfoOverflow = false;
353 #endif // PROFILE_INTERRUPT
356 for(i = 0; i < MAXTASKPARAMS; i++) {
357 runtime_locks[i].redirectlock = 0;
358 runtime_locks[i].value = 0;
363 inline __attribute__((always_inline))
364 void disruntimedata() {
366 #ifdef LOCALHASHTBL_TEST
367 freeRuntimeHash(gcpointertbl);
369 mgchashDelete(gcpointertbl);
371 //freeMGCHash(gcpointertbl);
372 freeMGCHash(gcforwardobjtbl);
373 // for mapping info structures
374 //freeRuntimeHash(gcrcoretbl);
376 freeRuntimeHash(lockRedirectTbl);
377 freeRuntimeHash(objRedirectLockTbl);
378 RUNFREE(locktable.bucket);
380 if(activetasks != NULL) {
381 genfreehashtable(activetasks);
383 if(currtpd != NULL) {
384 RUNFREE(currtpd->parameterArray);
388 BAMBOO_LOCAL_MEM_CLOSE();
389 BAMBOO_SHARE_MEM_CLOSE();
392 inline __attribute__((always_inline))
393 bool checkObjQueue() {
395 struct transObjInfo * objInfo = NULL;
399 #ifdef ACCURATEPROFILE
400 bool isChecking = false;
401 if(!isEmpty(&objqueue)) {
402 profileTaskStart("objqueue checking");
404 } // if(!isEmpty(&objqueue))
408 while(!isEmpty(&objqueue)) {
410 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
412 BAMBOO_DEBUGPRINT(0xf001);
415 //isInterrupt = false;
418 BAMBOO_DEBUGPRINT(0xeee1);
421 objInfo = (struct transObjInfo *)getItem(&objqueue);
422 obj = objInfo->objptr;
424 BAMBOO_DEBUGPRINT_REG((int)obj);
426 // grab lock and flush the obj
430 BAMBOO_WAITING_FOR_LOCK(0);
431 } // while(!lockflag)
434 BAMBOO_DEBUGPRINT_REG(grount);
449 BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
450 BAMBOO_CACHE_FLUSH_RANGE((int)obj,
451 classsize[((struct ___Object___ *)obj)->type]);
453 // enqueue the object
454 for(k = 0; k < objInfo->length; ++k) {
455 int taskindex = objInfo->queues[2 * k];
456 int paramindex = objInfo->queues[2 * k + 1];
457 struct parameterwrapper ** queues =
458 &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
460 BAMBOO_DEBUGPRINT_REG(taskindex);
461 BAMBOO_DEBUGPRINT_REG(paramindex);
462 struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
463 tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n",
464 BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj,
465 (long)obj, tmpptr->flag);
467 enqueueObject_I(obj, queues, 1);
469 BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
471 } // for(k = 0; k < objInfo->length; ++k)
472 releasewritelock_I(obj);
473 RUNFREE(objInfo->queues);
477 // put it at the end of the queue if no update version in the queue
478 struct QueueItem * qitem = getHead(&objqueue);
479 struct QueueItem * prev = NULL;
480 while(qitem != NULL) {
481 struct transObjInfo * tmpinfo =
482 (struct transObjInfo *)(qitem->objectptr);
483 if(tmpinfo->objptr == obj) {
484 // the same object in the queue, which should be enqueued
485 // recently. Current one is outdate, do not re-enqueue it
486 RUNFREE(objInfo->queues);
491 } // if(tmpinfo->objptr == obj)
492 qitem = getNextQueueItem(prev);
493 } // while(qitem != NULL)
494 // try to execute active tasks already enqueued first
495 addNewItem_I(&objqueue, objInfo);
497 //isInterrupt = true;
500 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
502 BAMBOO_DEBUGPRINT(0xf000);
506 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
508 BAMBOO_DEBUGPRINT(0xf000);
510 } // while(!isEmpty(&objqueue))
513 #ifdef ACCURATEPROFILE
521 BAMBOO_DEBUGPRINT(0xee02);
526 inline __attribute__((always_inline))
527 void checkCoreStatus() {
528 bool allStall = false;
532 (waitconfirm && (numconfirm == 0))) {
534 BAMBOO_DEBUGPRINT(0xee04);
535 BAMBOO_DEBUGPRINT_REG(waitconfirm);
537 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
539 BAMBOO_DEBUGPRINT(0xf001);
541 corestatus[BAMBOO_NUM_OF_CORE] = 0;
542 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
543 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
544 // check the status of all cores
547 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
549 for(i = 0; i < NUMCORESACTIVE; ++i) {
551 BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
553 if(corestatus[i] != 0) {
557 } // for(i = 0; i < NUMCORESACTIVE; ++i)
559 // check if the sum of send objs and receive obj are the same
560 // yes->check if the info is the latest; no->go on executing
562 for(i = 0; i < NUMCORESACTIVE; ++i) {
563 sumsendobj += numsendobjs[i];
565 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
567 } // for(i = 0; i < NUMCORESACTIVE; ++i)
568 for(i = 0; i < NUMCORESACTIVE; ++i) {
569 sumsendobj -= numreceiveobjs[i];
571 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
573 } // for(i = 0; i < NUMCORESACTIVE; ++i)
574 if(0 == sumsendobj) {
576 // the first time found all cores stall
577 // send out status confirm msg to all other cores
578 // reset the corestatus array too
580 BAMBOO_DEBUGPRINT(0xee05);
582 corestatus[BAMBOO_NUM_OF_CORE] = 1;
584 numconfirm = NUMCORESACTIVE - 1;
585 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
586 for(i = 1; i < NUMCORESACTIVE; ++i) {
588 // send status confirm msg to core i
589 send_msg_1(i, STATUSCONFIRM, false);
590 } // for(i = 1; i < NUMCORESACTIVE; ++i)
593 // all the core status info are the latest
594 // terminate; for profiling mode, send request to all
595 // other cores to pour out profiling data
597 BAMBOO_DEBUGPRINT(0xee06);
601 totalexetime = BAMBOO_GET_EXE_TIME() - bamboo_start_time;
604 //BAMBOO_DEBUGPRINT_REG(interrupttime);
607 BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME() - bamboo_start_time);
608 //BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
610 BAMBOO_DEBUGPRINT_REG(gc_num_flush_dtlb);
612 #ifndef BAMBOO_MEMPROF
613 BAMBOO_DEBUGPRINT(0xbbbbbbbb);
616 // profile mode, send msgs to other cores to request pouring
617 // out progiling data
619 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
621 BAMBOO_DEBUGPRINT(0xf000);
623 for(i = 1; i < NUMCORESACTIVE; ++i) {
624 // send profile request msg to core i
625 send_msg_2(i, PROFILEOUTPUT, totalexetime, false);
626 } // for(i = 1; i < NUMCORESACTIVE; ++i)
628 // pour profiling data on startup core
632 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
634 BAMBOO_DEBUGPRINT(0xf001);
636 profilestatus[BAMBOO_NUM_OF_CORE] = 0;
637 // check the status of all cores
640 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
642 for(i = 0; i < NUMCORESACTIVE; ++i) {
644 BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
646 if(profilestatus[i] != 0) {
650 } // for(i = 0; i < NUMCORESACTIVE; ++i)
653 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
655 BAMBOO_DEBUGPRINT(0xf000);
660 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
666 // gc_profile mode, output gc prfiling data
669 gc_outputProfileData();
670 #endif // #ifdef GC_PROFILE
671 #endif // #ifdef MULTICORE_GC
673 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
674 terminate(); // All done.
675 } // if(!waitconfirm)
677 // still some objects on the fly on the network
678 // reset the waitconfirm and numconfirm
680 BAMBOO_DEBUGPRINT(0xee07);
684 } // if(0 == sumsendobj)
686 // not all cores are stall, keep on waiting
688 BAMBOO_DEBUGPRINT(0xee08);
693 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
695 BAMBOO_DEBUGPRINT(0xf000);
697 } // if((!waitconfirm) ||
700 // main function for each core
701 inline void run(void * arg) {
705 bool sendStall = false;
707 bool tocontinue = false;
709 corenum = BAMBOO_GET_NUM_OF_CORE();
711 BAMBOO_DEBUGPRINT(0xeeee);
712 BAMBOO_DEBUGPRINT_REG(corenum);
713 BAMBOO_DEBUGPRINT(STARTUPCORE);
715 //BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME()); // TODO
717 // initialize runtime data structures
720 // other architecture related initialization
724 initializeexithandler();
726 // main process of the execution module
727 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
728 // non-executing cores, only processing communications
731 //isInterrupt = false;
735 /* Create queue of active tasks */
737 genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
738 (int (*)(void *,void *)) &comparetpd);
740 /* Process task information */
743 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
744 /* Create startup object */
745 createstartupobject(argc, argv);
749 BAMBOO_DEBUGPRINT(0xee00);
755 // check if need to do GC
761 // check if there are new active tasks can be executed
768 while(receiveObject() != -1) {
773 BAMBOO_DEBUGPRINT(0xee01);
776 // check if there are some pending objects,
777 // if yes, enqueue them and executetasks again
778 tocontinue = checkObjQueue();
782 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
785 BAMBOO_DEBUGPRINT(0xee03);
793 BAMBOO_DEBUGPRINT(0xee09);
799 // wait for some time
802 BAMBOO_DEBUGPRINT(0xee0a);
808 // send StallMsg to startup core
810 BAMBOO_DEBUGPRINT(0xee0b);
813 send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
814 self_numsendobjs, self_numreceiveobjs, false);
826 BAMBOO_DEBUGPRINT(0xee0c);
829 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
832 } // if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)
836 struct ___createstartupobject____I_locals {
839 struct ___StartupObject___ * ___startupobject___;
840 struct ArrayObject * ___stringarray___;
841 }; // struct ___createstartupobject____I_locals
843 void createstartupobject(int argc,
847 /* Allocate startup object */
849 struct ___createstartupobject____I_locals ___locals___={2, NULL, NULL, NULL};
850 struct ___StartupObject___ *startupobject=
851 (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
852 ___locals___.___startupobject___ = startupobject;
853 struct ArrayObject * stringarray=
854 allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
855 ___locals___.___stringarray___ = stringarray;
857 struct ___StartupObject___ *startupobject=
858 (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
859 struct ArrayObject * stringarray=
860 allocate_newarray(STRINGARRAYTYPE, argc-1);
862 /* Build array of strings */
863 startupobject->___parameters___=stringarray;
864 for(i=1; i<argc; i++) {
865 int length=strlen(argv[i]);
867 struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
869 struct ___String___ *newstring=NewString(argv[i],length);
871 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
875 startupobject->version = 0;
876 startupobject->lock = NULL;
878 /* Set initialized flag for startup object */
879 flagorandinit(startupobject,1,0xFFFFFFFF);
880 enqueueObject(startupobject, NULL, 0);
882 BAMBOO_CACHE_FLUSH_ALL();
886 int hashCodetpd(struct taskparamdescriptor *ftd) {
887 int hash=(int)ftd->task;
889 for(i=0; i<ftd->numParameters; i++) {
890 hash^=(int)ftd->parameterArray[i];
895 int comparetpd(struct taskparamdescriptor *ftd1,
896 struct taskparamdescriptor *ftd2) {
898 if (ftd1->task!=ftd2->task)
900 for(i=0; i<ftd1->numParameters; i++)
901 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
906 /* This function sets a tag. */
908 void tagset(void *ptr,
909 struct ___Object___ * obj,
910 struct ___TagDescriptor___ * tagd) {
912 void tagset(struct ___Object___ * obj,
913 struct ___TagDescriptor___ * tagd) {
915 struct ArrayObject * ao=NULL;
916 struct ___Object___ * tagptr=obj->___tags___;
918 obj->___tags___=(struct ___Object___ *)tagd;
920 /* Have to check if it is already set */
921 if (tagptr->type==TAGTYPE) {
922 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
927 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
928 struct ArrayObject * ao=
929 allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
930 obj=(struct ___Object___ *)ptrarray[2];
931 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
932 td=(struct ___TagDescriptor___ *) obj->___tags___;
934 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
937 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
938 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
939 obj->___tags___=(struct ___Object___ *) ao;
940 ao->___cachedCode___=2;
944 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
945 for(i=0; i<ao->___cachedCode___; i++) {
946 struct ___TagDescriptor___ * td=
947 ARRAYGET(ao, struct ___TagDescriptor___*, i);
952 if (ao->___cachedCode___<ao->___length___) {
953 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
954 ao->___cachedCode___++;
957 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
958 struct ArrayObject * aonew=
959 allocate_newarray(&ptrarray,TAGARRAYTYPE,
960 TAGARRAYINTERVAL+ao->___length___);
961 obj=(struct ___Object___ *)ptrarray[2];
962 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
963 ao=(struct ArrayObject *)obj->___tags___;
965 struct ArrayObject * aonew=
966 allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
969 aonew->___cachedCode___=ao->___length___+1;
970 for(i=0; i<ao->___length___; i++) {
971 ARRAYSET(aonew, struct ___TagDescriptor___*, i,
972 ARRAYGET(ao, struct ___TagDescriptor___*, i));
974 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
980 struct ___Object___ * tagset=tagd->flagptr;
983 } else if (tagset->type!=OBJECTARRAYTYPE) {
985 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
986 struct ArrayObject * ao=
987 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
988 obj=(struct ___Object___ *)ptrarray[2];
989 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
991 struct ArrayObject * ao=
992 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
994 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
995 ARRAYSET(ao, struct ___Object___ *, 1, obj);
996 ao->___cachedCode___=2;
997 tagd->flagptr=(struct ___Object___ *)ao;
999 struct ArrayObject *ao=(struct ArrayObject *) tagset;
1000 if (ao->___cachedCode___<ao->___length___) {
1001 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
1005 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
1006 struct ArrayObject * aonew=
1007 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
1008 OBJECTARRAYINTERVAL+ao->___length___);
1009 obj=(struct ___Object___ *)ptrarray[2];
1010 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
1011 ao=(struct ArrayObject *)tagd->flagptr;
1013 struct ArrayObject * aonew=
1014 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
1016 aonew->___cachedCode___=ao->___cachedCode___+1;
1017 for(i=0; i<ao->___length___; i++) {
1018 ARRAYSET(aonew, struct ___Object___*, i,
1019 ARRAYGET(ao, struct ___Object___*, i));
1021 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
1022 tagd->flagptr=(struct ___Object___ *) aonew;
1028 /* This function clears a tag. */
1030 void tagclear(void *ptr,
1031 struct ___Object___ * obj,
1032 struct ___TagDescriptor___ * tagd) {
1034 void tagclear(struct ___Object___ * obj,
1035 struct ___TagDescriptor___ * tagd) {
1037 /* We'll assume that tag is alway there.
1038 Need to statically check for this of course. */
1039 struct ___Object___ * tagptr=obj->___tags___;
1041 if (tagptr->type==TAGTYPE) {
1042 if ((struct ___TagDescriptor___ *)tagptr==tagd)
1043 obj->___tags___=NULL;
1045 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
1047 for(i=0; i<ao->___cachedCode___; i++) {
1048 struct ___TagDescriptor___ * td=
1049 ARRAYGET(ao, struct ___TagDescriptor___ *, i);
1051 ao->___cachedCode___--;
1052 if (i<ao->___cachedCode___)
1053 ARRAYSET(ao, struct ___TagDescriptor___ *, i,
1054 ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
1055 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
1056 if (ao->___cachedCode___==0)
1057 obj->___tags___=NULL;
1064 struct ___Object___ *tagset=tagd->flagptr;
1065 if (tagset->type!=OBJECTARRAYTYPE) {
1069 struct ArrayObject *ao=(struct ArrayObject *) tagset;
1071 for(i=0; i<ao->___cachedCode___; i++) {
1072 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
1074 ao->___cachedCode___--;
1075 if (i<ao->___cachedCode___)
1076 ARRAYSET(ao, struct ___Object___ *, i,
1077 ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
1078 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
1079 if (ao->___cachedCode___==0)
1090 /* This function allocates a new tag. */
1092 struct ___TagDescriptor___ * allocate_tag(void *ptr,
1094 struct ___TagDescriptor___ * v=
1095 (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
1096 classsize[TAGTYPE]);
1098 struct ___TagDescriptor___ * allocate_tag(int index) {
1099 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
1108 /* This function updates the flag for object ptr. It or's the flag
1109 with the or mask and and's it with the andmask. */
1111 void flagbody(struct ___Object___ *ptr,
1113 struct parameterwrapper ** queues,
1117 int flagcomp(const int *val1, const int *val2) {
1118 return (*val1)-(*val2);
1121 void flagorand(void * ptr,
1124 struct parameterwrapper ** queues,
1127 int oldflag=((int *)ptr)[1];
1128 int flag=ormask|oldflag;
1130 flagbody(ptr, flag, queues, length, false);
1134 bool intflagorand(void * ptr,
1138 int oldflag=((int *)ptr)[1];
1139 int flag=ormask|oldflag;
1141 if (flag==oldflag) /* Don't do anything */
1144 flagbody(ptr, flag, NULL, 0, false);
1150 void flagorandinit(void * ptr,
1153 int oldflag=((int *)ptr)[1];
1154 int flag=ormask|oldflag;
1156 flagbody(ptr,flag,NULL,0,true);
1159 void flagbody(struct ___Object___ *ptr,
1161 struct parameterwrapper ** vqueues,
1164 struct parameterwrapper * flagptr = NULL;
1166 struct parameterwrapper ** queues = vqueues;
1167 int length = vlength;
1169 int UNUSED, UNUSED2;
1170 int * enterflags = NULL;
1171 if((!isnew) && (queues == NULL)) {
1172 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
1173 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1174 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1181 /*Remove object from all queues */
1182 for(i = 0; i < length; ++i) {
1183 flagptr = queues[i];
1184 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
1185 (int *) &enterflags, &UNUSED, &UNUSED2);
1186 ObjectHashremove(flagptr->objectset, (int)ptr);
1187 if (enterflags!=NULL)
1188 RUNFREE(enterflags);
1192 void enqueueObject(void * vptr,
1193 struct parameterwrapper ** vqueues,
1195 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1198 //struct QueueItem *tmpptr;
1199 struct parameterwrapper * parameter=NULL;
1202 struct parameterwrapper * prevptr=NULL;
1203 struct ___Object___ *tagptr=NULL;
1204 struct parameterwrapper ** queues = vqueues;
1205 int length = vlength;
1206 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1209 if(queues == NULL) {
1210 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1211 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1213 tagptr=ptr->___tags___;
1215 /* Outer loop iterates through all parameter queues an object of
1216 this type could be in. */
1217 for(j = 0; j < length; ++j) {
1218 parameter = queues[j];
1220 if (parameter->numbertags>0) {
1222 goto nextloop; //that means the object has no tag
1223 //but that param needs tag
1224 else if(tagptr->type==TAGTYPE) { //one tag
1225 //struct ___TagDescriptor___ * tag=
1226 //(struct ___TagDescriptor___*) tagptr;
1227 for(i=0; i<parameter->numbertags; i++) {
1228 //slotid is parameter->tagarray[2*i];
1229 int tagid=parameter->tagarray[2*i+1];
1230 if (tagid!=tagptr->flag)
1231 goto nextloop; /*We don't have this tag */
1233 } else { //multiple tags
1234 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1235 for(i=0; i<parameter->numbertags; i++) {
1236 //slotid is parameter->tagarray[2*i];
1237 int tagid=parameter->tagarray[2*i+1];
1239 for(j=0; j<ao->___cachedCode___; j++) {
1240 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1251 for(i=0; i<parameter->numberofterms; i++) {
1252 int andmask=parameter->intarray[i*2];
1253 int checkmask=parameter->intarray[i*2+1];
1254 if ((ptr->flag&andmask)==checkmask) {
1255 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
1266 void enqueueObject_I(void * vptr,
1267 struct parameterwrapper ** vqueues,
1269 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1272 //struct QueueItem *tmpptr;
1273 struct parameterwrapper * parameter=NULL;
1276 struct parameterwrapper * prevptr=NULL;
1277 struct ___Object___ *tagptr=NULL;
1278 struct parameterwrapper ** queues = vqueues;
1279 int length = vlength;
1280 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1283 if(queues == NULL) {
1284 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1285 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1287 tagptr=ptr->___tags___;
1289 /* Outer loop iterates through all parameter queues an object of
1290 this type could be in. */
1291 for(j = 0; j < length; ++j) {
1292 parameter = queues[j];
1294 if (parameter->numbertags>0) {
1296 goto nextloop; //that means the object has no tag
1297 //but that param needs tag
1298 else if(tagptr->type==TAGTYPE) { //one tag
1299 //struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
1300 for(i=0; i<parameter->numbertags; i++) {
1301 //slotid is parameter->tagarray[2*i];
1302 int tagid=parameter->tagarray[2*i+1];
1303 if (tagid!=tagptr->flag)
1304 goto nextloop; /*We don't have this tag */
1306 } else { //multiple tags
1307 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1308 for(i=0; i<parameter->numbertags; i++) {
1309 //slotid is parameter->tagarray[2*i];
1310 int tagid=parameter->tagarray[2*i+1];
1312 for(j=0; j<ao->___cachedCode___; j++) {
1313 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1324 for(i=0; i<parameter->numberofterms; i++) {
1325 int andmask=parameter->intarray[i*2];
1326 int checkmask=parameter->intarray[i*2+1];
1327 if ((ptr->flag&andmask)==checkmask) {
1328 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1340 int * getAliasLock(void ** ptrs,
1342 struct RuntimeHash * tbl) {
1344 return (int*)(RUNMALLOC(sizeof(int)));
1349 bool redirect = false;
1350 int redirectlock = 0;
1351 for(; i < length; i++) {
1352 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1355 if(ptr->lock == NULL) {
1358 lock = (int)(ptr->lock);
1361 if(lock != redirectlock) {
1362 RuntimeHashadd(tbl, lock, redirectlock);
1365 if(RuntimeHashcontainskey(tbl, lock)) {
1366 // already redirected
1368 RuntimeHashget(tbl, lock, &redirectlock);
1369 for(; j < locklen; j++) {
1370 if(locks[j] != redirectlock) {
1371 RuntimeHashadd(tbl, locks[j], redirectlock);
1376 for(j = 0; j < locklen; j++) {
1377 if(locks[j] == lock) {
1380 } else if(locks[j] > lock) {
1387 locks[h] = locks[h-1];
1396 return (int *)redirectlock;
1398 return (int *)(locks[0]);
1403 void addAliasLock(void * ptr,
1405 struct ___Object___ * obj = (struct ___Object___ *)ptr;
1406 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1407 // originally no alias lock associated or have a different alias lock
1408 // flush it as the new one
1409 obj->lock = (int *)lock;
1414 inline void setTaskExitIndex(int index) {
1415 taskInfoArray[taskInfoIndex]->exitIndex = index;
1418 inline void addNewObjInfo(void * nobj) {
1419 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1420 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1422 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1427 // Only allocate local mem chunks to each core.
1428 // If a core has used up its local shared memory, start gc.
1429 void * localmalloc_I(int coren,
1433 int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
1436 int tofindb = gc_core2block[2*gccorenum+i]+(NUMCORES4GC*2)*j;
1437 int totest = tofindb;
1438 int bound = BAMBOO_SMEM_SIZE_L;
1442 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1443 int nsize = bamboo_smemtbl[totest];
1444 bool islocal = true;
1446 bool tocheck = true;
1447 // have some space in the block
1448 if(totest == tofindb) {
1449 // the first partition
1450 size = bound - nsize;
1451 } else if(nsize == 0) {
1452 // an empty partition, can be appended
1455 // not an empty partition, can not be appended
1456 // the last continuous block is not big enough, go to check the next
1460 } // if(totest == tofindb) else if(nsize == 0) else ...
1463 // have enough space in the block, malloc
1467 // no enough space yet, try to append next continuous block
1469 } // if(size > isize) else ...
1471 } // if(nsize < bound)
1473 // no space in the block, go to check the next block
1479 tofindb = totest = gc_core2block[2*gccorenum+i]+(NUMCORES4GC*2)*j;
1482 } // if(islocal) else ...
1483 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1484 // no more local mem, do not find suitable block
1487 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1490 if(foundsmem == 1) {
1491 // find suitable block
1492 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1493 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1494 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1496 // set bamboo_smemtbl
1497 for(i = tofindb; i <= totest; i++) {
1498 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1500 } else if(foundsmem == 2) {
1501 // no suitable block
1506 } // void * localmalloc_I(int, int, int *)
1509 // Allocate the local shared memory to each core with the highest priority,
1510 // if a core has used up its local shared memory, try to allocate the
1511 // shared memory that belong to its neighbours, if also failed, start gc.
1512 void * fixedmalloc_I(int coren,
1519 int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
1520 int coords_x = bamboo_cpu2coords[gccorenum*2];
1521 int coords_y = bamboo_cpu2coords[gccorenum*2+1];
1523 int tofindb = gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1524 int totest = tofindb;
1525 int bound = BAMBOO_SMEM_SIZE_L;
1529 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1530 int nsize = bamboo_smemtbl[totest];
1531 bool islocal = true;
1533 bool tocheck = true;
1534 // have some space in the block
1535 if(totest == tofindb) {
1536 // the first partition
1537 size = bound - nsize;
1538 } else if(nsize == 0) {
1539 // an empty partition, can be appended
1542 // not an empty partition, can not be appended
1543 // the last continuous block is not big enough, go to check the next
1547 } // if(totest == tofindb) else if(nsize == 0) else ...
1550 // have enough space in the block, malloc
1554 // no enough space yet, try to append next continuous block
1555 // TODO may consider to go to next local block?
1557 } // if(size > isize) else ...
1559 } // if(nsize < bound)
1561 // no space in the block, go to check the next block
1568 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1571 } // if(islocal) else ...
1572 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1573 // no more local mem, do not find suitable block on local mem
1574 // try to malloc shared memory assigned to the neighbour cores
1577 if(k >= NUM_CORES2TEST) {
1578 // no more memory available on either coren or its neighbour cores
1580 goto memsearchresult;
1582 } while(core2test[gccorenum][k] == -1);
1586 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1587 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1591 if(foundsmem == 1) {
1592 // find suitable block
1593 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1594 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1595 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1597 // set bamboo_smemtbl
1598 for(i = tofindb; i <= totest; i++) {
1599 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1601 } else if(foundsmem == 2) {
1602 // no suitable block
1607 } // void * fixedmalloc_I(int, int, int *)
1608 #endif // #ifdef SMEMF
1611 // Allocate the local shared memory to each core with the highest priority,
1612 // if a core has used up its local shared memory, try to allocate the
1613 // shared memory that belong to its neighbours first, if failed, check
1614 // current memory allocation rate, if it has already reached the threshold,
1615 // start gc, otherwise, allocate the shared memory globally. If all the
1616 // shared memory has been used up, start gc.
1617 void * mixedmalloc_I(int coren,
1624 int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
1626 int tofindb = gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1627 int totest = tofindb;
1628 int bound = BAMBOO_SMEM_SIZE_L;
1632 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1633 int nsize = bamboo_smemtbl[totest];
1634 bool islocal = true;
1636 bool tocheck = true;
1637 // have some space in the block
1638 if(totest == tofindb) {
1639 // the first partition
1640 size = bound - nsize;
1641 } else if(nsize == 0) {
1642 // an empty partition, can be appended
1645 // not an empty partition, can not be appended
1646 // the last continuous block is not big enough, go to check the next
1650 } // if(totest == tofindb) else if(nsize == 0) else ...
1653 // have enough space in the block, malloc
1657 // no enough space yet, try to append next continuous block
1658 // TODO may consider to go to next local block?
1660 } // if(size > isize) else ...
1662 } // if(nsize < bound)
1664 // no space in the block, go to check the next block
1671 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1674 } // if(islocal) else ...
1675 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1676 // no more local mem, do not find suitable block on local mem
1677 // try to malloc shared memory assigned to the neighbour cores
1680 if(k >= NUM_CORES2TEST) {
1681 if(gcmem_mixed_usedmem >= gcmem_mixed_threshold) {
1682 // no more memory available on either coren or its neighbour cores
1684 goto memmixedsearchresult;
1686 // try allocate globally
1687 mem = globalmalloc_I(coren, isize, allocsize);
1691 } while(core2test[gccorenum][k] == -1);
1695 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1696 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1699 memmixedsearchresult:
1700 if(foundsmem == 1) {
1701 // find suitable block
1702 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1703 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1704 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1706 // set bamboo_smemtbl
1707 for(i = tofindb; i <= totest; i++) {
1708 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1710 gcmem_mixed_usedmem += size;
1711 if(tofindb == bamboo_free_block) {
1712 bamboo_free_block = totest+1;
1714 } else if(foundsmem == 2) {
1715 // no suitable block
1720 } // void * mixedmalloc_I(int, int, int *)
1721 #endif // #ifdef SMEMM
1723 // Allocate all the memory chunks globally, do not consider the host cores
1724 // When all the shared memory are used up, start gc.
1725 void * globalmalloc_I(int coren,
1729 int tofindb = bamboo_free_block; //0;
1730 int totest = tofindb;
1731 int bound = BAMBOO_SMEM_SIZE_L;
1734 if(tofindb > gcnumblock-1-bamboo_reserved_smem) {
1735 // Out of shared memory
1740 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1741 int nsize = bamboo_smemtbl[totest];
1742 bool isnext = false;
1744 bool tocheck = true;
1745 // have some space in the block
1746 if(totest == tofindb) {
1747 // the first partition
1748 size = bound - nsize;
1749 } else if(nsize == 0) {
1750 // an empty partition, can be appended
1753 // not an empty partition, can not be appended
1754 // the last continuous block is not big enough, start another block
1757 } // if(totest == tofindb) else if(nsize == 0) else ...
1760 // have enough space in the block, malloc
1763 } // if(size > isize)
1767 } // if(nsize < bound) else ...
1769 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1770 // no more local mem, do not find suitable block
1773 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1775 // start another block
1780 if(foundsmem == 1) {
1781 // find suitable block
1782 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1783 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1784 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1786 // set bamboo_smemtbl
1787 for(int i = tofindb; i <= totest; i++) {
1788 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1790 if(tofindb == bamboo_free_block) {
1791 bamboo_free_block = totest+1;
1793 } else if(foundsmem == 2) {
1794 // no suitable block
1800 } // void * globalmalloc_I(int, int, int *)
1801 #endif // #ifdef MULTICORE_GC
1803 // malloc from the shared memory
1804 void * smemalloc_I(int coren,
1809 int isize = size+(BAMBOO_CACHE_LINE_SIZE);
1811 // go through the bamboo_smemtbl for suitable partitions
1812 switch(bamboo_smem_mode) {
1814 mem = localmalloc_I(coren, isize, allocsize);
1820 mem = fixedmalloc_I(coren, isize, allocsize);
1822 // not supported yet
1823 BAMBOO_EXIT(0xe001);
1830 mem = mixedmalloc_I(coren, isize, allocsize);
1832 // not supported yet
1833 BAMBOO_EXIT(0xe002);
1839 mem = globalmalloc_I(coren, isize, allocsize);
1849 int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size) : (BAMBOO_SMEM_SIZE);
1850 if(toallocate > bamboo_free_smem_size) {
1854 mem = (void *)bamboo_free_smemp;
1855 bamboo_free_smemp = ((void*)bamboo_free_smemp) + toallocate;
1856 bamboo_free_smem_size -= toallocate;
1858 *allocsize = toallocate;
1860 #endif // MULTICORE_GC
1861 // no enough shared global memory
1866 // inform other cores to stop and wait for gc
1868 for(int i = 0; i < NUMCORESACTIVE; i++) {
1869 // reuse the gcnumsendobjs & gcnumreceiveobjs
1870 gccorestatus[i] = 1;
1871 gcnumsendobjs[0][i] = 0;
1872 gcnumreceiveobjs[0][i] = 0;
1874 for(int i = 0; i < NUMCORESACTIVE; i++) {
1875 if(i != BAMBOO_NUM_OF_CORE) {
1876 if(BAMBOO_CHECK_SEND_MODE()) {
1877 cache_msg_1(i, GCSTARTPRE);
1879 send_msg_1(i, GCSTARTPRE, true);
1886 BAMBOO_DEBUGPRINT(0xa001);
1887 BAMBOO_EXIT(0xa001);
1891 } // void * smemalloc_I(int, int, int)
1893 INLINE int checkMsgLength_I(int size) {
1896 BAMBOO_DEBUGPRINT(0xcccc);
1899 int type = msgdata[msgdataindex];
1907 case GCSTARTMAPINFO:
1921 case GCSTARTCOMPACT:
1924 case GCFINISHMAPINFO:
1949 case REDIRECTGROUNT:
1951 case REDIRECTRELEASE:
1968 case GCFINISHCOMPACT:
1982 case TRANSOBJ: // nonfixed size
1988 msglength = msgdata[msgdataindex+1];
1997 BAMBOO_DEBUGPRINT_REG(type);
1998 BAMBOO_DEBUGPRINT_REG(size);
1999 BAMBOO_DEBUGPRINT_REG(msgdataindex);
2000 BAMBOO_DEBUGPRINT_REG(msgdatalast);
2001 BAMBOO_DEBUGPRINT_REG(msgdatafull);
2004 BAMBOO_DEBUGPRINT(msgdata[msgdataindex+i]);
2006 BAMBOO_EXIT(0xd005);
2012 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
2017 BAMBOO_DEBUGPRINT(0xffff);
2023 INLINE void processmsg_transobj_I() {
2024 #ifdef PROFILE_INTERRUPT
2025 /*if(!interruptInfoOverflow) {
2026 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
2027 interruptInfoArray[interruptInfoIndex] = intInfo;
2028 intInfo->startTime = BAMBOO_GET_EXE_TIME();
2029 intInfo->endTime = -1;
2033 struct transObjInfo * transObj=RUNMALLOC_I(sizeof(struct transObjInfo));
2037 BAMBOO_DEBUGPRINT(0xe880);
2040 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2042 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
2044 BAMBOO_EXIT(0xa002);
2046 // store the object and its corresponding queue info, enqueue it later
2047 transObj->objptr = (void *)msgdata[msgdataindex]; //[2]
2049 transObj->length = (msglength - 3) / 2;
2050 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
2051 for(k = 0; k < transObj->length; ++k) {
2052 transObj->queues[2*k] = msgdata[msgdataindex]; //[3+2*k];
2056 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
2059 transObj->queues[2*k+1] = msgdata[msgdataindex]; //[3+2*k+1];
2063 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
2067 // check if there is an existing duplicate item
2069 struct QueueItem * qitem = getHead(&objqueue);
2070 struct QueueItem * prev = NULL;
2071 while(qitem != NULL) {
2072 struct transObjInfo * tmpinfo =
2073 (struct transObjInfo *)(qitem->objectptr);
2074 if(tmpinfo->objptr == transObj->objptr) {
2075 // the same object, remove outdate one
2076 RUNFREE(tmpinfo->queues);
2078 removeItem(&objqueue, qitem);
2084 qitem = getHead(&objqueue);
2086 qitem = getNextQueueItem(prev);
2089 addNewItem_I(&objqueue, (void *)transObj);
2091 ++(self_numreceiveobjs);
2094 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
2095 // set the gcprecheck to enable checking again
2098 // send a update pregc information msg to the master core
2099 if(BAMBOO_CHECK_SEND_MODE()) {
2100 cache_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
2101 self_numsendobjs, self_numreceiveobjs);
2103 send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
2104 self_numsendobjs, self_numreceiveobjs, true);
2109 #ifdef PROFILE_INTERRUPT
2110 /*if(!interruptInfoOverflow) {
2111 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
2112 interruptInfoIndex++;
2113 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
2114 interruptInfoOverflow = true;
2120 INLINE void processmsg_transtall_I() {
2121 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2122 // non startup core can not receive stall msg
2124 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
2126 BAMBOO_EXIT(0xa003);
2128 int num_core = msgdata[msgdataindex]; //[1]
2130 if(num_core < NUMCORESACTIVE) {
2133 BAMBOO_DEBUGPRINT(0xe881);
2136 corestatus[num_core] = 0;
2137 numsendobjs[num_core] = msgdata[msgdataindex]; //[2];
2139 numreceiveobjs[num_core] = msgdata[msgdataindex]; //[3];
2144 #ifndef MULTICORE_GC
2145 INLINE void processmsg_lockrequest_I() {
2146 // check to see if there is a lock exist for the required obj
2147 // msgdata[1] -> lock type
2148 int locktype = msgdata[msgdataindex]; //[1];
2150 int data2 = msgdata[msgdataindex]; // obj pointer
2152 int data3 = msgdata[msgdataindex]; // lock
2154 int data4 = msgdata[msgdataindex]; // request core
2156 // -1: redirected, 0: approved, 1: denied
2157 int deny=processlockrequest(locktype, data3, data2, data4, data4, true);
2159 // this lock request is redirected
2162 // send response msg
2163 // for 32 bit machine, the size is always 4 words, cache the msg first
2164 int tmp = deny==1 ? LOCKDENY : LOCKGROUNT;
2165 if(BAMBOO_CHECK_SEND_MODE()) {
2166 cache_msg_4(data4, tmp, locktype, data2, data3);
2168 send_msg_4(data4, tmp, locktype, data2, data3, true);
2173 INLINE void processmsg_lockgrount_I() {
2175 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2177 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
2179 BAMBOO_EXIT(0xa004);
2181 int data2 = msgdata[msgdataindex];
2183 int data3 = msgdata[msgdataindex];
2185 if((lockobj == data2) && (lock2require == data3)) {
2188 BAMBOO_DEBUGPRINT(0xe882);
2197 // conflicts on lockresults
2199 BAMBOO_DEBUGPRINT_REG(data2);
2201 BAMBOO_EXIT(0xa005);
2205 INLINE void processmsg_lockdeny_I() {
2207 int data2 = msgdata[msgdataindex];
2209 int data3 = msgdata[msgdataindex];
2211 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2213 BAMBOO_DEBUGPRINT_REG(data2);
2215 BAMBOO_EXIT(0xa006);
2217 if((lockobj == data2) && (lock2require == data3)) {
2220 BAMBOO_DEBUGPRINT(0xe883);
2229 // conflicts on lockresults
2231 BAMBOO_DEBUGPRINT_REG(data2);
2233 BAMBOO_EXIT(0xa007);
2237 INLINE void processmsg_lockrelease_I() {
2238 int data1 = msgdata[msgdataindex];
2240 int data2 = msgdata[msgdataindex];
2242 // receive lock release msg
2243 processlockrelease(data1, data2, 0, false);
2246 INLINE void processmsg_redirectlock_I() {
2247 // check to see if there is a lock exist for the required obj
2248 int data1 = msgdata[msgdataindex];
2249 MSG_INDEXINC_I(); //msgdata[1]; // lock type
2250 int data2 = msgdata[msgdataindex];
2251 MSG_INDEXINC_I(); //msgdata[2]; // obj pointer
2252 int data3 = msgdata[msgdataindex];
2253 MSG_INDEXINC_I(); //msgdata[3]; // redirect lock
2254 int data4 = msgdata[msgdataindex];
2255 MSG_INDEXINC_I(); //msgdata[4]; // root request core
2256 int data5 = msgdata[msgdataindex];
2257 MSG_INDEXINC_I(); //msgdata[5]; // request core
2258 int deny = processlockrequest(data1, data3, data2, data5, data4, true);
2260 // this lock request is redirected
2263 // send response msg
2264 // for 32 bit machine, the size is always 4 words, cache the msg first
2265 if(BAMBOO_CHECK_SEND_MODE()) {
2266 cache_msg_4(data4, deny==1 ? REDIRECTDENY : REDIRECTGROUNT,
2267 data1, data2, data3);
2269 send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
2270 data1, data2, data3, true);
2275 INLINE void processmsg_redirectgrount_I() {
2277 int data2 = msgdata[msgdataindex];
2279 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2281 BAMBOO_DEBUGPRINT_REG(data2);
2283 BAMBOO_EXIT(0xa00a);
2285 if(lockobj == data2) {
2288 BAMBOO_DEBUGPRINT(0xe891);
2291 int data3 = msgdata[msgdataindex];
2295 RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
2300 // conflicts on lockresults
2302 BAMBOO_DEBUGPRINT_REG(data2);
2304 BAMBOO_EXIT(0xa00b);
2308 INLINE void processmsg_redirectdeny_I() {
2310 int data2 = msgdata[msgdataindex];
2312 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2314 BAMBOO_DEBUGPRINT_REG(data2);
2316 BAMBOO_EXIT(0xa00c);
2318 if(lockobj == data2) {
2321 BAMBOO_DEBUGPRINT(0xe892);
2330 // conflicts on lockresults
2332 BAMBOO_DEBUGPRINT_REG(data2);
2334 BAMBOO_EXIT(0xa00d);
2338 INLINE void processmsg_redirectrelease_I() {
2339 int data1 = msgdata[msgdataindex];
2341 int data2 = msgdata[msgdataindex];
2343 int data3 = msgdata[msgdataindex];
2345 processlockrelease(data1, data2, data3, true);
2347 #endif // #ifndef MULTICORE_GC
2350 INLINE void processmsg_profileoutput_I() {
2351 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
2352 // startup core can not receive profile output finish msg
2353 BAMBOO_EXIT(0xa008);
2357 BAMBOO_DEBUGPRINT(0xe885);
2361 totalexetime = msgdata[msgdataindex]; //[1]
2364 BAMBOO_DEBUGPRINT_REG(dot_num);
2366 outputProfileData();
2368 // cache the msg first
2369 if(BAMBOO_CHECK_SEND_MODE()) {
2370 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
2372 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE, true);
2376 INLINE void processmsg_profilefinish_I() {
2377 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2378 // non startup core can not receive profile output finish msg
2380 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex /*1*/]);
2382 BAMBOO_EXIT(0xa009);
2386 BAMBOO_DEBUGPRINT(0xe886);
2389 int data1 = msgdata[msgdataindex];
2391 profilestatus[data1] = 0;
2393 #endif // #ifdef PROFILE
2395 INLINE void processmsg_statusconfirm_I() {
2396 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2397 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2398 // wrong core to receive such msg
2399 BAMBOO_EXIT(0xa00e);
2401 // send response msg
2404 BAMBOO_DEBUGPRINT(0xe887);
2407 // cache the msg first
2408 if(BAMBOO_CHECK_SEND_MODE()) {
2409 cache_msg_5(STARTUPCORE, STATUSREPORT,
2410 busystatus ? 1 : 0, BAMBOO_NUM_OF_CORE,
2411 self_numsendobjs, self_numreceiveobjs);
2413 send_msg_5(STARTUPCORE, STATUSREPORT, busystatus?1:0,
2414 BAMBOO_NUM_OF_CORE, self_numsendobjs,
2415 self_numreceiveobjs, true);
2420 INLINE void processmsg_statusreport_I() {
2421 int data1 = msgdata[msgdataindex];
2423 int data2 = msgdata[msgdataindex];
2425 int data3 = msgdata[msgdataindex];
2427 int data4 = msgdata[msgdataindex];
2429 // receive a status confirm info
2430 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2431 // wrong core to receive such msg
2433 BAMBOO_DEBUGPRINT_REG(data2);
2435 BAMBOO_EXIT(0xa00f);
2439 BAMBOO_DEBUGPRINT(0xe888);
2445 corestatus[data2] = data1;
2446 numsendobjs[data2] = data3;
2447 numreceiveobjs[data2] = data4;
2451 INLINE void processmsg_terminate_I() {
2454 BAMBOO_DEBUGPRINT(0xe889);
2461 INLINE void processmsg_memrequest_I() {
2462 #ifdef PROFILE_INTERRUPT
2463 /*if(!interruptInfoOverflow) {
2464 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
2465 interruptInfoArray[interruptInfoIndex] = intInfo;
2466 intInfo->startTime = BAMBOO_GET_EXE_TIME();
2467 intInfo->endTime = -1;
2470 int data1 = msgdata[msgdataindex];
2472 int data2 = msgdata[msgdataindex];
2474 // receive a shared memory request msg
2475 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2476 // wrong core to receive such msg
2478 BAMBOO_DEBUGPRINT_REG(data2);
2480 BAMBOO_EXIT(0xa010);
2484 BAMBOO_DEBUGPRINT(0xe88a);
2491 // is currently doing gc, dump this msg
2492 if(INITPHASE == gcphase) {
2493 // if still in the initphase of gc, send a startinit msg again,
2494 // cache the msg first
2495 if(BAMBOO_CHECK_SEND_MODE()) {
2496 cache_msg_1(data2, GCSTARTINIT);
2498 send_msg_1(data2, GCSTARTINIT, true);
2503 mem = smemalloc_I(data2, data1, &allocsize);
2505 // send the start_va to request core, cache the msg first
2506 if(BAMBOO_CHECK_SEND_MODE()) {
2507 cache_msg_3(data2, MEMRESPONSE, mem, allocsize);
2509 send_msg_3(data2, MEMRESPONSE, mem, allocsize, true);
2512 // if mem == NULL, the gcflag of the startup core has been set
2513 // and all the other cores have been informed to start gc
2518 #ifdef PROFILE_INTERRUPT
2519 /*if(!interruptInfoOverflow) {
2520 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
2521 interruptInfoIndex++;
2522 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
2523 interruptInfoOverflow = true;
2529 INLINE void processmsg_memresponse_I() {
2530 int data1 = msgdata[msgdataindex];
2532 int data2 = msgdata[msgdataindex];
2534 // receive a shared memory response msg
2537 BAMBOO_DEBUGPRINT(0xe88b);
2541 // if is currently doing gc, dump this msg
2545 bamboo_smem_size = 0;
2548 bamboo_smem_zero_top = 0;
2552 // fill header to store the size of this mem block
2553 BAMBOO_MEMSET_WH(data1, '\0', BAMBOO_CACHE_LINE_SIZE);
2554 //memset(data1, 0, BAMBOO_CACHE_LINE_SIZE);
2555 (*((int*)data1)) = data2;
2556 bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
2557 bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
2558 bamboo_smem_zero_top = bamboo_cur_msp;
2560 bamboo_smem_size = data2;
2561 bamboo_cur_msp =(void*)(data1);
2571 INLINE void processmsg_gcstartpre_I() {
2573 // already stall for gc
2574 // send a update pregc information msg to the master core
2575 if(BAMBOO_CHECK_SEND_MODE()) {
2576 cache_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
2577 self_numsendobjs, self_numreceiveobjs);
2579 send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
2580 self_numsendobjs, self_numreceiveobjs, true);
2583 // the first time to be informed to start gc
2586 // is waiting for response of mem request
2587 // let it return NULL and start gc
2588 bamboo_smem_size = 0;
2589 bamboo_cur_msp = NULL;
2591 bamboo_smem_zero_top = NULL;
2596 INLINE void processmsg_gcstartinit_I() {
2597 gcphase = INITPHASE;
2600 INLINE void processmsg_gcstart_I() {
2603 BAMBOO_DEBUGPRINT(0xe88c);
2607 gcphase = MARKPHASE;
2610 INLINE void processmsg_gcstartcompact_I() {
2611 gcblock2fill = msgdata[msgdataindex];
2612 MSG_INDEXINC_I(); //msgdata[1];
2613 gcphase = COMPACTPHASE;
2616 INLINE void processmsg_gcstartmapinfo_I() {
2620 INLINE void processmsg_gcstartflush_I() {
2621 gcphase = FLUSHPHASE;
2624 INLINE void processmsg_gcfinishpre_I() {
2625 int data1 = msgdata[msgdataindex];
2627 int data2 = msgdata[msgdataindex];
2629 int data3 = msgdata[msgdataindex];
2631 // received a init phase finish msg
2632 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2633 // non startup core can not receive this msg
2635 BAMBOO_DEBUGPRINT_REG(data1);
2637 BAMBOO_EXIT(0xb000);
2639 // All cores should do init GC
2643 gccorestatus[data1] = 0;
2644 gcnumsendobjs[0][data1] = data2;
2645 gcnumreceiveobjs[0][data1] = data3;
2648 INLINE void processmsg_gcfinishinit_I() {
2649 int data1 = msgdata[msgdataindex];
2651 // received a init phase finish msg
2652 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2653 // non startup core can not receive this msg
2655 BAMBOO_DEBUGPRINT_REG(data1);
2657 BAMBOO_EXIT(0xb001);
2660 BAMBOO_DEBUGPRINT(0xe88c);
2661 BAMBOO_DEBUGPRINT_REG(data1);
2663 // All cores should do init GC
2664 if(data1 < NUMCORESACTIVE) {
2665 gccorestatus[data1] = 0;
2669 INLINE void processmsg_gcfinishmark_I() {
2670 int data1 = msgdata[msgdataindex];
2672 int data2 = msgdata[msgdataindex];
2674 int data3 = msgdata[msgdataindex];
2676 // received a mark phase finish msg
2677 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2678 // non startup core can not receive this msg
2680 BAMBOO_DEBUGPRINT_REG(data1);
2682 BAMBOO_EXIT(0xb002);
2684 // all cores should do mark
2685 if(data1 < NUMCORESACTIVE) {
2686 gccorestatus[data1] = 0;
2687 int entry_index = 0;
2690 entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
2693 entry_index = gcnumsrobjs_index;
2695 gcnumsendobjs[entry_index][data1] = data2;
2696 gcnumreceiveobjs[entry_index][data1] = data3;
2700 INLINE void processmsg_gcfinishcompact_I() {
2701 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2702 // non startup core can not receive this msg
2705 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
2707 BAMBOO_EXIT(0xb003);
2709 int cnum = msgdata[msgdataindex];
2710 MSG_INDEXINC_I(); //msgdata[1];
2711 int filledblocks = msgdata[msgdataindex];
2712 MSG_INDEXINC_I(); //msgdata[2];
2713 int heaptop = msgdata[msgdataindex];
2714 MSG_INDEXINC_I(); //msgdata[3];
2715 int data4 = msgdata[msgdataindex];
2716 MSG_INDEXINC_I(); //msgdata[4];
2717 // only gc cores need to do compact
2718 if(cnum < NUMCORES4GC) {
2719 if(COMPACTPHASE == gcphase) {
2720 gcfilledblocks[cnum] = filledblocks;
2721 gcloads[cnum] = heaptop;
2728 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
2729 // cache the msg first
2730 if(BAMBOO_CHECK_SEND_MODE()) {
2731 cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
2733 send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove, true);
2737 gccorestatus[cnum] = 0;
2739 } // if(cnum < NUMCORES4GC)
2742 INLINE void processmsg_gcfinishmapinfo_I() {
2743 int data1 = msgdata[msgdataindex];
2745 // received a map phase finish msg
2746 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2747 // non startup core can not receive this msg
2749 BAMBOO_DEBUGPRINT_REG(data1);
2751 BAMBOO_EXIT(0xb004);
2753 // all cores should do flush
2754 if(data1 < NUMCORES4GC) {
2755 gccorestatus[data1] = 0;
2760 INLINE void processmsg_gcfinishflush_I() {
2761 int data1 = msgdata[msgdataindex];
2763 // received a flush phase finish msg
2764 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2765 // non startup core can not receive this msg
2767 BAMBOO_DEBUGPRINT_REG(data1);
2769 BAMBOO_EXIT(0xb005);
2771 // all cores should do flush
2772 if(data1 < NUMCORESACTIVE) {
2773 gccorestatus[data1] = 0;
2777 INLINE void processmsg_gcmarkconfirm_I() {
2778 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2779 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2780 // wrong core to receive such msg
2781 BAMBOO_EXIT(0xb006);
2783 // send response msg, cahce the msg first
2784 if(BAMBOO_CHECK_SEND_MODE()) {
2785 cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2786 gcbusystatus, gcself_numsendobjs,
2787 gcself_numreceiveobjs);
2789 send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2790 gcbusystatus, gcself_numsendobjs,
2791 gcself_numreceiveobjs, true);
2796 INLINE void processmsg_gcmarkreport_I() {
2797 int data1 = msgdata[msgdataindex];
2799 int data2 = msgdata[msgdataindex];
2801 int data3 = msgdata[msgdataindex];
2803 int data4 = msgdata[msgdataindex];
2805 // received a marked phase finish confirm response msg
2806 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2807 // wrong core to receive such msg
2809 BAMBOO_DEBUGPRINT_REG(data2);
2811 BAMBOO_EXIT(0xb007);
2813 int entry_index = 0;
2817 entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
2819 // can never reach here
2821 entry_index = gcnumsrobjs_index;
2823 gccorestatus[data1] = data2;
2824 gcnumsendobjs[entry_index][data1] = data3;
2825 gcnumreceiveobjs[entry_index][data1] = data4;
2829 INLINE void processmsg_gcmarkedobj_I() {
2830 int data1 = msgdata[msgdataindex];
2832 // received a markedObj msg
2833 if(((int *)data1)[6] == INIT) {
2834 // this is the first time that this object is discovered,
2835 // set the flag as DISCOVERED
2836 ((int *)data1)[6] = DISCOVERED;
2837 gc_enqueue_I(data1);
2839 // set the remote flag
2840 ((int *)data1)[6] |= REMOTEM;
2841 gcself_numreceiveobjs++;
2842 gcbusystatus = true;
2845 INLINE void processmsg_gcmovestart_I() {
2847 gcdstcore = msgdata[msgdataindex];
2848 MSG_INDEXINC_I(); //msgdata[1];
2849 gcmovestartaddr = msgdata[msgdataindex];
2850 MSG_INDEXINC_I(); //msgdata[2];
2851 gcblock2fill = msgdata[msgdataindex];
2852 MSG_INDEXINC_I(); //msgdata[3];
2855 INLINE void processmsg_gcmaprequest_I() {
2857 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2859 void * dstptr = NULL;
2860 int data1 = msgdata[msgdataindex];
2863 // TODO unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2865 #ifdef LOCALHASHTBL_TEST
2866 RuntimeHashget(gcpointertbl, data1, &dstptr);
2868 dstptr = mgchashSearch(gcpointertbl, data1);
2870 //MGCHashget(gcpointertbl, data1, &dstptr);
2872 // TODO flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2874 int data2 = msgdata[msgdataindex];
2877 // TODO unsigned long long ttimei = BAMBOO_GET_EXE_TIME();
2879 if(NULL == dstptr) {
2880 // no such pointer in this core, something is wrong
2882 BAMBOO_DEBUGPRINT_REG(data1);
2883 BAMBOO_DEBUGPRINT_REG(data2);
2885 BAMBOO_EXIT(0xb009);
2886 //assume that the object was not moved, use the original address
2887 /*if(isMsgSending) {
2888 cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2890 send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2893 // send back the mapping info, cache the msg first
2894 if(BAMBOO_CHECK_SEND_MODE()) {
2895 cache_msg_3(data2, GCMAPINFO, data1, (int)dstptr);
2897 send_msg_3(data2, GCMAPINFO, data1, (int)dstptr, true);
2901 // TODO flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimei;
2902 //num_mapinforequest_i++;
2906 INLINE void processmsg_gcmapinfo_I() {
2908 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2910 int data1 = msgdata[msgdataindex];
2912 gcmappedobj = msgdata[msgdataindex]; // [2]
2914 #ifdef LOCALHASHTBL_TEST
2915 RuntimeHashadd_I(gcpointertbl, data1, gcmappedobj);
2917 mgchashInsert_I(gcpointertbl, data1, gcmappedobj);
2919 //MGCHashadd_I(gcpointertbl, data1, gcmappedobj);
2920 if(data1 == gcobj2map) {
2924 //flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2928 INLINE void processmsg_gcmaptbl_I() {
2929 int data1 = msgdata[msgdataindex];
2931 int data2 = msgdata[msgdataindex];
2933 gcrpointertbls[data2] = (mgcsharedhashtbl_t *)data1; //(struct GCSharedHash *)data1;
2936 INLINE void processmsg_gclobjinfo_I() {
2939 int data1 = msgdata[msgdataindex];
2941 int data2 = msgdata[msgdataindex];
2943 if(BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1) {
2945 BAMBOO_DEBUGPRINT_REG(data2);
2947 BAMBOO_EXIT(0xb00b);
2949 // store the mark result info
2951 gcloads[cnum] = msgdata[msgdataindex];
2952 MSG_INDEXINC_I(); // msgdata[3];
2953 int data4 = msgdata[msgdataindex];
2955 if(gcheaptop < data4) {
2958 // large obj info here
2959 for(int k = 5; k < data1; ) {
2960 int lobj = msgdata[msgdataindex];
2961 MSG_INDEXINC_I(); //msgdata[k++];
2962 int length = msgdata[msgdataindex];
2963 MSG_INDEXINC_I(); //msgdata[k++];
2964 gc_lobjenqueue_I(lobj, length, cnum);
2966 } // for(int k = 5; k < msgdata[1];)
2969 INLINE void processmsg_gclobjmapping_I() {
2970 int data1 = msgdata[msgdataindex];
2972 int data2 = msgdata[msgdataindex];
2974 #ifdef LOCALHASHTBL_TEST
2975 RuntimeHashadd_I(gcpointertbl, data1, data2);
2977 mgchashInsert_I(gcpointertbl, data1, data2);
2979 //MGCHashadd_I(gcpointertbl, data1, data2);
2980 mgcsharedhashInsert_I(gcsharedptbl, data1, data2);
2984 INLINE void processmsg_gcprofiles_I() {
2985 int data1 = msgdata[msgdataindex];
2987 int data2 = msgdata[msgdataindex];
2989 int data3 = msgdata[msgdataindex];
2991 gc_num_obj += data1;
2992 gc_num_liveobj += data2;
2993 gc_num_forwardobj += data3;
2997 #endif // #ifdef MULTICORE_GC
2999 // receive object transferred from other cores
3000 // or the terminate message from other cores
3001 // Should be invoked in critical sections!!
3002 // NOTICE: following format is for threadsimulate version only
3003 // RAW version please see previous description
3004 // format: type + object
3005 // type: -1--stall msg
3007 // return value: 0--received an object
3008 // 1--received nothing
3009 // 2--received a Stall Msg
3010 // 3--received a lock Msg
3011 // RAW version: -1 -- received nothing
3012 // otherwise -- received msg type
3013 int receiveObject(int send_port_pending) {
3014 #ifdef PROFILE_INTERRUPT
3015 if(!interruptInfoOverflow) {
3016 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
3017 interruptInfoArray[interruptInfoIndex] = intInfo;
3018 intInfo->startTime = BAMBOO_GET_EXE_TIME();
3019 intInfo->endTime = -1;
3023 // get the incoming msgs
3024 if(receiveMsg(send_port_pending) == -1) {
3028 // processing received msgs
3030 MSG_REMAINSIZE_I(&size);
3031 if((size == 0) || (checkMsgLength_I(size) == -1)) {
3033 // have new coming msg
3034 if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
3041 if(msglength <= size) {
3042 // have some whole msg
3044 type = msgdata[msgdataindex]; //[0]
3046 msgdatafull = false;
3048 //tprintf("msg type: %x\n", type);
3051 // receive a object transfer msg
3052 processmsg_transobj_I();
3057 // receive a stall msg
3058 processmsg_transtall_I();
3062 // GC version have no lock msgs
3063 #ifndef MULTICORE_GC
3065 // receive lock request msg, handle it right now
3066 processmsg_lockrequest_I();
3068 } // case LOCKREQUEST
3071 // receive lock grount msg
3072 processmsg_lockgrount_I();
3074 } // case LOCKGROUNT
3077 // receive lock deny msg
3078 processmsg_lockdeny_I();
3083 processmsg_lockrelease_I();
3085 } // case LOCKRELEASE
3086 #endif // #ifndef MULTICORE_GC
3089 case PROFILEOUTPUT: {
3090 // receive an output profile data request msg
3091 processmsg_profileoutput_I();
3093 } // case PROFILEOUTPUT
3095 case PROFILEFINISH: {
3096 // receive a profile output finish msg
3097 processmsg_profilefinish_I();
3099 } // case PROFILEFINISH
3100 #endif // #ifdef PROFILE
3102 // GC version has no lock msgs
3103 #ifndef MULTICORE_GC
3104 case REDIRECTLOCK: {
3105 // receive a redirect lock request msg, handle it right now
3106 processmsg_redirectlock_I();
3108 } // case REDIRECTLOCK
3110 case REDIRECTGROUNT: {
3111 // receive a lock grant msg with redirect info
3112 processmsg_redirectgrount_I();
3114 } // case REDIRECTGROUNT
3116 case REDIRECTDENY: {
3117 // receive a lock deny msg with redirect info
3118 processmsg_redirectdeny_I();
3120 } // case REDIRECTDENY
3122 case REDIRECTRELEASE: {
3123 // receive a lock release msg with redirect info
3124 processmsg_redirectrelease_I();
3126 } // case REDIRECTRELEASE
3127 #endif // #ifndef MULTICORE_GC
3129 case STATUSCONFIRM: {
3130 // receive a status confirm info
3131 processmsg_statusconfirm_I();
3133 } // case STATUSCONFIRM
3135 case STATUSREPORT: {
3136 processmsg_statusreport_I();
3138 } // case STATUSREPORT
3141 // receive a terminate msg
3142 processmsg_terminate_I();
3147 processmsg_memrequest_I();
3149 } // case MEMREQUEST
3152 processmsg_memresponse_I();
3154 } // case MEMRESPONSE
3159 processmsg_gcstartpre_I();
3161 } // case GCSTARTPRE
3164 processmsg_gcstartinit_I();
3166 } // case GCSTARTINIT
3169 // receive a start GC msg
3170 processmsg_gcstart_I();
3174 case GCSTARTCOMPACT: {
3175 // a compact phase start msg
3176 processmsg_gcstartcompact_I();
3178 } // case GCSTARTCOMPACT
3180 case GCSTARTMAPINFO: {
3181 // received a flush phase start msg
3182 processmsg_gcstartmapinfo_I();
3184 } // case GCSTARTFLUSH
3186 case GCSTARTFLUSH: {
3187 // received a flush phase start msg
3188 processmsg_gcstartflush_I();
3190 } // case GCSTARTFLUSH
3193 processmsg_gcfinishpre_I();
3195 } // case GCFINISHPRE
3197 case GCFINISHINIT: {
3198 processmsg_gcfinishinit_I();
3200 } // case GCFINISHINIT
3202 case GCFINISHMARK: {
3203 processmsg_gcfinishmark_I();
3205 } // case GCFINISHMARK
3207 case GCFINISHCOMPACT: {
3208 // received a compact phase finish msg
3209 processmsg_gcfinishcompact_I();
3211 } // case GCFINISHCOMPACT
3213 case GCFINISHMAPINFO: {
3214 processmsg_gcfinishmapinfo_I();
3216 } // case GCFINISHMAPINFO
3218 case GCFINISHFLUSH: {
3219 processmsg_gcfinishflush_I();
3221 } // case GCFINISHFLUSH
3224 // received a GC finish msg
3225 gcphase = FINISHPHASE;
3229 case GCMARKCONFIRM: {
3230 // received a marked phase finish confirm request msg
3231 // all cores should do mark
3232 processmsg_gcmarkconfirm_I();
3234 } // case GCMARKCONFIRM
3236 case GCMARKREPORT: {
3237 processmsg_gcmarkreport_I();
3239 } // case GCMARKREPORT
3242 processmsg_gcmarkedobj_I();
3244 } // case GCMARKEDOBJ
3247 // received a start moving objs msg
3248 processmsg_gcmovestart_I();
3250 } // case GCMOVESTART
3252 case GCMAPREQUEST: {
3253 // received a mapping info request msg
3254 processmsg_gcmaprequest_I();
3256 } // case GCMAPREQUEST
3259 // received a mapping info response msg
3260 processmsg_gcmapinfo_I();
3265 // received a mapping tbl response msg
3266 processmsg_gcmaptbl_I();
3270 case GCLOBJREQUEST: {
3271 // received a large objs info request msg
3272 transferMarkResults_I();
3274 } // case GCLOBJREQUEST
3277 // received a large objs info response msg
3278 processmsg_gclobjinfo_I();
3280 } // case GCLOBJINFO
3282 case GCLOBJMAPPING: {
3283 // received a large obj mapping info msg
3284 processmsg_gclobjmapping_I();
3286 } // case GCLOBJMAPPING
3288 #ifdef GC_PROFILE//_S
3290 // received a gcprofiles msg
3291 processmsg_gcprofiles_I();
3295 #endif // #ifdef MULTICORE_GC
3300 msglength = BAMBOO_MSG_BUF_LENGTH;
3302 //printf("++ msg: %x \n", type);
3304 if(msgdataindex != msgdatalast) {
3305 // still have available msg
3310 BAMBOO_DEBUGPRINT(0xe88d);
3314 // have new coming msg
3315 if(BAMBOO_MSG_AVAIL() != 0) {
3319 #ifdef PROFILE_INTERRUPT
3320 if(!interruptInfoOverflow) {
3321 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
3322 interruptInfoIndex++;
3323 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
3324 interruptInfoOverflow = true;
3333 BAMBOO_DEBUGPRINT(0xe88e);
3340 int enqueuetasks(struct parameterwrapper *parameter,
3341 struct parameterwrapper *prevptr,
3342 struct ___Object___ *ptr,
3344 int numenterflags) {
3345 void * taskpointerarray[MAXTASKPARAMS];
3347 //int numparams=parameter->task->numParameters;
3348 int numiterators=parameter->task->numTotal-1;
3351 struct taskdescriptor * task=parameter->task;
3353 //this add the object to parameterwrapper
3354 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
3355 numenterflags, enterflags==NULL);
3357 /* Add enqueued object to parameter vector */
3358 taskpointerarray[parameter->slot]=ptr;
3360 /* Reset iterators */
3361 for(j=0; j<numiterators; j++) {
3362 toiReset(¶meter->iterators[j]);
3365 /* Find initial state */
3366 for(j=0; j<numiterators; j++) {
3368 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3369 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3371 /* Need to backtrack */
3372 toiReset(¶meter->iterators[j]);
3376 /* Nothing to enqueue */
3382 /* Enqueue current state */
3384 struct taskparamdescriptor *tpd=
3385 RUNMALLOC(sizeof(struct taskparamdescriptor));
3387 tpd->numParameters=numiterators+1;
3388 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
3390 for(j=0; j<=numiterators; j++) {
3391 //store the actual parameters
3392 tpd->parameterArray[j]=taskpointerarray[j];
3395 if (( /*!gencontains(failedtasks, tpd)&&*/
3396 !gencontains(activetasks,tpd))) {
3397 genputtable(activetasks, tpd, tpd);
3399 RUNFREE(tpd->parameterArray);
3403 /* This loop iterates to the next parameter combination */
3404 if (numiterators==0)
3407 for(j=numiterators-1; j<numiterators; j++) {
3409 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3410 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3412 /* Need to backtrack */
3413 toiReset(¶meter->iterators[j]);
3417 /* Nothing more to enqueue */
3425 int enqueuetasks_I(struct parameterwrapper *parameter,
3426 struct parameterwrapper *prevptr,
3427 struct ___Object___ *ptr,
3429 int numenterflags) {
3430 void * taskpointerarray[MAXTASKPARAMS];
3432 //int numparams=parameter->task->numParameters;
3433 int numiterators=parameter->task->numTotal-1;
3438 struct taskdescriptor * task=parameter->task;
3440 //this add the object to parameterwrapper
3441 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
3442 numenterflags, enterflags==NULL);
3444 /* Add enqueued object to parameter vector */
3445 taskpointerarray[parameter->slot]=ptr;
3447 /* Reset iterators */
3448 for(j=0; j<numiterators; j++) {
3449 toiReset(¶meter->iterators[j]);
3452 /* Find initial state */
3453 for(j=0; j<numiterators; j++) {
3455 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3456 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3458 /* Need to backtrack */
3459 toiReset(¶meter->iterators[j]);
3463 /* Nothing to enqueue */
3469 /* Enqueue current state */
3471 struct taskparamdescriptor *tpd=
3472 RUNMALLOC_I(sizeof(struct taskparamdescriptor));
3474 tpd->numParameters=numiterators+1;
3475 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
3477 for(j=0; j<=numiterators; j++) {
3478 //store the actual parameters
3479 tpd->parameterArray[j]=taskpointerarray[j];
3482 if (( /*!gencontains(failedtasks, tpd)&&*/
3483 !gencontains(activetasks,tpd))) {
3484 genputtable_I(activetasks, tpd, tpd);
3486 RUNFREE(tpd->parameterArray);
3490 /* This loop iterates to the next parameter combination */
3491 if (numiterators==0)
3494 for(j=numiterators-1; j<numiterators; j++) {
3496 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
3497 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3499 /* Need to backtrack */
3500 toiReset(¶meter->iterators[j]);
3504 /* Nothing more to enqueue */
3518 int containstag(struct ___Object___ *ptr,
3519 struct ___TagDescriptor___ *tag);
3521 #ifndef MULTICORE_GC
3522 void releasewritelock_r(void * lock, void * redirectlock) {
3524 int reallock = (int)lock;
3525 targetcore = (reallock >> 5) % NUMCORES;
3528 BAMBOO_DEBUGPRINT(0xe671);
3529 BAMBOO_DEBUGPRINT_REG((int)lock);
3530 BAMBOO_DEBUGPRINT_REG(reallock);
3531 BAMBOO_DEBUGPRINT_REG(targetcore);
3534 if(targetcore == BAMBOO_NUM_OF_CORE) {
3535 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3537 BAMBOO_DEBUGPRINT(0xf001);
3539 // reside on this core
3540 if(!RuntimeHashcontainskey(locktbl, reallock)) {
3541 // no locks for this object, something is wrong
3542 BAMBOO_EXIT(0xa00b);
3545 struct LockValue * lockvalue = NULL;
3547 BAMBOO_DEBUGPRINT(0xe672);
3549 RuntimeHashget(locktbl, reallock, &rwlock_obj);
3550 lockvalue = (struct LockValue *)rwlock_obj;
3552 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
3555 lockvalue->redirectlock = (int)redirectlock;
3557 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
3560 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3562 BAMBOO_DEBUGPRINT(0xf000);
3566 // send lock release with redirect info msg
3567 // for 32 bit machine, the size is always 4 words
3568 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock,
3569 (int)redirectlock, false);
3574 void executetasks() {
3575 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
3578 struct ___Object___ * tmpparam = NULL;
3579 struct parameterdescriptor * pd=NULL;
3580 struct parameterwrapper *pw=NULL;
3590 while(hashsize(activetasks)>0) {
3592 if(gcflag) gc(NULL);
3595 BAMBOO_DEBUGPRINT(0xe990);
3598 /* See if there are any active tasks */
3599 //if (hashsize(activetasks)>0) {
3602 #ifdef ACCURATEPROFILE
3603 profileTaskStart("tpd checking");
3607 //clock1 = BAMBOO_GET_EXE_TIME();
3610 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
3611 genfreekey(activetasks, currtpd);
3613 numparams=currtpd->task->numParameters;
3614 numtotal=currtpd->task->numTotal;
3616 // clear the lockRedirectTbl
3617 // (TODO, this table should be empty after all locks are released)
3619 /*for(j = 0; j < MAXTASKPARAMS; j++) {
3620 runtime_locks[j].redirectlock = 0;
3621 runtime_locks[j].value = 0;
3623 // get all required locks
3624 runtime_locklen = 0;
3625 // check which locks are needed
3626 for(i = 0; i < numparams; i++) {
3627 void * param = currtpd->parameterArray[i];
3631 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
3633 taskpointerarray[i+OFFSET]=param;
3636 if(((struct ___Object___ *)param)->lock == NULL) {
3637 tmplock = (int)param;
3639 tmplock = (int)(((struct ___Object___ *)param)->lock);
3641 // insert into the locks array
3642 for(j = 0; j < runtime_locklen; j++) {
3643 if(runtime_locks[j].value == tmplock) {
3646 } else if(runtime_locks[j].value > tmplock) {
3651 int h = runtime_locklen;
3653 runtime_locks[h].redirectlock = runtime_locks[h-1].redirectlock;
3654 runtime_locks[h].value = runtime_locks[h-1].value;
3656 runtime_locks[j].value = tmplock;
3657 runtime_locks[j].redirectlock = (int)param;
3660 } // line 2713: for(i = 0; i < numparams; i++)
3661 // grab these required locks
3663 BAMBOO_DEBUGPRINT(0xe991);
3666 //clock2 = BAMBOO_GET_EXE_TIME();
3668 for(i = 0; i < runtime_locklen; i++) {
3669 int * lock = (int *)(runtime_locks[i].redirectlock);
3671 // require locks for this parameter if it is not a startup object
3673 BAMBOO_DEBUGPRINT_REG((int)lock);
3674 BAMBOO_DEBUGPRINT_REG((int)(runtime_locks[i].value));
3677 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3679 BAMBOO_DEBUGPRINT(0xf001);
3682 //isInterrupt = false;
3685 BAMBOO_WAITING_FOR_LOCK(0);
3689 while(BAMBOO_WAITING_FOR_LOCK(0) != -1) {
3693 grount = lockresult;
3703 //isInterrupt = true;
3705 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3707 BAMBOO_DEBUGPRINT(0xf000);
3712 BAMBOO_DEBUGPRINT(0xe992);
3713 BAMBOO_DEBUGPRINT_REG(lock);
3715 // check if has the lock already
3716 // can not get the lock, try later
3717 // release all grabbed locks for previous parameters
3718 for(j = 0; j < i; ++j) {
3719 lock = (int*)(runtime_locks[j].redirectlock);
3720 releasewritelock(lock);
3722 genputtable(activetasks, currtpd, currtpd);
3723 if(hashsize(activetasks) == 1) {
3724 // only one task right now, wait a little while before next try
3730 #ifdef ACCURATEPROFILE
3731 // fail, set the end of the checkTaskInfo
3738 } // line 2752: for(i = 0; i < runtime_locklen; i++)
3741 clock3 = BAMBOO_GET_EXE_TIME();
3742 //tprintf("sort: %d, grab: %d \n", clock2-clock1, clock3-clock2);*/
3745 BAMBOO_DEBUGPRINT(0xe993);
3747 /* Make sure that the parameters are still in the queues */
3748 for(i=0; i<numparams; i++) {
3749 void * parameter=currtpd->parameterArray[i];
3753 BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
3754 classsize[((struct ___Object___ *)parameter)->type]);
3756 tmpparam = (struct ___Object___ *)parameter;
3757 pd=currtpd->task->descriptorarray[i];
3758 pw=(struct parameterwrapper *) pd->queue;
3759 /* Check that object is still in queue */
3761 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
3763 BAMBOO_DEBUGPRINT(0xe994);
3764 BAMBOO_DEBUGPRINT_REG(parameter);
3766 // release grabbed locks
3767 for(j = 0; j < runtime_locklen; ++j) {
3768 int * lock = (int *)(runtime_locks[j].redirectlock);
3769 releasewritelock(lock);
3771 RUNFREE(currtpd->parameterArray);
3777 /* Check if the object's flags still meets requirements */
3781 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
3782 andmask=pw->intarray[tmpi*2];
3783 checkmask=pw->intarray[tmpi*2+1];
3784 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
3790 // flags are never suitable
3791 // remove this obj from the queue
3793 int UNUSED, UNUSED2;
3796 BAMBOO_DEBUGPRINT(0xe995);
3797 BAMBOO_DEBUGPRINT_REG(parameter);
3799 ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
3800 (int *) &enterflags, &UNUSED, &UNUSED2);
3801 ObjectHashremove(pw->objectset, (int)parameter);
3802 if (enterflags!=NULL)
3803 RUNFREE(enterflags);
3804 // release grabbed locks
3805 for(j = 0; j < runtime_locklen; ++j) {
3806 int * lock = (int *)(runtime_locks[j].redirectlock);
3807 releasewritelock(lock);
3809 RUNFREE(currtpd->parameterArray);
3813 #ifdef ACCURATEPROFILE
3814 // fail, set the end of the checkTaskInfo
3819 } // line 2878: if (!ismet)
3823 /* Check that object still has necessary tags */
3824 for(j=0; j<pd->numbertags; j++) {
3825 int slotid=pd->tagarray[2*j]+numparams;
3826 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
3827 if (!containstag(parameter, tagd)) {
3829 BAMBOO_DEBUGPRINT(0xe996);
3832 // release grabbed locks
3834 for(tmpj = 0; tmpj < runtime_locklen; ++tmpj) {
3835 int * lock = (int *)(runtime_locks[tmpj].redirectlock);
3836 releasewritelock(lock);
3839 RUNFREE(currtpd->parameterArray);
3843 } // line2911: if (!containstag(parameter, tagd))
3844 } // line 2808: for(j=0; j<pd->numbertags; j++)
3846 taskpointerarray[i+OFFSET]=parameter;
3847 } // line 2824: for(i=0; i<numparams; i++)
3849 for(; i<numtotal; i++) {
3850 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
3855 /* Actually call task */
3857 ((int *)taskpointerarray)[0]=currtpd->numParameters;
3858 taskpointerarray[1]=NULL;
3861 #ifdef ACCURATEPROFILE
3862 // check finish, set the end of the checkTaskInfo
3865 profileTaskStart(currtpd->task->name);
3869 //clock4 = BAMBOO_GET_EXE_TIME();
3870 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3873 BAMBOO_DEBUGPRINT(0xe997);
3875 ((void (*)(void **))currtpd->task->taskptr)(taskpointerarray);
3878 //clock5 = BAMBOO_GET_EXE_TIME();
3879 // tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3882 #ifdef ACCURATEPROFILE
3883 // task finish, set the end of the checkTaskInfo
3885 // new a PostTaskInfo for the post-task execution
3886 profileTaskStart("post task execution");
3890 BAMBOO_DEBUGPRINT(0xe998);
3891 BAMBOO_DEBUGPRINT_REG(islock);
3896 BAMBOO_DEBUGPRINT(0xe999);
3898 for(i = 0; i < runtime_locklen; ++i) {
3899 void * ptr = (void *)(runtime_locks[i].redirectlock);
3900 int * lock = (int *)(runtime_locks[i].value);
3902 BAMBOO_DEBUGPRINT_REG((int)ptr);
3903 BAMBOO_DEBUGPRINT_REG((int)lock);
3904 BAMBOO_DEBUGPRINT_REG(*((int*)lock+5));
3906 #ifndef MULTICORE_GC
3907 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
3909 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
3910 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
3911 releasewritelock_r(lock, (int *)redirectlock);
3916 releasewritelock(ptr);
3919 } // line 3015: if(islock)
3922 //clock6 = BAMBOO_GET_EXE_TIME();
3923 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3926 // post task execution finish, set the end of the postTaskInfo
3930 // Free up task parameter descriptor
3931 RUNFREE(currtpd->parameterArray);
3935 BAMBOO_DEBUGPRINT(0xe99a);
3938 //clock7 = BAMBOO_GET_EXE_TIME();
3939 //tprintf("sort: %d, grab: %d, check: %d, release: %d, other %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3), (int)(clock6-clock5), (int)(clock7-clock6));
3942 //} // if (hashsize(activetasks)>0)
3943 } // while(hashsize(activetasks)>0)
3945 BAMBOO_DEBUGPRINT(0xe99b);
3949 /* This function processes an objects tags */
3950 void processtags(struct parameterdescriptor *pd,
3952 struct parameterwrapper *parameter,
3953 int * iteratorcount,
3958 for(i=0; i<pd->numbertags; i++) {
3959 int slotid=pd->tagarray[2*i];
3960 int tagid=pd->tagarray[2*i+1];
3962 if (statusarray[slotid+numparams]==0) {
3963 parameter->iterators[*iteratorcount].istag=1;
3964 parameter->iterators[*iteratorcount].tagid=tagid;
3965 parameter->iterators[*iteratorcount].slot=slotid+numparams;
3966 parameter->iterators[*iteratorcount].tagobjectslot=index;
3967 statusarray[slotid+numparams]=1;
3974 void processobject(struct parameterwrapper *parameter,
3976 struct parameterdescriptor *pd,
3982 struct ObjectHash * objectset=
3983 ((struct parameterwrapper *)pd->queue)->objectset;
3985 parameter->iterators[*iteratorcount].istag=0;
3986 parameter->iterators[*iteratorcount].slot=index;
3987 parameter->iterators[*iteratorcount].objectset=objectset;
3988 statusarray[index]=1;
3990 for(i=0; i<pd->numbertags; i++) {
3991 int slotid=pd->tagarray[2*i];
3992 //int tagid=pd->tagarray[2*i+1];
3993 if (statusarray[slotid+numparams]!=0) {
3994 /* This tag has already been enqueued, use it to narrow search */
3995 parameter->iterators[*iteratorcount].tagbindings[tagcount]=
4000 parameter->iterators[*iteratorcount].numtags=tagcount;
4005 /* This function builds the iterators for a task & parameter */
4007 void builditerators(struct taskdescriptor * task,
4009 struct parameterwrapper * parameter) {
4010 int statusarray[MAXTASKPARAMS];
4012 int numparams=task->numParameters;
4013 int iteratorcount=0;
4014 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
4016 statusarray[index]=1; /* Initial parameter */
4017 /* Process tags for initial iterator */
4019 processtags(task->descriptorarray[index], index, parameter,
4020 &iteratorcount, statusarray, numparams);
4024 /* Check for objects with existing tags */
4025 for(i=0; i<numparams; i++) {
4026 if (statusarray[i]==0) {
4027 struct parameterdescriptor *pd=task->descriptorarray[i];
4029 for(j=0; j<pd->numbertags; j++) {
4030 int slotid=pd->tagarray[2*j];
4031 if(statusarray[slotid+numparams]!=0) {
4032 processobject(parameter, i, pd, &iteratorcount, statusarray,
4034 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
4041 /* Next do objects w/ unbound tags*/
4043 for(i=0; i<numparams; i++) {
4044 if (statusarray[i]==0) {
4045 struct parameterdescriptor *pd=task->descriptorarray[i];
4046 if (pd->numbertags>0) {
4047 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
4048 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
4054 /* Nothing with a tag enqueued */
4056 for(i=0; i<numparams; i++) {
4057 if (statusarray[i]==0) {
4058 struct parameterdescriptor *pd=task->descriptorarray[i];
4059 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
4060 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
4073 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
4076 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
4077 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
4079 printf("%s\n", task->name);
4081 for(j=0; j<task->numParameters; j++) {
4082 struct parameterdescriptor *param=task->descriptorarray[j];
4083 struct parameterwrapper *parameter=param->queue;
4084 struct ObjectHash * set=parameter->objectset;
4085 struct ObjectIterator objit;
4087 printf(" Parameter %d\n", j);
4089 ObjectHashiterator(set, &objit);
4090 while(ObjhasNext(&objit)) {
4091 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
4092 struct ___Object___ * tagptr=obj->___tags___;
4093 int nonfailed=Objdata4(&objit);
4094 int numflags=Objdata3(&objit);
4095 int flags=Objdata2(&objit);
4098 printf(" Contains %lx\n", obj);
4099 printf(" flag=%d\n", obj->flag);
4102 } else if (tagptr->type==TAGTYPE) {
4104 printf(" tag=%lx\n",tagptr);
4110 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
4111 for(; tagindex<ao->___cachedCode___; tagindex++) {
4113 printf(" tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*,
4126 /* This function processes the task information to create queues for
4127 each parameter type. */
4129 void processtasks() {
4131 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
4134 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
4135 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
4138 /* Build objectsets */
4139 for(j=0; j<task->numParameters; j++) {
4140 struct parameterdescriptor *param=task->descriptorarray[j];
4141 struct parameterwrapper *parameter=param->queue;
4142 parameter->objectset=allocateObjectHash(10);
4143 parameter->task=task;
4146 /* Build iterators for parameters */
4147 for(j=0; j<task->numParameters; j++) {
4148 struct parameterdescriptor *param=task->descriptorarray[j];
4149 struct parameterwrapper *parameter=param->queue;
4150 builditerators(task, j, parameter);
4155 void toiReset(struct tagobjectiterator * it) {
4158 } else if (it->numtags>0) {
4161 ObjectHashiterator(it->objectset, &it->it);
4165 int toiHasNext(struct tagobjectiterator *it,
4166 void ** objectarray OPTARG(int * failed)) {
4169 /* Get object with tags */
4170 struct ___Object___ *obj=objectarray[it->tagobjectslot];
4171 struct ___Object___ *tagptr=obj->___tags___;
4172 if (tagptr->type==TAGTYPE) {
4173 if ((it->tagobjindex==0)&& /* First object */
4174 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
4179 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
4180 int tagindex=it->tagobjindex;
4181 for(; tagindex<ao->___cachedCode___; tagindex++) {
4182 struct ___TagDescriptor___ *td=
4183 ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
4184 if (td->flag==it->tagid) {
4185 it->tagobjindex=tagindex; /* Found right type of tag */
4191 } else if (it->numtags>0) {
4192 /* Use tags to locate appropriate objects */
4193 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
4194 struct ___Object___ *objptr=tag->flagptr;
4196 if (objptr->type!=OBJECTARRAYTYPE) {
4197 if (it->tagobjindex>0)
4199 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
4201 for(i=1; i<it->numtags; i++) {
4202 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
4203 if (!containstag(objptr,tag2))
4208 struct ArrayObject *ao=(struct ArrayObject *) objptr;
4211 for(tagindex=it->tagobjindex; tagindex<ao->___cachedCode___; tagindex++) {
4212 struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
4213 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
4215 for(i=1; i<it->numtags; i++) {
4216 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
4217 if (!containstag(objptr,tag2))
4220 it->tagobjindex=tagindex;
4225 it->tagobjindex=tagindex;
4229 return ObjhasNext(&it->it);
4233 int containstag(struct ___Object___ *ptr,
4234 struct ___TagDescriptor___ *tag) {
4236 struct ___Object___ * objptr=tag->flagptr;
4237 if (objptr->type==OBJECTARRAYTYPE) {
4238 struct ArrayObject *ao=(struct ArrayObject *)objptr;
4239 for(j=0; j<ao->___cachedCode___; j++) {
4240 if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
4250 void toiNext(struct tagobjectiterator *it,
4251 void ** objectarray OPTARG(int * failed)) {
4252 /* hasNext has all of the intelligence */
4255 /* Get object with tags */
4256 struct ___Object___ *obj=objectarray[it->tagobjectslot];
4257 struct ___Object___ *tagptr=obj->___tags___;
4258 if (tagptr->type==TAGTYPE) {
4260 objectarray[it->slot]=tagptr;
4262 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
4263 objectarray[it->slot]=
4264 ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
4266 } else if (it->numtags>0) {
4267 /* Use tags to locate appropriate objects */
4268 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
4269 struct ___Object___ *objptr=tag->flagptr;
4270 if (objptr->type!=OBJECTARRAYTYPE) {
4272 objectarray[it->slot]=objptr;
4274 struct ArrayObject *ao=(struct ArrayObject *) objptr;
4275 objectarray[it->slot]=
4276 ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
4279 /* Iterate object */
4280 objectarray[it->slot]=(void *)Objkey(&it->it);
4286 inline void profileTaskStart(char * taskname) {
4287 if(!taskInfoOverflow) {
4288 TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
4289 taskInfoArray[taskInfoIndex] = taskInfo;
4290 taskInfo->taskName = taskname;
4291 taskInfo->startTime = BAMBOO_GET_EXE_TIME();
4292 taskInfo->endTime = -1;
4293 taskInfo->exitIndex = -1;
4294 taskInfo->newObjs = NULL;
4298 inline void profileTaskEnd() {
4299 if(!taskInfoOverflow) {
4300 taskInfoArray[taskInfoIndex]->endTime = BAMBOO_GET_EXE_TIME();
4302 if(taskInfoIndex == TASKINFOLENGTH) {
4303 taskInfoOverflow = true;
4304 //taskInfoIndex = 0;
4309 // output the profiling data
4310 void outputProfileData() {
4313 unsigned long long totaltasktime = 0;
4314 unsigned long long preprocessingtime = 0;
4315 unsigned long long objqueuecheckingtime = 0;
4316 unsigned long long postprocessingtime = 0;
4317 //int interruptiontime = 0;
4318 unsigned long long other = 0;
4319 unsigned long long averagetasktime = 0;
4322 printf("Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
4323 // output task related info
4324 for(i = 0; i < taskInfoIndex; i++) {
4325 TaskInfo* tmpTInfo = taskInfoArray[i];
4326 unsigned long long duration = tmpTInfo->endTime - tmpTInfo->startTime;
4327 printf("%s, %lld, %lld, %lld, %lld",
4328 tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime,
4329 duration, tmpTInfo->exitIndex);
4330 // summarize new obj info
4331 if(tmpTInfo->newObjs != NULL) {
4332 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
4333 struct RuntimeIterator * iter = NULL;
4334 while(0 == isEmpty(tmpTInfo->newObjs)) {
4335 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
4336 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
4338 RuntimeHashget(nobjtbl, (int)objtype, &num);
4339 RuntimeHashremovekey(nobjtbl, (int)objtype);
4341 RuntimeHashadd(nobjtbl, (int)objtype, num);
4343 RuntimeHashadd(nobjtbl, (int)objtype, 1);
4345 //printf(stderr, "new obj!\n");
4348 // output all new obj info
4349 iter = RuntimeHashcreateiterator(nobjtbl);
4350 while(RunhasNext(iter)) {
4351 char * objtype = (char *)Runkey(iter);
4352 int num = Runnext(iter);
4353 printf(", %s, %d", objtype, num);
4357 if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
4358 preprocessingtime += duration;
4359 } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
4360 postprocessingtime += duration;
4361 } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
4362 objqueuecheckingtime += duration;
4364 totaltasktime += duration;
4365 averagetasktime += duration;
4370 if(taskInfoOverflow) {
4371 printf("Caution: task info overflow!\n");
4374 other = totalexetime-totaltasktime-preprocessingtime-postprocessingtime;
4375 averagetasktime /= tasknum;
4377 printf("\nTotal time: %lld\n", totalexetime);
4378 printf("Total task execution time: %lld (%d%%)\n", totaltasktime,
4379 (int)(((double)totaltasktime/(double)totalexetime)*100));
4380 printf("Total objqueue checking time: %lld (%d%%)\n",
4381 objqueuecheckingtime,
4382 (int)(((double)objqueuecheckingtime/(double)totalexetime)*100));
4383 printf("Total pre-processing time: %lld (%d%%)\n", preprocessingtime,
4384 (int)(((double)preprocessingtime/(double)totalexetime)*100));
4385 printf("Total post-processing time: %lld (%d%%)\n", postprocessingtime,
4386 (int)(((double)postprocessingtime/(double)totalexetime)*100));
4387 printf("Other time: %lld (%d%%)\n", other,
4388 (int)(((double)other/(double)totalexetime)*100));
4391 printf("\nAverage task execution time: %lld\n", averagetasktime);
4393 //printf("\nTotal time spent for interruptions: %lld\n", interrupttime);
4398 BAMBOO_DEBUGPRINT(0xdddd);
4399 // output task related info
4400 for(i= 0; i < taskInfoIndex; i++) {
4401 TaskInfo* tmpTInfo = taskInfoArray[i];
4402 char* tmpName = tmpTInfo->taskName;
4403 int nameLen = strlen(tmpName);
4404 BAMBOO_DEBUGPRINT(0xddda);
4405 for(j = 0; j < nameLen; j++) {
4406 BAMBOO_DEBUGPRINT_REG(tmpName[j]);
4408 BAMBOO_DEBUGPRINT(0xdddb);
4409 BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
4410 BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
4411 BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
4412 if(tmpTInfo->newObjs != NULL) {
4413 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
4414 struct RuntimeIterator * iter = NULL;
4415 while(0 == isEmpty(tmpTInfo->newObjs)) {
4416 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
4417 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
4419 RuntimeHashget(nobjtbl, (int)objtype, &num);
4420 RuntimeHashremovekey(nobjtbl, (int)objtype);
4422 RuntimeHashadd(nobjtbl, (int)objtype, num);
4424 RuntimeHashadd(nobjtbl, (int)objtype, 1);
4428 // ouput all new obj info
4429 iter = RuntimeHashcreateiterator(nobjtbl);
4430 while(RunhasNext(iter)) {
4431 char * objtype = (char *)Runkey(iter);
4432 int num = Runnext(iter);
4433 int nameLen = strlen(objtype);
4434 BAMBOO_DEBUGPRINT(0xddda);
4435 for(j = 0; j < nameLen; j++) {
4436 BAMBOO_DEBUGPRINT_REG(objtype[j]);
4438 BAMBOO_DEBUGPRINT(0xdddb);
4439 BAMBOO_DEBUGPRINT_REG(num);
4442 BAMBOO_DEBUGPRINT(0xdddc);
4445 if(taskInfoOverflow) {
4446 BAMBOO_DEBUGPRINT(0xefee);
4449 #ifdef PROFILE_INTERRUPT
4450 // output interrupt related info
4451 for(i = 0; i < interruptInfoIndex; i++) {
4452 InterruptInfo* tmpIInfo = interruptInfoArray[i];
4453 BAMBOO_DEBUGPRINT(0xddde);
4454 BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
4455 BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
4456 BAMBOO_DEBUGPRINT(0xdddf);
4459 if(interruptInfoOverflow) {
4460 BAMBOO_DEBUGPRINT(0xefef);
4462 #endif // PROFILE_INTERRUPT
4464 BAMBOO_DEBUGPRINT(0xeeee);
4467 #endif // #ifdef PROFILE