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][5] = {
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][5] = {
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[i] = 0;
206 gcnumreceiveobjs[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;
229 self_numsendobjs = 0;
230 self_numreceiveobjs = 0;
232 for(i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
237 msglength = BAMBOO_MSG_BUF_LENGTH;
239 for(i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
245 isMsgHanging = false;
246 //isMsgSending = false;
249 bamboo_cur_msp = NULL;
250 bamboo_smem_size = 0;
251 totransobjqueue = createQueue_I();
254 bamboo_smem_zero_top = NULL;
256 gcprocessing = false;
257 gcphase = FINISHPHASE;
259 gcself_numsendobjs = 0;
260 gcself_numreceiveobjs = 0;
261 gcmarkedptrbound = 0;
262 //mgchashCreate(2000, 0.75);
263 gcpointertbl = allocateRuntimeHash_I(20);
264 //gcpointertbl = allocateMGCHash(20);
265 gcforwardobjtbl = allocateMGCHash_I(20, 3);
268 //gcismapped = false;
277 gcsbstarttbl = BAMBOO_BASE_VA;
278 bamboo_smemtbl = (void *)gcsbstarttbl
279 + (BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE)*sizeof(INTPTR);
280 if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
281 int t_size = ((BAMBOO_RMSP_SIZE)-sizeof(mgcsharedhashtbl_t)*2
282 -128*sizeof(size_t))/sizeof(mgcsharedhashlistnode_t)-2;
284 unsigned int tmp_k = 1 << (sizeof(int)*8 -1);
285 while(((t_size & tmp_k) == 0) && (kk < sizeof(int)*8)) {
286 t_size = t_size << 1;
289 t_size = tmp_k >> kk;
290 gcsharedptbl = mgcsharedhashCreate_I(t_size,0.30);//allocateGCSharedHash_I(20);
294 BAMBOO_MEMSET_WH(gcrpointertbls,0,sizeof(mgcsharedhashtbl_t *)*NUMCORES4GC);
295 //sizeof(struct RuntimeHash *)*NUMCORES4GC);
297 gcmem_mixed_threshold =
298 (unsigned int)((BAMBOO_SHARED_MEM_SIZE-(gcbaseva-BAMBOO_BASE_VA))*0.8);
299 gcmem_mixed_usedmem = 0;
302 // create the lock table, lockresult table and obj queue
305 (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
306 /* Set allocation blocks*/
307 locktable.listhead=NULL;
308 locktable.listtail=NULL;
310 locktable.numelements = 0;
315 lockRedirectTbl = allocateRuntimeHash_I(20);
316 objRedirectLockTbl = allocateRuntimeHash_I(20);
321 objqueue.head = NULL;
322 objqueue.tail = NULL;
328 //isInterrupt = true;
332 taskInfoOverflow = false;
334 interruptInfoIndex = 0;
335 interruptInfoOverflow = false;
338 for(i = 0; i < MAXTASKPARAMS; i++) {
339 runtime_locks[i].redirectlock = 0;
340 runtime_locks[i].value = 0;
345 inline __attribute__((always_inline))
346 void disruntimedata() {
349 freeRuntimeHash(gcpointertbl);
350 //freeMGCHash(gcpointertbl);
351 freeMGCHash(gcforwardobjtbl);
352 // for mapping info structures
353 //freeRuntimeHash(gcrcoretbl);
355 freeRuntimeHash(lockRedirectTbl);
356 freeRuntimeHash(objRedirectLockTbl);
357 RUNFREE(locktable.bucket);
359 if(activetasks != NULL) {
360 genfreehashtable(activetasks);
362 if(currtpd != NULL) {
363 RUNFREE(currtpd->parameterArray);
367 BAMBOO_LOCAL_MEM_CLOSE();
368 BAMBOO_SHARE_MEM_CLOSE();
371 inline __attribute__((always_inline))
372 bool checkObjQueue() {
374 struct transObjInfo * objInfo = NULL;
378 #ifdef ACCURATEPROFILE
379 bool isChecking = false;
380 if(!isEmpty(&objqueue)) {
381 profileTaskStart("objqueue checking");
383 } // if(!isEmpty(&objqueue))
387 while(!isEmpty(&objqueue)) {
389 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
391 BAMBOO_DEBUGPRINT(0xf001);
394 //isInterrupt = false;
397 BAMBOO_DEBUGPRINT(0xeee1);
400 objInfo = (struct transObjInfo *)getItem(&objqueue);
401 obj = objInfo->objptr;
403 BAMBOO_DEBUGPRINT_REG((int)obj);
405 // grab lock and flush the obj
409 BAMBOO_WAITING_FOR_LOCK(0);
410 } // while(!lockflag)
413 BAMBOO_DEBUGPRINT_REG(grount);
428 BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
429 BAMBOO_CACHE_FLUSH_RANGE((int)obj,
430 classsize[((struct ___Object___ *)obj)->type]);
432 // enqueue the object
433 for(k = 0; k < objInfo->length; ++k) {
434 int taskindex = objInfo->queues[2 * k];
435 int paramindex = objInfo->queues[2 * k + 1];
436 struct parameterwrapper ** queues =
437 &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
439 BAMBOO_DEBUGPRINT_REG(taskindex);
440 BAMBOO_DEBUGPRINT_REG(paramindex);
441 struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
442 tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n",
443 BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj,
444 (long)obj, tmpptr->flag);
446 enqueueObject_I(obj, queues, 1);
448 BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
450 } // for(k = 0; k < objInfo->length; ++k)
451 releasewritelock_I(obj);
452 RUNFREE(objInfo->queues);
456 // put it at the end of the queue if no update version in the queue
457 struct QueueItem * qitem = getHead(&objqueue);
458 struct QueueItem * prev = NULL;
459 while(qitem != NULL) {
460 struct transObjInfo * tmpinfo =
461 (struct transObjInfo *)(qitem->objectptr);
462 if(tmpinfo->objptr == obj) {
463 // the same object in the queue, which should be enqueued
464 // recently. Current one is outdate, do not re-enqueue it
465 RUNFREE(objInfo->queues);
470 } // if(tmpinfo->objptr == obj)
471 qitem = getNextQueueItem(prev);
472 } // while(qitem != NULL)
473 // try to execute active tasks already enqueued first
474 addNewItem_I(&objqueue, objInfo);
476 //isInterrupt = true;
479 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
481 BAMBOO_DEBUGPRINT(0xf000);
485 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
487 BAMBOO_DEBUGPRINT(0xf000);
489 } // while(!isEmpty(&objqueue))
492 #ifdef ACCURATEPROFILE
500 BAMBOO_DEBUGPRINT(0xee02);
505 inline __attribute__((always_inline))
506 void checkCoreStatus() {
507 bool allStall = false;
511 (waitconfirm && (numconfirm == 0))) {
513 BAMBOO_DEBUGPRINT(0xee04);
514 BAMBOO_DEBUGPRINT_REG(waitconfirm);
516 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
518 BAMBOO_DEBUGPRINT(0xf001);
520 corestatus[BAMBOO_NUM_OF_CORE] = 0;
521 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
522 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
523 // check the status of all cores
526 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
528 for(i = 0; i < NUMCORESACTIVE; ++i) {
530 BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
532 if(corestatus[i] != 0) {
536 } // for(i = 0; i < NUMCORESACTIVE; ++i)
538 // check if the sum of send objs and receive obj are the same
539 // yes->check if the info is the latest; no->go on executing
541 for(i = 0; i < NUMCORESACTIVE; ++i) {
542 sumsendobj += numsendobjs[i];
544 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
546 } // for(i = 0; i < NUMCORESACTIVE; ++i)
547 for(i = 0; i < NUMCORESACTIVE; ++i) {
548 sumsendobj -= numreceiveobjs[i];
550 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
552 } // for(i = 0; i < NUMCORESACTIVE; ++i)
553 if(0 == sumsendobj) {
555 // the first time found all cores stall
556 // send out status confirm msg to all other cores
557 // reset the corestatus array too
559 BAMBOO_DEBUGPRINT(0xee05);
561 corestatus[BAMBOO_NUM_OF_CORE] = 1;
563 numconfirm = NUMCORESACTIVE - 1;
564 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
565 for(i = 1; i < NUMCORESACTIVE; ++i) {
567 // send status confirm msg to core i
568 send_msg_1(i, STATUSCONFIRM, false);
569 } // for(i = 1; i < NUMCORESACTIVE; ++i)
572 // all the core status info are the latest
573 // terminate; for profiling mode, send request to all
574 // other cores to pour out profiling data
576 BAMBOO_DEBUGPRINT(0xee06);
580 totalexetime = BAMBOO_GET_EXE_TIME() - bamboo_start_time;
583 //BAMBOO_DEBUGPRINT_REG(interrupttime);
586 BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME() - bamboo_start_time);
587 //BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
588 BAMBOO_DEBUGPRINT(0xbbbbbbbb);
590 // profile mode, send msgs to other cores to request pouring
591 // out progiling data
593 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
595 BAMBOO_DEBUGPRINT(0xf000);
597 for(i = 1; i < NUMCORESACTIVE; ++i) {
598 // send profile request msg to core i
599 send_msg_2(i, PROFILEOUTPUT, totalexetime, false);
600 } // for(i = 1; i < NUMCORESACTIVE; ++i)
601 // pour profiling data on startup core
604 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
606 BAMBOO_DEBUGPRINT(0xf001);
608 profilestatus[BAMBOO_NUM_OF_CORE] = 0;
609 // check the status of all cores
612 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
614 for(i = 0; i < NUMCORESACTIVE; ++i) {
616 BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
618 if(profilestatus[i] != 0) {
622 } // for(i = 0; i < NUMCORESACTIVE; ++i)
625 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
627 BAMBOO_DEBUGPRINT(0xf000);
632 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
638 // gc_profile mode, ourput gc prfiling data
641 gc_outputProfileData();
642 #endif // #ifdef GC_PROFILE
643 #endif // #ifdef MULTICORE_GC
645 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
646 terminate(); // All done.
647 } // if(!waitconfirm)
649 // still some objects on the fly on the network
650 // reset the waitconfirm and numconfirm
652 BAMBOO_DEBUGPRINT(0xee07);
656 } // if(0 == sumsendobj)
658 // not all cores are stall, keep on waiting
660 BAMBOO_DEBUGPRINT(0xee08);
665 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
667 BAMBOO_DEBUGPRINT(0xf000);
669 } // if((!waitconfirm) ||
672 // main function for each core
673 inline void run(void * arg) {
677 bool sendStall = false;
679 bool tocontinue = false;
681 corenum = BAMBOO_GET_NUM_OF_CORE();
683 BAMBOO_DEBUGPRINT(0xeeee);
684 BAMBOO_DEBUGPRINT_REG(corenum);
685 BAMBOO_DEBUGPRINT(STARTUPCORE);
688 // initialize runtime data structures
691 // other architecture related initialization
695 initializeexithandler();
697 // main process of the execution module
698 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
699 // non-executing cores, only processing communications
702 BAMBOO_DEBUGPRINT(0xee01);
703 BAMBOO_DEBUGPRINT_REG(taskInfoIndex);
704 BAMBOO_DEBUGPRINT_REG(taskInfoOverflow);
705 profileTaskStart("msg handling");
709 //isInterrupt = false;
713 /* Create queue of active tasks */
715 genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
716 (int (*)(void *,void *)) &comparetpd);
718 /* Process task information */
721 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
722 /* Create startup object */
723 createstartupobject(argc, argv);
727 BAMBOO_DEBUGPRINT(0xee00);
732 // check if need to do GC
736 // check if there are new active tasks can be executed
743 while(receiveObject() != -1) {
748 BAMBOO_DEBUGPRINT(0xee01);
751 // check if there are some pending objects,
752 // if yes, enqueue them and executetasks again
753 tocontinue = checkObjQueue();
757 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
760 BAMBOO_DEBUGPRINT(0xee03);
768 BAMBOO_DEBUGPRINT(0xee09);
774 // wait for some time
777 BAMBOO_DEBUGPRINT(0xee0a);
783 // send StallMsg to startup core
785 BAMBOO_DEBUGPRINT(0xee0b);
788 send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
789 self_numsendobjs, self_numreceiveobjs, false);
801 BAMBOO_DEBUGPRINT(0xee0c);
804 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
807 } // if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)
811 struct ___createstartupobject____I_locals {
814 struct ___StartupObject___ * ___startupobject___;
815 struct ArrayObject * ___stringarray___;
816 }; // struct ___createstartupobject____I_locals
818 void createstartupobject(int argc,
822 /* Allocate startup object */
824 struct ___createstartupobject____I_locals ___locals___={2, NULL, NULL, NULL};
825 struct ___StartupObject___ *startupobject=
826 (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
827 ___locals___.___startupobject___ = startupobject;
828 struct ArrayObject * stringarray=
829 allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
830 ___locals___.___stringarray___ = stringarray;
832 struct ___StartupObject___ *startupobject=
833 (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
834 struct ArrayObject * stringarray=
835 allocate_newarray(STRINGARRAYTYPE, argc-1);
837 /* Build array of strings */
838 startupobject->___parameters___=stringarray;
839 for(i=1; i<argc; i++) {
840 int length=strlen(argv[i]);
842 struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
844 struct ___String___ *newstring=NewString(argv[i],length);
846 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
850 startupobject->version = 0;
851 startupobject->lock = NULL;
853 /* Set initialized flag for startup object */
854 flagorandinit(startupobject,1,0xFFFFFFFF);
855 enqueueObject(startupobject, NULL, 0);
857 BAMBOO_CACHE_FLUSH_ALL();
861 int hashCodetpd(struct taskparamdescriptor *ftd) {
862 int hash=(int)ftd->task;
864 for(i=0; i<ftd->numParameters; i++) {
865 hash^=(int)ftd->parameterArray[i];
870 int comparetpd(struct taskparamdescriptor *ftd1,
871 struct taskparamdescriptor *ftd2) {
873 if (ftd1->task!=ftd2->task)
875 for(i=0; i<ftd1->numParameters; i++)
876 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
881 /* This function sets a tag. */
883 void tagset(void *ptr,
884 struct ___Object___ * obj,
885 struct ___TagDescriptor___ * tagd) {
887 void tagset(struct ___Object___ * obj,
888 struct ___TagDescriptor___ * tagd) {
890 struct ArrayObject * ao=NULL;
891 struct ___Object___ * tagptr=obj->___tags___;
893 obj->___tags___=(struct ___Object___ *)tagd;
895 /* Have to check if it is already set */
896 if (tagptr->type==TAGTYPE) {
897 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
902 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
903 struct ArrayObject * ao=
904 allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
905 obj=(struct ___Object___ *)ptrarray[2];
906 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
907 td=(struct ___TagDescriptor___ *) obj->___tags___;
909 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
912 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
913 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
914 obj->___tags___=(struct ___Object___ *) ao;
915 ao->___cachedCode___=2;
919 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
920 for(i=0; i<ao->___cachedCode___; i++) {
921 struct ___TagDescriptor___ * td=
922 ARRAYGET(ao, struct ___TagDescriptor___*, i);
927 if (ao->___cachedCode___<ao->___length___) {
928 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
929 ao->___cachedCode___++;
932 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
933 struct ArrayObject * aonew=
934 allocate_newarray(&ptrarray,TAGARRAYTYPE,
935 TAGARRAYINTERVAL+ao->___length___);
936 obj=(struct ___Object___ *)ptrarray[2];
937 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
938 ao=(struct ArrayObject *)obj->___tags___;
940 struct ArrayObject * aonew=
941 allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
944 aonew->___cachedCode___=ao->___length___+1;
945 for(i=0; i<ao->___length___; i++) {
946 ARRAYSET(aonew, struct ___TagDescriptor___*, i,
947 ARRAYGET(ao, struct ___TagDescriptor___*, i));
949 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
955 struct ___Object___ * tagset=tagd->flagptr;
958 } else if (tagset->type!=OBJECTARRAYTYPE) {
960 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
961 struct ArrayObject * ao=
962 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
963 obj=(struct ___Object___ *)ptrarray[2];
964 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
966 struct ArrayObject * ao=
967 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
969 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
970 ARRAYSET(ao, struct ___Object___ *, 1, obj);
971 ao->___cachedCode___=2;
972 tagd->flagptr=(struct ___Object___ *)ao;
974 struct ArrayObject *ao=(struct ArrayObject *) tagset;
975 if (ao->___cachedCode___<ao->___length___) {
976 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
980 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
981 struct ArrayObject * aonew=
982 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
983 OBJECTARRAYINTERVAL+ao->___length___);
984 obj=(struct ___Object___ *)ptrarray[2];
985 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
986 ao=(struct ArrayObject *)tagd->flagptr;
988 struct ArrayObject * aonew=
989 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
991 aonew->___cachedCode___=ao->___cachedCode___+1;
992 for(i=0; i<ao->___length___; i++) {
993 ARRAYSET(aonew, struct ___Object___*, i,
994 ARRAYGET(ao, struct ___Object___*, i));
996 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
997 tagd->flagptr=(struct ___Object___ *) aonew;
1003 /* This function clears a tag. */
1005 void tagclear(void *ptr,
1006 struct ___Object___ * obj,
1007 struct ___TagDescriptor___ * tagd) {
1009 void tagclear(struct ___Object___ * obj,
1010 struct ___TagDescriptor___ * tagd) {
1012 /* We'll assume that tag is alway there.
1013 Need to statically check for this of course. */
1014 struct ___Object___ * tagptr=obj->___tags___;
1016 if (tagptr->type==TAGTYPE) {
1017 if ((struct ___TagDescriptor___ *)tagptr==tagd)
1018 obj->___tags___=NULL;
1020 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
1022 for(i=0; i<ao->___cachedCode___; i++) {
1023 struct ___TagDescriptor___ * td=
1024 ARRAYGET(ao, struct ___TagDescriptor___ *, i);
1026 ao->___cachedCode___--;
1027 if (i<ao->___cachedCode___)
1028 ARRAYSET(ao, struct ___TagDescriptor___ *, i,
1029 ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
1030 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
1031 if (ao->___cachedCode___==0)
1032 obj->___tags___=NULL;
1039 struct ___Object___ *tagset=tagd->flagptr;
1040 if (tagset->type!=OBJECTARRAYTYPE) {
1044 struct ArrayObject *ao=(struct ArrayObject *) tagset;
1046 for(i=0; i<ao->___cachedCode___; i++) {
1047 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
1049 ao->___cachedCode___--;
1050 if (i<ao->___cachedCode___)
1051 ARRAYSET(ao, struct ___Object___ *, i,
1052 ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
1053 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
1054 if (ao->___cachedCode___==0)
1065 /* This function allocates a new tag. */
1067 struct ___TagDescriptor___ * allocate_tag(void *ptr,
1069 struct ___TagDescriptor___ * v=
1070 (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
1071 classsize[TAGTYPE]);
1073 struct ___TagDescriptor___ * allocate_tag(int index) {
1074 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
1083 /* This function updates the flag for object ptr. It or's the flag
1084 with the or mask and and's it with the andmask. */
1086 void flagbody(struct ___Object___ *ptr,
1088 struct parameterwrapper ** queues,
1092 int flagcomp(const int *val1, const int *val2) {
1093 return (*val1)-(*val2);
1096 void flagorand(void * ptr,
1099 struct parameterwrapper ** queues,
1102 int oldflag=((int *)ptr)[1];
1103 int flag=ormask|oldflag;
1105 flagbody(ptr, flag, queues, length, false);
1109 bool intflagorand(void * ptr,
1113 int oldflag=((int *)ptr)[1];
1114 int flag=ormask|oldflag;
1116 if (flag==oldflag) /* Don't do anything */
1119 flagbody(ptr, flag, NULL, 0, false);
1125 void flagorandinit(void * ptr,
1128 int oldflag=((int *)ptr)[1];
1129 int flag=ormask|oldflag;
1131 flagbody(ptr,flag,NULL,0,true);
1134 void flagbody(struct ___Object___ *ptr,
1136 struct parameterwrapper ** vqueues,
1139 struct parameterwrapper * flagptr = NULL;
1141 struct parameterwrapper ** queues = vqueues;
1142 int length = vlength;
1144 int UNUSED, UNUSED2;
1145 int * enterflags = NULL;
1146 if((!isnew) && (queues == NULL)) {
1147 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
1148 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1149 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1156 /*Remove object from all queues */
1157 for(i = 0; i < length; ++i) {
1158 flagptr = queues[i];
1159 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
1160 (int *) &enterflags, &UNUSED, &UNUSED2);
1161 ObjectHashremove(flagptr->objectset, (int)ptr);
1162 if (enterflags!=NULL)
1163 RUNFREE(enterflags);
1167 void enqueueObject(void * vptr,
1168 struct parameterwrapper ** vqueues,
1170 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1173 //struct QueueItem *tmpptr;
1174 struct parameterwrapper * parameter=NULL;
1177 struct parameterwrapper * prevptr=NULL;
1178 struct ___Object___ *tagptr=NULL;
1179 struct parameterwrapper ** queues = vqueues;
1180 int length = vlength;
1181 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1184 if(queues == NULL) {
1185 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1186 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1188 tagptr=ptr->___tags___;
1190 /* Outer loop iterates through all parameter queues an object of
1191 this type could be in. */
1192 for(j = 0; j < length; ++j) {
1193 parameter = queues[j];
1195 if (parameter->numbertags>0) {
1197 goto nextloop; //that means the object has no tag
1198 //but that param needs tag
1199 else if(tagptr->type==TAGTYPE) { //one tag
1200 //struct ___TagDescriptor___ * tag=
1201 //(struct ___TagDescriptor___*) tagptr;
1202 for(i=0; i<parameter->numbertags; i++) {
1203 //slotid is parameter->tagarray[2*i];
1204 int tagid=parameter->tagarray[2*i+1];
1205 if (tagid!=tagptr->flag)
1206 goto nextloop; /*We don't have this tag */
1208 } else { //multiple tags
1209 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1210 for(i=0; i<parameter->numbertags; i++) {
1211 //slotid is parameter->tagarray[2*i];
1212 int tagid=parameter->tagarray[2*i+1];
1214 for(j=0; j<ao->___cachedCode___; j++) {
1215 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1226 for(i=0; i<parameter->numberofterms; i++) {
1227 int andmask=parameter->intarray[i*2];
1228 int checkmask=parameter->intarray[i*2+1];
1229 if ((ptr->flag&andmask)==checkmask) {
1230 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
1241 void enqueueObject_I(void * vptr,
1242 struct parameterwrapper ** vqueues,
1244 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1247 //struct QueueItem *tmpptr;
1248 struct parameterwrapper * parameter=NULL;
1251 struct parameterwrapper * prevptr=NULL;
1252 struct ___Object___ *tagptr=NULL;
1253 struct parameterwrapper ** queues = vqueues;
1254 int length = vlength;
1255 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1258 if(queues == NULL) {
1259 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1260 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1262 tagptr=ptr->___tags___;
1264 /* Outer loop iterates through all parameter queues an object of
1265 this type could be in. */
1266 for(j = 0; j < length; ++j) {
1267 parameter = queues[j];
1269 if (parameter->numbertags>0) {
1271 goto nextloop; //that means the object has no tag
1272 //but that param needs tag
1273 else if(tagptr->type==TAGTYPE) { //one tag
1274 //struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
1275 for(i=0; i<parameter->numbertags; i++) {
1276 //slotid is parameter->tagarray[2*i];
1277 int tagid=parameter->tagarray[2*i+1];
1278 if (tagid!=tagptr->flag)
1279 goto nextloop; /*We don't have this tag */
1281 } else { //multiple tags
1282 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1283 for(i=0; i<parameter->numbertags; i++) {
1284 //slotid is parameter->tagarray[2*i];
1285 int tagid=parameter->tagarray[2*i+1];
1287 for(j=0; j<ao->___cachedCode___; j++) {
1288 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1299 for(i=0; i<parameter->numberofterms; i++) {
1300 int andmask=parameter->intarray[i*2];
1301 int checkmask=parameter->intarray[i*2+1];
1302 if ((ptr->flag&andmask)==checkmask) {
1303 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1315 int * getAliasLock(void ** ptrs,
1317 struct RuntimeHash * tbl) {
1319 return (int*)(RUNMALLOC(sizeof(int)));
1324 bool redirect = false;
1325 int redirectlock = 0;
1326 for(; i < length; i++) {
1327 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1330 if(ptr->lock == NULL) {
1333 lock = (int)(ptr->lock);
1336 if(lock != redirectlock) {
1337 RuntimeHashadd(tbl, lock, redirectlock);
1340 if(RuntimeHashcontainskey(tbl, lock)) {
1341 // already redirected
1343 RuntimeHashget(tbl, lock, &redirectlock);
1344 for(; j < locklen; j++) {
1345 if(locks[j] != redirectlock) {
1346 RuntimeHashadd(tbl, locks[j], redirectlock);
1351 for(j = 0; j < locklen; j++) {
1352 if(locks[j] == lock) {
1355 } else if(locks[j] > lock) {
1362 locks[h] = locks[h-1];
1371 return (int *)redirectlock;
1373 return (int *)(locks[0]);
1378 void addAliasLock(void * ptr,
1380 struct ___Object___ * obj = (struct ___Object___ *)ptr;
1381 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1382 // originally no alias lock associated or have a different alias lock
1383 // flush it as the new one
1384 obj->lock = (int *)lock;
1389 inline void setTaskExitIndex(int index) {
1390 taskInfoArray[taskInfoIndex]->exitIndex = index;
1393 inline void addNewObjInfo(void * nobj) {
1394 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1395 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1397 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1402 // Only allocate local mem chunks to each core.
1403 // If a core has used up its local shared memory, start gc.
1404 void * localmalloc_I(int coren,
1410 int tofindb = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1411 int totest = tofindb;
1412 int bound = BAMBOO_SMEM_SIZE_L;
1416 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1417 int nsize = bamboo_smemtbl[totest];
1418 bool islocal = true;
1420 bool tocheck = true;
1421 // have some space in the block
1422 if(totest == tofindb) {
1423 // the first partition
1424 size = bound - nsize;
1425 } else if(nsize == 0) {
1426 // an empty partition, can be appended
1429 // not an empty partition, can not be appended
1430 // the last continuous block is not big enough, go to check the next
1434 } // if(totest == tofindb) else if(nsize == 0) else ...
1437 // have enough space in the block, malloc
1441 // no enough space yet, try to append next continuous block
1443 } // if(size > isize) else ...
1445 } // if(nsize < bound)
1447 // no space in the block, go to check the next block
1453 tofindb = totest = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1456 } // if(islocal) else ...
1457 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1458 // no more local mem, do not find suitable block
1461 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1464 if(foundsmem == 1) {
1465 // find suitable block
1466 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1467 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1468 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1470 // set bamboo_smemtbl
1471 for(i = tofindb; i <= totest; i++) {
1472 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1474 } else if(foundsmem == 2) {
1475 // no suitable block
1480 } // void * localmalloc_I(int, int, int *)
1483 // Allocate the local shared memory to each core with the highest priority,
1484 // if a core has used up its local shared memory, try to allocate the
1485 // shared memory that belong to its neighbours, if also failed, start gc.
1486 void * fixedmalloc_I(int coren,
1493 int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
1494 int coords_x = bamboo_cpu2coords[gccorenum*2];
1495 int coords_y = bamboo_cpu2coords[gccorenum*2+1];
1497 int tofindb = gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1498 int totest = tofindb;
1499 int bound = BAMBOO_SMEM_SIZE_L;
1503 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1504 int nsize = bamboo_smemtbl[totest];
1505 bool islocal = true;
1507 bool tocheck = true;
1508 // have some space in the block
1509 if(totest == tofindb) {
1510 // the first partition
1511 size = bound - nsize;
1512 } else if(nsize == 0) {
1513 // an empty partition, can be appended
1516 // not an empty partition, can not be appended
1517 // the last continuous block is not big enough, go to check the next
1521 } // if(totest == tofindb) else if(nsize == 0) else ...
1524 // have enough space in the block, malloc
1528 // no enough space yet, try to append next continuous block
1529 // TODO may consider to go to next local block?
1531 } // if(size > isize) else ...
1533 } // if(nsize < bound)
1535 // no space in the block, go to check the next block
1542 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1545 } // if(islocal) else ...
1546 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1547 // no more local mem, do not find suitable block on local mem
1548 // try to malloc shared memory assigned to the neighbour cores
1551 if(k >= NUM_CORES2TEST) {
1552 // no more memory available on either coren or its neighbour cores
1554 goto memsearchresult;
1556 } while(core2test[gccorenum][k] == -1);
1559 tofindb=totest=gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1560 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1564 if(foundsmem == 1) {
1565 // find suitable block
1566 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1567 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1568 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1570 // set bamboo_smemtbl
1571 for(i = tofindb; i <= totest; i++) {
1572 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1574 } else if(foundsmem == 2) {
1575 // no suitable block
1580 } // void * fixedmalloc_I(int, int, int *)
1581 #endif // #ifdef SMEMF
1584 // Allocate the local shared memory to each core with the highest priority,
1585 // if a core has used up its local shared memory, try to allocate the
1586 // shared memory that belong to its neighbours first, if failed, check
1587 // current memory allocation rate, if it has already reached the threshold,
1588 // start gc, otherwise, allocate the shared memory globally. If all the
1589 // shared memory has been used up, start gc.
1590 void * mixedmalloc_I(int coren,
1597 int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
1598 int coords_x = bamboo_cpu2coords[gccorenum*2];
1599 int coords_y = bamboo_cpu2coords[gccorenum*2+1];
1601 int tofindb = gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1602 int totest = tofindb;
1603 int bound = BAMBOO_SMEM_SIZE_L;
1607 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1608 int nsize = bamboo_smemtbl[totest];
1609 bool islocal = true;
1611 bool tocheck = true;
1612 // have some space in the block
1613 if(totest == tofindb) {
1614 // the first partition
1615 size = bound - nsize;
1616 } else if(nsize == 0) {
1617 // an empty partition, can be appended
1620 // not an empty partition, can not be appended
1621 // the last continuous block is not big enough, go to check the next
1625 } // if(totest == tofindb) else if(nsize == 0) else ...
1628 // have enough space in the block, malloc
1632 // no enough space yet, try to append next continuous block
1633 // TODO may consider to go to next local block?
1635 } // if(size > isize) else ...
1637 } // if(nsize < bound)
1639 // no space in the block, go to check the next block
1646 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1649 } // if(islocal) else ...
1650 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1651 // no more local mem, do not find suitable block on local mem
1652 // try to malloc shared memory assigned to the neighbour cores
1655 if(k >= NUM_CORES2TEST) {
1656 if(gcmem_mixed_usedmem >= gcmem_mixed_threshold) {
1657 // no more memory available on either coren or its neighbour cores
1659 goto memmixedsearchresult;
1661 // try allocate globally
1662 mem = globalmalloc_I(coren, isize, allocsize);
1666 } while(core2test[gccorenum][k] == -1);
1670 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1671 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1674 memmixedsearchresult:
1675 if(foundsmem == 1) {
1676 // find suitable block
1677 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1678 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1679 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1681 // set bamboo_smemtbl
1682 for(i = tofindb; i <= totest; i++) {
1683 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1685 gcmem_mixed_usedmem += size;
1686 if(tofindb == bamboo_free_block) {
1687 bamboo_free_block = totest+1;
1689 } else if(foundsmem == 2) {
1690 // no suitable block
1695 } // void * mixedmalloc_I(int, int, int *)
1696 #endif // #ifdef SMEMM
1698 // Allocate all the memory chunks globally, do not consider the host cores
1699 // When all the shared memory are used up, start gc.
1700 void * globalmalloc_I(int coren,
1704 int tofindb = bamboo_free_block; //0;
1705 int totest = tofindb;
1706 int bound = BAMBOO_SMEM_SIZE_L;
1709 if(tofindb > gcnumblock-1-bamboo_reserved_smem) {
1710 // Out of shared memory
1715 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1716 int nsize = bamboo_smemtbl[totest];
1717 bool isnext = false;
1719 bool tocheck = true;
1720 // have some space in the block
1721 if(totest == tofindb) {
1722 // the first partition
1723 size = bound - nsize;
1724 } else if(nsize == 0) {
1725 // an empty partition, can be appended
1728 // not an empty partition, can not be appended
1729 // the last continuous block is not big enough, start another block
1732 } // if(totest == tofindb) else if(nsize == 0) else ...
1735 // have enough space in the block, malloc
1738 } // if(size > isize)
1742 } // if(nsize < bound) else ...
1744 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1745 // no more local mem, do not find suitable block
1748 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1750 // start another block
1755 if(foundsmem == 1) {
1756 // find suitable block
1757 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1758 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1759 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1761 // set bamboo_smemtbl
1762 for(int i = tofindb; i <= totest; i++) {
1763 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1765 if(tofindb == bamboo_free_block) {
1766 bamboo_free_block = totest+1;
1768 } else if(foundsmem == 2) {
1769 // no suitable block
1775 } // void * globalmalloc_I(int, int, int *)
1776 #endif // #ifdef MULTICORE_GC
1778 // malloc from the shared memory
1779 void * smemalloc_I(int coren,
1784 int isize = size+(BAMBOO_CACHE_LINE_SIZE);
1786 // go through the bamboo_smemtbl for suitable partitions
1787 switch(bamboo_smem_mode) {
1789 mem = localmalloc_I(coren, isize, allocsize);
1795 mem = fixedmalloc_I(coren, isize, allocsize);
1797 // not supported yet
1798 BAMBOO_EXIT(0xe001);
1805 mem = mixedmalloc_I(coren, isize, allocsize);
1807 // not supported yet
1808 BAMBOO_EXIT(0xe002);
1814 mem = globalmalloc_I(coren, isize, allocsize);
1826 /*if(!interruptInfoOverflow) {
1827 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
1828 interruptInfoArray[interruptInfoIndex] = intInfo;
1829 intInfo->startTime = BAMBOO_GET_EXE_TIME();
1830 intInfo->endTime = -1;
1833 int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size) : (BAMBOO_SMEM_SIZE);
1834 //mem = mspace_calloc(bamboo_free_msp, 1, toallocate);
1835 if(toallocate > bamboo_free_smem_size) {
1839 mem = (void *)bamboo_free_smemp;
1840 bamboo_free_smemp = ((void*)bamboo_free_smemp) + toallocate;
1841 bamboo_free_smem_size -= toallocate;
1842 //BAMBOO_MEMSET_WH(mem, '\0', toallocate);
1844 *allocsize = toallocate;
1846 /*if(!interruptInfoOverflow) {
1847 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
1848 interruptInfoIndex++;
1849 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
1850 interruptInfoOverflow = true;
1855 #endif // MULTICORE_GC
1856 // no enough shared global memory
1862 BAMBOO_DEBUGPRINT(0xa001);
1863 BAMBOO_EXIT(0xa001);
1867 } // void * smemalloc_I(int, int, int)
1869 INLINE int checkMsgLength_I(int size) {
1872 BAMBOO_DEBUGPRINT(0xcccc);
1875 int type = msgdata[msgdataindex];
1882 case GCSTARTMAPINFO:
1896 case GCSTARTCOMPACT:
1899 case GCFINISHMAPINFO:
1924 case REDIRECTGROUNT:
1926 case REDIRECTRELEASE:
1939 case GCFINISHCOMPACT:
1953 case TRANSOBJ: // nonfixed size
1959 msglength = msgdata[msgdataindex+1];
1968 BAMBOO_DEBUGPRINT_REG(type);
1969 BAMBOO_DEBUGPRINT_REG(size);
1970 BAMBOO_DEBUGPRINT_REG(msgdataindex);
1971 BAMBOO_DEBUGPRINT_REG(msgdatalast);
1972 BAMBOO_DEBUGPRINT_REG(msgdatafull);
1975 BAMBOO_DEBUGPRINT(msgdata[msgdataindex+i]);
1977 BAMBOO_EXIT(0xd005);
1983 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
1988 BAMBOO_DEBUGPRINT(0xffff);
1994 INLINE void processmsg_transobj_I() {
1996 struct transObjInfo * transObj=RUNMALLOC_I(sizeof(struct transObjInfo));
2000 BAMBOO_DEBUGPRINT(0xe880);
2003 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2005 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
2007 BAMBOO_EXIT(0xa002);
2009 // store the object and its corresponding queue info, enqueue it later
2010 transObj->objptr = (void *)msgdata[msgdataindex]; //[2]
2012 transObj->length = (msglength - 3) / 2;
2013 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
2014 for(k = 0; k < transObj->length; ++k) {
2015 transObj->queues[2*k] = msgdata[msgdataindex]; //[3+2*k];
2019 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
2022 transObj->queues[2*k+1] = msgdata[msgdataindex]; //[3+2*k+1];
2026 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
2030 // check if there is an existing duplicate item
2032 struct QueueItem * qitem = getHead(&objqueue);
2033 struct QueueItem * prev = NULL;
2034 while(qitem != NULL) {
2035 struct transObjInfo * tmpinfo =
2036 (struct transObjInfo *)(qitem->objectptr);
2037 if(tmpinfo->objptr == transObj->objptr) {
2038 // the same object, remove outdate one
2039 RUNFREE(tmpinfo->queues);
2041 removeItem(&objqueue, qitem);
2047 qitem = getHead(&objqueue);
2049 qitem = getNextQueueItem(prev);
2052 addNewItem_I(&objqueue, (void *)transObj);
2054 ++(self_numreceiveobjs);
2057 INLINE void processmsg_transtall_I() {
2058 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2059 // non startup core can not receive stall msg
2061 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
2063 BAMBOO_EXIT(0xa003);
2065 int num_core = msgdata[msgdataindex]; //[1]
2067 if(num_core < NUMCORESACTIVE) {
2070 BAMBOO_DEBUGPRINT(0xe881);
2073 corestatus[num_core] = 0;
2074 numsendobjs[num_core] = msgdata[msgdataindex]; //[2];
2076 numreceiveobjs[num_core] = msgdata[msgdataindex]; //[3];
2081 #ifndef MULTICORE_GC
2082 INLINE void processmsg_lockrequest_I() {
2083 // check to see if there is a lock exist for the required obj
2084 // msgdata[1] -> lock type
2085 int locktype = msgdata[msgdataindex]; //[1];
2087 int data2 = msgdata[msgdataindex]; // obj pointer
2089 int data3 = msgdata[msgdataindex]; // lock
2091 int data4 = msgdata[msgdataindex]; // request core
2093 // -1: redirected, 0: approved, 1: denied
2094 int deny=processlockrequest(locktype, data3, data2, data4, data4, true);
2096 // this lock request is redirected
2099 // send response msg
2100 // for 32 bit machine, the size is always 4 words, cache the msg first
2101 int tmp = deny==1 ? LOCKDENY : LOCKGROUNT;
2102 if(BAMBOO_CHECK_SEND_MODE()) {
2103 cache_msg_4(data4, tmp, locktype, data2, data3);
2105 send_msg_4(data4, tmp, locktype, data2, data3, true);
2110 INLINE void processmsg_lockgrount_I() {
2112 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2114 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
2116 BAMBOO_EXIT(0xa004);
2118 int data2 = msgdata[msgdataindex];
2120 int data3 = msgdata[msgdataindex];
2122 if((lockobj == data2) && (lock2require == data3)) {
2125 BAMBOO_DEBUGPRINT(0xe882);
2134 // conflicts on lockresults
2136 BAMBOO_DEBUGPRINT_REG(data2);
2138 BAMBOO_EXIT(0xa005);
2142 INLINE void processmsg_lockdeny_I() {
2144 int data2 = msgdata[msgdataindex];
2146 int data3 = msgdata[msgdataindex];
2148 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2150 BAMBOO_DEBUGPRINT_REG(data2);
2152 BAMBOO_EXIT(0xa006);
2154 if((lockobj == data2) && (lock2require == data3)) {
2157 BAMBOO_DEBUGPRINT(0xe883);
2166 // conflicts on lockresults
2168 BAMBOO_DEBUGPRINT_REG(data2);
2170 BAMBOO_EXIT(0xa007);
2174 INLINE void processmsg_lockrelease_I() {
2175 int data1 = msgdata[msgdataindex];
2177 int data2 = msgdata[msgdataindex];
2179 // receive lock release msg
2180 processlockrelease(data1, data2, 0, false);
2183 INLINE void processmsg_redirectlock_I() {
2184 // check to see if there is a lock exist for the required obj
2185 int data1 = msgdata[msgdataindex];
2186 MSG_INDEXINC_I(); //msgdata[1]; // lock type
2187 int data2 = msgdata[msgdataindex];
2188 MSG_INDEXINC_I(); //msgdata[2]; // obj pointer
2189 int data3 = msgdata[msgdataindex];
2190 MSG_INDEXINC_I(); //msgdata[3]; // redirect lock
2191 int data4 = msgdata[msgdataindex];
2192 MSG_INDEXINC_I(); //msgdata[4]; // root request core
2193 int data5 = msgdata[msgdataindex];
2194 MSG_INDEXINC_I(); //msgdata[5]; // request core
2195 int deny = processlockrequest(data1, data3, data2, data5, data4, true);
2197 // this lock request is redirected
2200 // send response msg
2201 // for 32 bit machine, the size is always 4 words, cache the msg first
2202 if(BAMBOO_CHECK_SEND_MODE()) {
2203 cache_msg_4(data4, deny==1 ? REDIRECTDENY : REDIRECTGROUNT,
2204 data1, data2, data3);
2206 send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
2207 data1, data2, data3, true);
2212 INLINE void processmsg_redirectgrount_I() {
2214 int data2 = msgdata[msgdataindex];
2216 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2218 BAMBOO_DEBUGPRINT_REG(data2);
2220 BAMBOO_EXIT(0xa00a);
2222 if(lockobj == data2) {
2225 BAMBOO_DEBUGPRINT(0xe891);
2228 int data3 = msgdata[msgdataindex];
2232 RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
2237 // conflicts on lockresults
2239 BAMBOO_DEBUGPRINT_REG(data2);
2241 BAMBOO_EXIT(0xa00b);
2245 INLINE void processmsg_redirectdeny_I() {
2247 int data2 = msgdata[msgdataindex];
2249 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2251 BAMBOO_DEBUGPRINT_REG(data2);
2253 BAMBOO_EXIT(0xa00c);
2255 if(lockobj == data2) {
2258 BAMBOO_DEBUGPRINT(0xe892);
2267 // conflicts on lockresults
2269 BAMBOO_DEBUGPRINT_REG(data2);
2271 BAMBOO_EXIT(0xa00d);
2275 INLINE void processmsg_redirectrelease_I() {
2276 int data1 = msgdata[msgdataindex];
2278 int data2 = msgdata[msgdataindex];
2280 int data3 = msgdata[msgdataindex];
2282 processlockrelease(data1, data2, data3, true);
2284 #endif // #ifndef MULTICORE_GC
2287 INLINE void processmsg_profileoutput_I() {
2288 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
2289 // startup core can not receive profile output finish msg
2290 BAMBOO_EXIT(0xa008);
2294 BAMBOO_DEBUGPRINT(0xe885);
2298 totalexetime = msgdata[msgdataindex]; //[1]
2300 outputProfileData();
2301 // cache the msg first
2302 if(BAMBOO_CHECK_SEND_MODE()) {
2303 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
2305 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE, true);
2309 INLINE void processmsg_profilefinish_I() {
2310 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2311 // non startup core can not receive profile output finish msg
2313 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex /*1*/]);
2315 BAMBOO_EXIT(0xa009);
2319 BAMBOO_DEBUGPRINT(0xe886);
2322 int data1 = msgdata[msgdataindex];
2324 profilestatus[data1] = 0;
2326 #endif // #ifdef PROFILE
2328 INLINE void processmsg_statusconfirm_I() {
2329 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2330 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2331 // wrong core to receive such msg
2332 BAMBOO_EXIT(0xa00e);
2334 // send response msg
2337 BAMBOO_DEBUGPRINT(0xe887);
2340 // cache the msg first
2341 if(BAMBOO_CHECK_SEND_MODE()) {
2342 cache_msg_5(STARTUPCORE, STATUSREPORT,
2343 busystatus ? 1 : 0, BAMBOO_NUM_OF_CORE,
2344 self_numsendobjs, self_numreceiveobjs);
2346 send_msg_5(STARTUPCORE, STATUSREPORT, busystatus?1:0,
2347 BAMBOO_NUM_OF_CORE, self_numsendobjs,
2348 self_numreceiveobjs, true);
2353 INLINE void processmsg_statusreport_I() {
2354 int data1 = msgdata[msgdataindex];
2356 int data2 = msgdata[msgdataindex];
2358 int data3 = msgdata[msgdataindex];
2360 int data4 = msgdata[msgdataindex];
2362 // receive a status confirm info
2363 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2364 // wrong core to receive such msg
2366 BAMBOO_DEBUGPRINT_REG(data2);
2368 BAMBOO_EXIT(0xa00f);
2372 BAMBOO_DEBUGPRINT(0xe888);
2378 corestatus[data2] = data1;
2379 numsendobjs[data2] = data3;
2380 numreceiveobjs[data2] = data4;
2384 INLINE void processmsg_terminate_I() {
2387 BAMBOO_DEBUGPRINT(0xe889);
2394 INLINE void processmsg_memrequest_I() {
2396 if(!interruptInfoOverflow) {
2397 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
2398 interruptInfoArray[interruptInfoIndex] = intInfo;
2399 intInfo->startTime = BAMBOO_GET_EXE_TIME();
2400 intInfo->endTime = -1;
2403 int data1 = msgdata[msgdataindex];
2405 int data2 = msgdata[msgdataindex];
2407 // receive a shared memory request msg
2408 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2409 // wrong core to receive such msg
2411 BAMBOO_DEBUGPRINT_REG(data2);
2413 BAMBOO_EXIT(0xa010);
2417 BAMBOO_DEBUGPRINT(0xe88a);
2424 // is currently doing gc, dump this msg
2425 if(INITPHASE == gcphase) {
2426 // if still in the initphase of gc, send a startinit msg again,
2427 // cache the msg first
2428 if(BAMBOO_CHECK_SEND_MODE()) {
2429 cache_msg_1(data2, GCSTARTINIT);
2431 send_msg_1(data2, GCSTARTINIT, true);
2436 mem = smemalloc_I(data2, data1, &allocsize);
2438 // send the start_va to request core, cache the msg first
2439 if(BAMBOO_CHECK_SEND_MODE()) {
2440 cache_msg_3(data2, MEMRESPONSE, mem, allocsize);
2442 send_msg_3(data2, MEMRESPONSE, mem, allocsize, true);
2444 } // if mem == NULL, the gcflag of the startup core has been set
2445 // and the gc should be started later, then a GCSTARTINIT msg
2446 // will be sent to the requesting core to notice it to start gc
2447 // and try malloc again
2453 if(!interruptInfoOverflow) {
2454 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
2455 interruptInfoIndex++;
2456 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
2457 interruptInfoOverflow = true;
2463 INLINE void processmsg_memresponse_I() {
2464 int data1 = msgdata[msgdataindex];
2466 int data2 = msgdata[msgdataindex];
2468 // receive a shared memory response msg
2471 BAMBOO_DEBUGPRINT(0xe88b);
2475 // if is currently doing gc, dump this msg
2479 bamboo_smem_size = 0;
2482 bamboo_smem_zero_top = 0;
2486 // fill header to store the size of this mem block
2487 BAMBOO_MEMSET_WH(data1, '\0', BAMBOO_CACHE_LINE_SIZE);
2488 //memset(data1, 0, BAMBOO_CACHE_LINE_SIZE);
2489 (*((int*)data1)) = data2;
2490 bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
2491 bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
2492 bamboo_smem_zero_top = bamboo_cur_msp;
2494 bamboo_smem_size = data2;
2495 bamboo_cur_msp =(void*)(data1);
2505 INLINE void processmsg_gcstartinit_I() {
2507 gcphase = INITPHASE;
2509 // is waiting for response of mem request
2510 // let it return NULL and start gc
2511 bamboo_smem_size = 0;
2512 bamboo_cur_msp = NULL;
2514 bamboo_smem_zero_top = NULL;
2518 INLINE void processmsg_gcstart_I() {
2521 BAMBOO_DEBUGPRINT(0xe88c);
2525 gcphase = MARKPHASE;
2528 INLINE void processmsg_gcstartcompact_I() {
2529 gcblock2fill = msgdata[msgdataindex];
2530 MSG_INDEXINC_I(); //msgdata[1];
2531 gcphase = COMPACTPHASE;
2534 INLINE void processmsg_gcstartmapinfo_I() {
2538 INLINE void processmsg_gcstartflush_I() {
2539 gcphase = FLUSHPHASE;
2542 INLINE void processmsg_gcfinishinit_I() {
2543 int data1 = msgdata[msgdataindex];
2545 // received a init phase finish msg
2546 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2547 // non startup core can not receive this msg
2549 BAMBOO_DEBUGPRINT_REG(data1);
2551 BAMBOO_EXIT(0xb001);
2554 BAMBOO_DEBUGPRINT(0xe88c);
2555 BAMBOO_DEBUGPRINT_REG(data1);
2557 // All cores should do init GC
2558 if(data1 < NUMCORESACTIVE) {
2559 gccorestatus[data1] = 0;
2563 INLINE void processmsg_gcfinishmark_I() {
2564 int data1 = msgdata[msgdataindex];
2566 int data2 = msgdata[msgdataindex];
2568 int data3 = msgdata[msgdataindex];
2570 // received a mark phase finish msg
2571 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2572 // non startup core can not receive this msg
2574 BAMBOO_DEBUGPRINT_REG(data1);
2576 BAMBOO_EXIT(0xb002);
2578 // all cores should do mark
2579 if(data1 < NUMCORESACTIVE) {
2580 gccorestatus[data1] = 0;
2581 gcnumsendobjs[data1] = data2;
2582 gcnumreceiveobjs[data1] = data3;
2586 INLINE void processmsg_gcfinishcompact_I() {
2587 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2588 // non startup core can not receive this msg
2591 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
2593 BAMBOO_EXIT(0xb003);
2595 int cnum = msgdata[msgdataindex];
2596 MSG_INDEXINC_I(); //msgdata[1];
2597 int filledblocks = msgdata[msgdataindex];
2598 MSG_INDEXINC_I(); //msgdata[2];
2599 int heaptop = msgdata[msgdataindex];
2600 MSG_INDEXINC_I(); //msgdata[3];
2601 int data4 = msgdata[msgdataindex];
2602 MSG_INDEXINC_I(); //msgdata[4];
2603 // only gc cores need to do compact
2604 if(cnum < NUMCORES4GC) {
2605 if(COMPACTPHASE == gcphase) {
2606 gcfilledblocks[cnum] = filledblocks;
2607 gcloads[cnum] = heaptop;
2614 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
2615 // cache the msg first
2616 if(BAMBOO_CHECK_SEND_MODE()) {
2617 cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
2619 send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove, true);
2623 gccorestatus[cnum] = 0;
2625 } // if(cnum < NUMCORES4GC)
2628 INLINE void processmsg_gcfinishmapinfo_I() {
2629 int data1 = msgdata[msgdataindex];
2631 // received a map phase finish msg
2632 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2633 // non startup core can not receive this msg
2636 BAMBOO_DEBUGPRINT_REG(data1);
2638 BAMBOO_EXIT(0xb004);
2640 // all cores should do flush
2641 if(data1 < NUMCORES4GC) {
2642 gccorestatus[data1] = 0;
2647 INLINE void processmsg_gcfinishflush_I() {
2648 int data1 = msgdata[msgdataindex];
2650 // received a flush phase finish msg
2651 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2652 // non startup core can not receive this msg
2655 BAMBOO_DEBUGPRINT_REG(data1);
2657 BAMBOO_EXIT(0xb005);
2659 // all cores should do flush
2660 if(data1 < NUMCORESACTIVE) {
2661 gccorestatus[data1] = 0;
2665 INLINE void processmsg_gcmarkconfirm_I() {
2666 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2667 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2668 // wrong core to receive such msg
2669 BAMBOO_EXIT(0xb006);
2671 // send response msg, cahce the msg first
2672 if(BAMBOO_CHECK_SEND_MODE()) {
2673 cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2674 gcbusystatus, gcself_numsendobjs,
2675 gcself_numreceiveobjs);
2677 send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2678 gcbusystatus, gcself_numsendobjs,
2679 gcself_numreceiveobjs, true);
2684 INLINE void processmsg_gcmarkreport_I() {
2685 int data1 = msgdata[msgdataindex];
2687 int data2 = msgdata[msgdataindex];
2689 int data3 = msgdata[msgdataindex];
2691 int data4 = msgdata[msgdataindex];
2693 // received a marked phase finish confirm response msg
2694 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2695 // wrong core to receive such msg
2697 BAMBOO_DEBUGPRINT_REG(data2);
2699 BAMBOO_EXIT(0xb007);
2704 gccorestatus[data1] = data2;
2705 gcnumsendobjs[data1] = data3;
2706 gcnumreceiveobjs[data1] = data4;
2710 INLINE void processmsg_gcmarkedobj_I() {
2711 int data1 = msgdata[msgdataindex];
2713 // received a markedObj msg
2714 if(((int *)data1)[6] == INIT) {
2715 // this is the first time that this object is discovered,
2716 // set the flag as DISCOVERED
2717 ((int *)data1)[6] = DISCOVERED;
2718 gc_enqueue_I(data1);
2720 // set the remote flag
2721 ((int *)data1)[6] |= REMOTEM;
2722 gcself_numreceiveobjs++;
2723 gcbusystatus = true;
2726 INLINE void processmsg_gcmovestart_I() {
2728 gcdstcore = msgdata[msgdataindex];
2729 MSG_INDEXINC_I(); //msgdata[1];
2730 gcmovestartaddr = msgdata[msgdataindex];
2731 MSG_INDEXINC_I(); //msgdata[2];
2732 gcblock2fill = msgdata[msgdataindex];
2733 MSG_INDEXINC_I(); //msgdata[3];
2736 INLINE void processmsg_gcmaprequest_I() {
2738 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2740 void * dstptr = NULL;
2741 int data1 = msgdata[msgdataindex];
2743 //dstptr = mgchashSearch(msgdata[1]);
2745 // TODO unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2747 RuntimeHashget(gcpointertbl, data1, &dstptr);
2749 // TODO flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2751 int data2 = msgdata[msgdataindex];
2753 //MGCHashget(gcpointertbl, msgdata[1], &dstptr);
2755 // TODO unsigned long long ttimei = BAMBOO_GET_EXE_TIME();
2757 if(NULL == dstptr) {
2758 // no such pointer in this core, something is wrong
2760 BAMBOO_DEBUGPRINT_REG(data1);
2761 BAMBOO_DEBUGPRINT_REG(data2);
2763 BAMBOO_EXIT(0xb009);
2764 //assume that the object was not moved, use the original address
2765 /*if(isMsgSending) {
2766 cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2768 send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2771 // send back the mapping info, cache the msg first
2772 if(BAMBOO_CHECK_SEND_MODE()) {
2773 cache_msg_3(data2, GCMAPINFO, data1, (int)dstptr);
2775 send_msg_3(data2, GCMAPINFO, data1, (int)dstptr, true);
2779 // TODO flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimei;
2780 //num_mapinforequest_i++;
2784 INLINE void processmsg_gcmapinfo_I() {
2786 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2788 int data1 = msgdata[msgdataindex];
2790 gcmappedobj = msgdata[msgdataindex]; // [2]
2792 //mgchashReplace_I(msgdata[1], msgdata[2]);
2793 //mgchashInsert_I(gcobj2map, gcmappedobj);
2794 RuntimeHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2795 /*struct nodemappinginfo * nodeinfo =
2796 (struct nodemappinginfo *)RUNMALLOC_I(sizeof(struct nodemappinginfo));
2797 nodeinfo->ptr = (void *)gcmappedobj;
2798 nodeinfo->cores = NULL;
2799 RuntimeHashadd_I(gcpointertbl, data1, (int)nodeinfo);*/
2800 //MGCHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2801 if(data1 == gcobj2map) {
2805 //flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2809 INLINE void processmsg_gcmaptbl_I() {
2810 int data1 = msgdata[msgdataindex];
2812 int data2 = msgdata[msgdataindex];
2814 gcrpointertbls[data2] = (mgcsharedhashtbl_t *)data1; //(struct GCSharedHash *)data1;
2817 INLINE void processmsg_gclobjinfo_I() {
2820 int data1 = msgdata[msgdataindex];
2822 int data2 = msgdata[msgdataindex];
2824 if(BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1) {
2826 BAMBOO_DEBUGPRINT_REG(data2);
2828 BAMBOO_EXIT(0xb00b);
2830 // store the mark result info
2832 gcloads[cnum] = msgdata[msgdataindex];
2833 MSG_INDEXINC_I(); // msgdata[3];
2834 int data4 = msgdata[msgdataindex];
2836 if(gcheaptop < data4) {
2839 // large obj info here
2840 for(int k = 5; k < data1; ) {
2841 int lobj = msgdata[msgdataindex];
2842 MSG_INDEXINC_I(); //msgdata[k++];
2843 int length = msgdata[msgdataindex];
2844 MSG_INDEXINC_I(); //msgdata[k++];
2845 gc_lobjenqueue_I(lobj, length, cnum);
2847 } // for(int k = 5; k < msgdata[1];)
2850 INLINE void processmsg_gclobjmapping_I() {
2851 int data1 = msgdata[msgdataindex];
2853 int data2 = msgdata[msgdataindex];
2855 //mgchashInsert_I(msgdata[1], msgdata[2]);
2856 RuntimeHashadd_I(gcpointertbl, data1, data2);
2857 mgcsharedhashInsert_I(gcsharedptbl, data1, data2);
2858 //GCSharedHashadd_I(gcsharedptbl, data1, data2);
2859 //MGCHashadd_I(gcpointertbl, msgdata[1], msgdata[2]);
2861 #endif // #ifdef MULTICORE_GC
2863 // receive object transferred from other cores
2864 // or the terminate message from other cores
2865 // Should be invoked in critical sections!!
2866 // NOTICE: following format is for threadsimulate version only
2867 // RAW version please see previous description
2868 // format: type + object
2869 // type: -1--stall msg
2871 // return value: 0--received an object
2872 // 1--received nothing
2873 // 2--received a Stall Msg
2874 // 3--received a lock Msg
2875 // RAW version: -1 -- received nothing
2876 // otherwise -- received msg type
2877 int receiveObject(int send_port_pending) {
2879 // get the incoming msgs
2880 if(receiveMsg(send_port_pending) == -1) {
2884 // processing received msgs
2886 MSG_REMAINSIZE_I(&size);
2887 if((size == 0) || (checkMsgLength_I(size) == -1)) {
2889 // have new coming msg
2890 if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
2897 if(msglength <= size) {
2898 // have some whole msg
2899 //if(msgdataindex == msglength) {
2900 // received a whole msg
2902 type = msgdata[msgdataindex]; //[0]
2904 msgdatafull = false;
2906 //tprintf("msg type: %x\n", type);
2909 // receive a object transfer msg
2910 processmsg_transobj_I();
2915 // receive a stall msg
2916 processmsg_transtall_I();
2920 // GC version have no lock msgs
2921 #ifndef MULTICORE_GC
2923 // receive lock request msg, handle it right now
2924 processmsg_lockrequest_I();
2926 } // case LOCKREQUEST
2929 // receive lock grount msg
2930 processmsg_lockgrount_I();
2932 } // case LOCKGROUNT
2935 // receive lock deny msg
2936 processmsg_lockdeny_I();
2941 processmsg_lockrelease_I();
2943 } // case LOCKRELEASE
2944 #endif // #ifndef MULTICORE_GC
2947 case PROFILEOUTPUT: {
2948 // receive an output profile data request msg
2949 processmsg_profileoutput_I();
2951 } // case PROFILEOUTPUT
2953 case PROFILEFINISH: {
2954 // receive a profile output finish msg
2955 processmsg_profilefinish_I();
2957 } // case PROFILEFINISH
2958 #endif // #ifdef PROFILE
2960 // GC version has no lock msgs
2961 #ifndef MULTICORE_GC
2962 case REDIRECTLOCK: {
2963 // receive a redirect lock request msg, handle it right now
2964 processmsg_redirectlock_I();
2966 } // case REDIRECTLOCK
2968 case REDIRECTGROUNT: {
2969 // receive a lock grant msg with redirect info
2970 processmsg_redirectgrount_I();
2972 } // case REDIRECTGROUNT
2974 case REDIRECTDENY: {
2975 // receive a lock deny msg with redirect info
2976 processmsg_redirectdeny_I();
2978 } // case REDIRECTDENY
2980 case REDIRECTRELEASE: {
2981 // receive a lock release msg with redirect info
2982 processmsg_redirectrelease_I();
2984 } // case REDIRECTRELEASE
2985 #endif // #ifndef MULTICORE_GC
2987 case STATUSCONFIRM: {
2988 // receive a status confirm info
2989 processmsg_statusconfirm_I();
2991 } // case STATUSCONFIRM
2993 case STATUSREPORT: {
2994 processmsg_statusreport_I();
2996 } // case STATUSREPORT
2999 // receive a terminate msg
3000 processmsg_terminate_I();
3005 processmsg_memrequest_I();
3007 } // case MEMREQUEST
3010 processmsg_memresponse_I();
3012 } // case MEMRESPONSE
3017 processmsg_gcstartinit_I();
3019 } // case GCSTARTINIT
3022 // receive a start GC msg
3023 processmsg_gcstart_I();
3027 case GCSTARTCOMPACT: {
3028 // a compact phase start msg
3029 processmsg_gcstartcompact_I();
3031 } // case GCSTARTCOMPACT
3033 case GCSTARTMAPINFO: {
3034 // received a flush phase start msg
3035 processmsg_gcstartmapinfo_I();
3037 } // case GCSTARTFLUSH
3039 case GCSTARTFLUSH: {
3040 // received a flush phase start msg
3041 processmsg_gcstartflush_I();
3043 } // case GCSTARTFLUSH
3045 case GCFINISHINIT: {
3046 processmsg_gcfinishinit_I();
3048 } // case GCFINISHINIT
3050 case GCFINISHMARK: {
3051 processmsg_gcfinishmark_I();
3053 } // case GCFINISHMARK
3055 case GCFINISHCOMPACT: {
3056 // received a compact phase finish msg
3057 processmsg_gcfinishcompact_I();
3059 } // case GCFINISHCOMPACT
3061 case GCFINISHMAPINFO: {
3062 processmsg_gcfinishmapinfo_I();
3064 } // case GCFINISHMAPINFO
3066 case GCFINISHFLUSH: {
3067 processmsg_gcfinishflush_I();
3069 } // case GCFINISHFLUSH
3072 // received a GC finish msg
3073 gcphase = FINISHPHASE;
3077 case GCMARKCONFIRM: {
3078 // received a marked phase finish confirm request msg
3079 // all cores should do mark
3080 processmsg_gcmarkconfirm_I();
3082 } // case GCMARKCONFIRM
3084 case GCMARKREPORT: {
3085 processmsg_gcmarkreport_I();
3087 } // case GCMARKREPORT
3090 processmsg_gcmarkedobj_I();
3092 } // case GCMARKEDOBJ
3095 // received a start moving objs msg
3096 processmsg_gcmovestart_I();
3098 } // case GCMOVESTART
3100 case GCMAPREQUEST: {
3101 // received a mapping info request msg
3102 processmsg_gcmaprequest_I();
3104 } // case GCMAPREQUEST
3107 // received a mapping info response msg
3108 processmsg_gcmapinfo_I();
3113 // received a mapping tbl response msg
3114 processmsg_gcmaptbl_I();
3118 case GCLOBJREQUEST: {
3119 // received a large objs info request msg
3120 transferMarkResults_I();
3122 } // case GCLOBJREQUEST
3125 // received a large objs info response msg
3126 processmsg_gclobjinfo_I();
3128 } // case GCLOBJINFO
3130 case GCLOBJMAPPING: {
3131 // received a large obj mapping info msg
3132 processmsg_gclobjmapping_I();
3134 } // case GCLOBJMAPPING
3136 #endif // #ifdef MULTICORE_GC
3141 //memset(msgdata, '\0', sizeof(int) * msgdataindex);
3143 msglength = BAMBOO_MSG_BUF_LENGTH;
3145 //printf("++ msg: %x \n", type);
3147 if(msgdataindex != msgdatalast) {
3148 // still have available msg
3153 BAMBOO_DEBUGPRINT(0xe88d);
3157 // have new coming msg
3158 if(BAMBOO_MSG_AVAIL() != 0) {
3172 BAMBOO_DEBUGPRINT(0xe88e);
3176 /* if(isInterrupt) {
3184 int enqueuetasks(struct parameterwrapper *parameter,
3185 struct parameterwrapper *prevptr,
3186 struct ___Object___ *ptr,
3188 int numenterflags) {
3189 void * taskpointerarray[MAXTASKPARAMS];
3191 //int numparams=parameter->task->numParameters;
3192 int numiterators=parameter->task->numTotal-1;
3195 struct taskdescriptor * task=parameter->task;
3197 //this add the object to parameterwrapper
3198 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
3199 numenterflags, enterflags==NULL);
3201 /* Add enqueued object to parameter vector */
3202 taskpointerarray[parameter->slot]=ptr;
3204 /* Reset iterators */
3205 for(j=0; j<numiterators; j++) {
3206 toiReset(¶meter->iterators[j]);
3209 /* Find initial state */
3210 for(j=0; j<numiterators; j++) {
3212 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3213 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3215 /* Need to backtrack */
3216 toiReset(¶meter->iterators[j]);
3220 /* Nothing to enqueue */
3226 /* Enqueue current state */
3228 struct taskparamdescriptor *tpd=
3229 RUNMALLOC(sizeof(struct taskparamdescriptor));
3231 tpd->numParameters=numiterators+1;
3232 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
3234 for(j=0; j<=numiterators; j++) {
3235 //store the actual parameters
3236 tpd->parameterArray[j]=taskpointerarray[j];
3239 if (( /*!gencontains(failedtasks, tpd)&&*/
3240 !gencontains(activetasks,tpd))) {
3241 genputtable(activetasks, tpd, tpd);
3243 RUNFREE(tpd->parameterArray);
3247 /* This loop iterates to the next parameter combination */
3248 if (numiterators==0)
3251 for(j=numiterators-1; j<numiterators; j++) {
3253 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3254 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3256 /* Need to backtrack */
3257 toiReset(¶meter->iterators[j]);
3261 /* Nothing more to enqueue */
3269 int enqueuetasks_I(struct parameterwrapper *parameter,
3270 struct parameterwrapper *prevptr,
3271 struct ___Object___ *ptr,
3273 int numenterflags) {
3274 void * taskpointerarray[MAXTASKPARAMS];
3276 //int numparams=parameter->task->numParameters;
3277 int numiterators=parameter->task->numTotal-1;
3282 struct taskdescriptor * task=parameter->task;
3284 //this add the object to parameterwrapper
3285 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
3286 numenterflags, enterflags==NULL);
3288 /* Add enqueued object to parameter vector */
3289 taskpointerarray[parameter->slot]=ptr;
3291 /* Reset iterators */
3292 for(j=0; j<numiterators; j++) {
3293 toiReset(¶meter->iterators[j]);
3296 /* Find initial state */
3297 for(j=0; j<numiterators; j++) {
3299 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3300 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3302 /* Need to backtrack */
3303 toiReset(¶meter->iterators[j]);
3307 /* Nothing to enqueue */
3313 /* Enqueue current state */
3315 struct taskparamdescriptor *tpd=
3316 RUNMALLOC_I(sizeof(struct taskparamdescriptor));
3318 tpd->numParameters=numiterators+1;
3319 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
3321 for(j=0; j<=numiterators; j++) {
3322 //store the actual parameters
3323 tpd->parameterArray[j]=taskpointerarray[j];
3326 if (( /*!gencontains(failedtasks, tpd)&&*/
3327 !gencontains(activetasks,tpd))) {
3328 genputtable_I(activetasks, tpd, tpd);
3330 RUNFREE(tpd->parameterArray);
3334 /* This loop iterates to the next parameter combination */
3335 if (numiterators==0)
3338 for(j=numiterators-1; j<numiterators; j++) {
3340 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
3341 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3343 /* Need to backtrack */
3344 toiReset(¶meter->iterators[j]);
3348 /* Nothing more to enqueue */
3362 int containstag(struct ___Object___ *ptr,
3363 struct ___TagDescriptor___ *tag);
3365 #ifndef MULTICORE_GC
3366 void releasewritelock_r(void * lock, void * redirectlock) {
3368 int reallock = (int)lock;
3369 targetcore = (reallock >> 5) % NUMCORES;
3372 BAMBOO_DEBUGPRINT(0xe671);
3373 BAMBOO_DEBUGPRINT_REG((int)lock);
3374 BAMBOO_DEBUGPRINT_REG(reallock);
3375 BAMBOO_DEBUGPRINT_REG(targetcore);
3378 if(targetcore == BAMBOO_NUM_OF_CORE) {
3379 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3381 BAMBOO_DEBUGPRINT(0xf001);
3383 // reside on this core
3384 if(!RuntimeHashcontainskey(locktbl, reallock)) {
3385 // no locks for this object, something is wrong
3386 BAMBOO_EXIT(0xa00b);
3389 struct LockValue * lockvalue = NULL;
3391 BAMBOO_DEBUGPRINT(0xe672);
3393 RuntimeHashget(locktbl, reallock, &rwlock_obj);
3394 lockvalue = (struct LockValue *)rwlock_obj;
3396 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
3399 lockvalue->redirectlock = (int)redirectlock;
3401 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
3404 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3406 BAMBOO_DEBUGPRINT(0xf000);
3410 // send lock release with redirect info msg
3411 // for 32 bit machine, the size is always 4 words
3412 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock,
3413 (int)redirectlock, false);
3418 void executetasks() {
3419 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
3422 struct ___Object___ * tmpparam = NULL;
3423 struct parameterdescriptor * pd=NULL;
3424 struct parameterwrapper *pw=NULL;
3434 while(hashsize(activetasks)>0) {
3439 BAMBOO_DEBUGPRINT(0xe990);
3442 /* See if there are any active tasks */
3443 //if (hashsize(activetasks)>0) {
3446 #ifdef ACCURATEPROFILE
3447 profileTaskStart("tpd checking");
3451 //clock1 = BAMBOO_GET_EXE_TIME();
3454 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
3455 genfreekey(activetasks, currtpd);
3457 numparams=currtpd->task->numParameters;
3458 numtotal=currtpd->task->numTotal;
3460 // clear the lockRedirectTbl
3461 // (TODO, this table should be empty after all locks are released)
3463 /*for(j = 0; j < MAXTASKPARAMS; j++) {
3464 runtime_locks[j].redirectlock = 0;
3465 runtime_locks[j].value = 0;
3467 // get all required locks
3468 runtime_locklen = 0;
3469 // check which locks are needed
3470 for(i = 0; i < numparams; i++) {
3471 void * param = currtpd->parameterArray[i];
3475 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
3477 taskpointerarray[i+OFFSET]=param;
3480 if(((struct ___Object___ *)param)->lock == NULL) {
3481 tmplock = (int)param;
3483 tmplock = (int)(((struct ___Object___ *)param)->lock);
3485 // insert into the locks array
3486 for(j = 0; j < runtime_locklen; j++) {
3487 if(runtime_locks[j].value == tmplock) {
3490 } else if(runtime_locks[j].value > tmplock) {
3495 int h = runtime_locklen;
3497 runtime_locks[h].redirectlock = runtime_locks[h-1].redirectlock;
3498 runtime_locks[h].value = runtime_locks[h-1].value;
3500 runtime_locks[j].value = tmplock;
3501 runtime_locks[j].redirectlock = (int)param;
3504 } // line 2713: for(i = 0; i < numparams; i++)
3505 // grab these required locks
3507 BAMBOO_DEBUGPRINT(0xe991);
3510 //clock2 = BAMBOO_GET_EXE_TIME();
3512 for(i = 0; i < runtime_locklen; i++) {
3513 int * lock = (int *)(runtime_locks[i].redirectlock);
3515 // require locks for this parameter if it is not a startup object
3517 BAMBOO_DEBUGPRINT_REG((int)lock);
3518 BAMBOO_DEBUGPRINT_REG((int)(runtime_locks[i].value));
3521 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3523 BAMBOO_DEBUGPRINT(0xf001);
3526 //isInterrupt = false;
3529 BAMBOO_WAITING_FOR_LOCK(0);
3533 while(BAMBOO_WAITING_FOR_LOCK(0) != -1) {
3537 grount = lockresult;
3547 //isInterrupt = true;
3549 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3551 BAMBOO_DEBUGPRINT(0xf000);
3556 BAMBOO_DEBUGPRINT(0xe992);
3557 BAMBOO_DEBUGPRINT_REG(lock);
3559 // check if has the lock already
3560 // can not get the lock, try later
3561 // release all grabbed locks for previous parameters
3562 for(j = 0; j < i; ++j) {
3563 lock = (int*)(runtime_locks[j].redirectlock);
3564 releasewritelock(lock);
3566 genputtable(activetasks, currtpd, currtpd);
3567 if(hashsize(activetasks) == 1) {
3568 // only one task right now, wait a little while before next try
3574 #ifdef ACCURATEPROFILE
3575 // fail, set the end of the checkTaskInfo
3582 } // line 2752: for(i = 0; i < runtime_locklen; i++)
3585 clock3 = BAMBOO_GET_EXE_TIME();
3586 //tprintf("sort: %d, grab: %d \n", clock2-clock1, clock3-clock2);*/
3589 BAMBOO_DEBUGPRINT(0xe993);
3591 /* Make sure that the parameters are still in the queues */
3592 for(i=0; i<numparams; i++) {
3593 void * parameter=currtpd->parameterArray[i];
3597 BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
3598 classsize[((struct ___Object___ *)parameter)->type]);
3600 tmpparam = (struct ___Object___ *)parameter;
3601 pd=currtpd->task->descriptorarray[i];
3602 pw=(struct parameterwrapper *) pd->queue;
3603 /* Check that object is still in queue */
3605 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
3607 BAMBOO_DEBUGPRINT(0xe994);
3608 BAMBOO_DEBUGPRINT_REG(parameter);
3610 // release grabbed locks
3611 for(j = 0; j < runtime_locklen; ++j) {
3612 int * lock = (int *)(runtime_locks[j].redirectlock);
3613 releasewritelock(lock);
3615 RUNFREE(currtpd->parameterArray);
3621 /* Check if the object's flags still meets requirements */
3625 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
3626 andmask=pw->intarray[tmpi*2];
3627 checkmask=pw->intarray[tmpi*2+1];
3628 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
3634 // flags are never suitable
3635 // remove this obj from the queue
3637 int UNUSED, UNUSED2;
3640 BAMBOO_DEBUGPRINT(0xe995);
3641 BAMBOO_DEBUGPRINT_REG(parameter);
3643 ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
3644 (int *) &enterflags, &UNUSED, &UNUSED2);
3645 ObjectHashremove(pw->objectset, (int)parameter);
3646 if (enterflags!=NULL)
3647 RUNFREE(enterflags);
3648 // release grabbed locks
3649 for(j = 0; j < runtime_locklen; ++j) {
3650 int * lock = (int *)(runtime_locks[j].redirectlock);
3651 releasewritelock(lock);
3653 RUNFREE(currtpd->parameterArray);
3657 #ifdef ACCURATEPROFILE
3658 // fail, set the end of the checkTaskInfo
3663 } // line 2878: if (!ismet)
3667 /* Check that object still has necessary tags */
3668 for(j=0; j<pd->numbertags; j++) {
3669 int slotid=pd->tagarray[2*j]+numparams;
3670 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
3671 if (!containstag(parameter, tagd)) {
3673 BAMBOO_DEBUGPRINT(0xe996);
3676 // release grabbed locks
3678 for(tmpj = 0; tmpj < runtime_locklen; ++tmpj) {
3679 int * lock = (int *)(runtime_locks[tmpj].redirectlock);
3680 releasewritelock(lock);
3683 RUNFREE(currtpd->parameterArray);
3687 } // line2911: if (!containstag(parameter, tagd))
3688 } // line 2808: for(j=0; j<pd->numbertags; j++)
3690 taskpointerarray[i+OFFSET]=parameter;
3691 } // line 2824: for(i=0; i<numparams; i++)
3693 for(; i<numtotal; i++) {
3694 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
3699 /* Actually call task */
3701 ((int *)taskpointerarray)[0]=currtpd->numParameters;
3702 taskpointerarray[1]=NULL;
3705 #ifdef ACCURATEPROFILE
3706 // check finish, set the end of the checkTaskInfo
3709 profileTaskStart(currtpd->task->name);
3713 //clock4 = BAMBOO_GET_EXE_TIME();
3714 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3717 BAMBOO_DEBUGPRINT(0xe997);
3719 ((void (*)(void **))currtpd->task->taskptr)(taskpointerarray);
3722 //clock5 = BAMBOO_GET_EXE_TIME();
3723 // tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3726 #ifdef ACCURATEPROFILE
3727 // task finish, set the end of the checkTaskInfo
3729 // new a PostTaskInfo for the post-task execution
3730 profileTaskStart("post task execution");
3734 BAMBOO_DEBUGPRINT(0xe998);
3735 BAMBOO_DEBUGPRINT_REG(islock);
3740 BAMBOO_DEBUGPRINT(0xe999);
3742 for(i = 0; i < runtime_locklen; ++i) {
3743 void * ptr = (void *)(runtime_locks[i].redirectlock);
3744 int * lock = (int *)(runtime_locks[i].value);
3746 BAMBOO_DEBUGPRINT_REG((int)ptr);
3747 BAMBOO_DEBUGPRINT_REG((int)lock);
3748 BAMBOO_DEBUGPRINT_REG(*((int*)lock+5));
3750 #ifndef MULTICORE_GC
3751 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
3753 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
3754 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
3755 releasewritelock_r(lock, (int *)redirectlock);
3760 releasewritelock(ptr);
3763 } // line 3015: if(islock)
3766 //clock6 = BAMBOO_GET_EXE_TIME();
3767 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3770 // post task execution finish, set the end of the postTaskInfo
3774 // Free up task parameter descriptor
3775 RUNFREE(currtpd->parameterArray);
3779 BAMBOO_DEBUGPRINT(0xe99a);
3782 //clock7 = BAMBOO_GET_EXE_TIME();
3783 //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));
3786 //} // if (hashsize(activetasks)>0)
3787 } // while(hashsize(activetasks)>0)
3789 BAMBOO_DEBUGPRINT(0xe99b);
3793 /* This function processes an objects tags */
3794 void processtags(struct parameterdescriptor *pd,
3796 struct parameterwrapper *parameter,
3797 int * iteratorcount,
3802 for(i=0; i<pd->numbertags; i++) {
3803 int slotid=pd->tagarray[2*i];
3804 int tagid=pd->tagarray[2*i+1];
3806 if (statusarray[slotid+numparams]==0) {
3807 parameter->iterators[*iteratorcount].istag=1;
3808 parameter->iterators[*iteratorcount].tagid=tagid;
3809 parameter->iterators[*iteratorcount].slot=slotid+numparams;
3810 parameter->iterators[*iteratorcount].tagobjectslot=index;
3811 statusarray[slotid+numparams]=1;
3818 void processobject(struct parameterwrapper *parameter,
3820 struct parameterdescriptor *pd,
3826 struct ObjectHash * objectset=
3827 ((struct parameterwrapper *)pd->queue)->objectset;
3829 parameter->iterators[*iteratorcount].istag=0;
3830 parameter->iterators[*iteratorcount].slot=index;
3831 parameter->iterators[*iteratorcount].objectset=objectset;
3832 statusarray[index]=1;
3834 for(i=0; i<pd->numbertags; i++) {
3835 int slotid=pd->tagarray[2*i];
3836 //int tagid=pd->tagarray[2*i+1];
3837 if (statusarray[slotid+numparams]!=0) {
3838 /* This tag has already been enqueued, use it to narrow search */
3839 parameter->iterators[*iteratorcount].tagbindings[tagcount]=
3844 parameter->iterators[*iteratorcount].numtags=tagcount;
3849 /* This function builds the iterators for a task & parameter */
3851 void builditerators(struct taskdescriptor * task,
3853 struct parameterwrapper * parameter) {
3854 int statusarray[MAXTASKPARAMS];
3856 int numparams=task->numParameters;
3857 int iteratorcount=0;
3858 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
3860 statusarray[index]=1; /* Initial parameter */
3861 /* Process tags for initial iterator */
3863 processtags(task->descriptorarray[index], index, parameter,
3864 &iteratorcount, statusarray, numparams);
3868 /* Check for objects with existing tags */
3869 for(i=0; i<numparams; i++) {
3870 if (statusarray[i]==0) {
3871 struct parameterdescriptor *pd=task->descriptorarray[i];
3873 for(j=0; j<pd->numbertags; j++) {
3874 int slotid=pd->tagarray[2*j];
3875 if(statusarray[slotid+numparams]!=0) {
3876 processobject(parameter, i, pd, &iteratorcount, statusarray,
3878 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3885 /* Next do objects w/ unbound tags*/
3887 for(i=0; i<numparams; i++) {
3888 if (statusarray[i]==0) {
3889 struct parameterdescriptor *pd=task->descriptorarray[i];
3890 if (pd->numbertags>0) {
3891 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3892 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3898 /* Nothing with a tag enqueued */
3900 for(i=0; i<numparams; i++) {
3901 if (statusarray[i]==0) {
3902 struct parameterdescriptor *pd=task->descriptorarray[i];
3903 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3904 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3917 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3920 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3921 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3923 printf("%s\n", task->name);
3925 for(j=0; j<task->numParameters; j++) {
3926 struct parameterdescriptor *param=task->descriptorarray[j];
3927 struct parameterwrapper *parameter=param->queue;
3928 struct ObjectHash * set=parameter->objectset;
3929 struct ObjectIterator objit;
3931 printf(" Parameter %d\n", j);
3933 ObjectHashiterator(set, &objit);
3934 while(ObjhasNext(&objit)) {
3935 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
3936 struct ___Object___ * tagptr=obj->___tags___;
3937 int nonfailed=Objdata4(&objit);
3938 int numflags=Objdata3(&objit);
3939 int flags=Objdata2(&objit);
3942 printf(" Contains %lx\n", obj);
3943 printf(" flag=%d\n", obj->flag);
3946 } else if (tagptr->type==TAGTYPE) {
3948 printf(" tag=%lx\n",tagptr);
3954 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
3955 for(; tagindex<ao->___cachedCode___; tagindex++) {
3957 printf(" tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*,
3970 /* This function processes the task information to create queues for
3971 each parameter type. */
3973 void processtasks() {
3975 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3978 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3979 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3982 /* Build objectsets */
3983 for(j=0; j<task->numParameters; j++) {
3984 struct parameterdescriptor *param=task->descriptorarray[j];
3985 struct parameterwrapper *parameter=param->queue;
3986 parameter->objectset=allocateObjectHash(10);
3987 parameter->task=task;
3990 /* Build iterators for parameters */
3991 for(j=0; j<task->numParameters; j++) {
3992 struct parameterdescriptor *param=task->descriptorarray[j];
3993 struct parameterwrapper *parameter=param->queue;
3994 builditerators(task, j, parameter);
3999 void toiReset(struct tagobjectiterator * it) {
4002 } else if (it->numtags>0) {
4005 ObjectHashiterator(it->objectset, &it->it);
4009 int toiHasNext(struct tagobjectiterator *it,
4010 void ** objectarray OPTARG(int * failed)) {
4013 /* Get object with tags */
4014 struct ___Object___ *obj=objectarray[it->tagobjectslot];
4015 struct ___Object___ *tagptr=obj->___tags___;
4016 if (tagptr->type==TAGTYPE) {
4017 if ((it->tagobjindex==0)&& /* First object */
4018 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
4023 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
4024 int tagindex=it->tagobjindex;
4025 for(; tagindex<ao->___cachedCode___; tagindex++) {
4026 struct ___TagDescriptor___ *td=
4027 ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
4028 if (td->flag==it->tagid) {
4029 it->tagobjindex=tagindex; /* Found right type of tag */
4035 } else if (it->numtags>0) {
4036 /* Use tags to locate appropriate objects */
4037 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
4038 struct ___Object___ *objptr=tag->flagptr;
4040 if (objptr->type!=OBJECTARRAYTYPE) {
4041 if (it->tagobjindex>0)
4043 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
4045 for(i=1; i<it->numtags; i++) {
4046 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
4047 if (!containstag(objptr,tag2))
4052 struct ArrayObject *ao=(struct ArrayObject *) objptr;
4055 for(tagindex=it->tagobjindex; tagindex<ao->___cachedCode___; tagindex++) {
4056 struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
4057 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
4059 for(i=1; i<it->numtags; i++) {
4060 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
4061 if (!containstag(objptr,tag2))
4064 it->tagobjindex=tagindex;
4069 it->tagobjindex=tagindex;
4073 return ObjhasNext(&it->it);
4077 int containstag(struct ___Object___ *ptr,
4078 struct ___TagDescriptor___ *tag) {
4080 struct ___Object___ * objptr=tag->flagptr;
4081 if (objptr->type==OBJECTARRAYTYPE) {
4082 struct ArrayObject *ao=(struct ArrayObject *)objptr;
4083 for(j=0; j<ao->___cachedCode___; j++) {
4084 if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
4094 void toiNext(struct tagobjectiterator *it,
4095 void ** objectarray OPTARG(int * failed)) {
4096 /* hasNext has all of the intelligence */
4099 /* Get object with tags */
4100 struct ___Object___ *obj=objectarray[it->tagobjectslot];
4101 struct ___Object___ *tagptr=obj->___tags___;
4102 if (tagptr->type==TAGTYPE) {
4104 objectarray[it->slot]=tagptr;
4106 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
4107 objectarray[it->slot]=
4108 ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
4110 } else if (it->numtags>0) {
4111 /* Use tags to locate appropriate objects */
4112 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
4113 struct ___Object___ *objptr=tag->flagptr;
4114 if (objptr->type!=OBJECTARRAYTYPE) {
4116 objectarray[it->slot]=objptr;
4118 struct ArrayObject *ao=(struct ArrayObject *) objptr;
4119 objectarray[it->slot]=
4120 ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
4123 /* Iterate object */
4124 objectarray[it->slot]=(void *)Objkey(&it->it);
4130 inline void profileTaskStart(char * taskname) {
4131 if(!taskInfoOverflow) {
4132 TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
4133 taskInfoArray[taskInfoIndex] = taskInfo;
4134 taskInfo->taskName = taskname;
4135 taskInfo->startTime = BAMBOO_GET_EXE_TIME();
4136 taskInfo->endTime = -1;
4137 taskInfo->exitIndex = -1;
4138 taskInfo->newObjs = NULL;
4142 inline void profileTaskEnd() {
4143 if(!taskInfoOverflow) {
4144 taskInfoArray[taskInfoIndex]->endTime = BAMBOO_GET_EXE_TIME();
4146 if(taskInfoIndex == TASKINFOLENGTH) {
4147 taskInfoOverflow = true;
4148 //taskInfoIndex = 0;
4153 // output the profiling data
4154 void outputProfileData() {
4157 unsigned long long totaltasktime = 0;
4158 unsigned long long preprocessingtime = 0;
4159 unsigned long long objqueuecheckingtime = 0;
4160 unsigned long long postprocessingtime = 0;
4161 //int interruptiontime = 0;
4162 unsigned long long other = 0;
4163 unsigned long long averagetasktime = 0;
4166 printf("Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
4167 // output task related info
4168 for(i = 0; i < taskInfoIndex; i++) {
4169 TaskInfo* tmpTInfo = taskInfoArray[i];
4170 unsigned long long duration = tmpTInfo->endTime - tmpTInfo->startTime;
4171 printf("%s, %lld, %lld, %lld, %lld",
4172 tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime,
4173 duration, tmpTInfo->exitIndex);
4174 // summarize new obj info
4175 if(tmpTInfo->newObjs != NULL) {
4176 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
4177 struct RuntimeIterator * iter = NULL;
4178 while(0 == isEmpty(tmpTInfo->newObjs)) {
4179 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
4180 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
4182 RuntimeHashget(nobjtbl, (int)objtype, &num);
4183 RuntimeHashremovekey(nobjtbl, (int)objtype);
4185 RuntimeHashadd(nobjtbl, (int)objtype, num);
4187 RuntimeHashadd(nobjtbl, (int)objtype, 1);
4189 //printf(stderr, "new obj!\n");
4192 // output all new obj info
4193 iter = RuntimeHashcreateiterator(nobjtbl);
4194 while(RunhasNext(iter)) {
4195 char * objtype = (char *)Runkey(iter);
4196 int num = Runnext(iter);
4197 printf(", %s, %d", objtype, num);
4201 if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
4202 preprocessingtime += duration;
4203 } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
4204 postprocessingtime += duration;
4205 } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
4206 objqueuecheckingtime += duration;
4208 totaltasktime += duration;
4209 averagetasktime += duration;
4214 if(taskInfoOverflow) {
4215 printf("Caution: task info overflow!\n");
4218 other = totalexetime-totaltasktime-preprocessingtime-postprocessingtime;
4219 averagetasktime /= tasknum;
4221 printf("\nTotal time: %lld\n", totalexetime);
4222 printf("Total task execution time: %lld (%d%%)\n", totaltasktime,
4223 (int)(((double)totaltasktime/(double)totalexetime)*100));
4224 printf("Total objqueue checking time: %lld (%d%%)\n",
4225 objqueuecheckingtime,
4226 (int)(((double)objqueuecheckingtime/(double)totalexetime)*100));
4227 printf("Total pre-processing time: %lld (%d%%)\n", preprocessingtime,
4228 (int)(((double)preprocessingtime/(double)totalexetime)*100));
4229 printf("Total post-processing time: %lld (%d%%)\n", postprocessingtime,
4230 (int)(((double)postprocessingtime/(double)totalexetime)*100));
4231 printf("Other time: %lld (%d%%)\n", other,
4232 (int)(((double)other/(double)totalexetime)*100));
4235 printf("\nAverage task execution time: %lld\n", averagetasktime);
4237 //printf("\nTotal time spent for interruptions: %lld\n", interrupttime);
4242 BAMBOO_DEBUGPRINT(0xdddd);
4243 // output task related info
4244 for(i= 0; i < taskInfoIndex; i++) {
4245 TaskInfo* tmpTInfo = taskInfoArray[i];
4246 char* tmpName = tmpTInfo->taskName;
4247 int nameLen = strlen(tmpName);
4248 BAMBOO_DEBUGPRINT(0xddda);
4249 for(j = 0; j < nameLen; j++) {
4250 BAMBOO_DEBUGPRINT_REG(tmpName[j]);
4252 BAMBOO_DEBUGPRINT(0xdddb);
4253 BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
4254 BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
4255 BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
4256 if(tmpTInfo->newObjs != NULL) {
4257 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
4258 struct RuntimeIterator * iter = NULL;
4259 while(0 == isEmpty(tmpTInfo->newObjs)) {
4260 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
4261 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
4263 RuntimeHashget(nobjtbl, (int)objtype, &num);
4264 RuntimeHashremovekey(nobjtbl, (int)objtype);
4266 RuntimeHashadd(nobjtbl, (int)objtype, num);
4268 RuntimeHashadd(nobjtbl, (int)objtype, 1);
4272 // ouput all new obj info
4273 iter = RuntimeHashcreateiterator(nobjtbl);
4274 while(RunhasNext(iter)) {
4275 char * objtype = (char *)Runkey(iter);
4276 int num = Runnext(iter);
4277 int nameLen = strlen(objtype);
4278 BAMBOO_DEBUGPRINT(0xddda);
4279 for(j = 0; j < nameLen; j++) {
4280 BAMBOO_DEBUGPRINT_REG(objtype[j]);
4282 BAMBOO_DEBUGPRINT(0xdddb);
4283 BAMBOO_DEBUGPRINT_REG(num);
4286 BAMBOO_DEBUGPRINT(0xdddc);
4289 if(taskInfoOverflow) {
4290 BAMBOO_DEBUGPRINT(0xefee);
4293 // output interrupt related info
4294 for(i = 0; i < interruptInfoIndex; i++) {
4295 InterruptInfo* tmpIInfo = interruptInfoArray[i];
4296 BAMBOO_DEBUGPRINT(0xddde);
4297 BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
4298 BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
4299 BAMBOO_DEBUGPRINT(0xdddf);
4302 if(interruptInfoOverflow) {
4303 BAMBOO_DEBUGPRINT(0xefef);
4306 BAMBOO_DEBUGPRINT(0xeeee);
4309 #endif // #ifdef PROFILE