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;
261 gcself_numsendobjs = 0;
262 gcself_numreceiveobjs = 0;
263 gcmarkedptrbound = 0;
264 #ifdef LOCALHASHTBL_TEST
265 gcpointertbl = allocateRuntimeHash_I(20);
267 gcpointertbl = mgchashCreate_I(2000, 0.75);
269 //gcpointertbl = allocateMGCHash_I(20);
270 gcforwardobjtbl = allocateMGCHash_I(20, 3);
273 //gcismapped = false;
282 gcsbstarttbl = BAMBOO_BASE_VA;
283 bamboo_smemtbl = (void *)gcsbstarttbl
284 + (BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE)*sizeof(INTPTR);
285 if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
286 int t_size = ((BAMBOO_RMSP_SIZE)-sizeof(mgcsharedhashtbl_t)*2
287 -128*sizeof(size_t))/sizeof(mgcsharedhashlistnode_t)-2;
289 unsigned int tmp_k = 1 << (sizeof(int)*8 -1);
290 while(((t_size & tmp_k) == 0) && (kk < sizeof(int)*8)) {
291 t_size = t_size << 1;
294 t_size = tmp_k >> kk;
295 gcsharedptbl = mgcsharedhashCreate_I(t_size,0.30);//allocateGCSharedHash_I(20);
299 BAMBOO_MEMSET_WH(gcrpointertbls,0,sizeof(mgcsharedhashtbl_t *)*NUMCORES4GC);
300 //sizeof(struct RuntimeHash *)*NUMCORES4GC);
302 gcmem_mixed_threshold = (unsigned int)((BAMBOO_SHARED_MEM_SIZE
303 -bamboo_reserved_smem*BAMBOO_SMEM_SIZE)*0.8);
304 gcmem_mixed_usedmem = 0;
309 gc_num_forwardobj = 0;
310 gc_num_profiles = NUMCORESACTIVE - 1;
313 // create the lock table, lockresult table and obj queue
316 (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
317 /* Set allocation blocks*/
318 locktable.listhead=NULL;
319 locktable.listtail=NULL;
321 locktable.numelements = 0;
326 lockRedirectTbl = allocateRuntimeHash_I(20);
327 objRedirectLockTbl = allocateRuntimeHash_I(20);
332 objqueue.head = NULL;
333 objqueue.tail = NULL;
339 //isInterrupt = true;
343 taskInfoOverflow = false;
345 interruptInfoIndex = 0;
346 interruptInfoOverflow = false;
349 for(i = 0; i < MAXTASKPARAMS; i++) {
350 runtime_locks[i].redirectlock = 0;
351 runtime_locks[i].value = 0;
356 inline __attribute__((always_inline))
357 void disruntimedata() {
359 #ifdef LOCALHASHTBL_TEST
360 freeRuntimeHash(gcpointertbl);
362 mgchashDelete(gcpointertbl);
364 //freeMGCHash(gcpointertbl);
365 freeMGCHash(gcforwardobjtbl);
366 // for mapping info structures
367 //freeRuntimeHash(gcrcoretbl);
369 freeRuntimeHash(lockRedirectTbl);
370 freeRuntimeHash(objRedirectLockTbl);
371 RUNFREE(locktable.bucket);
373 if(activetasks != NULL) {
374 genfreehashtable(activetasks);
376 if(currtpd != NULL) {
377 RUNFREE(currtpd->parameterArray);
381 BAMBOO_LOCAL_MEM_CLOSE();
382 BAMBOO_SHARE_MEM_CLOSE();
385 inline __attribute__((always_inline))
386 bool checkObjQueue() {
388 struct transObjInfo * objInfo = NULL;
392 #ifdef ACCURATEPROFILE
393 bool isChecking = false;
394 if(!isEmpty(&objqueue)) {
395 profileTaskStart("objqueue checking");
397 } // if(!isEmpty(&objqueue))
401 while(!isEmpty(&objqueue)) {
403 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
405 BAMBOO_DEBUGPRINT(0xf001);
408 //isInterrupt = false;
411 BAMBOO_DEBUGPRINT(0xeee1);
414 objInfo = (struct transObjInfo *)getItem(&objqueue);
415 obj = objInfo->objptr;
417 BAMBOO_DEBUGPRINT_REG((int)obj);
419 // grab lock and flush the obj
423 BAMBOO_WAITING_FOR_LOCK(0);
424 } // while(!lockflag)
427 BAMBOO_DEBUGPRINT_REG(grount);
442 BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
443 BAMBOO_CACHE_FLUSH_RANGE((int)obj,
444 classsize[((struct ___Object___ *)obj)->type]);
446 // enqueue the object
447 for(k = 0; k < objInfo->length; ++k) {
448 int taskindex = objInfo->queues[2 * k];
449 int paramindex = objInfo->queues[2 * k + 1];
450 struct parameterwrapper ** queues =
451 &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
453 BAMBOO_DEBUGPRINT_REG(taskindex);
454 BAMBOO_DEBUGPRINT_REG(paramindex);
455 struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
456 tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n",
457 BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj,
458 (long)obj, tmpptr->flag);
460 enqueueObject_I(obj, queues, 1);
462 BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
464 } // for(k = 0; k < objInfo->length; ++k)
465 releasewritelock_I(obj);
466 RUNFREE(objInfo->queues);
470 // put it at the end of the queue if no update version in the queue
471 struct QueueItem * qitem = getHead(&objqueue);
472 struct QueueItem * prev = NULL;
473 while(qitem != NULL) {
474 struct transObjInfo * tmpinfo =
475 (struct transObjInfo *)(qitem->objectptr);
476 if(tmpinfo->objptr == obj) {
477 // the same object in the queue, which should be enqueued
478 // recently. Current one is outdate, do not re-enqueue it
479 RUNFREE(objInfo->queues);
484 } // if(tmpinfo->objptr == obj)
485 qitem = getNextQueueItem(prev);
486 } // while(qitem != NULL)
487 // try to execute active tasks already enqueued first
488 addNewItem_I(&objqueue, objInfo);
490 //isInterrupt = true;
493 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
495 BAMBOO_DEBUGPRINT(0xf000);
499 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
501 BAMBOO_DEBUGPRINT(0xf000);
503 } // while(!isEmpty(&objqueue))
506 #ifdef ACCURATEPROFILE
514 BAMBOO_DEBUGPRINT(0xee02);
519 inline __attribute__((always_inline))
520 void checkCoreStatus() {
521 bool allStall = false;
525 (waitconfirm && (numconfirm == 0))) {
527 BAMBOO_DEBUGPRINT(0xee04);
528 BAMBOO_DEBUGPRINT_REG(waitconfirm);
530 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
532 BAMBOO_DEBUGPRINT(0xf001);
534 corestatus[BAMBOO_NUM_OF_CORE] = 0;
535 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
536 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
537 // check the status of all cores
540 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
542 for(i = 0; i < NUMCORESACTIVE; ++i) {
544 BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
546 if(corestatus[i] != 0) {
550 } // for(i = 0; i < NUMCORESACTIVE; ++i)
552 // check if the sum of send objs and receive obj are the same
553 // yes->check if the info is the latest; no->go on executing
555 for(i = 0; i < NUMCORESACTIVE; ++i) {
556 sumsendobj += numsendobjs[i];
558 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
560 } // for(i = 0; i < NUMCORESACTIVE; ++i)
561 for(i = 0; i < NUMCORESACTIVE; ++i) {
562 sumsendobj -= numreceiveobjs[i];
564 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
566 } // for(i = 0; i < NUMCORESACTIVE; ++i)
567 if(0 == sumsendobj) {
569 // the first time found all cores stall
570 // send out status confirm msg to all other cores
571 // reset the corestatus array too
573 BAMBOO_DEBUGPRINT(0xee05);
575 corestatus[BAMBOO_NUM_OF_CORE] = 1;
577 numconfirm = NUMCORESACTIVE - 1;
578 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
579 for(i = 1; i < NUMCORESACTIVE; ++i) {
581 // send status confirm msg to core i
582 send_msg_1(i, STATUSCONFIRM, false);
583 } // for(i = 1; i < NUMCORESACTIVE; ++i)
586 // all the core status info are the latest
587 // terminate; for profiling mode, send request to all
588 // other cores to pour out profiling data
590 BAMBOO_DEBUGPRINT(0xee06);
594 totalexetime = BAMBOO_GET_EXE_TIME() - bamboo_start_time;
597 //BAMBOO_DEBUGPRINT_REG(interrupttime);
600 BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME() - bamboo_start_time);
601 //BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
602 BAMBOO_DEBUGPRINT(0xbbbbbbbb);
604 // profile mode, send msgs to other cores to request pouring
605 // out progiling data
607 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
609 BAMBOO_DEBUGPRINT(0xf000);
611 for(i = 1; i < NUMCORESACTIVE; ++i) {
612 // send profile request msg to core i
613 send_msg_2(i, PROFILEOUTPUT, totalexetime, false);
614 } // for(i = 1; i < NUMCORESACTIVE; ++i)
615 // pour profiling data on startup core
618 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
620 BAMBOO_DEBUGPRINT(0xf001);
622 profilestatus[BAMBOO_NUM_OF_CORE] = 0;
623 // check the status of all cores
626 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
628 for(i = 0; i < NUMCORESACTIVE; ++i) {
630 BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
632 if(profilestatus[i] != 0) {
636 } // for(i = 0; i < NUMCORESACTIVE; ++i)
639 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
641 BAMBOO_DEBUGPRINT(0xf000);
646 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
652 // gc_profile mode, ourput gc prfiling data
655 gc_outputProfileData();
656 #endif // #ifdef GC_PROFILE
657 #endif // #ifdef MULTICORE_GC
659 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
660 terminate(); // All done.
661 } // if(!waitconfirm)
663 // still some objects on the fly on the network
664 // reset the waitconfirm and numconfirm
666 BAMBOO_DEBUGPRINT(0xee07);
670 } // if(0 == sumsendobj)
672 // not all cores are stall, keep on waiting
674 BAMBOO_DEBUGPRINT(0xee08);
679 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
681 BAMBOO_DEBUGPRINT(0xf000);
683 } // if((!waitconfirm) ||
686 // main function for each core
687 inline void run(void * arg) {
691 bool sendStall = false;
693 bool tocontinue = false;
695 corenum = BAMBOO_GET_NUM_OF_CORE();
697 BAMBOO_DEBUGPRINT(0xeeee);
698 BAMBOO_DEBUGPRINT_REG(corenum);
699 BAMBOO_DEBUGPRINT(STARTUPCORE);
702 // initialize runtime data structures
705 // other architecture related initialization
709 initializeexithandler();
711 // main process of the execution module
712 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
713 // non-executing cores, only processing communications
716 BAMBOO_DEBUGPRINT(0xee01);
717 BAMBOO_DEBUGPRINT_REG(taskInfoIndex);
718 BAMBOO_DEBUGPRINT_REG(taskInfoOverflow);
719 profileTaskStart("msg handling");
723 //isInterrupt = false;
727 /* Create queue of active tasks */
729 genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
730 (int (*)(void *,void *)) &comparetpd);
732 /* Process task information */
735 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
736 /* Create startup object */
737 createstartupobject(argc, argv);
741 BAMBOO_DEBUGPRINT(0xee00);
746 // check if need to do GC
750 // check if there are new active tasks can be executed
757 while(receiveObject() != -1) {
762 BAMBOO_DEBUGPRINT(0xee01);
765 // check if there are some pending objects,
766 // if yes, enqueue them and executetasks again
767 tocontinue = checkObjQueue();
771 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
774 BAMBOO_DEBUGPRINT(0xee03);
782 BAMBOO_DEBUGPRINT(0xee09);
788 // wait for some time
791 BAMBOO_DEBUGPRINT(0xee0a);
797 // send StallMsg to startup core
799 BAMBOO_DEBUGPRINT(0xee0b);
802 send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
803 self_numsendobjs, self_numreceiveobjs, false);
815 BAMBOO_DEBUGPRINT(0xee0c);
818 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
821 } // if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)
825 struct ___createstartupobject____I_locals {
828 struct ___StartupObject___ * ___startupobject___;
829 struct ArrayObject * ___stringarray___;
830 }; // struct ___createstartupobject____I_locals
832 void createstartupobject(int argc,
836 /* Allocate startup object */
838 struct ___createstartupobject____I_locals ___locals___={2, NULL, NULL, NULL};
839 struct ___StartupObject___ *startupobject=
840 (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
841 ___locals___.___startupobject___ = startupobject;
842 struct ArrayObject * stringarray=
843 allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
844 ___locals___.___stringarray___ = stringarray;
846 struct ___StartupObject___ *startupobject=
847 (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
848 struct ArrayObject * stringarray=
849 allocate_newarray(STRINGARRAYTYPE, argc-1);
851 /* Build array of strings */
852 startupobject->___parameters___=stringarray;
853 for(i=1; i<argc; i++) {
854 int length=strlen(argv[i]);
856 struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
858 struct ___String___ *newstring=NewString(argv[i],length);
860 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
864 startupobject->version = 0;
865 startupobject->lock = NULL;
867 /* Set initialized flag for startup object */
868 flagorandinit(startupobject,1,0xFFFFFFFF);
869 enqueueObject(startupobject, NULL, 0);
871 BAMBOO_CACHE_FLUSH_ALL();
875 int hashCodetpd(struct taskparamdescriptor *ftd) {
876 int hash=(int)ftd->task;
878 for(i=0; i<ftd->numParameters; i++) {
879 hash^=(int)ftd->parameterArray[i];
884 int comparetpd(struct taskparamdescriptor *ftd1,
885 struct taskparamdescriptor *ftd2) {
887 if (ftd1->task!=ftd2->task)
889 for(i=0; i<ftd1->numParameters; i++)
890 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
895 /* This function sets a tag. */
897 void tagset(void *ptr,
898 struct ___Object___ * obj,
899 struct ___TagDescriptor___ * tagd) {
901 void tagset(struct ___Object___ * obj,
902 struct ___TagDescriptor___ * tagd) {
904 struct ArrayObject * ao=NULL;
905 struct ___Object___ * tagptr=obj->___tags___;
907 obj->___tags___=(struct ___Object___ *)tagd;
909 /* Have to check if it is already set */
910 if (tagptr->type==TAGTYPE) {
911 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
916 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
917 struct ArrayObject * ao=
918 allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
919 obj=(struct ___Object___ *)ptrarray[2];
920 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
921 td=(struct ___TagDescriptor___ *) obj->___tags___;
923 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
926 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
927 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
928 obj->___tags___=(struct ___Object___ *) ao;
929 ao->___cachedCode___=2;
933 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
934 for(i=0; i<ao->___cachedCode___; i++) {
935 struct ___TagDescriptor___ * td=
936 ARRAYGET(ao, struct ___TagDescriptor___*, i);
941 if (ao->___cachedCode___<ao->___length___) {
942 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
943 ao->___cachedCode___++;
946 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
947 struct ArrayObject * aonew=
948 allocate_newarray(&ptrarray,TAGARRAYTYPE,
949 TAGARRAYINTERVAL+ao->___length___);
950 obj=(struct ___Object___ *)ptrarray[2];
951 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
952 ao=(struct ArrayObject *)obj->___tags___;
954 struct ArrayObject * aonew=
955 allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
958 aonew->___cachedCode___=ao->___length___+1;
959 for(i=0; i<ao->___length___; i++) {
960 ARRAYSET(aonew, struct ___TagDescriptor___*, i,
961 ARRAYGET(ao, struct ___TagDescriptor___*, i));
963 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
969 struct ___Object___ * tagset=tagd->flagptr;
972 } else if (tagset->type!=OBJECTARRAYTYPE) {
974 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
975 struct ArrayObject * ao=
976 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
977 obj=(struct ___Object___ *)ptrarray[2];
978 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
980 struct ArrayObject * ao=
981 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
983 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
984 ARRAYSET(ao, struct ___Object___ *, 1, obj);
985 ao->___cachedCode___=2;
986 tagd->flagptr=(struct ___Object___ *)ao;
988 struct ArrayObject *ao=(struct ArrayObject *) tagset;
989 if (ao->___cachedCode___<ao->___length___) {
990 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
994 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
995 struct ArrayObject * aonew=
996 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
997 OBJECTARRAYINTERVAL+ao->___length___);
998 obj=(struct ___Object___ *)ptrarray[2];
999 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
1000 ao=(struct ArrayObject *)tagd->flagptr;
1002 struct ArrayObject * aonew=
1003 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
1005 aonew->___cachedCode___=ao->___cachedCode___+1;
1006 for(i=0; i<ao->___length___; i++) {
1007 ARRAYSET(aonew, struct ___Object___*, i,
1008 ARRAYGET(ao, struct ___Object___*, i));
1010 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
1011 tagd->flagptr=(struct ___Object___ *) aonew;
1017 /* This function clears a tag. */
1019 void tagclear(void *ptr,
1020 struct ___Object___ * obj,
1021 struct ___TagDescriptor___ * tagd) {
1023 void tagclear(struct ___Object___ * obj,
1024 struct ___TagDescriptor___ * tagd) {
1026 /* We'll assume that tag is alway there.
1027 Need to statically check for this of course. */
1028 struct ___Object___ * tagptr=obj->___tags___;
1030 if (tagptr->type==TAGTYPE) {
1031 if ((struct ___TagDescriptor___ *)tagptr==tagd)
1032 obj->___tags___=NULL;
1034 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
1036 for(i=0; i<ao->___cachedCode___; i++) {
1037 struct ___TagDescriptor___ * td=
1038 ARRAYGET(ao, struct ___TagDescriptor___ *, i);
1040 ao->___cachedCode___--;
1041 if (i<ao->___cachedCode___)
1042 ARRAYSET(ao, struct ___TagDescriptor___ *, i,
1043 ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
1044 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
1045 if (ao->___cachedCode___==0)
1046 obj->___tags___=NULL;
1053 struct ___Object___ *tagset=tagd->flagptr;
1054 if (tagset->type!=OBJECTARRAYTYPE) {
1058 struct ArrayObject *ao=(struct ArrayObject *) tagset;
1060 for(i=0; i<ao->___cachedCode___; i++) {
1061 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
1063 ao->___cachedCode___--;
1064 if (i<ao->___cachedCode___)
1065 ARRAYSET(ao, struct ___Object___ *, i,
1066 ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
1067 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
1068 if (ao->___cachedCode___==0)
1079 /* This function allocates a new tag. */
1081 struct ___TagDescriptor___ * allocate_tag(void *ptr,
1083 struct ___TagDescriptor___ * v=
1084 (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
1085 classsize[TAGTYPE]);
1087 struct ___TagDescriptor___ * allocate_tag(int index) {
1088 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
1097 /* This function updates the flag for object ptr. It or's the flag
1098 with the or mask and and's it with the andmask. */
1100 void flagbody(struct ___Object___ *ptr,
1102 struct parameterwrapper ** queues,
1106 int flagcomp(const int *val1, const int *val2) {
1107 return (*val1)-(*val2);
1110 void flagorand(void * ptr,
1113 struct parameterwrapper ** queues,
1116 int oldflag=((int *)ptr)[1];
1117 int flag=ormask|oldflag;
1119 flagbody(ptr, flag, queues, length, false);
1123 bool intflagorand(void * ptr,
1127 int oldflag=((int *)ptr)[1];
1128 int flag=ormask|oldflag;
1130 if (flag==oldflag) /* Don't do anything */
1133 flagbody(ptr, flag, NULL, 0, false);
1139 void flagorandinit(void * ptr,
1142 int oldflag=((int *)ptr)[1];
1143 int flag=ormask|oldflag;
1145 flagbody(ptr,flag,NULL,0,true);
1148 void flagbody(struct ___Object___ *ptr,
1150 struct parameterwrapper ** vqueues,
1153 struct parameterwrapper * flagptr = NULL;
1155 struct parameterwrapper ** queues = vqueues;
1156 int length = vlength;
1158 int UNUSED, UNUSED2;
1159 int * enterflags = NULL;
1160 if((!isnew) && (queues == NULL)) {
1161 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
1162 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1163 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1170 /*Remove object from all queues */
1171 for(i = 0; i < length; ++i) {
1172 flagptr = queues[i];
1173 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
1174 (int *) &enterflags, &UNUSED, &UNUSED2);
1175 ObjectHashremove(flagptr->objectset, (int)ptr);
1176 if (enterflags!=NULL)
1177 RUNFREE(enterflags);
1181 void enqueueObject(void * vptr,
1182 struct parameterwrapper ** vqueues,
1184 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1187 //struct QueueItem *tmpptr;
1188 struct parameterwrapper * parameter=NULL;
1191 struct parameterwrapper * prevptr=NULL;
1192 struct ___Object___ *tagptr=NULL;
1193 struct parameterwrapper ** queues = vqueues;
1194 int length = vlength;
1195 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1198 if(queues == NULL) {
1199 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1200 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1202 tagptr=ptr->___tags___;
1204 /* Outer loop iterates through all parameter queues an object of
1205 this type could be in. */
1206 for(j = 0; j < length; ++j) {
1207 parameter = queues[j];
1209 if (parameter->numbertags>0) {
1211 goto nextloop; //that means the object has no tag
1212 //but that param needs tag
1213 else if(tagptr->type==TAGTYPE) { //one tag
1214 //struct ___TagDescriptor___ * tag=
1215 //(struct ___TagDescriptor___*) tagptr;
1216 for(i=0; i<parameter->numbertags; i++) {
1217 //slotid is parameter->tagarray[2*i];
1218 int tagid=parameter->tagarray[2*i+1];
1219 if (tagid!=tagptr->flag)
1220 goto nextloop; /*We don't have this tag */
1222 } else { //multiple tags
1223 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1224 for(i=0; i<parameter->numbertags; i++) {
1225 //slotid is parameter->tagarray[2*i];
1226 int tagid=parameter->tagarray[2*i+1];
1228 for(j=0; j<ao->___cachedCode___; j++) {
1229 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1240 for(i=0; i<parameter->numberofterms; i++) {
1241 int andmask=parameter->intarray[i*2];
1242 int checkmask=parameter->intarray[i*2+1];
1243 if ((ptr->flag&andmask)==checkmask) {
1244 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
1255 void enqueueObject_I(void * vptr,
1256 struct parameterwrapper ** vqueues,
1258 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1261 //struct QueueItem *tmpptr;
1262 struct parameterwrapper * parameter=NULL;
1265 struct parameterwrapper * prevptr=NULL;
1266 struct ___Object___ *tagptr=NULL;
1267 struct parameterwrapper ** queues = vqueues;
1268 int length = vlength;
1269 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1272 if(queues == NULL) {
1273 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1274 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1276 tagptr=ptr->___tags___;
1278 /* Outer loop iterates through all parameter queues an object of
1279 this type could be in. */
1280 for(j = 0; j < length; ++j) {
1281 parameter = queues[j];
1283 if (parameter->numbertags>0) {
1285 goto nextloop; //that means the object has no tag
1286 //but that param needs tag
1287 else if(tagptr->type==TAGTYPE) { //one tag
1288 //struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
1289 for(i=0; i<parameter->numbertags; i++) {
1290 //slotid is parameter->tagarray[2*i];
1291 int tagid=parameter->tagarray[2*i+1];
1292 if (tagid!=tagptr->flag)
1293 goto nextloop; /*We don't have this tag */
1295 } else { //multiple tags
1296 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1297 for(i=0; i<parameter->numbertags; i++) {
1298 //slotid is parameter->tagarray[2*i];
1299 int tagid=parameter->tagarray[2*i+1];
1301 for(j=0; j<ao->___cachedCode___; j++) {
1302 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1313 for(i=0; i<parameter->numberofterms; i++) {
1314 int andmask=parameter->intarray[i*2];
1315 int checkmask=parameter->intarray[i*2+1];
1316 if ((ptr->flag&andmask)==checkmask) {
1317 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1329 int * getAliasLock(void ** ptrs,
1331 struct RuntimeHash * tbl) {
1333 return (int*)(RUNMALLOC(sizeof(int)));
1338 bool redirect = false;
1339 int redirectlock = 0;
1340 for(; i < length; i++) {
1341 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1344 if(ptr->lock == NULL) {
1347 lock = (int)(ptr->lock);
1350 if(lock != redirectlock) {
1351 RuntimeHashadd(tbl, lock, redirectlock);
1354 if(RuntimeHashcontainskey(tbl, lock)) {
1355 // already redirected
1357 RuntimeHashget(tbl, lock, &redirectlock);
1358 for(; j < locklen; j++) {
1359 if(locks[j] != redirectlock) {
1360 RuntimeHashadd(tbl, locks[j], redirectlock);
1365 for(j = 0; j < locklen; j++) {
1366 if(locks[j] == lock) {
1369 } else if(locks[j] > lock) {
1376 locks[h] = locks[h-1];
1385 return (int *)redirectlock;
1387 return (int *)(locks[0]);
1392 void addAliasLock(void * ptr,
1394 struct ___Object___ * obj = (struct ___Object___ *)ptr;
1395 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1396 // originally no alias lock associated or have a different alias lock
1397 // flush it as the new one
1398 obj->lock = (int *)lock;
1403 inline void setTaskExitIndex(int index) {
1404 taskInfoArray[taskInfoIndex]->exitIndex = index;
1407 inline void addNewObjInfo(void * nobj) {
1408 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1409 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1411 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1416 // Only allocate local mem chunks to each core.
1417 // If a core has used up its local shared memory, start gc.
1418 void * localmalloc_I(int coren,
1422 int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
1425 int tofindb = gc_core2block[2*gccorenum+i]+(NUMCORES4GC*2)*j;
1426 int totest = tofindb;
1427 int bound = BAMBOO_SMEM_SIZE_L;
1431 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1432 int nsize = bamboo_smemtbl[totest];
1433 bool islocal = true;
1435 bool tocheck = true;
1436 // have some space in the block
1437 if(totest == tofindb) {
1438 // the first partition
1439 size = bound - nsize;
1440 } else if(nsize == 0) {
1441 // an empty partition, can be appended
1444 // not an empty partition, can not be appended
1445 // the last continuous block is not big enough, go to check the next
1449 } // if(totest == tofindb) else if(nsize == 0) else ...
1452 // have enough space in the block, malloc
1456 // no enough space yet, try to append next continuous block
1458 } // if(size > isize) else ...
1460 } // if(nsize < bound)
1462 // no space in the block, go to check the next block
1468 tofindb = totest = gc_core2block[2*gccorenum+i]+(NUMCORES4GC*2)*j;
1471 } // if(islocal) else ...
1472 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1473 // no more local mem, do not find suitable block
1476 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1479 if(foundsmem == 1) {
1480 // find suitable block
1481 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1482 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1483 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1485 // set bamboo_smemtbl
1486 for(i = tofindb; i <= totest; i++) {
1487 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1489 } else if(foundsmem == 2) {
1490 // no suitable block
1495 } // void * localmalloc_I(int, int, int *)
1498 // Allocate the local shared memory to each core with the highest priority,
1499 // if a core has used up its local shared memory, try to allocate the
1500 // shared memory that belong to its neighbours, if also failed, start gc.
1501 void * fixedmalloc_I(int coren,
1508 int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
1509 int coords_x = bamboo_cpu2coords[gccorenum*2];
1510 int coords_y = bamboo_cpu2coords[gccorenum*2+1];
1512 int tofindb = gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1513 int totest = tofindb;
1514 int bound = BAMBOO_SMEM_SIZE_L;
1518 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1519 int nsize = bamboo_smemtbl[totest];
1520 bool islocal = true;
1522 bool tocheck = true;
1523 // have some space in the block
1524 if(totest == tofindb) {
1525 // the first partition
1526 size = bound - nsize;
1527 } else if(nsize == 0) {
1528 // an empty partition, can be appended
1531 // not an empty partition, can not be appended
1532 // the last continuous block is not big enough, go to check the next
1536 } // if(totest == tofindb) else if(nsize == 0) else ...
1539 // have enough space in the block, malloc
1543 // no enough space yet, try to append next continuous block
1544 // TODO may consider to go to next local block?
1546 } // if(size > isize) else ...
1548 } // if(nsize < bound)
1550 // no space in the block, go to check the next block
1557 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1560 } // if(islocal) else ...
1561 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1562 // no more local mem, do not find suitable block on local mem
1563 // try to malloc shared memory assigned to the neighbour cores
1566 if(k >= NUM_CORES2TEST) {
1567 // no more memory available on either coren or its neighbour cores
1569 goto memsearchresult;
1571 } while(core2test[gccorenum][k] == -1);
1574 tofindb=totest=gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1575 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1579 if(foundsmem == 1) {
1580 // find suitable block
1581 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1582 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1583 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1585 // set bamboo_smemtbl
1586 for(i = tofindb; i <= totest; i++) {
1587 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1589 } else if(foundsmem == 2) {
1590 // no suitable block
1595 } // void * fixedmalloc_I(int, int, int *)
1596 #endif // #ifdef SMEMF
1599 // Allocate the local shared memory to each core with the highest priority,
1600 // if a core has used up its local shared memory, try to allocate the
1601 // shared memory that belong to its neighbours first, if failed, check
1602 // current memory allocation rate, if it has already reached the threshold,
1603 // start gc, otherwise, allocate the shared memory globally. If all the
1604 // shared memory has been used up, start gc.
1605 void * mixedmalloc_I(int coren,
1612 int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
1614 int tofindb = gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1615 int totest = tofindb;
1616 int bound = BAMBOO_SMEM_SIZE_L;
1620 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1621 int nsize = bamboo_smemtbl[totest];
1622 bool islocal = true;
1624 bool tocheck = true;
1625 // have some space in the block
1626 if(totest == tofindb) {
1627 // the first partition
1628 size = bound - nsize;
1629 } else if(nsize == 0) {
1630 // an empty partition, can be appended
1633 // not an empty partition, can not be appended
1634 // the last continuous block is not big enough, go to check the next
1638 } // if(totest == tofindb) else if(nsize == 0) else ...
1641 // have enough space in the block, malloc
1645 // no enough space yet, try to append next continuous block
1646 // TODO may consider to go to next local block?
1648 } // if(size > isize) else ...
1650 } // if(nsize < bound)
1652 // no space in the block, go to check the next block
1659 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1662 } // if(islocal) else ...
1663 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1664 // no more local mem, do not find suitable block on local mem
1665 // try to malloc shared memory assigned to the neighbour cores
1668 if(k >= NUM_CORES2TEST) {
1669 if(gcmem_mixed_usedmem >= gcmem_mixed_threshold) {
1670 // no more memory available on either coren or its neighbour cores
1672 goto memmixedsearchresult;
1674 // try allocate globally
1675 mem = globalmalloc_I(coren, isize, allocsize);
1679 } while(core2test[gccorenum][k] == -1);
1683 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1684 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1687 memmixedsearchresult:
1688 if(foundsmem == 1) {
1689 // find suitable block
1690 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1691 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1692 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1694 // set bamboo_smemtbl
1695 for(i = tofindb; i <= totest; i++) {
1696 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1698 gcmem_mixed_usedmem += size;
1699 if(tofindb == bamboo_free_block) {
1700 bamboo_free_block = totest+1;
1702 } else if(foundsmem == 2) {
1703 // no suitable block
1708 } // void * mixedmalloc_I(int, int, int *)
1709 #endif // #ifdef SMEMM
1711 // Allocate all the memory chunks globally, do not consider the host cores
1712 // When all the shared memory are used up, start gc.
1713 void * globalmalloc_I(int coren,
1717 int tofindb = bamboo_free_block; //0;
1718 int totest = tofindb;
1719 int bound = BAMBOO_SMEM_SIZE_L;
1722 if(tofindb > gcnumblock-1-bamboo_reserved_smem) {
1723 // Out of shared memory
1728 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1729 int nsize = bamboo_smemtbl[totest];
1730 bool isnext = false;
1732 bool tocheck = true;
1733 // have some space in the block
1734 if(totest == tofindb) {
1735 // the first partition
1736 size = bound - nsize;
1737 } else if(nsize == 0) {
1738 // an empty partition, can be appended
1741 // not an empty partition, can not be appended
1742 // the last continuous block is not big enough, start another block
1745 } // if(totest == tofindb) else if(nsize == 0) else ...
1748 // have enough space in the block, malloc
1751 } // if(size > isize)
1755 } // if(nsize < bound) else ...
1757 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1758 // no more local mem, do not find suitable block
1761 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1763 // start another block
1768 if(foundsmem == 1) {
1769 // find suitable block
1770 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1771 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1772 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1774 // set bamboo_smemtbl
1775 for(int i = tofindb; i <= totest; i++) {
1776 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1778 if(tofindb == bamboo_free_block) {
1779 bamboo_free_block = totest+1;
1781 } else if(foundsmem == 2) {
1782 // no suitable block
1788 } // void * globalmalloc_I(int, int, int *)
1789 #endif // #ifdef MULTICORE_GC
1791 // malloc from the shared memory
1792 void * smemalloc_I(int coren,
1797 int isize = size+(BAMBOO_CACHE_LINE_SIZE);
1799 // go through the bamboo_smemtbl for suitable partitions
1800 switch(bamboo_smem_mode) {
1802 mem = localmalloc_I(coren, isize, allocsize);
1808 mem = fixedmalloc_I(coren, isize, allocsize);
1810 // not supported yet
1811 BAMBOO_EXIT(0xe001);
1818 mem = mixedmalloc_I(coren, isize, allocsize);
1820 // not supported yet
1821 BAMBOO_EXIT(0xe002);
1827 mem = globalmalloc_I(coren, isize, allocsize);
1839 /*if(!interruptInfoOverflow) {
1840 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
1841 interruptInfoArray[interruptInfoIndex] = intInfo;
1842 intInfo->startTime = BAMBOO_GET_EXE_TIME();
1843 intInfo->endTime = -1;
1846 int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size) : (BAMBOO_SMEM_SIZE);
1847 //mem = mspace_calloc(bamboo_free_msp, 1, toallocate);
1848 if(toallocate > bamboo_free_smem_size) {
1852 mem = (void *)bamboo_free_smemp;
1853 bamboo_free_smemp = ((void*)bamboo_free_smemp) + toallocate;
1854 bamboo_free_smem_size -= toallocate;
1855 //BAMBOO_MEMSET_WH(mem, '\0', toallocate);
1857 *allocsize = toallocate;
1859 /*if(!interruptInfoOverflow) {
1860 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
1861 interruptInfoIndex++;
1862 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
1863 interruptInfoOverflow = true;
1868 #endif // MULTICORE_GC
1869 // no enough shared global memory
1875 BAMBOO_DEBUGPRINT(0xa001);
1876 BAMBOO_EXIT(0xa001);
1880 } // void * smemalloc_I(int, int, int)
1882 INLINE int checkMsgLength_I(int size) {
1885 BAMBOO_DEBUGPRINT(0xcccc);
1888 int type = msgdata[msgdataindex];
1895 case GCSTARTMAPINFO:
1909 case GCSTARTCOMPACT:
1912 case GCFINISHMAPINFO:
1937 case REDIRECTGROUNT:
1939 case REDIRECTRELEASE:
1955 case GCFINISHCOMPACT:
1969 case TRANSOBJ: // nonfixed size
1975 msglength = msgdata[msgdataindex+1];
1984 BAMBOO_DEBUGPRINT_REG(type);
1985 BAMBOO_DEBUGPRINT_REG(size);
1986 BAMBOO_DEBUGPRINT_REG(msgdataindex);
1987 BAMBOO_DEBUGPRINT_REG(msgdatalast);
1988 BAMBOO_DEBUGPRINT_REG(msgdatafull);
1991 BAMBOO_DEBUGPRINT(msgdata[msgdataindex+i]);
1993 BAMBOO_EXIT(0xd005);
1999 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
2004 BAMBOO_DEBUGPRINT(0xffff);
2010 INLINE void processmsg_transobj_I() {
2012 struct transObjInfo * transObj=RUNMALLOC_I(sizeof(struct transObjInfo));
2016 BAMBOO_DEBUGPRINT(0xe880);
2019 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2021 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
2023 BAMBOO_EXIT(0xa002);
2025 // store the object and its corresponding queue info, enqueue it later
2026 transObj->objptr = (void *)msgdata[msgdataindex]; //[2]
2028 transObj->length = (msglength - 3) / 2;
2029 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
2030 for(k = 0; k < transObj->length; ++k) {
2031 transObj->queues[2*k] = msgdata[msgdataindex]; //[3+2*k];
2035 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
2038 transObj->queues[2*k+1] = msgdata[msgdataindex]; //[3+2*k+1];
2042 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
2046 // check if there is an existing duplicate item
2048 struct QueueItem * qitem = getHead(&objqueue);
2049 struct QueueItem * prev = NULL;
2050 while(qitem != NULL) {
2051 struct transObjInfo * tmpinfo =
2052 (struct transObjInfo *)(qitem->objectptr);
2053 if(tmpinfo->objptr == transObj->objptr) {
2054 // the same object, remove outdate one
2055 RUNFREE(tmpinfo->queues);
2057 removeItem(&objqueue, qitem);
2063 qitem = getHead(&objqueue);
2065 qitem = getNextQueueItem(prev);
2068 addNewItem_I(&objqueue, (void *)transObj);
2070 ++(self_numreceiveobjs);
2073 INLINE void processmsg_transtall_I() {
2074 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2075 // non startup core can not receive stall msg
2077 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
2079 BAMBOO_EXIT(0xa003);
2081 int num_core = msgdata[msgdataindex]; //[1]
2083 if(num_core < NUMCORESACTIVE) {
2086 BAMBOO_DEBUGPRINT(0xe881);
2089 corestatus[num_core] = 0;
2090 numsendobjs[num_core] = msgdata[msgdataindex]; //[2];
2092 numreceiveobjs[num_core] = msgdata[msgdataindex]; //[3];
2097 #ifndef MULTICORE_GC
2098 INLINE void processmsg_lockrequest_I() {
2099 // check to see if there is a lock exist for the required obj
2100 // msgdata[1] -> lock type
2101 int locktype = msgdata[msgdataindex]; //[1];
2103 int data2 = msgdata[msgdataindex]; // obj pointer
2105 int data3 = msgdata[msgdataindex]; // lock
2107 int data4 = msgdata[msgdataindex]; // request core
2109 // -1: redirected, 0: approved, 1: denied
2110 int deny=processlockrequest(locktype, data3, data2, data4, data4, true);
2112 // this lock request is redirected
2115 // send response msg
2116 // for 32 bit machine, the size is always 4 words, cache the msg first
2117 int tmp = deny==1 ? LOCKDENY : LOCKGROUNT;
2118 if(BAMBOO_CHECK_SEND_MODE()) {
2119 cache_msg_4(data4, tmp, locktype, data2, data3);
2121 send_msg_4(data4, tmp, locktype, data2, data3, true);
2126 INLINE void processmsg_lockgrount_I() {
2128 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2130 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
2132 BAMBOO_EXIT(0xa004);
2134 int data2 = msgdata[msgdataindex];
2136 int data3 = msgdata[msgdataindex];
2138 if((lockobj == data2) && (lock2require == data3)) {
2141 BAMBOO_DEBUGPRINT(0xe882);
2150 // conflicts on lockresults
2152 BAMBOO_DEBUGPRINT_REG(data2);
2154 BAMBOO_EXIT(0xa005);
2158 INLINE void processmsg_lockdeny_I() {
2160 int data2 = msgdata[msgdataindex];
2162 int data3 = msgdata[msgdataindex];
2164 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2166 BAMBOO_DEBUGPRINT_REG(data2);
2168 BAMBOO_EXIT(0xa006);
2170 if((lockobj == data2) && (lock2require == data3)) {
2173 BAMBOO_DEBUGPRINT(0xe883);
2182 // conflicts on lockresults
2184 BAMBOO_DEBUGPRINT_REG(data2);
2186 BAMBOO_EXIT(0xa007);
2190 INLINE void processmsg_lockrelease_I() {
2191 int data1 = msgdata[msgdataindex];
2193 int data2 = msgdata[msgdataindex];
2195 // receive lock release msg
2196 processlockrelease(data1, data2, 0, false);
2199 INLINE void processmsg_redirectlock_I() {
2200 // check to see if there is a lock exist for the required obj
2201 int data1 = msgdata[msgdataindex];
2202 MSG_INDEXINC_I(); //msgdata[1]; // lock type
2203 int data2 = msgdata[msgdataindex];
2204 MSG_INDEXINC_I(); //msgdata[2]; // obj pointer
2205 int data3 = msgdata[msgdataindex];
2206 MSG_INDEXINC_I(); //msgdata[3]; // redirect lock
2207 int data4 = msgdata[msgdataindex];
2208 MSG_INDEXINC_I(); //msgdata[4]; // root request core
2209 int data5 = msgdata[msgdataindex];
2210 MSG_INDEXINC_I(); //msgdata[5]; // request core
2211 int deny = processlockrequest(data1, data3, data2, data5, data4, true);
2213 // this lock request is redirected
2216 // send response msg
2217 // for 32 bit machine, the size is always 4 words, cache the msg first
2218 if(BAMBOO_CHECK_SEND_MODE()) {
2219 cache_msg_4(data4, deny==1 ? REDIRECTDENY : REDIRECTGROUNT,
2220 data1, data2, data3);
2222 send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
2223 data1, data2, data3, true);
2228 INLINE void processmsg_redirectgrount_I() {
2230 int data2 = msgdata[msgdataindex];
2232 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2234 BAMBOO_DEBUGPRINT_REG(data2);
2236 BAMBOO_EXIT(0xa00a);
2238 if(lockobj == data2) {
2241 BAMBOO_DEBUGPRINT(0xe891);
2244 int data3 = msgdata[msgdataindex];
2248 RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
2253 // conflicts on lockresults
2255 BAMBOO_DEBUGPRINT_REG(data2);
2257 BAMBOO_EXIT(0xa00b);
2261 INLINE void processmsg_redirectdeny_I() {
2263 int data2 = msgdata[msgdataindex];
2265 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2267 BAMBOO_DEBUGPRINT_REG(data2);
2269 BAMBOO_EXIT(0xa00c);
2271 if(lockobj == data2) {
2274 BAMBOO_DEBUGPRINT(0xe892);
2283 // conflicts on lockresults
2285 BAMBOO_DEBUGPRINT_REG(data2);
2287 BAMBOO_EXIT(0xa00d);
2291 INLINE void processmsg_redirectrelease_I() {
2292 int data1 = msgdata[msgdataindex];
2294 int data2 = msgdata[msgdataindex];
2296 int data3 = msgdata[msgdataindex];
2298 processlockrelease(data1, data2, data3, true);
2300 #endif // #ifndef MULTICORE_GC
2303 INLINE void processmsg_profileoutput_I() {
2304 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
2305 // startup core can not receive profile output finish msg
2306 BAMBOO_EXIT(0xa008);
2310 BAMBOO_DEBUGPRINT(0xe885);
2314 totalexetime = msgdata[msgdataindex]; //[1]
2316 outputProfileData();
2317 // cache the msg first
2318 if(BAMBOO_CHECK_SEND_MODE()) {
2319 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
2321 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE, true);
2325 INLINE void processmsg_profilefinish_I() {
2326 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2327 // non startup core can not receive profile output finish msg
2329 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex /*1*/]);
2331 BAMBOO_EXIT(0xa009);
2335 BAMBOO_DEBUGPRINT(0xe886);
2338 int data1 = msgdata[msgdataindex];
2340 profilestatus[data1] = 0;
2342 #endif // #ifdef PROFILE
2344 INLINE void processmsg_statusconfirm_I() {
2345 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2346 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2347 // wrong core to receive such msg
2348 BAMBOO_EXIT(0xa00e);
2350 // send response msg
2353 BAMBOO_DEBUGPRINT(0xe887);
2356 // cache the msg first
2357 if(BAMBOO_CHECK_SEND_MODE()) {
2358 cache_msg_5(STARTUPCORE, STATUSREPORT,
2359 busystatus ? 1 : 0, BAMBOO_NUM_OF_CORE,
2360 self_numsendobjs, self_numreceiveobjs);
2362 send_msg_5(STARTUPCORE, STATUSREPORT, busystatus?1:0,
2363 BAMBOO_NUM_OF_CORE, self_numsendobjs,
2364 self_numreceiveobjs, true);
2369 INLINE void processmsg_statusreport_I() {
2370 int data1 = msgdata[msgdataindex];
2372 int data2 = msgdata[msgdataindex];
2374 int data3 = msgdata[msgdataindex];
2376 int data4 = msgdata[msgdataindex];
2378 // receive a status confirm info
2379 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2380 // wrong core to receive such msg
2382 BAMBOO_DEBUGPRINT_REG(data2);
2384 BAMBOO_EXIT(0xa00f);
2388 BAMBOO_DEBUGPRINT(0xe888);
2394 corestatus[data2] = data1;
2395 numsendobjs[data2] = data3;
2396 numreceiveobjs[data2] = data4;
2400 INLINE void processmsg_terminate_I() {
2403 BAMBOO_DEBUGPRINT(0xe889);
2410 INLINE void processmsg_memrequest_I() {
2412 if(!interruptInfoOverflow) {
2413 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
2414 interruptInfoArray[interruptInfoIndex] = intInfo;
2415 intInfo->startTime = BAMBOO_GET_EXE_TIME();
2416 intInfo->endTime = -1;
2419 int data1 = msgdata[msgdataindex];
2421 int data2 = msgdata[msgdataindex];
2423 // receive a shared memory request msg
2424 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2425 // wrong core to receive such msg
2427 BAMBOO_DEBUGPRINT_REG(data2);
2429 BAMBOO_EXIT(0xa010);
2433 BAMBOO_DEBUGPRINT(0xe88a);
2440 // is currently doing gc, dump this msg
2441 if(INITPHASE == gcphase) {
2442 // if still in the initphase of gc, send a startinit msg again,
2443 // cache the msg first
2444 if(BAMBOO_CHECK_SEND_MODE()) {
2445 cache_msg_1(data2, GCSTARTINIT);
2447 send_msg_1(data2, GCSTARTINIT, true);
2452 mem = smemalloc_I(data2, data1, &allocsize);
2454 // send the start_va to request core, cache the msg first
2455 if(BAMBOO_CHECK_SEND_MODE()) {
2456 cache_msg_3(data2, MEMRESPONSE, mem, allocsize);
2458 send_msg_3(data2, MEMRESPONSE, mem, allocsize, true);
2460 } // if mem == NULL, the gcflag of the startup core has been set
2461 // and the gc should be started later, then a GCSTARTINIT msg
2462 // will be sent to the requesting core to notice it to start gc
2463 // and try malloc again
2469 if(!interruptInfoOverflow) {
2470 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
2471 interruptInfoIndex++;
2472 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
2473 interruptInfoOverflow = true;
2479 INLINE void processmsg_memresponse_I() {
2480 int data1 = msgdata[msgdataindex];
2482 int data2 = msgdata[msgdataindex];
2484 // receive a shared memory response msg
2487 BAMBOO_DEBUGPRINT(0xe88b);
2491 // if is currently doing gc, dump this msg
2495 bamboo_smem_size = 0;
2498 bamboo_smem_zero_top = 0;
2502 // fill header to store the size of this mem block
2503 BAMBOO_MEMSET_WH(data1, '\0', BAMBOO_CACHE_LINE_SIZE);
2504 //memset(data1, 0, BAMBOO_CACHE_LINE_SIZE);
2505 (*((int*)data1)) = data2;
2506 bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
2507 bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
2508 bamboo_smem_zero_top = bamboo_cur_msp;
2510 bamboo_smem_size = data2;
2511 bamboo_cur_msp =(void*)(data1);
2521 INLINE void processmsg_gcstartinit_I() {
2523 gcphase = INITPHASE;
2525 // is waiting for response of mem request
2526 // let it return NULL and start gc
2527 bamboo_smem_size = 0;
2528 bamboo_cur_msp = NULL;
2530 bamboo_smem_zero_top = NULL;
2534 INLINE void processmsg_gcstart_I() {
2537 BAMBOO_DEBUGPRINT(0xe88c);
2541 gcphase = MARKPHASE;
2544 INLINE void processmsg_gcstartcompact_I() {
2545 gcblock2fill = msgdata[msgdataindex];
2546 MSG_INDEXINC_I(); //msgdata[1];
2547 gcphase = COMPACTPHASE;
2550 INLINE void processmsg_gcstartmapinfo_I() {
2554 INLINE void processmsg_gcstartflush_I() {
2555 gcphase = FLUSHPHASE;
2558 INLINE void processmsg_gcfinishinit_I() {
2559 int data1 = msgdata[msgdataindex];
2561 // received a init phase finish msg
2562 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2563 // non startup core can not receive this msg
2565 BAMBOO_DEBUGPRINT_REG(data1);
2567 BAMBOO_EXIT(0xb001);
2570 BAMBOO_DEBUGPRINT(0xe88c);
2571 BAMBOO_DEBUGPRINT_REG(data1);
2573 // All cores should do init GC
2574 if(data1 < NUMCORESACTIVE) {
2575 gccorestatus[data1] = 0;
2579 INLINE void processmsg_gcfinishmark_I() {
2580 int data1 = msgdata[msgdataindex];
2582 int data2 = msgdata[msgdataindex];
2584 int data3 = msgdata[msgdataindex];
2586 // received a mark phase finish msg
2587 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2588 // non startup core can not receive this msg
2590 BAMBOO_DEBUGPRINT_REG(data1);
2592 BAMBOO_EXIT(0xb002);
2594 // all cores should do mark
2595 if(data1 < NUMCORESACTIVE) {
2596 gccorestatus[data1] = 0;
2597 int entry_index = 0;
2600 entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
2603 entry_index = gcnumsrobjs_index;
2605 gcnumsendobjs[entry_index][data1] = data2;
2606 gcnumreceiveobjs[entry_index][data1] = data3;
2610 INLINE void processmsg_gcfinishcompact_I() {
2611 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2612 // non startup core can not receive this msg
2615 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
2617 BAMBOO_EXIT(0xb003);
2619 int cnum = msgdata[msgdataindex];
2620 MSG_INDEXINC_I(); //msgdata[1];
2621 int filledblocks = msgdata[msgdataindex];
2622 MSG_INDEXINC_I(); //msgdata[2];
2623 int heaptop = msgdata[msgdataindex];
2624 MSG_INDEXINC_I(); //msgdata[3];
2625 int data4 = msgdata[msgdataindex];
2626 MSG_INDEXINC_I(); //msgdata[4];
2627 // only gc cores need to do compact
2628 if(cnum < NUMCORES4GC) {
2629 if(COMPACTPHASE == gcphase) {
2630 gcfilledblocks[cnum] = filledblocks;
2631 gcloads[cnum] = heaptop;
2638 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
2639 // cache the msg first
2640 if(BAMBOO_CHECK_SEND_MODE()) {
2641 cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
2643 send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove, true);
2647 gccorestatus[cnum] = 0;
2649 } // if(cnum < NUMCORES4GC)
2652 INLINE void processmsg_gcfinishmapinfo_I() {
2653 int data1 = msgdata[msgdataindex];
2655 // received a map phase finish msg
2656 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2657 // non startup core can not receive this msg
2660 BAMBOO_DEBUGPRINT_REG(data1);
2662 BAMBOO_EXIT(0xb004);
2664 // all cores should do flush
2665 if(data1 < NUMCORES4GC) {
2666 gccorestatus[data1] = 0;
2671 INLINE void processmsg_gcfinishflush_I() {
2672 int data1 = msgdata[msgdataindex];
2674 // received a flush phase finish msg
2675 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2676 // non startup core can not receive this msg
2679 BAMBOO_DEBUGPRINT_REG(data1);
2681 BAMBOO_EXIT(0xb005);
2683 // all cores should do flush
2684 if(data1 < NUMCORESACTIVE) {
2685 gccorestatus[data1] = 0;
2689 INLINE void processmsg_gcmarkconfirm_I() {
2690 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2691 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2692 // wrong core to receive such msg
2693 BAMBOO_EXIT(0xb006);
2695 // send response msg, cahce the msg first
2696 if(BAMBOO_CHECK_SEND_MODE()) {
2697 cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2698 gcbusystatus, gcself_numsendobjs,
2699 gcself_numreceiveobjs);
2701 send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2702 gcbusystatus, gcself_numsendobjs,
2703 gcself_numreceiveobjs, true);
2708 INLINE void processmsg_gcmarkreport_I() {
2709 int data1 = msgdata[msgdataindex];
2711 int data2 = msgdata[msgdataindex];
2713 int data3 = msgdata[msgdataindex];
2715 int data4 = msgdata[msgdataindex];
2717 // received a marked phase finish confirm response msg
2718 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2719 // wrong core to receive such msg
2721 BAMBOO_DEBUGPRINT_REG(data2);
2723 BAMBOO_EXIT(0xb007);
2725 int entry_index = 0;
2729 entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
2731 // can never reach here
2733 entry_index = gcnumsrobjs_index;
2735 gccorestatus[data1] = data2;
2736 gcnumsendobjs[entry_index][data1] = data3;
2737 gcnumreceiveobjs[entry_index][data1] = data4;
2741 INLINE void processmsg_gcmarkedobj_I() {
2742 int data1 = msgdata[msgdataindex];
2744 // received a markedObj msg
2745 if(((int *)data1)[6] == INIT) {
2746 // this is the first time that this object is discovered,
2747 // set the flag as DISCOVERED
2748 ((int *)data1)[6] = DISCOVERED;
2749 gc_enqueue_I(data1);
2751 // set the remote flag
2752 ((int *)data1)[6] |= REMOTEM;
2753 gcself_numreceiveobjs++;
2754 gcbusystatus = true;
2757 INLINE void processmsg_gcmovestart_I() {
2759 gcdstcore = msgdata[msgdataindex];
2760 MSG_INDEXINC_I(); //msgdata[1];
2761 gcmovestartaddr = msgdata[msgdataindex];
2762 MSG_INDEXINC_I(); //msgdata[2];
2763 gcblock2fill = msgdata[msgdataindex];
2764 MSG_INDEXINC_I(); //msgdata[3];
2767 INLINE void processmsg_gcmaprequest_I() {
2769 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2771 void * dstptr = NULL;
2772 int data1 = msgdata[msgdataindex];
2775 // TODO unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2777 #ifdef LOCALHASHTBL_TEST
2778 RuntimeHashget(gcpointertbl, data1, &dstptr);
2780 dstptr = mgchashSearch(gcpointertbl, data1);
2782 //MGCHashget(gcpointertbl, data1, &dstptr);
2784 // TODO flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2786 int data2 = msgdata[msgdataindex];
2789 // TODO unsigned long long ttimei = BAMBOO_GET_EXE_TIME();
2791 if(NULL == dstptr) {
2792 // no such pointer in this core, something is wrong
2794 BAMBOO_DEBUGPRINT_REG(data1);
2795 BAMBOO_DEBUGPRINT_REG(data2);
2797 BAMBOO_EXIT(0xb009);
2798 //assume that the object was not moved, use the original address
2799 /*if(isMsgSending) {
2800 cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2802 send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2805 // send back the mapping info, cache the msg first
2806 if(BAMBOO_CHECK_SEND_MODE()) {
2807 cache_msg_3(data2, GCMAPINFO, data1, (int)dstptr);
2809 send_msg_3(data2, GCMAPINFO, data1, (int)dstptr, true);
2813 // TODO flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimei;
2814 //num_mapinforequest_i++;
2818 INLINE void processmsg_gcmapinfo_I() {
2820 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2822 int data1 = msgdata[msgdataindex];
2824 gcmappedobj = msgdata[msgdataindex]; // [2]
2826 #ifdef LOCALHASHTBL_TEST
2827 RuntimeHashadd_I(gcpointertbl, data1, gcmappedobj);
2829 mgchashInsert_I(gcpointertbl, data1, gcmappedobj);
2831 //MGCHashadd_I(gcpointertbl, data1, gcmappedobj);
2832 if(data1 == gcobj2map) {
2836 //flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2840 INLINE void processmsg_gcmaptbl_I() {
2841 int data1 = msgdata[msgdataindex];
2843 int data2 = msgdata[msgdataindex];
2845 gcrpointertbls[data2] = (mgcsharedhashtbl_t *)data1; //(struct GCSharedHash *)data1;
2848 INLINE void processmsg_gclobjinfo_I() {
2851 int data1 = msgdata[msgdataindex];
2853 int data2 = msgdata[msgdataindex];
2855 if(BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1) {
2857 BAMBOO_DEBUGPRINT_REG(data2);
2859 BAMBOO_EXIT(0xb00b);
2861 // store the mark result info
2863 gcloads[cnum] = msgdata[msgdataindex];
2864 MSG_INDEXINC_I(); // msgdata[3];
2865 int data4 = msgdata[msgdataindex];
2867 if(gcheaptop < data4) {
2870 // large obj info here
2871 for(int k = 5; k < data1; ) {
2872 int lobj = msgdata[msgdataindex];
2873 MSG_INDEXINC_I(); //msgdata[k++];
2874 int length = msgdata[msgdataindex];
2875 MSG_INDEXINC_I(); //msgdata[k++];
2876 gc_lobjenqueue_I(lobj, length, cnum);
2878 } // for(int k = 5; k < msgdata[1];)
2881 INLINE void processmsg_gclobjmapping_I() {
2882 int data1 = msgdata[msgdataindex];
2884 int data2 = msgdata[msgdataindex];
2886 #ifdef LOCALHASHTBL_TEST
2887 RuntimeHashadd_I(gcpointertbl, data1, data2);
2889 mgchashInsert_I(gcpointertbl, data1, data2);
2891 //MGCHashadd_I(gcpointertbl, data1, data2);
2892 mgcsharedhashInsert_I(gcsharedptbl, data1, data2);
2896 INLINE void processmsg_gcprofiles_I() {
2897 int data1 = msgdata[msgdataindex];
2899 int data2 = msgdata[msgdataindex];
2901 int data3 = msgdata[msgdataindex];
2903 gc_num_obj += data1;
2904 gc_num_liveobj += data2;
2905 gc_num_forwardobj += data3;
2909 #endif // #ifdef MULTICORE_GC
2911 // receive object transferred from other cores
2912 // or the terminate message from other cores
2913 // Should be invoked in critical sections!!
2914 // NOTICE: following format is for threadsimulate version only
2915 // RAW version please see previous description
2916 // format: type + object
2917 // type: -1--stall msg
2919 // return value: 0--received an object
2920 // 1--received nothing
2921 // 2--received a Stall Msg
2922 // 3--received a lock Msg
2923 // RAW version: -1 -- received nothing
2924 // otherwise -- received msg type
2925 int receiveObject(int send_port_pending) {
2927 // get the incoming msgs
2928 if(receiveMsg(send_port_pending) == -1) {
2932 // processing received msgs
2934 MSG_REMAINSIZE_I(&size);
2935 if((size == 0) || (checkMsgLength_I(size) == -1)) {
2937 // have new coming msg
2938 if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
2945 if(msglength <= size) {
2946 // have some whole msg
2947 //if(msgdataindex == msglength) {
2948 // received a whole msg
2950 type = msgdata[msgdataindex]; //[0]
2952 msgdatafull = false;
2954 //tprintf("msg type: %x\n", type);
2957 // receive a object transfer msg
2958 processmsg_transobj_I();
2963 // receive a stall msg
2964 processmsg_transtall_I();
2968 // GC version have no lock msgs
2969 #ifndef MULTICORE_GC
2971 // receive lock request msg, handle it right now
2972 processmsg_lockrequest_I();
2974 } // case LOCKREQUEST
2977 // receive lock grount msg
2978 processmsg_lockgrount_I();
2980 } // case LOCKGROUNT
2983 // receive lock deny msg
2984 processmsg_lockdeny_I();
2989 processmsg_lockrelease_I();
2991 } // case LOCKRELEASE
2992 #endif // #ifndef MULTICORE_GC
2995 case PROFILEOUTPUT: {
2996 // receive an output profile data request msg
2997 processmsg_profileoutput_I();
2999 } // case PROFILEOUTPUT
3001 case PROFILEFINISH: {
3002 // receive a profile output finish msg
3003 processmsg_profilefinish_I();
3005 } // case PROFILEFINISH
3006 #endif // #ifdef PROFILE
3008 // GC version has no lock msgs
3009 #ifndef MULTICORE_GC
3010 case REDIRECTLOCK: {
3011 // receive a redirect lock request msg, handle it right now
3012 processmsg_redirectlock_I();
3014 } // case REDIRECTLOCK
3016 case REDIRECTGROUNT: {
3017 // receive a lock grant msg with redirect info
3018 processmsg_redirectgrount_I();
3020 } // case REDIRECTGROUNT
3022 case REDIRECTDENY: {
3023 // receive a lock deny msg with redirect info
3024 processmsg_redirectdeny_I();
3026 } // case REDIRECTDENY
3028 case REDIRECTRELEASE: {
3029 // receive a lock release msg with redirect info
3030 processmsg_redirectrelease_I();
3032 } // case REDIRECTRELEASE
3033 #endif // #ifndef MULTICORE_GC
3035 case STATUSCONFIRM: {
3036 // receive a status confirm info
3037 processmsg_statusconfirm_I();
3039 } // case STATUSCONFIRM
3041 case STATUSREPORT: {
3042 processmsg_statusreport_I();
3044 } // case STATUSREPORT
3047 // receive a terminate msg
3048 processmsg_terminate_I();
3053 processmsg_memrequest_I();
3055 } // case MEMREQUEST
3058 processmsg_memresponse_I();
3060 } // case MEMRESPONSE
3065 processmsg_gcstartinit_I();
3067 } // case GCSTARTINIT
3070 // receive a start GC msg
3071 processmsg_gcstart_I();
3075 case GCSTARTCOMPACT: {
3076 // a compact phase start msg
3077 processmsg_gcstartcompact_I();
3079 } // case GCSTARTCOMPACT
3081 case GCSTARTMAPINFO: {
3082 // received a flush phase start msg
3083 processmsg_gcstartmapinfo_I();
3085 } // case GCSTARTFLUSH
3087 case GCSTARTFLUSH: {
3088 // received a flush phase start msg
3089 processmsg_gcstartflush_I();
3091 } // case GCSTARTFLUSH
3093 case GCFINISHINIT: {
3094 processmsg_gcfinishinit_I();
3096 } // case GCFINISHINIT
3098 case GCFINISHMARK: {
3099 processmsg_gcfinishmark_I();
3101 } // case GCFINISHMARK
3103 case GCFINISHCOMPACT: {
3104 // received a compact phase finish msg
3105 processmsg_gcfinishcompact_I();
3107 } // case GCFINISHCOMPACT
3109 case GCFINISHMAPINFO: {
3110 processmsg_gcfinishmapinfo_I();
3112 } // case GCFINISHMAPINFO
3114 case GCFINISHFLUSH: {
3115 processmsg_gcfinishflush_I();
3117 } // case GCFINISHFLUSH
3120 // received a GC finish msg
3121 gcphase = FINISHPHASE;
3125 case GCMARKCONFIRM: {
3126 // received a marked phase finish confirm request msg
3127 // all cores should do mark
3128 processmsg_gcmarkconfirm_I();
3130 } // case GCMARKCONFIRM
3132 case GCMARKREPORT: {
3133 processmsg_gcmarkreport_I();
3135 } // case GCMARKREPORT
3138 processmsg_gcmarkedobj_I();
3140 } // case GCMARKEDOBJ
3143 // received a start moving objs msg
3144 processmsg_gcmovestart_I();
3146 } // case GCMOVESTART
3148 case GCMAPREQUEST: {
3149 // received a mapping info request msg
3150 processmsg_gcmaprequest_I();
3152 } // case GCMAPREQUEST
3155 // received a mapping info response msg
3156 processmsg_gcmapinfo_I();
3161 // received a mapping tbl response msg
3162 processmsg_gcmaptbl_I();
3166 case GCLOBJREQUEST: {
3167 // received a large objs info request msg
3168 transferMarkResults_I();
3170 } // case GCLOBJREQUEST
3173 // received a large objs info response msg
3174 processmsg_gclobjinfo_I();
3176 } // case GCLOBJINFO
3178 case GCLOBJMAPPING: {
3179 // received a large obj mapping info msg
3180 processmsg_gclobjmapping_I();
3182 } // case GCLOBJMAPPING
3186 // received a gcprofiles msg
3187 processmsg_gcprofiles_I();
3191 #endif // #ifdef MULTICORE_GC
3196 //memset(msgdata, '\0', sizeof(int) * msgdataindex);
3198 msglength = BAMBOO_MSG_BUF_LENGTH;
3200 //printf("++ msg: %x \n", type);
3202 if(msgdataindex != msgdatalast) {
3203 // still have available msg
3208 BAMBOO_DEBUGPRINT(0xe88d);
3212 // have new coming msg
3213 if(BAMBOO_MSG_AVAIL() != 0) {
3227 BAMBOO_DEBUGPRINT(0xe88e);
3231 /* if(isInterrupt) {
3239 int enqueuetasks(struct parameterwrapper *parameter,
3240 struct parameterwrapper *prevptr,
3241 struct ___Object___ *ptr,
3243 int numenterflags) {
3244 void * taskpointerarray[MAXTASKPARAMS];
3246 //int numparams=parameter->task->numParameters;
3247 int numiterators=parameter->task->numTotal-1;
3250 struct taskdescriptor * task=parameter->task;
3252 //this add the object to parameterwrapper
3253 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
3254 numenterflags, enterflags==NULL);
3256 /* Add enqueued object to parameter vector */
3257 taskpointerarray[parameter->slot]=ptr;
3259 /* Reset iterators */
3260 for(j=0; j<numiterators; j++) {
3261 toiReset(¶meter->iterators[j]);
3264 /* Find initial state */
3265 for(j=0; j<numiterators; j++) {
3267 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3268 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3270 /* Need to backtrack */
3271 toiReset(¶meter->iterators[j]);
3275 /* Nothing to enqueue */
3281 /* Enqueue current state */
3283 struct taskparamdescriptor *tpd=
3284 RUNMALLOC(sizeof(struct taskparamdescriptor));
3286 tpd->numParameters=numiterators+1;
3287 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
3289 for(j=0; j<=numiterators; j++) {
3290 //store the actual parameters
3291 tpd->parameterArray[j]=taskpointerarray[j];
3294 if (( /*!gencontains(failedtasks, tpd)&&*/
3295 !gencontains(activetasks,tpd))) {
3296 genputtable(activetasks, tpd, tpd);
3298 RUNFREE(tpd->parameterArray);
3302 /* This loop iterates to the next parameter combination */
3303 if (numiterators==0)
3306 for(j=numiterators-1; j<numiterators; j++) {
3308 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3309 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3311 /* Need to backtrack */
3312 toiReset(¶meter->iterators[j]);
3316 /* Nothing more to enqueue */
3324 int enqueuetasks_I(struct parameterwrapper *parameter,
3325 struct parameterwrapper *prevptr,
3326 struct ___Object___ *ptr,
3328 int numenterflags) {
3329 void * taskpointerarray[MAXTASKPARAMS];
3331 //int numparams=parameter->task->numParameters;
3332 int numiterators=parameter->task->numTotal-1;
3337 struct taskdescriptor * task=parameter->task;
3339 //this add the object to parameterwrapper
3340 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
3341 numenterflags, enterflags==NULL);
3343 /* Add enqueued object to parameter vector */
3344 taskpointerarray[parameter->slot]=ptr;
3346 /* Reset iterators */
3347 for(j=0; j<numiterators; j++) {
3348 toiReset(¶meter->iterators[j]);
3351 /* Find initial state */
3352 for(j=0; j<numiterators; j++) {
3354 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3355 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3357 /* Need to backtrack */
3358 toiReset(¶meter->iterators[j]);
3362 /* Nothing to enqueue */
3368 /* Enqueue current state */
3370 struct taskparamdescriptor *tpd=
3371 RUNMALLOC_I(sizeof(struct taskparamdescriptor));
3373 tpd->numParameters=numiterators+1;
3374 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
3376 for(j=0; j<=numiterators; j++) {
3377 //store the actual parameters
3378 tpd->parameterArray[j]=taskpointerarray[j];
3381 if (( /*!gencontains(failedtasks, tpd)&&*/
3382 !gencontains(activetasks,tpd))) {
3383 genputtable_I(activetasks, tpd, tpd);
3385 RUNFREE(tpd->parameterArray);
3389 /* This loop iterates to the next parameter combination */
3390 if (numiterators==0)
3393 for(j=numiterators-1; j<numiterators; j++) {
3395 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
3396 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3398 /* Need to backtrack */
3399 toiReset(¶meter->iterators[j]);
3403 /* Nothing more to enqueue */
3417 int containstag(struct ___Object___ *ptr,
3418 struct ___TagDescriptor___ *tag);
3420 #ifndef MULTICORE_GC
3421 void releasewritelock_r(void * lock, void * redirectlock) {
3423 int reallock = (int)lock;
3424 targetcore = (reallock >> 5) % NUMCORES;
3427 BAMBOO_DEBUGPRINT(0xe671);
3428 BAMBOO_DEBUGPRINT_REG((int)lock);
3429 BAMBOO_DEBUGPRINT_REG(reallock);
3430 BAMBOO_DEBUGPRINT_REG(targetcore);
3433 if(targetcore == BAMBOO_NUM_OF_CORE) {
3434 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3436 BAMBOO_DEBUGPRINT(0xf001);
3438 // reside on this core
3439 if(!RuntimeHashcontainskey(locktbl, reallock)) {
3440 // no locks for this object, something is wrong
3441 BAMBOO_EXIT(0xa00b);
3444 struct LockValue * lockvalue = NULL;
3446 BAMBOO_DEBUGPRINT(0xe672);
3448 RuntimeHashget(locktbl, reallock, &rwlock_obj);
3449 lockvalue = (struct LockValue *)rwlock_obj;
3451 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
3454 lockvalue->redirectlock = (int)redirectlock;
3456 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
3459 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3461 BAMBOO_DEBUGPRINT(0xf000);
3465 // send lock release with redirect info msg
3466 // for 32 bit machine, the size is always 4 words
3467 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock,
3468 (int)redirectlock, false);
3473 void executetasks() {
3474 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
3477 struct ___Object___ * tmpparam = NULL;
3478 struct parameterdescriptor * pd=NULL;
3479 struct parameterwrapper *pw=NULL;
3489 while(hashsize(activetasks)>0) {
3494 BAMBOO_DEBUGPRINT(0xe990);
3497 /* See if there are any active tasks */
3498 //if (hashsize(activetasks)>0) {
3501 #ifdef ACCURATEPROFILE
3502 profileTaskStart("tpd checking");
3506 //clock1 = BAMBOO_GET_EXE_TIME();
3509 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
3510 genfreekey(activetasks, currtpd);
3512 numparams=currtpd->task->numParameters;
3513 numtotal=currtpd->task->numTotal;
3515 // clear the lockRedirectTbl
3516 // (TODO, this table should be empty after all locks are released)
3518 /*for(j = 0; j < MAXTASKPARAMS; j++) {
3519 runtime_locks[j].redirectlock = 0;
3520 runtime_locks[j].value = 0;
3522 // get all required locks
3523 runtime_locklen = 0;
3524 // check which locks are needed
3525 for(i = 0; i < numparams; i++) {
3526 void * param = currtpd->parameterArray[i];
3530 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
3532 taskpointerarray[i+OFFSET]=param;
3535 if(((struct ___Object___ *)param)->lock == NULL) {
3536 tmplock = (int)param;
3538 tmplock = (int)(((struct ___Object___ *)param)->lock);
3540 // insert into the locks array
3541 for(j = 0; j < runtime_locklen; j++) {
3542 if(runtime_locks[j].value == tmplock) {
3545 } else if(runtime_locks[j].value > tmplock) {
3550 int h = runtime_locklen;
3552 runtime_locks[h].redirectlock = runtime_locks[h-1].redirectlock;
3553 runtime_locks[h].value = runtime_locks[h-1].value;
3555 runtime_locks[j].value = tmplock;
3556 runtime_locks[j].redirectlock = (int)param;
3559 } // line 2713: for(i = 0; i < numparams; i++)
3560 // grab these required locks
3562 BAMBOO_DEBUGPRINT(0xe991);
3565 //clock2 = BAMBOO_GET_EXE_TIME();
3567 for(i = 0; i < runtime_locklen; i++) {
3568 int * lock = (int *)(runtime_locks[i].redirectlock);
3570 // require locks for this parameter if it is not a startup object
3572 BAMBOO_DEBUGPRINT_REG((int)lock);
3573 BAMBOO_DEBUGPRINT_REG((int)(runtime_locks[i].value));
3576 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3578 BAMBOO_DEBUGPRINT(0xf001);
3581 //isInterrupt = false;
3584 BAMBOO_WAITING_FOR_LOCK(0);
3588 while(BAMBOO_WAITING_FOR_LOCK(0) != -1) {
3592 grount = lockresult;
3602 //isInterrupt = true;
3604 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3606 BAMBOO_DEBUGPRINT(0xf000);
3611 BAMBOO_DEBUGPRINT(0xe992);
3612 BAMBOO_DEBUGPRINT_REG(lock);
3614 // check if has the lock already
3615 // can not get the lock, try later
3616 // release all grabbed locks for previous parameters
3617 for(j = 0; j < i; ++j) {
3618 lock = (int*)(runtime_locks[j].redirectlock);
3619 releasewritelock(lock);
3621 genputtable(activetasks, currtpd, currtpd);
3622 if(hashsize(activetasks) == 1) {
3623 // only one task right now, wait a little while before next try
3629 #ifdef ACCURATEPROFILE
3630 // fail, set the end of the checkTaskInfo
3637 } // line 2752: for(i = 0; i < runtime_locklen; i++)
3640 clock3 = BAMBOO_GET_EXE_TIME();
3641 //tprintf("sort: %d, grab: %d \n", clock2-clock1, clock3-clock2);*/
3644 BAMBOO_DEBUGPRINT(0xe993);
3646 /* Make sure that the parameters are still in the queues */
3647 for(i=0; i<numparams; i++) {
3648 void * parameter=currtpd->parameterArray[i];
3652 BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
3653 classsize[((struct ___Object___ *)parameter)->type]);
3655 tmpparam = (struct ___Object___ *)parameter;
3656 pd=currtpd->task->descriptorarray[i];
3657 pw=(struct parameterwrapper *) pd->queue;
3658 /* Check that object is still in queue */
3660 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
3662 BAMBOO_DEBUGPRINT(0xe994);
3663 BAMBOO_DEBUGPRINT_REG(parameter);
3665 // release grabbed locks
3666 for(j = 0; j < runtime_locklen; ++j) {
3667 int * lock = (int *)(runtime_locks[j].redirectlock);
3668 releasewritelock(lock);
3670 RUNFREE(currtpd->parameterArray);
3676 /* Check if the object's flags still meets requirements */
3680 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
3681 andmask=pw->intarray[tmpi*2];
3682 checkmask=pw->intarray[tmpi*2+1];
3683 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
3689 // flags are never suitable
3690 // remove this obj from the queue
3692 int UNUSED, UNUSED2;
3695 BAMBOO_DEBUGPRINT(0xe995);
3696 BAMBOO_DEBUGPRINT_REG(parameter);
3698 ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
3699 (int *) &enterflags, &UNUSED, &UNUSED2);
3700 ObjectHashremove(pw->objectset, (int)parameter);
3701 if (enterflags!=NULL)
3702 RUNFREE(enterflags);
3703 // release grabbed locks
3704 for(j = 0; j < runtime_locklen; ++j) {
3705 int * lock = (int *)(runtime_locks[j].redirectlock);
3706 releasewritelock(lock);
3708 RUNFREE(currtpd->parameterArray);
3712 #ifdef ACCURATEPROFILE
3713 // fail, set the end of the checkTaskInfo
3718 } // line 2878: if (!ismet)
3722 /* Check that object still has necessary tags */
3723 for(j=0; j<pd->numbertags; j++) {
3724 int slotid=pd->tagarray[2*j]+numparams;
3725 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
3726 if (!containstag(parameter, tagd)) {
3728 BAMBOO_DEBUGPRINT(0xe996);
3731 // release grabbed locks
3733 for(tmpj = 0; tmpj < runtime_locklen; ++tmpj) {
3734 int * lock = (int *)(runtime_locks[tmpj].redirectlock);
3735 releasewritelock(lock);
3738 RUNFREE(currtpd->parameterArray);
3742 } // line2911: if (!containstag(parameter, tagd))
3743 } // line 2808: for(j=0; j<pd->numbertags; j++)
3745 taskpointerarray[i+OFFSET]=parameter;
3746 } // line 2824: for(i=0; i<numparams; i++)
3748 for(; i<numtotal; i++) {
3749 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
3754 /* Actually call task */
3756 ((int *)taskpointerarray)[0]=currtpd->numParameters;
3757 taskpointerarray[1]=NULL;
3760 #ifdef ACCURATEPROFILE
3761 // check finish, set the end of the checkTaskInfo
3764 profileTaskStart(currtpd->task->name);
3768 //clock4 = BAMBOO_GET_EXE_TIME();
3769 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3772 BAMBOO_DEBUGPRINT(0xe997);
3774 ((void (*)(void **))currtpd->task->taskptr)(taskpointerarray);
3777 //clock5 = BAMBOO_GET_EXE_TIME();
3778 // tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3781 #ifdef ACCURATEPROFILE
3782 // task finish, set the end of the checkTaskInfo
3784 // new a PostTaskInfo for the post-task execution
3785 profileTaskStart("post task execution");
3789 BAMBOO_DEBUGPRINT(0xe998);
3790 BAMBOO_DEBUGPRINT_REG(islock);
3795 BAMBOO_DEBUGPRINT(0xe999);
3797 for(i = 0; i < runtime_locklen; ++i) {
3798 void * ptr = (void *)(runtime_locks[i].redirectlock);
3799 int * lock = (int *)(runtime_locks[i].value);
3801 BAMBOO_DEBUGPRINT_REG((int)ptr);
3802 BAMBOO_DEBUGPRINT_REG((int)lock);
3803 BAMBOO_DEBUGPRINT_REG(*((int*)lock+5));
3805 #ifndef MULTICORE_GC
3806 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
3808 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
3809 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
3810 releasewritelock_r(lock, (int *)redirectlock);
3815 releasewritelock(ptr);
3818 } // line 3015: if(islock)
3821 //clock6 = BAMBOO_GET_EXE_TIME();
3822 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3825 // post task execution finish, set the end of the postTaskInfo
3829 // Free up task parameter descriptor
3830 RUNFREE(currtpd->parameterArray);
3834 BAMBOO_DEBUGPRINT(0xe99a);
3837 //clock7 = BAMBOO_GET_EXE_TIME();
3838 //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));
3841 //} // if (hashsize(activetasks)>0)
3842 } // while(hashsize(activetasks)>0)
3844 BAMBOO_DEBUGPRINT(0xe99b);
3848 /* This function processes an objects tags */
3849 void processtags(struct parameterdescriptor *pd,
3851 struct parameterwrapper *parameter,
3852 int * iteratorcount,
3857 for(i=0; i<pd->numbertags; i++) {
3858 int slotid=pd->tagarray[2*i];
3859 int tagid=pd->tagarray[2*i+1];
3861 if (statusarray[slotid+numparams]==0) {
3862 parameter->iterators[*iteratorcount].istag=1;
3863 parameter->iterators[*iteratorcount].tagid=tagid;
3864 parameter->iterators[*iteratorcount].slot=slotid+numparams;
3865 parameter->iterators[*iteratorcount].tagobjectslot=index;
3866 statusarray[slotid+numparams]=1;
3873 void processobject(struct parameterwrapper *parameter,
3875 struct parameterdescriptor *pd,
3881 struct ObjectHash * objectset=
3882 ((struct parameterwrapper *)pd->queue)->objectset;
3884 parameter->iterators[*iteratorcount].istag=0;
3885 parameter->iterators[*iteratorcount].slot=index;
3886 parameter->iterators[*iteratorcount].objectset=objectset;
3887 statusarray[index]=1;
3889 for(i=0; i<pd->numbertags; i++) {
3890 int slotid=pd->tagarray[2*i];
3891 //int tagid=pd->tagarray[2*i+1];
3892 if (statusarray[slotid+numparams]!=0) {
3893 /* This tag has already been enqueued, use it to narrow search */
3894 parameter->iterators[*iteratorcount].tagbindings[tagcount]=
3899 parameter->iterators[*iteratorcount].numtags=tagcount;
3904 /* This function builds the iterators for a task & parameter */
3906 void builditerators(struct taskdescriptor * task,
3908 struct parameterwrapper * parameter) {
3909 int statusarray[MAXTASKPARAMS];
3911 int numparams=task->numParameters;
3912 int iteratorcount=0;
3913 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
3915 statusarray[index]=1; /* Initial parameter */
3916 /* Process tags for initial iterator */
3918 processtags(task->descriptorarray[index], index, parameter,
3919 &iteratorcount, statusarray, numparams);
3923 /* Check for objects with existing tags */
3924 for(i=0; i<numparams; i++) {
3925 if (statusarray[i]==0) {
3926 struct parameterdescriptor *pd=task->descriptorarray[i];
3928 for(j=0; j<pd->numbertags; j++) {
3929 int slotid=pd->tagarray[2*j];
3930 if(statusarray[slotid+numparams]!=0) {
3931 processobject(parameter, i, pd, &iteratorcount, statusarray,
3933 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3940 /* Next do objects w/ unbound tags*/
3942 for(i=0; i<numparams; i++) {
3943 if (statusarray[i]==0) {
3944 struct parameterdescriptor *pd=task->descriptorarray[i];
3945 if (pd->numbertags>0) {
3946 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3947 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3953 /* Nothing with a tag enqueued */
3955 for(i=0; i<numparams; i++) {
3956 if (statusarray[i]==0) {
3957 struct parameterdescriptor *pd=task->descriptorarray[i];
3958 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3959 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3972 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3975 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3976 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3978 printf("%s\n", task->name);
3980 for(j=0; j<task->numParameters; j++) {
3981 struct parameterdescriptor *param=task->descriptorarray[j];
3982 struct parameterwrapper *parameter=param->queue;
3983 struct ObjectHash * set=parameter->objectset;
3984 struct ObjectIterator objit;
3986 printf(" Parameter %d\n", j);
3988 ObjectHashiterator(set, &objit);
3989 while(ObjhasNext(&objit)) {
3990 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
3991 struct ___Object___ * tagptr=obj->___tags___;
3992 int nonfailed=Objdata4(&objit);
3993 int numflags=Objdata3(&objit);
3994 int flags=Objdata2(&objit);
3997 printf(" Contains %lx\n", obj);
3998 printf(" flag=%d\n", obj->flag);
4001 } else if (tagptr->type==TAGTYPE) {
4003 printf(" tag=%lx\n",tagptr);
4009 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
4010 for(; tagindex<ao->___cachedCode___; tagindex++) {
4012 printf(" tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*,
4025 /* This function processes the task information to create queues for
4026 each parameter type. */
4028 void processtasks() {
4030 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
4033 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
4034 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
4037 /* Build objectsets */
4038 for(j=0; j<task->numParameters; j++) {
4039 struct parameterdescriptor *param=task->descriptorarray[j];
4040 struct parameterwrapper *parameter=param->queue;
4041 parameter->objectset=allocateObjectHash(10);
4042 parameter->task=task;
4045 /* Build iterators for parameters */
4046 for(j=0; j<task->numParameters; j++) {
4047 struct parameterdescriptor *param=task->descriptorarray[j];
4048 struct parameterwrapper *parameter=param->queue;
4049 builditerators(task, j, parameter);
4054 void toiReset(struct tagobjectiterator * it) {
4057 } else if (it->numtags>0) {
4060 ObjectHashiterator(it->objectset, &it->it);
4064 int toiHasNext(struct tagobjectiterator *it,
4065 void ** objectarray OPTARG(int * failed)) {
4068 /* Get object with tags */
4069 struct ___Object___ *obj=objectarray[it->tagobjectslot];
4070 struct ___Object___ *tagptr=obj->___tags___;
4071 if (tagptr->type==TAGTYPE) {
4072 if ((it->tagobjindex==0)&& /* First object */
4073 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
4078 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
4079 int tagindex=it->tagobjindex;
4080 for(; tagindex<ao->___cachedCode___; tagindex++) {
4081 struct ___TagDescriptor___ *td=
4082 ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
4083 if (td->flag==it->tagid) {
4084 it->tagobjindex=tagindex; /* Found right type of tag */
4090 } else if (it->numtags>0) {
4091 /* Use tags to locate appropriate objects */
4092 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
4093 struct ___Object___ *objptr=tag->flagptr;
4095 if (objptr->type!=OBJECTARRAYTYPE) {
4096 if (it->tagobjindex>0)
4098 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
4100 for(i=1; i<it->numtags; i++) {
4101 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
4102 if (!containstag(objptr,tag2))
4107 struct ArrayObject *ao=(struct ArrayObject *) objptr;
4110 for(tagindex=it->tagobjindex; tagindex<ao->___cachedCode___; tagindex++) {
4111 struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
4112 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
4114 for(i=1; i<it->numtags; i++) {
4115 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
4116 if (!containstag(objptr,tag2))
4119 it->tagobjindex=tagindex;
4124 it->tagobjindex=tagindex;
4128 return ObjhasNext(&it->it);
4132 int containstag(struct ___Object___ *ptr,
4133 struct ___TagDescriptor___ *tag) {
4135 struct ___Object___ * objptr=tag->flagptr;
4136 if (objptr->type==OBJECTARRAYTYPE) {
4137 struct ArrayObject *ao=(struct ArrayObject *)objptr;
4138 for(j=0; j<ao->___cachedCode___; j++) {
4139 if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
4149 void toiNext(struct tagobjectiterator *it,
4150 void ** objectarray OPTARG(int * failed)) {
4151 /* hasNext has all of the intelligence */
4154 /* Get object with tags */
4155 struct ___Object___ *obj=objectarray[it->tagobjectslot];
4156 struct ___Object___ *tagptr=obj->___tags___;
4157 if (tagptr->type==TAGTYPE) {
4159 objectarray[it->slot]=tagptr;
4161 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
4162 objectarray[it->slot]=
4163 ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
4165 } else if (it->numtags>0) {
4166 /* Use tags to locate appropriate objects */
4167 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
4168 struct ___Object___ *objptr=tag->flagptr;
4169 if (objptr->type!=OBJECTARRAYTYPE) {
4171 objectarray[it->slot]=objptr;
4173 struct ArrayObject *ao=(struct ArrayObject *) objptr;
4174 objectarray[it->slot]=
4175 ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
4178 /* Iterate object */
4179 objectarray[it->slot]=(void *)Objkey(&it->it);
4185 inline void profileTaskStart(char * taskname) {
4186 if(!taskInfoOverflow) {
4187 TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
4188 taskInfoArray[taskInfoIndex] = taskInfo;
4189 taskInfo->taskName = taskname;
4190 taskInfo->startTime = BAMBOO_GET_EXE_TIME();
4191 taskInfo->endTime = -1;
4192 taskInfo->exitIndex = -1;
4193 taskInfo->newObjs = NULL;
4197 inline void profileTaskEnd() {
4198 if(!taskInfoOverflow) {
4199 taskInfoArray[taskInfoIndex]->endTime = BAMBOO_GET_EXE_TIME();
4201 if(taskInfoIndex == TASKINFOLENGTH) {
4202 taskInfoOverflow = true;
4203 //taskInfoIndex = 0;
4208 // output the profiling data
4209 void outputProfileData() {
4212 unsigned long long totaltasktime = 0;
4213 unsigned long long preprocessingtime = 0;
4214 unsigned long long objqueuecheckingtime = 0;
4215 unsigned long long postprocessingtime = 0;
4216 //int interruptiontime = 0;
4217 unsigned long long other = 0;
4218 unsigned long long averagetasktime = 0;
4221 printf("Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
4222 // output task related info
4223 for(i = 0; i < taskInfoIndex; i++) {
4224 TaskInfo* tmpTInfo = taskInfoArray[i];
4225 unsigned long long duration = tmpTInfo->endTime - tmpTInfo->startTime;
4226 printf("%s, %lld, %lld, %lld, %lld",
4227 tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime,
4228 duration, tmpTInfo->exitIndex);
4229 // summarize new obj info
4230 if(tmpTInfo->newObjs != NULL) {
4231 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
4232 struct RuntimeIterator * iter = NULL;
4233 while(0 == isEmpty(tmpTInfo->newObjs)) {
4234 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
4235 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
4237 RuntimeHashget(nobjtbl, (int)objtype, &num);
4238 RuntimeHashremovekey(nobjtbl, (int)objtype);
4240 RuntimeHashadd(nobjtbl, (int)objtype, num);
4242 RuntimeHashadd(nobjtbl, (int)objtype, 1);
4244 //printf(stderr, "new obj!\n");
4247 // output all new obj info
4248 iter = RuntimeHashcreateiterator(nobjtbl);
4249 while(RunhasNext(iter)) {
4250 char * objtype = (char *)Runkey(iter);
4251 int num = Runnext(iter);
4252 printf(", %s, %d", objtype, num);
4256 if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
4257 preprocessingtime += duration;
4258 } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
4259 postprocessingtime += duration;
4260 } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
4261 objqueuecheckingtime += duration;
4263 totaltasktime += duration;
4264 averagetasktime += duration;
4269 if(taskInfoOverflow) {
4270 printf("Caution: task info overflow!\n");
4273 other = totalexetime-totaltasktime-preprocessingtime-postprocessingtime;
4274 averagetasktime /= tasknum;
4276 printf("\nTotal time: %lld\n", totalexetime);
4277 printf("Total task execution time: %lld (%d%%)\n", totaltasktime,
4278 (int)(((double)totaltasktime/(double)totalexetime)*100));
4279 printf("Total objqueue checking time: %lld (%d%%)\n",
4280 objqueuecheckingtime,
4281 (int)(((double)objqueuecheckingtime/(double)totalexetime)*100));
4282 printf("Total pre-processing time: %lld (%d%%)\n", preprocessingtime,
4283 (int)(((double)preprocessingtime/(double)totalexetime)*100));
4284 printf("Total post-processing time: %lld (%d%%)\n", postprocessingtime,
4285 (int)(((double)postprocessingtime/(double)totalexetime)*100));
4286 printf("Other time: %lld (%d%%)\n", other,
4287 (int)(((double)other/(double)totalexetime)*100));
4290 printf("\nAverage task execution time: %lld\n", averagetasktime);
4292 //printf("\nTotal time spent for interruptions: %lld\n", interrupttime);
4297 BAMBOO_DEBUGPRINT(0xdddd);
4298 // output task related info
4299 for(i= 0; i < taskInfoIndex; i++) {
4300 TaskInfo* tmpTInfo = taskInfoArray[i];
4301 char* tmpName = tmpTInfo->taskName;
4302 int nameLen = strlen(tmpName);
4303 BAMBOO_DEBUGPRINT(0xddda);
4304 for(j = 0; j < nameLen; j++) {
4305 BAMBOO_DEBUGPRINT_REG(tmpName[j]);
4307 BAMBOO_DEBUGPRINT(0xdddb);
4308 BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
4309 BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
4310 BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
4311 if(tmpTInfo->newObjs != NULL) {
4312 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
4313 struct RuntimeIterator * iter = NULL;
4314 while(0 == isEmpty(tmpTInfo->newObjs)) {
4315 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
4316 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
4318 RuntimeHashget(nobjtbl, (int)objtype, &num);
4319 RuntimeHashremovekey(nobjtbl, (int)objtype);
4321 RuntimeHashadd(nobjtbl, (int)objtype, num);
4323 RuntimeHashadd(nobjtbl, (int)objtype, 1);
4327 // ouput all new obj info
4328 iter = RuntimeHashcreateiterator(nobjtbl);
4329 while(RunhasNext(iter)) {
4330 char * objtype = (char *)Runkey(iter);
4331 int num = Runnext(iter);
4332 int nameLen = strlen(objtype);
4333 BAMBOO_DEBUGPRINT(0xddda);
4334 for(j = 0; j < nameLen; j++) {
4335 BAMBOO_DEBUGPRINT_REG(objtype[j]);
4337 BAMBOO_DEBUGPRINT(0xdddb);
4338 BAMBOO_DEBUGPRINT_REG(num);
4341 BAMBOO_DEBUGPRINT(0xdddc);
4344 if(taskInfoOverflow) {
4345 BAMBOO_DEBUGPRINT(0xefee);
4348 // output interrupt related info
4349 for(i = 0; i < interruptInfoIndex; i++) {
4350 InterruptInfo* tmpIInfo = interruptInfoArray[i];
4351 BAMBOO_DEBUGPRINT(0xddde);
4352 BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
4353 BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
4354 BAMBOO_DEBUGPRINT(0xdddf);
4357 if(interruptInfoOverflow) {
4358 BAMBOO_DEBUGPRINT(0xefef);
4361 BAMBOO_DEBUGPRINT(0xeeee);
4364 #endif // #ifdef PROFILE