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 #ifdef LOCALHASHTBL_TEST
263 gcpointertbl = allocateRuntimeHash_I(20);
265 gcpointertbl = mgchashCreate_I(2000, 0.75);
267 //gcpointertbl = allocateMGCHash_I(20);
268 gcforwardobjtbl = allocateMGCHash_I(20, 3);
271 //gcismapped = false;
280 gcsbstarttbl = BAMBOO_BASE_VA;
281 bamboo_smemtbl = (void *)gcsbstarttbl
282 + (BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE)*sizeof(INTPTR);
283 if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
284 int t_size = ((BAMBOO_RMSP_SIZE)-sizeof(mgcsharedhashtbl_t)*2
285 -128*sizeof(size_t))/sizeof(mgcsharedhashlistnode_t)-2;
287 unsigned int tmp_k = 1 << (sizeof(int)*8 -1);
288 while(((t_size & tmp_k) == 0) && (kk < sizeof(int)*8)) {
289 t_size = t_size << 1;
292 t_size = tmp_k >> kk;
293 gcsharedptbl = mgcsharedhashCreate_I(t_size,0.30);//allocateGCSharedHash_I(20);
297 BAMBOO_MEMSET_WH(gcrpointertbls,0,sizeof(mgcsharedhashtbl_t *)*NUMCORES4GC);
298 //sizeof(struct RuntimeHash *)*NUMCORES4GC);
300 gcmem_mixed_threshold =
301 (unsigned int)((BAMBOO_SHARED_MEM_SIZE-(gcbaseva-BAMBOO_BASE_VA))*0.8);
302 gcmem_mixed_usedmem = 0;
305 // create the lock table, lockresult table and obj queue
308 (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
309 /* Set allocation blocks*/
310 locktable.listhead=NULL;
311 locktable.listtail=NULL;
313 locktable.numelements = 0;
318 lockRedirectTbl = allocateRuntimeHash_I(20);
319 objRedirectLockTbl = allocateRuntimeHash_I(20);
324 objqueue.head = NULL;
325 objqueue.tail = NULL;
331 //isInterrupt = true;
335 taskInfoOverflow = false;
337 interruptInfoIndex = 0;
338 interruptInfoOverflow = false;
341 for(i = 0; i < MAXTASKPARAMS; i++) {
342 runtime_locks[i].redirectlock = 0;
343 runtime_locks[i].value = 0;
348 inline __attribute__((always_inline))
349 void disruntimedata() {
351 #ifdef LOCALHASHTBL_TEST
352 freeRuntimeHash(gcpointertbl);
354 mgchashDelete(gcpointertbl);
356 //freeMGCHash(gcpointertbl);
357 freeMGCHash(gcforwardobjtbl);
358 // for mapping info structures
359 //freeRuntimeHash(gcrcoretbl);
361 freeRuntimeHash(lockRedirectTbl);
362 freeRuntimeHash(objRedirectLockTbl);
363 RUNFREE(locktable.bucket);
365 if(activetasks != NULL) {
366 genfreehashtable(activetasks);
368 if(currtpd != NULL) {
369 RUNFREE(currtpd->parameterArray);
373 BAMBOO_LOCAL_MEM_CLOSE();
374 BAMBOO_SHARE_MEM_CLOSE();
377 inline __attribute__((always_inline))
378 bool checkObjQueue() {
380 struct transObjInfo * objInfo = NULL;
384 #ifdef ACCURATEPROFILE
385 bool isChecking = false;
386 if(!isEmpty(&objqueue)) {
387 profileTaskStart("objqueue checking");
389 } // if(!isEmpty(&objqueue))
393 while(!isEmpty(&objqueue)) {
395 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
397 BAMBOO_DEBUGPRINT(0xf001);
400 //isInterrupt = false;
403 BAMBOO_DEBUGPRINT(0xeee1);
406 objInfo = (struct transObjInfo *)getItem(&objqueue);
407 obj = objInfo->objptr;
409 BAMBOO_DEBUGPRINT_REG((int)obj);
411 // grab lock and flush the obj
415 BAMBOO_WAITING_FOR_LOCK(0);
416 } // while(!lockflag)
419 BAMBOO_DEBUGPRINT_REG(grount);
434 BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
435 BAMBOO_CACHE_FLUSH_RANGE((int)obj,
436 classsize[((struct ___Object___ *)obj)->type]);
438 // enqueue the object
439 for(k = 0; k < objInfo->length; ++k) {
440 int taskindex = objInfo->queues[2 * k];
441 int paramindex = objInfo->queues[2 * k + 1];
442 struct parameterwrapper ** queues =
443 &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
445 BAMBOO_DEBUGPRINT_REG(taskindex);
446 BAMBOO_DEBUGPRINT_REG(paramindex);
447 struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
448 tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n",
449 BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj,
450 (long)obj, tmpptr->flag);
452 enqueueObject_I(obj, queues, 1);
454 BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
456 } // for(k = 0; k < objInfo->length; ++k)
457 releasewritelock_I(obj);
458 RUNFREE(objInfo->queues);
462 // put it at the end of the queue if no update version in the queue
463 struct QueueItem * qitem = getHead(&objqueue);
464 struct QueueItem * prev = NULL;
465 while(qitem != NULL) {
466 struct transObjInfo * tmpinfo =
467 (struct transObjInfo *)(qitem->objectptr);
468 if(tmpinfo->objptr == obj) {
469 // the same object in the queue, which should be enqueued
470 // recently. Current one is outdate, do not re-enqueue it
471 RUNFREE(objInfo->queues);
476 } // if(tmpinfo->objptr == obj)
477 qitem = getNextQueueItem(prev);
478 } // while(qitem != NULL)
479 // try to execute active tasks already enqueued first
480 addNewItem_I(&objqueue, objInfo);
482 //isInterrupt = true;
485 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
487 BAMBOO_DEBUGPRINT(0xf000);
491 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
493 BAMBOO_DEBUGPRINT(0xf000);
495 } // while(!isEmpty(&objqueue))
498 #ifdef ACCURATEPROFILE
506 BAMBOO_DEBUGPRINT(0xee02);
511 inline __attribute__((always_inline))
512 void checkCoreStatus() {
513 bool allStall = false;
517 (waitconfirm && (numconfirm == 0))) {
519 BAMBOO_DEBUGPRINT(0xee04);
520 BAMBOO_DEBUGPRINT_REG(waitconfirm);
522 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
524 BAMBOO_DEBUGPRINT(0xf001);
526 corestatus[BAMBOO_NUM_OF_CORE] = 0;
527 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
528 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
529 // check the status of all cores
532 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
534 for(i = 0; i < NUMCORESACTIVE; ++i) {
536 BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
538 if(corestatus[i] != 0) {
542 } // for(i = 0; i < NUMCORESACTIVE; ++i)
544 // check if the sum of send objs and receive obj are the same
545 // yes->check if the info is the latest; no->go on executing
547 for(i = 0; i < NUMCORESACTIVE; ++i) {
548 sumsendobj += numsendobjs[i];
550 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
552 } // for(i = 0; i < NUMCORESACTIVE; ++i)
553 for(i = 0; i < NUMCORESACTIVE; ++i) {
554 sumsendobj -= numreceiveobjs[i];
556 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
558 } // for(i = 0; i < NUMCORESACTIVE; ++i)
559 if(0 == sumsendobj) {
561 // the first time found all cores stall
562 // send out status confirm msg to all other cores
563 // reset the corestatus array too
565 BAMBOO_DEBUGPRINT(0xee05);
567 corestatus[BAMBOO_NUM_OF_CORE] = 1;
569 numconfirm = NUMCORESACTIVE - 1;
570 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
571 for(i = 1; i < NUMCORESACTIVE; ++i) {
573 // send status confirm msg to core i
574 send_msg_1(i, STATUSCONFIRM, false);
575 } // for(i = 1; i < NUMCORESACTIVE; ++i)
578 // all the core status info are the latest
579 // terminate; for profiling mode, send request to all
580 // other cores to pour out profiling data
582 BAMBOO_DEBUGPRINT(0xee06);
586 totalexetime = BAMBOO_GET_EXE_TIME() - bamboo_start_time;
589 //BAMBOO_DEBUGPRINT_REG(interrupttime);
592 BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME() - bamboo_start_time);
593 //BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
594 BAMBOO_DEBUGPRINT(0xbbbbbbbb);
596 // profile mode, send msgs to other cores to request pouring
597 // out progiling data
599 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
601 BAMBOO_DEBUGPRINT(0xf000);
603 for(i = 1; i < NUMCORESACTIVE; ++i) {
604 // send profile request msg to core i
605 send_msg_2(i, PROFILEOUTPUT, totalexetime, false);
606 } // for(i = 1; i < NUMCORESACTIVE; ++i)
607 // pour profiling data on startup core
610 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
612 BAMBOO_DEBUGPRINT(0xf001);
614 profilestatus[BAMBOO_NUM_OF_CORE] = 0;
615 // check the status of all cores
618 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
620 for(i = 0; i < NUMCORESACTIVE; ++i) {
622 BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
624 if(profilestatus[i] != 0) {
628 } // for(i = 0; i < NUMCORESACTIVE; ++i)
631 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
633 BAMBOO_DEBUGPRINT(0xf000);
638 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
644 // gc_profile mode, ourput gc prfiling data
647 gc_outputProfileData();
648 #endif // #ifdef GC_PROFILE
649 #endif // #ifdef MULTICORE_GC
651 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
652 terminate(); // All done.
653 } // if(!waitconfirm)
655 // still some objects on the fly on the network
656 // reset the waitconfirm and numconfirm
658 BAMBOO_DEBUGPRINT(0xee07);
662 } // if(0 == sumsendobj)
664 // not all cores are stall, keep on waiting
666 BAMBOO_DEBUGPRINT(0xee08);
671 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
673 BAMBOO_DEBUGPRINT(0xf000);
675 } // if((!waitconfirm) ||
678 // main function for each core
679 inline void run(void * arg) {
683 bool sendStall = false;
685 bool tocontinue = false;
687 corenum = BAMBOO_GET_NUM_OF_CORE();
689 BAMBOO_DEBUGPRINT(0xeeee);
690 BAMBOO_DEBUGPRINT_REG(corenum);
691 BAMBOO_DEBUGPRINT(STARTUPCORE);
694 // initialize runtime data structures
697 // other architecture related initialization
701 initializeexithandler();
703 // main process of the execution module
704 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
705 // non-executing cores, only processing communications
708 BAMBOO_DEBUGPRINT(0xee01);
709 BAMBOO_DEBUGPRINT_REG(taskInfoIndex);
710 BAMBOO_DEBUGPRINT_REG(taskInfoOverflow);
711 profileTaskStart("msg handling");
715 //isInterrupt = false;
719 /* Create queue of active tasks */
721 genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
722 (int (*)(void *,void *)) &comparetpd);
724 /* Process task information */
727 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
728 /* Create startup object */
729 createstartupobject(argc, argv);
733 BAMBOO_DEBUGPRINT(0xee00);
738 // check if need to do GC
742 // check if there are new active tasks can be executed
749 while(receiveObject() != -1) {
754 BAMBOO_DEBUGPRINT(0xee01);
757 // check if there are some pending objects,
758 // if yes, enqueue them and executetasks again
759 tocontinue = checkObjQueue();
763 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
766 BAMBOO_DEBUGPRINT(0xee03);
774 BAMBOO_DEBUGPRINT(0xee09);
780 // wait for some time
783 BAMBOO_DEBUGPRINT(0xee0a);
789 // send StallMsg to startup core
791 BAMBOO_DEBUGPRINT(0xee0b);
794 send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
795 self_numsendobjs, self_numreceiveobjs, false);
807 BAMBOO_DEBUGPRINT(0xee0c);
810 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
813 } // if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)
817 struct ___createstartupobject____I_locals {
820 struct ___StartupObject___ * ___startupobject___;
821 struct ArrayObject * ___stringarray___;
822 }; // struct ___createstartupobject____I_locals
824 void createstartupobject(int argc,
828 /* Allocate startup object */
830 struct ___createstartupobject____I_locals ___locals___={2, NULL, NULL, NULL};
831 struct ___StartupObject___ *startupobject=
832 (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
833 ___locals___.___startupobject___ = startupobject;
834 struct ArrayObject * stringarray=
835 allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
836 ___locals___.___stringarray___ = stringarray;
838 struct ___StartupObject___ *startupobject=
839 (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
840 struct ArrayObject * stringarray=
841 allocate_newarray(STRINGARRAYTYPE, argc-1);
843 /* Build array of strings */
844 startupobject->___parameters___=stringarray;
845 for(i=1; i<argc; i++) {
846 int length=strlen(argv[i]);
848 struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
850 struct ___String___ *newstring=NewString(argv[i],length);
852 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
856 startupobject->version = 0;
857 startupobject->lock = NULL;
859 /* Set initialized flag for startup object */
860 flagorandinit(startupobject,1,0xFFFFFFFF);
861 enqueueObject(startupobject, NULL, 0);
863 BAMBOO_CACHE_FLUSH_ALL();
867 int hashCodetpd(struct taskparamdescriptor *ftd) {
868 int hash=(int)ftd->task;
870 for(i=0; i<ftd->numParameters; i++) {
871 hash^=(int)ftd->parameterArray[i];
876 int comparetpd(struct taskparamdescriptor *ftd1,
877 struct taskparamdescriptor *ftd2) {
879 if (ftd1->task!=ftd2->task)
881 for(i=0; i<ftd1->numParameters; i++)
882 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
887 /* This function sets a tag. */
889 void tagset(void *ptr,
890 struct ___Object___ * obj,
891 struct ___TagDescriptor___ * tagd) {
893 void tagset(struct ___Object___ * obj,
894 struct ___TagDescriptor___ * tagd) {
896 struct ArrayObject * ao=NULL;
897 struct ___Object___ * tagptr=obj->___tags___;
899 obj->___tags___=(struct ___Object___ *)tagd;
901 /* Have to check if it is already set */
902 if (tagptr->type==TAGTYPE) {
903 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
908 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
909 struct ArrayObject * ao=
910 allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
911 obj=(struct ___Object___ *)ptrarray[2];
912 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
913 td=(struct ___TagDescriptor___ *) obj->___tags___;
915 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
918 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
919 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
920 obj->___tags___=(struct ___Object___ *) ao;
921 ao->___cachedCode___=2;
925 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
926 for(i=0; i<ao->___cachedCode___; i++) {
927 struct ___TagDescriptor___ * td=
928 ARRAYGET(ao, struct ___TagDescriptor___*, i);
933 if (ao->___cachedCode___<ao->___length___) {
934 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
935 ao->___cachedCode___++;
938 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
939 struct ArrayObject * aonew=
940 allocate_newarray(&ptrarray,TAGARRAYTYPE,
941 TAGARRAYINTERVAL+ao->___length___);
942 obj=(struct ___Object___ *)ptrarray[2];
943 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
944 ao=(struct ArrayObject *)obj->___tags___;
946 struct ArrayObject * aonew=
947 allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
950 aonew->___cachedCode___=ao->___length___+1;
951 for(i=0; i<ao->___length___; i++) {
952 ARRAYSET(aonew, struct ___TagDescriptor___*, i,
953 ARRAYGET(ao, struct ___TagDescriptor___*, i));
955 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
961 struct ___Object___ * tagset=tagd->flagptr;
964 } else if (tagset->type!=OBJECTARRAYTYPE) {
966 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
967 struct ArrayObject * ao=
968 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
969 obj=(struct ___Object___ *)ptrarray[2];
970 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
972 struct ArrayObject * ao=
973 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
975 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
976 ARRAYSET(ao, struct ___Object___ *, 1, obj);
977 ao->___cachedCode___=2;
978 tagd->flagptr=(struct ___Object___ *)ao;
980 struct ArrayObject *ao=(struct ArrayObject *) tagset;
981 if (ao->___cachedCode___<ao->___length___) {
982 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
986 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
987 struct ArrayObject * aonew=
988 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
989 OBJECTARRAYINTERVAL+ao->___length___);
990 obj=(struct ___Object___ *)ptrarray[2];
991 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
992 ao=(struct ArrayObject *)tagd->flagptr;
994 struct ArrayObject * aonew=
995 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
997 aonew->___cachedCode___=ao->___cachedCode___+1;
998 for(i=0; i<ao->___length___; i++) {
999 ARRAYSET(aonew, struct ___Object___*, i,
1000 ARRAYGET(ao, struct ___Object___*, i));
1002 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
1003 tagd->flagptr=(struct ___Object___ *) aonew;
1009 /* This function clears a tag. */
1011 void tagclear(void *ptr,
1012 struct ___Object___ * obj,
1013 struct ___TagDescriptor___ * tagd) {
1015 void tagclear(struct ___Object___ * obj,
1016 struct ___TagDescriptor___ * tagd) {
1018 /* We'll assume that tag is alway there.
1019 Need to statically check for this of course. */
1020 struct ___Object___ * tagptr=obj->___tags___;
1022 if (tagptr->type==TAGTYPE) {
1023 if ((struct ___TagDescriptor___ *)tagptr==tagd)
1024 obj->___tags___=NULL;
1026 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
1028 for(i=0; i<ao->___cachedCode___; i++) {
1029 struct ___TagDescriptor___ * td=
1030 ARRAYGET(ao, struct ___TagDescriptor___ *, i);
1032 ao->___cachedCode___--;
1033 if (i<ao->___cachedCode___)
1034 ARRAYSET(ao, struct ___TagDescriptor___ *, i,
1035 ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
1036 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
1037 if (ao->___cachedCode___==0)
1038 obj->___tags___=NULL;
1045 struct ___Object___ *tagset=tagd->flagptr;
1046 if (tagset->type!=OBJECTARRAYTYPE) {
1050 struct ArrayObject *ao=(struct ArrayObject *) tagset;
1052 for(i=0; i<ao->___cachedCode___; i++) {
1053 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
1055 ao->___cachedCode___--;
1056 if (i<ao->___cachedCode___)
1057 ARRAYSET(ao, struct ___Object___ *, i,
1058 ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
1059 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
1060 if (ao->___cachedCode___==0)
1071 /* This function allocates a new tag. */
1073 struct ___TagDescriptor___ * allocate_tag(void *ptr,
1075 struct ___TagDescriptor___ * v=
1076 (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
1077 classsize[TAGTYPE]);
1079 struct ___TagDescriptor___ * allocate_tag(int index) {
1080 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
1089 /* This function updates the flag for object ptr. It or's the flag
1090 with the or mask and and's it with the andmask. */
1092 void flagbody(struct ___Object___ *ptr,
1094 struct parameterwrapper ** queues,
1098 int flagcomp(const int *val1, const int *val2) {
1099 return (*val1)-(*val2);
1102 void flagorand(void * ptr,
1105 struct parameterwrapper ** queues,
1108 int oldflag=((int *)ptr)[1];
1109 int flag=ormask|oldflag;
1111 flagbody(ptr, flag, queues, length, false);
1115 bool intflagorand(void * ptr,
1119 int oldflag=((int *)ptr)[1];
1120 int flag=ormask|oldflag;
1122 if (flag==oldflag) /* Don't do anything */
1125 flagbody(ptr, flag, NULL, 0, false);
1131 void flagorandinit(void * ptr,
1134 int oldflag=((int *)ptr)[1];
1135 int flag=ormask|oldflag;
1137 flagbody(ptr,flag,NULL,0,true);
1140 void flagbody(struct ___Object___ *ptr,
1142 struct parameterwrapper ** vqueues,
1145 struct parameterwrapper * flagptr = NULL;
1147 struct parameterwrapper ** queues = vqueues;
1148 int length = vlength;
1150 int UNUSED, UNUSED2;
1151 int * enterflags = NULL;
1152 if((!isnew) && (queues == NULL)) {
1153 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
1154 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1155 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1162 /*Remove object from all queues */
1163 for(i = 0; i < length; ++i) {
1164 flagptr = queues[i];
1165 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
1166 (int *) &enterflags, &UNUSED, &UNUSED2);
1167 ObjectHashremove(flagptr->objectset, (int)ptr);
1168 if (enterflags!=NULL)
1169 RUNFREE(enterflags);
1173 void enqueueObject(void * vptr,
1174 struct parameterwrapper ** vqueues,
1176 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1179 //struct QueueItem *tmpptr;
1180 struct parameterwrapper * parameter=NULL;
1183 struct parameterwrapper * prevptr=NULL;
1184 struct ___Object___ *tagptr=NULL;
1185 struct parameterwrapper ** queues = vqueues;
1186 int length = vlength;
1187 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1190 if(queues == NULL) {
1191 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1192 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1194 tagptr=ptr->___tags___;
1196 /* Outer loop iterates through all parameter queues an object of
1197 this type could be in. */
1198 for(j = 0; j < length; ++j) {
1199 parameter = queues[j];
1201 if (parameter->numbertags>0) {
1203 goto nextloop; //that means the object has no tag
1204 //but that param needs tag
1205 else if(tagptr->type==TAGTYPE) { //one tag
1206 //struct ___TagDescriptor___ * tag=
1207 //(struct ___TagDescriptor___*) tagptr;
1208 for(i=0; i<parameter->numbertags; i++) {
1209 //slotid is parameter->tagarray[2*i];
1210 int tagid=parameter->tagarray[2*i+1];
1211 if (tagid!=tagptr->flag)
1212 goto nextloop; /*We don't have this tag */
1214 } else { //multiple tags
1215 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1216 for(i=0; i<parameter->numbertags; i++) {
1217 //slotid is parameter->tagarray[2*i];
1218 int tagid=parameter->tagarray[2*i+1];
1220 for(j=0; j<ao->___cachedCode___; j++) {
1221 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1232 for(i=0; i<parameter->numberofterms; i++) {
1233 int andmask=parameter->intarray[i*2];
1234 int checkmask=parameter->intarray[i*2+1];
1235 if ((ptr->flag&andmask)==checkmask) {
1236 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
1247 void enqueueObject_I(void * vptr,
1248 struct parameterwrapper ** vqueues,
1250 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1253 //struct QueueItem *tmpptr;
1254 struct parameterwrapper * parameter=NULL;
1257 struct parameterwrapper * prevptr=NULL;
1258 struct ___Object___ *tagptr=NULL;
1259 struct parameterwrapper ** queues = vqueues;
1260 int length = vlength;
1261 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1264 if(queues == NULL) {
1265 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1266 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1268 tagptr=ptr->___tags___;
1270 /* Outer loop iterates through all parameter queues an object of
1271 this type could be in. */
1272 for(j = 0; j < length; ++j) {
1273 parameter = queues[j];
1275 if (parameter->numbertags>0) {
1277 goto nextloop; //that means the object has no tag
1278 //but that param needs tag
1279 else if(tagptr->type==TAGTYPE) { //one tag
1280 //struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
1281 for(i=0; i<parameter->numbertags; i++) {
1282 //slotid is parameter->tagarray[2*i];
1283 int tagid=parameter->tagarray[2*i+1];
1284 if (tagid!=tagptr->flag)
1285 goto nextloop; /*We don't have this tag */
1287 } else { //multiple tags
1288 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1289 for(i=0; i<parameter->numbertags; i++) {
1290 //slotid is parameter->tagarray[2*i];
1291 int tagid=parameter->tagarray[2*i+1];
1293 for(j=0; j<ao->___cachedCode___; j++) {
1294 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1305 for(i=0; i<parameter->numberofterms; i++) {
1306 int andmask=parameter->intarray[i*2];
1307 int checkmask=parameter->intarray[i*2+1];
1308 if ((ptr->flag&andmask)==checkmask) {
1309 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1321 int * getAliasLock(void ** ptrs,
1323 struct RuntimeHash * tbl) {
1325 return (int*)(RUNMALLOC(sizeof(int)));
1330 bool redirect = false;
1331 int redirectlock = 0;
1332 for(; i < length; i++) {
1333 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1336 if(ptr->lock == NULL) {
1339 lock = (int)(ptr->lock);
1342 if(lock != redirectlock) {
1343 RuntimeHashadd(tbl, lock, redirectlock);
1346 if(RuntimeHashcontainskey(tbl, lock)) {
1347 // already redirected
1349 RuntimeHashget(tbl, lock, &redirectlock);
1350 for(; j < locklen; j++) {
1351 if(locks[j] != redirectlock) {
1352 RuntimeHashadd(tbl, locks[j], redirectlock);
1357 for(j = 0; j < locklen; j++) {
1358 if(locks[j] == lock) {
1361 } else if(locks[j] > lock) {
1368 locks[h] = locks[h-1];
1377 return (int *)redirectlock;
1379 return (int *)(locks[0]);
1384 void addAliasLock(void * ptr,
1386 struct ___Object___ * obj = (struct ___Object___ *)ptr;
1387 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1388 // originally no alias lock associated or have a different alias lock
1389 // flush it as the new one
1390 obj->lock = (int *)lock;
1395 inline void setTaskExitIndex(int index) {
1396 taskInfoArray[taskInfoIndex]->exitIndex = index;
1399 inline void addNewObjInfo(void * nobj) {
1400 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1401 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1403 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1408 // Only allocate local mem chunks to each core.
1409 // If a core has used up its local shared memory, start gc.
1410 void * localmalloc_I(int coren,
1416 int tofindb = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1417 int totest = tofindb;
1418 int bound = BAMBOO_SMEM_SIZE_L;
1422 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1423 int nsize = bamboo_smemtbl[totest];
1424 bool islocal = true;
1426 bool tocheck = true;
1427 // have some space in the block
1428 if(totest == tofindb) {
1429 // the first partition
1430 size = bound - nsize;
1431 } else if(nsize == 0) {
1432 // an empty partition, can be appended
1435 // not an empty partition, can not be appended
1436 // the last continuous block is not big enough, go to check the next
1440 } // if(totest == tofindb) else if(nsize == 0) else ...
1443 // have enough space in the block, malloc
1447 // no enough space yet, try to append next continuous block
1449 } // if(size > isize) else ...
1451 } // if(nsize < bound)
1453 // no space in the block, go to check the next block
1459 tofindb = totest = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1462 } // if(islocal) else ...
1463 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1464 // no more local mem, do not find suitable block
1467 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1470 if(foundsmem == 1) {
1471 // find suitable block
1472 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1473 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1474 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1476 // set bamboo_smemtbl
1477 for(i = tofindb; i <= totest; i++) {
1478 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1480 } else if(foundsmem == 2) {
1481 // no suitable block
1486 } // void * localmalloc_I(int, int, int *)
1489 // Allocate the local shared memory to each core with the highest priority,
1490 // if a core has used up its local shared memory, try to allocate the
1491 // shared memory that belong to its neighbours, if also failed, start gc.
1492 void * fixedmalloc_I(int coren,
1499 int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
1500 int coords_x = bamboo_cpu2coords[gccorenum*2];
1501 int coords_y = bamboo_cpu2coords[gccorenum*2+1];
1503 int tofindb = gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1504 int totest = tofindb;
1505 int bound = BAMBOO_SMEM_SIZE_L;
1509 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1510 int nsize = bamboo_smemtbl[totest];
1511 bool islocal = true;
1513 bool tocheck = true;
1514 // have some space in the block
1515 if(totest == tofindb) {
1516 // the first partition
1517 size = bound - nsize;
1518 } else if(nsize == 0) {
1519 // an empty partition, can be appended
1522 // not an empty partition, can not be appended
1523 // the last continuous block is not big enough, go to check the next
1527 } // if(totest == tofindb) else if(nsize == 0) else ...
1530 // have enough space in the block, malloc
1534 // no enough space yet, try to append next continuous block
1535 // TODO may consider to go to next local block?
1537 } // if(size > isize) else ...
1539 } // if(nsize < bound)
1541 // no space in the block, go to check the next block
1548 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1551 } // if(islocal) else ...
1552 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1553 // no more local mem, do not find suitable block on local mem
1554 // try to malloc shared memory assigned to the neighbour cores
1557 if(k >= NUM_CORES2TEST) {
1558 // no more memory available on either coren or its neighbour cores
1560 goto memsearchresult;
1562 } while(core2test[gccorenum][k] == -1);
1565 tofindb=totest=gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1566 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1570 if(foundsmem == 1) {
1571 // find suitable block
1572 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1573 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1574 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1576 // set bamboo_smemtbl
1577 for(i = tofindb; i <= totest; i++) {
1578 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1580 } else if(foundsmem == 2) {
1581 // no suitable block
1586 } // void * fixedmalloc_I(int, int, int *)
1587 #endif // #ifdef SMEMF
1590 // Allocate the local shared memory to each core with the highest priority,
1591 // if a core has used up its local shared memory, try to allocate the
1592 // shared memory that belong to its neighbours first, if failed, check
1593 // current memory allocation rate, if it has already reached the threshold,
1594 // start gc, otherwise, allocate the shared memory globally. If all the
1595 // shared memory has been used up, start gc.
1596 void * mixedmalloc_I(int coren,
1603 int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
1604 int coords_x = bamboo_cpu2coords[gccorenum*2];
1605 int coords_y = bamboo_cpu2coords[gccorenum*2+1];
1607 int tofindb = gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1608 int totest = tofindb;
1609 int bound = BAMBOO_SMEM_SIZE_L;
1613 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1614 int nsize = bamboo_smemtbl[totest];
1615 bool islocal = true;
1617 bool tocheck = true;
1618 // have some space in the block
1619 if(totest == tofindb) {
1620 // the first partition
1621 size = bound - nsize;
1622 } else if(nsize == 0) {
1623 // an empty partition, can be appended
1626 // not an empty partition, can not be appended
1627 // the last continuous block is not big enough, go to check the next
1631 } // if(totest == tofindb) else if(nsize == 0) else ...
1634 // have enough space in the block, malloc
1638 // no enough space yet, try to append next continuous block
1639 // TODO may consider to go to next local block?
1641 } // if(size > isize) else ...
1643 } // if(nsize < bound)
1645 // no space in the block, go to check the next block
1652 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1655 } // if(islocal) else ...
1656 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1657 // no more local mem, do not find suitable block on local mem
1658 // try to malloc shared memory assigned to the neighbour cores
1661 if(k >= NUM_CORES2TEST) {
1662 if(gcmem_mixed_usedmem >= gcmem_mixed_threshold) {
1663 // no more memory available on either coren or its neighbour cores
1665 goto memmixedsearchresult;
1667 // try allocate globally
1668 mem = globalmalloc_I(coren, isize, allocsize);
1672 } while(core2test[gccorenum][k] == -1);
1676 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1677 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1680 memmixedsearchresult:
1681 if(foundsmem == 1) {
1682 // find suitable block
1683 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1684 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1685 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1687 // set bamboo_smemtbl
1688 for(i = tofindb; i <= totest; i++) {
1689 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1691 gcmem_mixed_usedmem += size;
1692 if(tofindb == bamboo_free_block) {
1693 bamboo_free_block = totest+1;
1695 } else if(foundsmem == 2) {
1696 // no suitable block
1701 } // void * mixedmalloc_I(int, int, int *)
1702 #endif // #ifdef SMEMM
1704 // Allocate all the memory chunks globally, do not consider the host cores
1705 // When all the shared memory are used up, start gc.
1706 void * globalmalloc_I(int coren,
1710 int tofindb = bamboo_free_block; //0;
1711 int totest = tofindb;
1712 int bound = BAMBOO_SMEM_SIZE_L;
1715 if(tofindb > gcnumblock-1-bamboo_reserved_smem) {
1716 // Out of shared memory
1721 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1722 int nsize = bamboo_smemtbl[totest];
1723 bool isnext = false;
1725 bool tocheck = true;
1726 // have some space in the block
1727 if(totest == tofindb) {
1728 // the first partition
1729 size = bound - nsize;
1730 } else if(nsize == 0) {
1731 // an empty partition, can be appended
1734 // not an empty partition, can not be appended
1735 // the last continuous block is not big enough, start another block
1738 } // if(totest == tofindb) else if(nsize == 0) else ...
1741 // have enough space in the block, malloc
1744 } // if(size > isize)
1748 } // if(nsize < bound) else ...
1750 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1751 // no more local mem, do not find suitable block
1754 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1756 // start another block
1761 if(foundsmem == 1) {
1762 // find suitable block
1763 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1764 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1765 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1767 // set bamboo_smemtbl
1768 for(int i = tofindb; i <= totest; i++) {
1769 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1771 if(tofindb == bamboo_free_block) {
1772 bamboo_free_block = totest+1;
1774 } else if(foundsmem == 2) {
1775 // no suitable block
1781 } // void * globalmalloc_I(int, int, int *)
1782 #endif // #ifdef MULTICORE_GC
1784 // malloc from the shared memory
1785 void * smemalloc_I(int coren,
1790 int isize = size+(BAMBOO_CACHE_LINE_SIZE);
1792 // go through the bamboo_smemtbl for suitable partitions
1793 switch(bamboo_smem_mode) {
1795 mem = localmalloc_I(coren, isize, allocsize);
1801 mem = fixedmalloc_I(coren, isize, allocsize);
1803 // not supported yet
1804 BAMBOO_EXIT(0xe001);
1811 mem = mixedmalloc_I(coren, isize, allocsize);
1813 // not supported yet
1814 BAMBOO_EXIT(0xe002);
1820 mem = globalmalloc_I(coren, isize, allocsize);
1832 /*if(!interruptInfoOverflow) {
1833 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
1834 interruptInfoArray[interruptInfoIndex] = intInfo;
1835 intInfo->startTime = BAMBOO_GET_EXE_TIME();
1836 intInfo->endTime = -1;
1839 int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size) : (BAMBOO_SMEM_SIZE);
1840 //mem = mspace_calloc(bamboo_free_msp, 1, toallocate);
1841 if(toallocate > bamboo_free_smem_size) {
1845 mem = (void *)bamboo_free_smemp;
1846 bamboo_free_smemp = ((void*)bamboo_free_smemp) + toallocate;
1847 bamboo_free_smem_size -= toallocate;
1848 //BAMBOO_MEMSET_WH(mem, '\0', toallocate);
1850 *allocsize = toallocate;
1852 /*if(!interruptInfoOverflow) {
1853 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
1854 interruptInfoIndex++;
1855 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
1856 interruptInfoOverflow = true;
1861 #endif // MULTICORE_GC
1862 // no enough shared global memory
1868 BAMBOO_DEBUGPRINT(0xa001);
1869 BAMBOO_EXIT(0xa001);
1873 } // void * smemalloc_I(int, int, int)
1875 INLINE int checkMsgLength_I(int size) {
1878 BAMBOO_DEBUGPRINT(0xcccc);
1881 int type = msgdata[msgdataindex];
1888 case GCSTARTMAPINFO:
1902 case GCSTARTCOMPACT:
1905 case GCFINISHMAPINFO:
1930 case REDIRECTGROUNT:
1932 case REDIRECTRELEASE:
1945 case GCFINISHCOMPACT:
1959 case TRANSOBJ: // nonfixed size
1965 msglength = msgdata[msgdataindex+1];
1974 BAMBOO_DEBUGPRINT_REG(type);
1975 BAMBOO_DEBUGPRINT_REG(size);
1976 BAMBOO_DEBUGPRINT_REG(msgdataindex);
1977 BAMBOO_DEBUGPRINT_REG(msgdatalast);
1978 BAMBOO_DEBUGPRINT_REG(msgdatafull);
1981 BAMBOO_DEBUGPRINT(msgdata[msgdataindex+i]);
1983 BAMBOO_EXIT(0xd005);
1989 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
1994 BAMBOO_DEBUGPRINT(0xffff);
2000 INLINE void processmsg_transobj_I() {
2002 struct transObjInfo * transObj=RUNMALLOC_I(sizeof(struct transObjInfo));
2006 BAMBOO_DEBUGPRINT(0xe880);
2009 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2011 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
2013 BAMBOO_EXIT(0xa002);
2015 // store the object and its corresponding queue info, enqueue it later
2016 transObj->objptr = (void *)msgdata[msgdataindex]; //[2]
2018 transObj->length = (msglength - 3) / 2;
2019 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
2020 for(k = 0; k < transObj->length; ++k) {
2021 transObj->queues[2*k] = msgdata[msgdataindex]; //[3+2*k];
2025 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
2028 transObj->queues[2*k+1] = msgdata[msgdataindex]; //[3+2*k+1];
2032 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
2036 // check if there is an existing duplicate item
2038 struct QueueItem * qitem = getHead(&objqueue);
2039 struct QueueItem * prev = NULL;
2040 while(qitem != NULL) {
2041 struct transObjInfo * tmpinfo =
2042 (struct transObjInfo *)(qitem->objectptr);
2043 if(tmpinfo->objptr == transObj->objptr) {
2044 // the same object, remove outdate one
2045 RUNFREE(tmpinfo->queues);
2047 removeItem(&objqueue, qitem);
2053 qitem = getHead(&objqueue);
2055 qitem = getNextQueueItem(prev);
2058 addNewItem_I(&objqueue, (void *)transObj);
2060 ++(self_numreceiveobjs);
2063 INLINE void processmsg_transtall_I() {
2064 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2065 // non startup core can not receive stall msg
2067 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
2069 BAMBOO_EXIT(0xa003);
2071 int num_core = msgdata[msgdataindex]; //[1]
2073 if(num_core < NUMCORESACTIVE) {
2076 BAMBOO_DEBUGPRINT(0xe881);
2079 corestatus[num_core] = 0;
2080 numsendobjs[num_core] = msgdata[msgdataindex]; //[2];
2082 numreceiveobjs[num_core] = msgdata[msgdataindex]; //[3];
2087 #ifndef MULTICORE_GC
2088 INLINE void processmsg_lockrequest_I() {
2089 // check to see if there is a lock exist for the required obj
2090 // msgdata[1] -> lock type
2091 int locktype = msgdata[msgdataindex]; //[1];
2093 int data2 = msgdata[msgdataindex]; // obj pointer
2095 int data3 = msgdata[msgdataindex]; // lock
2097 int data4 = msgdata[msgdataindex]; // request core
2099 // -1: redirected, 0: approved, 1: denied
2100 int deny=processlockrequest(locktype, data3, data2, data4, data4, true);
2102 // this lock request is redirected
2105 // send response msg
2106 // for 32 bit machine, the size is always 4 words, cache the msg first
2107 int tmp = deny==1 ? LOCKDENY : LOCKGROUNT;
2108 if(BAMBOO_CHECK_SEND_MODE()) {
2109 cache_msg_4(data4, tmp, locktype, data2, data3);
2111 send_msg_4(data4, tmp, locktype, data2, data3, true);
2116 INLINE void processmsg_lockgrount_I() {
2118 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2120 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
2122 BAMBOO_EXIT(0xa004);
2124 int data2 = msgdata[msgdataindex];
2126 int data3 = msgdata[msgdataindex];
2128 if((lockobj == data2) && (lock2require == data3)) {
2131 BAMBOO_DEBUGPRINT(0xe882);
2140 // conflicts on lockresults
2142 BAMBOO_DEBUGPRINT_REG(data2);
2144 BAMBOO_EXIT(0xa005);
2148 INLINE void processmsg_lockdeny_I() {
2150 int data2 = msgdata[msgdataindex];
2152 int data3 = msgdata[msgdataindex];
2154 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2156 BAMBOO_DEBUGPRINT_REG(data2);
2158 BAMBOO_EXIT(0xa006);
2160 if((lockobj == data2) && (lock2require == data3)) {
2163 BAMBOO_DEBUGPRINT(0xe883);
2172 // conflicts on lockresults
2174 BAMBOO_DEBUGPRINT_REG(data2);
2176 BAMBOO_EXIT(0xa007);
2180 INLINE void processmsg_lockrelease_I() {
2181 int data1 = msgdata[msgdataindex];
2183 int data2 = msgdata[msgdataindex];
2185 // receive lock release msg
2186 processlockrelease(data1, data2, 0, false);
2189 INLINE void processmsg_redirectlock_I() {
2190 // check to see if there is a lock exist for the required obj
2191 int data1 = msgdata[msgdataindex];
2192 MSG_INDEXINC_I(); //msgdata[1]; // lock type
2193 int data2 = msgdata[msgdataindex];
2194 MSG_INDEXINC_I(); //msgdata[2]; // obj pointer
2195 int data3 = msgdata[msgdataindex];
2196 MSG_INDEXINC_I(); //msgdata[3]; // redirect lock
2197 int data4 = msgdata[msgdataindex];
2198 MSG_INDEXINC_I(); //msgdata[4]; // root request core
2199 int data5 = msgdata[msgdataindex];
2200 MSG_INDEXINC_I(); //msgdata[5]; // request core
2201 int deny = processlockrequest(data1, data3, data2, data5, data4, true);
2203 // this lock request is redirected
2206 // send response msg
2207 // for 32 bit machine, the size is always 4 words, cache the msg first
2208 if(BAMBOO_CHECK_SEND_MODE()) {
2209 cache_msg_4(data4, deny==1 ? REDIRECTDENY : REDIRECTGROUNT,
2210 data1, data2, data3);
2212 send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
2213 data1, data2, data3, true);
2218 INLINE void processmsg_redirectgrount_I() {
2220 int data2 = msgdata[msgdataindex];
2222 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2224 BAMBOO_DEBUGPRINT_REG(data2);
2226 BAMBOO_EXIT(0xa00a);
2228 if(lockobj == data2) {
2231 BAMBOO_DEBUGPRINT(0xe891);
2234 int data3 = msgdata[msgdataindex];
2238 RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
2243 // conflicts on lockresults
2245 BAMBOO_DEBUGPRINT_REG(data2);
2247 BAMBOO_EXIT(0xa00b);
2251 INLINE void processmsg_redirectdeny_I() {
2253 int data2 = msgdata[msgdataindex];
2255 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2257 BAMBOO_DEBUGPRINT_REG(data2);
2259 BAMBOO_EXIT(0xa00c);
2261 if(lockobj == data2) {
2264 BAMBOO_DEBUGPRINT(0xe892);
2273 // conflicts on lockresults
2275 BAMBOO_DEBUGPRINT_REG(data2);
2277 BAMBOO_EXIT(0xa00d);
2281 INLINE void processmsg_redirectrelease_I() {
2282 int data1 = msgdata[msgdataindex];
2284 int data2 = msgdata[msgdataindex];
2286 int data3 = msgdata[msgdataindex];
2288 processlockrelease(data1, data2, data3, true);
2290 #endif // #ifndef MULTICORE_GC
2293 INLINE void processmsg_profileoutput_I() {
2294 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
2295 // startup core can not receive profile output finish msg
2296 BAMBOO_EXIT(0xa008);
2300 BAMBOO_DEBUGPRINT(0xe885);
2304 totalexetime = msgdata[msgdataindex]; //[1]
2306 outputProfileData();
2307 // cache the msg first
2308 if(BAMBOO_CHECK_SEND_MODE()) {
2309 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
2311 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE, true);
2315 INLINE void processmsg_profilefinish_I() {
2316 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2317 // non startup core can not receive profile output finish msg
2319 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex /*1*/]);
2321 BAMBOO_EXIT(0xa009);
2325 BAMBOO_DEBUGPRINT(0xe886);
2328 int data1 = msgdata[msgdataindex];
2330 profilestatus[data1] = 0;
2332 #endif // #ifdef PROFILE
2334 INLINE void processmsg_statusconfirm_I() {
2335 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2336 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2337 // wrong core to receive such msg
2338 BAMBOO_EXIT(0xa00e);
2340 // send response msg
2343 BAMBOO_DEBUGPRINT(0xe887);
2346 // cache the msg first
2347 if(BAMBOO_CHECK_SEND_MODE()) {
2348 cache_msg_5(STARTUPCORE, STATUSREPORT,
2349 busystatus ? 1 : 0, BAMBOO_NUM_OF_CORE,
2350 self_numsendobjs, self_numreceiveobjs);
2352 send_msg_5(STARTUPCORE, STATUSREPORT, busystatus?1:0,
2353 BAMBOO_NUM_OF_CORE, self_numsendobjs,
2354 self_numreceiveobjs, true);
2359 INLINE void processmsg_statusreport_I() {
2360 int data1 = msgdata[msgdataindex];
2362 int data2 = msgdata[msgdataindex];
2364 int data3 = msgdata[msgdataindex];
2366 int data4 = msgdata[msgdataindex];
2368 // receive a status confirm info
2369 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2370 // wrong core to receive such msg
2372 BAMBOO_DEBUGPRINT_REG(data2);
2374 BAMBOO_EXIT(0xa00f);
2378 BAMBOO_DEBUGPRINT(0xe888);
2384 corestatus[data2] = data1;
2385 numsendobjs[data2] = data3;
2386 numreceiveobjs[data2] = data4;
2390 INLINE void processmsg_terminate_I() {
2393 BAMBOO_DEBUGPRINT(0xe889);
2400 INLINE void processmsg_memrequest_I() {
2402 if(!interruptInfoOverflow) {
2403 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
2404 interruptInfoArray[interruptInfoIndex] = intInfo;
2405 intInfo->startTime = BAMBOO_GET_EXE_TIME();
2406 intInfo->endTime = -1;
2409 int data1 = msgdata[msgdataindex];
2411 int data2 = msgdata[msgdataindex];
2413 // receive a shared memory request msg
2414 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2415 // wrong core to receive such msg
2417 BAMBOO_DEBUGPRINT_REG(data2);
2419 BAMBOO_EXIT(0xa010);
2423 BAMBOO_DEBUGPRINT(0xe88a);
2430 // is currently doing gc, dump this msg
2431 if(INITPHASE == gcphase) {
2432 // if still in the initphase of gc, send a startinit msg again,
2433 // cache the msg first
2434 if(BAMBOO_CHECK_SEND_MODE()) {
2435 cache_msg_1(data2, GCSTARTINIT);
2437 send_msg_1(data2, GCSTARTINIT, true);
2442 mem = smemalloc_I(data2, data1, &allocsize);
2444 // send the start_va to request core, cache the msg first
2445 if(BAMBOO_CHECK_SEND_MODE()) {
2446 cache_msg_3(data2, MEMRESPONSE, mem, allocsize);
2448 send_msg_3(data2, MEMRESPONSE, mem, allocsize, true);
2450 } // if mem == NULL, the gcflag of the startup core has been set
2451 // and the gc should be started later, then a GCSTARTINIT msg
2452 // will be sent to the requesting core to notice it to start gc
2453 // and try malloc again
2459 if(!interruptInfoOverflow) {
2460 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
2461 interruptInfoIndex++;
2462 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
2463 interruptInfoOverflow = true;
2469 INLINE void processmsg_memresponse_I() {
2470 int data1 = msgdata[msgdataindex];
2472 int data2 = msgdata[msgdataindex];
2474 // receive a shared memory response msg
2477 BAMBOO_DEBUGPRINT(0xe88b);
2481 // if is currently doing gc, dump this msg
2485 bamboo_smem_size = 0;
2488 bamboo_smem_zero_top = 0;
2492 // fill header to store the size of this mem block
2493 BAMBOO_MEMSET_WH(data1, '\0', BAMBOO_CACHE_LINE_SIZE);
2494 //memset(data1, 0, BAMBOO_CACHE_LINE_SIZE);
2495 (*((int*)data1)) = data2;
2496 bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
2497 bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
2498 bamboo_smem_zero_top = bamboo_cur_msp;
2500 bamboo_smem_size = data2;
2501 bamboo_cur_msp =(void*)(data1);
2511 INLINE void processmsg_gcstartinit_I() {
2513 gcphase = INITPHASE;
2515 // is waiting for response of mem request
2516 // let it return NULL and start gc
2517 bamboo_smem_size = 0;
2518 bamboo_cur_msp = NULL;
2520 bamboo_smem_zero_top = NULL;
2524 INLINE void processmsg_gcstart_I() {
2527 BAMBOO_DEBUGPRINT(0xe88c);
2531 gcphase = MARKPHASE;
2534 INLINE void processmsg_gcstartcompact_I() {
2535 gcblock2fill = msgdata[msgdataindex];
2536 MSG_INDEXINC_I(); //msgdata[1];
2537 gcphase = COMPACTPHASE;
2540 INLINE void processmsg_gcstartmapinfo_I() {
2544 INLINE void processmsg_gcstartflush_I() {
2545 gcphase = FLUSHPHASE;
2548 INLINE void processmsg_gcfinishinit_I() {
2549 int data1 = msgdata[msgdataindex];
2551 // received a init phase finish msg
2552 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2553 // non startup core can not receive this msg
2555 BAMBOO_DEBUGPRINT_REG(data1);
2557 BAMBOO_EXIT(0xb001);
2560 BAMBOO_DEBUGPRINT(0xe88c);
2561 BAMBOO_DEBUGPRINT_REG(data1);
2563 // All cores should do init GC
2564 if(data1 < NUMCORESACTIVE) {
2565 gccorestatus[data1] = 0;
2569 INLINE void processmsg_gcfinishmark_I() {
2570 int data1 = msgdata[msgdataindex];
2572 int data2 = msgdata[msgdataindex];
2574 int data3 = msgdata[msgdataindex];
2576 // received a mark phase finish msg
2577 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2578 // non startup core can not receive this msg
2580 BAMBOO_DEBUGPRINT_REG(data1);
2582 BAMBOO_EXIT(0xb002);
2584 // all cores should do mark
2585 if(data1 < NUMCORESACTIVE) {
2586 gccorestatus[data1] = 0;
2587 gcnumsendobjs[data1] = data2;
2588 gcnumreceiveobjs[data1] = data3;
2592 INLINE void processmsg_gcfinishcompact_I() {
2593 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2594 // non startup core can not receive this msg
2597 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
2599 BAMBOO_EXIT(0xb003);
2601 int cnum = msgdata[msgdataindex];
2602 MSG_INDEXINC_I(); //msgdata[1];
2603 int filledblocks = msgdata[msgdataindex];
2604 MSG_INDEXINC_I(); //msgdata[2];
2605 int heaptop = msgdata[msgdataindex];
2606 MSG_INDEXINC_I(); //msgdata[3];
2607 int data4 = msgdata[msgdataindex];
2608 MSG_INDEXINC_I(); //msgdata[4];
2609 // only gc cores need to do compact
2610 if(cnum < NUMCORES4GC) {
2611 if(COMPACTPHASE == gcphase) {
2612 gcfilledblocks[cnum] = filledblocks;
2613 gcloads[cnum] = heaptop;
2620 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
2621 // cache the msg first
2622 if(BAMBOO_CHECK_SEND_MODE()) {
2623 cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
2625 send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove, true);
2629 gccorestatus[cnum] = 0;
2631 } // if(cnum < NUMCORES4GC)
2634 INLINE void processmsg_gcfinishmapinfo_I() {
2635 int data1 = msgdata[msgdataindex];
2637 // received a map phase finish msg
2638 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2639 // non startup core can not receive this msg
2642 BAMBOO_DEBUGPRINT_REG(data1);
2644 BAMBOO_EXIT(0xb004);
2646 // all cores should do flush
2647 if(data1 < NUMCORES4GC) {
2648 gccorestatus[data1] = 0;
2653 INLINE void processmsg_gcfinishflush_I() {
2654 int data1 = msgdata[msgdataindex];
2656 // received a flush phase finish msg
2657 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2658 // non startup core can not receive this msg
2661 BAMBOO_DEBUGPRINT_REG(data1);
2663 BAMBOO_EXIT(0xb005);
2665 // all cores should do flush
2666 if(data1 < NUMCORESACTIVE) {
2667 gccorestatus[data1] = 0;
2671 INLINE void processmsg_gcmarkconfirm_I() {
2672 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2673 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2674 // wrong core to receive such msg
2675 BAMBOO_EXIT(0xb006);
2677 // send response msg, cahce the msg first
2678 if(BAMBOO_CHECK_SEND_MODE()) {
2679 cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2680 gcbusystatus, gcself_numsendobjs,
2681 gcself_numreceiveobjs);
2683 send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2684 gcbusystatus, gcself_numsendobjs,
2685 gcself_numreceiveobjs, true);
2690 INLINE void processmsg_gcmarkreport_I() {
2691 int data1 = msgdata[msgdataindex];
2693 int data2 = msgdata[msgdataindex];
2695 int data3 = msgdata[msgdataindex];
2697 int data4 = msgdata[msgdataindex];
2699 // received a marked phase finish confirm response msg
2700 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2701 // wrong core to receive such msg
2703 BAMBOO_DEBUGPRINT_REG(data2);
2705 BAMBOO_EXIT(0xb007);
2710 gccorestatus[data1] = data2;
2711 gcnumsendobjs[data1] = data3;
2712 gcnumreceiveobjs[data1] = data4;
2716 INLINE void processmsg_gcmarkedobj_I() {
2717 int data1 = msgdata[msgdataindex];
2719 // received a markedObj msg
2720 if(((int *)data1)[6] == INIT) {
2721 // this is the first time that this object is discovered,
2722 // set the flag as DISCOVERED
2723 ((int *)data1)[6] = DISCOVERED;
2724 gc_enqueue_I(data1);
2726 // set the remote flag
2727 ((int *)data1)[6] |= REMOTEM;
2728 gcself_numreceiveobjs++;
2729 gcbusystatus = true;
2732 INLINE void processmsg_gcmovestart_I() {
2734 gcdstcore = msgdata[msgdataindex];
2735 MSG_INDEXINC_I(); //msgdata[1];
2736 gcmovestartaddr = msgdata[msgdataindex];
2737 MSG_INDEXINC_I(); //msgdata[2];
2738 gcblock2fill = msgdata[msgdataindex];
2739 MSG_INDEXINC_I(); //msgdata[3];
2742 INLINE void processmsg_gcmaprequest_I() {
2744 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2746 void * dstptr = NULL;
2747 int data1 = msgdata[msgdataindex];
2750 // TODO unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2752 #ifdef LOCALHASHTBL_TEST
2753 RuntimeHashget(gcpointertbl, data1, &dstptr);
2755 dstptr = mgchashSearch(gcpointertbl, data1);
2757 //MGCHashget(gcpointertbl, data1, &dstptr);
2759 // TODO flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2761 int data2 = msgdata[msgdataindex];
2764 // TODO unsigned long long ttimei = BAMBOO_GET_EXE_TIME();
2766 if(NULL == dstptr) {
2767 // no such pointer in this core, something is wrong
2769 BAMBOO_DEBUGPRINT_REG(data1);
2770 BAMBOO_DEBUGPRINT_REG(data2);
2772 BAMBOO_EXIT(0xb009);
2773 //assume that the object was not moved, use the original address
2774 /*if(isMsgSending) {
2775 cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2777 send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2780 // send back the mapping info, cache the msg first
2781 if(BAMBOO_CHECK_SEND_MODE()) {
2782 cache_msg_3(data2, GCMAPINFO, data1, (int)dstptr);
2784 send_msg_3(data2, GCMAPINFO, data1, (int)dstptr, true);
2788 // TODO flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimei;
2789 //num_mapinforequest_i++;
2793 INLINE void processmsg_gcmapinfo_I() {
2795 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2797 int data1 = msgdata[msgdataindex];
2799 gcmappedobj = msgdata[msgdataindex]; // [2]
2801 #ifdef LOCALHASHTBL_TEST
2802 RuntimeHashadd_I(gcpointertbl, data1, gcmappedobj);
2804 mgchashInsert_I(gcpointertbl, data1, gcmappedobj);
2806 //MGCHashadd_I(gcpointertbl, data1, gcmappedobj);
2807 if(data1 == gcobj2map) {
2811 //flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2815 INLINE void processmsg_gcmaptbl_I() {
2816 int data1 = msgdata[msgdataindex];
2818 int data2 = msgdata[msgdataindex];
2820 gcrpointertbls[data2] = (mgcsharedhashtbl_t *)data1; //(struct GCSharedHash *)data1;
2823 INLINE void processmsg_gclobjinfo_I() {
2826 int data1 = msgdata[msgdataindex];
2828 int data2 = msgdata[msgdataindex];
2830 if(BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1) {
2832 BAMBOO_DEBUGPRINT_REG(data2);
2834 BAMBOO_EXIT(0xb00b);
2836 // store the mark result info
2838 gcloads[cnum] = msgdata[msgdataindex];
2839 MSG_INDEXINC_I(); // msgdata[3];
2840 int data4 = msgdata[msgdataindex];
2842 if(gcheaptop < data4) {
2845 // large obj info here
2846 for(int k = 5; k < data1; ) {
2847 int lobj = msgdata[msgdataindex];
2848 MSG_INDEXINC_I(); //msgdata[k++];
2849 int length = msgdata[msgdataindex];
2850 MSG_INDEXINC_I(); //msgdata[k++];
2851 gc_lobjenqueue_I(lobj, length, cnum);
2853 } // for(int k = 5; k < msgdata[1];)
2856 INLINE void processmsg_gclobjmapping_I() {
2857 int data1 = msgdata[msgdataindex];
2859 int data2 = msgdata[msgdataindex];
2861 #ifdef LOCALHASHTBL_TEST
2862 RuntimeHashadd_I(gcpointertbl, data1, data2);
2864 mgchashInsert_I(gcpointertbl, data1, data2);
2866 //MGCHashadd_I(gcpointertbl, data1, data2);
2867 mgcsharedhashInsert_I(gcsharedptbl, data1, data2);
2869 #endif // #ifdef MULTICORE_GC
2871 // receive object transferred from other cores
2872 // or the terminate message from other cores
2873 // Should be invoked in critical sections!!
2874 // NOTICE: following format is for threadsimulate version only
2875 // RAW version please see previous description
2876 // format: type + object
2877 // type: -1--stall msg
2879 // return value: 0--received an object
2880 // 1--received nothing
2881 // 2--received a Stall Msg
2882 // 3--received a lock Msg
2883 // RAW version: -1 -- received nothing
2884 // otherwise -- received msg type
2885 int receiveObject(int send_port_pending) {
2887 // get the incoming msgs
2888 if(receiveMsg(send_port_pending) == -1) {
2892 // processing received msgs
2894 MSG_REMAINSIZE_I(&size);
2895 if((size == 0) || (checkMsgLength_I(size) == -1)) {
2897 // have new coming msg
2898 if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
2905 if(msglength <= size) {
2906 // have some whole msg
2907 //if(msgdataindex == msglength) {
2908 // received a whole msg
2910 type = msgdata[msgdataindex]; //[0]
2912 msgdatafull = false;
2914 //tprintf("msg type: %x\n", type);
2917 // receive a object transfer msg
2918 processmsg_transobj_I();
2923 // receive a stall msg
2924 processmsg_transtall_I();
2928 // GC version have no lock msgs
2929 #ifndef MULTICORE_GC
2931 // receive lock request msg, handle it right now
2932 processmsg_lockrequest_I();
2934 } // case LOCKREQUEST
2937 // receive lock grount msg
2938 processmsg_lockgrount_I();
2940 } // case LOCKGROUNT
2943 // receive lock deny msg
2944 processmsg_lockdeny_I();
2949 processmsg_lockrelease_I();
2951 } // case LOCKRELEASE
2952 #endif // #ifndef MULTICORE_GC
2955 case PROFILEOUTPUT: {
2956 // receive an output profile data request msg
2957 processmsg_profileoutput_I();
2959 } // case PROFILEOUTPUT
2961 case PROFILEFINISH: {
2962 // receive a profile output finish msg
2963 processmsg_profilefinish_I();
2965 } // case PROFILEFINISH
2966 #endif // #ifdef PROFILE
2968 // GC version has no lock msgs
2969 #ifndef MULTICORE_GC
2970 case REDIRECTLOCK: {
2971 // receive a redirect lock request msg, handle it right now
2972 processmsg_redirectlock_I();
2974 } // case REDIRECTLOCK
2976 case REDIRECTGROUNT: {
2977 // receive a lock grant msg with redirect info
2978 processmsg_redirectgrount_I();
2980 } // case REDIRECTGROUNT
2982 case REDIRECTDENY: {
2983 // receive a lock deny msg with redirect info
2984 processmsg_redirectdeny_I();
2986 } // case REDIRECTDENY
2988 case REDIRECTRELEASE: {
2989 // receive a lock release msg with redirect info
2990 processmsg_redirectrelease_I();
2992 } // case REDIRECTRELEASE
2993 #endif // #ifndef MULTICORE_GC
2995 case STATUSCONFIRM: {
2996 // receive a status confirm info
2997 processmsg_statusconfirm_I();
2999 } // case STATUSCONFIRM
3001 case STATUSREPORT: {
3002 processmsg_statusreport_I();
3004 } // case STATUSREPORT
3007 // receive a terminate msg
3008 processmsg_terminate_I();
3013 processmsg_memrequest_I();
3015 } // case MEMREQUEST
3018 processmsg_memresponse_I();
3020 } // case MEMRESPONSE
3025 processmsg_gcstartinit_I();
3027 } // case GCSTARTINIT
3030 // receive a start GC msg
3031 processmsg_gcstart_I();
3035 case GCSTARTCOMPACT: {
3036 // a compact phase start msg
3037 processmsg_gcstartcompact_I();
3039 } // case GCSTARTCOMPACT
3041 case GCSTARTMAPINFO: {
3042 // received a flush phase start msg
3043 processmsg_gcstartmapinfo_I();
3045 } // case GCSTARTFLUSH
3047 case GCSTARTFLUSH: {
3048 // received a flush phase start msg
3049 processmsg_gcstartflush_I();
3051 } // case GCSTARTFLUSH
3053 case GCFINISHINIT: {
3054 processmsg_gcfinishinit_I();
3056 } // case GCFINISHINIT
3058 case GCFINISHMARK: {
3059 processmsg_gcfinishmark_I();
3061 } // case GCFINISHMARK
3063 case GCFINISHCOMPACT: {
3064 // received a compact phase finish msg
3065 processmsg_gcfinishcompact_I();
3067 } // case GCFINISHCOMPACT
3069 case GCFINISHMAPINFO: {
3070 processmsg_gcfinishmapinfo_I();
3072 } // case GCFINISHMAPINFO
3074 case GCFINISHFLUSH: {
3075 processmsg_gcfinishflush_I();
3077 } // case GCFINISHFLUSH
3080 // received a GC finish msg
3081 gcphase = FINISHPHASE;
3085 case GCMARKCONFIRM: {
3086 // received a marked phase finish confirm request msg
3087 // all cores should do mark
3088 processmsg_gcmarkconfirm_I();
3090 } // case GCMARKCONFIRM
3092 case GCMARKREPORT: {
3093 processmsg_gcmarkreport_I();
3095 } // case GCMARKREPORT
3098 processmsg_gcmarkedobj_I();
3100 } // case GCMARKEDOBJ
3103 // received a start moving objs msg
3104 processmsg_gcmovestart_I();
3106 } // case GCMOVESTART
3108 case GCMAPREQUEST: {
3109 // received a mapping info request msg
3110 processmsg_gcmaprequest_I();
3112 } // case GCMAPREQUEST
3115 // received a mapping info response msg
3116 processmsg_gcmapinfo_I();
3121 // received a mapping tbl response msg
3122 processmsg_gcmaptbl_I();
3126 case GCLOBJREQUEST: {
3127 // received a large objs info request msg
3128 transferMarkResults_I();
3130 } // case GCLOBJREQUEST
3133 // received a large objs info response msg
3134 processmsg_gclobjinfo_I();
3136 } // case GCLOBJINFO
3138 case GCLOBJMAPPING: {
3139 // received a large obj mapping info msg
3140 processmsg_gclobjmapping_I();
3142 } // case GCLOBJMAPPING
3144 #endif // #ifdef MULTICORE_GC
3149 //memset(msgdata, '\0', sizeof(int) * msgdataindex);
3151 msglength = BAMBOO_MSG_BUF_LENGTH;
3153 //printf("++ msg: %x \n", type);
3155 if(msgdataindex != msgdatalast) {
3156 // still have available msg
3161 BAMBOO_DEBUGPRINT(0xe88d);
3165 // have new coming msg
3166 if(BAMBOO_MSG_AVAIL() != 0) {
3180 BAMBOO_DEBUGPRINT(0xe88e);
3184 /* if(isInterrupt) {
3192 int enqueuetasks(struct parameterwrapper *parameter,
3193 struct parameterwrapper *prevptr,
3194 struct ___Object___ *ptr,
3196 int numenterflags) {
3197 void * taskpointerarray[MAXTASKPARAMS];
3199 //int numparams=parameter->task->numParameters;
3200 int numiterators=parameter->task->numTotal-1;
3203 struct taskdescriptor * task=parameter->task;
3205 //this add the object to parameterwrapper
3206 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
3207 numenterflags, enterflags==NULL);
3209 /* Add enqueued object to parameter vector */
3210 taskpointerarray[parameter->slot]=ptr;
3212 /* Reset iterators */
3213 for(j=0; j<numiterators; j++) {
3214 toiReset(¶meter->iterators[j]);
3217 /* Find initial state */
3218 for(j=0; j<numiterators; j++) {
3220 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3221 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3223 /* Need to backtrack */
3224 toiReset(¶meter->iterators[j]);
3228 /* Nothing to enqueue */
3234 /* Enqueue current state */
3236 struct taskparamdescriptor *tpd=
3237 RUNMALLOC(sizeof(struct taskparamdescriptor));
3239 tpd->numParameters=numiterators+1;
3240 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
3242 for(j=0; j<=numiterators; j++) {
3243 //store the actual parameters
3244 tpd->parameterArray[j]=taskpointerarray[j];
3247 if (( /*!gencontains(failedtasks, tpd)&&*/
3248 !gencontains(activetasks,tpd))) {
3249 genputtable(activetasks, tpd, tpd);
3251 RUNFREE(tpd->parameterArray);
3255 /* This loop iterates to the next parameter combination */
3256 if (numiterators==0)
3259 for(j=numiterators-1; j<numiterators; j++) {
3261 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3262 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3264 /* Need to backtrack */
3265 toiReset(¶meter->iterators[j]);
3269 /* Nothing more to enqueue */
3277 int enqueuetasks_I(struct parameterwrapper *parameter,
3278 struct parameterwrapper *prevptr,
3279 struct ___Object___ *ptr,
3281 int numenterflags) {
3282 void * taskpointerarray[MAXTASKPARAMS];
3284 //int numparams=parameter->task->numParameters;
3285 int numiterators=parameter->task->numTotal-1;
3290 struct taskdescriptor * task=parameter->task;
3292 //this add the object to parameterwrapper
3293 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
3294 numenterflags, enterflags==NULL);
3296 /* Add enqueued object to parameter vector */
3297 taskpointerarray[parameter->slot]=ptr;
3299 /* Reset iterators */
3300 for(j=0; j<numiterators; j++) {
3301 toiReset(¶meter->iterators[j]);
3304 /* Find initial state */
3305 for(j=0; j<numiterators; j++) {
3307 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3308 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3310 /* Need to backtrack */
3311 toiReset(¶meter->iterators[j]);
3315 /* Nothing to enqueue */
3321 /* Enqueue current state */
3323 struct taskparamdescriptor *tpd=
3324 RUNMALLOC_I(sizeof(struct taskparamdescriptor));
3326 tpd->numParameters=numiterators+1;
3327 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
3329 for(j=0; j<=numiterators; j++) {
3330 //store the actual parameters
3331 tpd->parameterArray[j]=taskpointerarray[j];
3334 if (( /*!gencontains(failedtasks, tpd)&&*/
3335 !gencontains(activetasks,tpd))) {
3336 genputtable_I(activetasks, tpd, tpd);
3338 RUNFREE(tpd->parameterArray);
3342 /* This loop iterates to the next parameter combination */
3343 if (numiterators==0)
3346 for(j=numiterators-1; j<numiterators; j++) {
3348 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
3349 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3351 /* Need to backtrack */
3352 toiReset(¶meter->iterators[j]);
3356 /* Nothing more to enqueue */
3370 int containstag(struct ___Object___ *ptr,
3371 struct ___TagDescriptor___ *tag);
3373 #ifndef MULTICORE_GC
3374 void releasewritelock_r(void * lock, void * redirectlock) {
3376 int reallock = (int)lock;
3377 targetcore = (reallock >> 5) % NUMCORES;
3380 BAMBOO_DEBUGPRINT(0xe671);
3381 BAMBOO_DEBUGPRINT_REG((int)lock);
3382 BAMBOO_DEBUGPRINT_REG(reallock);
3383 BAMBOO_DEBUGPRINT_REG(targetcore);
3386 if(targetcore == BAMBOO_NUM_OF_CORE) {
3387 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3389 BAMBOO_DEBUGPRINT(0xf001);
3391 // reside on this core
3392 if(!RuntimeHashcontainskey(locktbl, reallock)) {
3393 // no locks for this object, something is wrong
3394 BAMBOO_EXIT(0xa00b);
3397 struct LockValue * lockvalue = NULL;
3399 BAMBOO_DEBUGPRINT(0xe672);
3401 RuntimeHashget(locktbl, reallock, &rwlock_obj);
3402 lockvalue = (struct LockValue *)rwlock_obj;
3404 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
3407 lockvalue->redirectlock = (int)redirectlock;
3409 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
3412 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3414 BAMBOO_DEBUGPRINT(0xf000);
3418 // send lock release with redirect info msg
3419 // for 32 bit machine, the size is always 4 words
3420 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock,
3421 (int)redirectlock, false);
3426 void executetasks() {
3427 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
3430 struct ___Object___ * tmpparam = NULL;
3431 struct parameterdescriptor * pd=NULL;
3432 struct parameterwrapper *pw=NULL;
3442 while(hashsize(activetasks)>0) {
3447 BAMBOO_DEBUGPRINT(0xe990);
3450 /* See if there are any active tasks */
3451 //if (hashsize(activetasks)>0) {
3454 #ifdef ACCURATEPROFILE
3455 profileTaskStart("tpd checking");
3459 //clock1 = BAMBOO_GET_EXE_TIME();
3462 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
3463 genfreekey(activetasks, currtpd);
3465 numparams=currtpd->task->numParameters;
3466 numtotal=currtpd->task->numTotal;
3468 // clear the lockRedirectTbl
3469 // (TODO, this table should be empty after all locks are released)
3471 /*for(j = 0; j < MAXTASKPARAMS; j++) {
3472 runtime_locks[j].redirectlock = 0;
3473 runtime_locks[j].value = 0;
3475 // get all required locks
3476 runtime_locklen = 0;
3477 // check which locks are needed
3478 for(i = 0; i < numparams; i++) {
3479 void * param = currtpd->parameterArray[i];
3483 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
3485 taskpointerarray[i+OFFSET]=param;
3488 if(((struct ___Object___ *)param)->lock == NULL) {
3489 tmplock = (int)param;
3491 tmplock = (int)(((struct ___Object___ *)param)->lock);
3493 // insert into the locks array
3494 for(j = 0; j < runtime_locklen; j++) {
3495 if(runtime_locks[j].value == tmplock) {
3498 } else if(runtime_locks[j].value > tmplock) {
3503 int h = runtime_locklen;
3505 runtime_locks[h].redirectlock = runtime_locks[h-1].redirectlock;
3506 runtime_locks[h].value = runtime_locks[h-1].value;
3508 runtime_locks[j].value = tmplock;
3509 runtime_locks[j].redirectlock = (int)param;
3512 } // line 2713: for(i = 0; i < numparams; i++)
3513 // grab these required locks
3515 BAMBOO_DEBUGPRINT(0xe991);
3518 //clock2 = BAMBOO_GET_EXE_TIME();
3520 for(i = 0; i < runtime_locklen; i++) {
3521 int * lock = (int *)(runtime_locks[i].redirectlock);
3523 // require locks for this parameter if it is not a startup object
3525 BAMBOO_DEBUGPRINT_REG((int)lock);
3526 BAMBOO_DEBUGPRINT_REG((int)(runtime_locks[i].value));
3529 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3531 BAMBOO_DEBUGPRINT(0xf001);
3534 //isInterrupt = false;
3537 BAMBOO_WAITING_FOR_LOCK(0);
3541 while(BAMBOO_WAITING_FOR_LOCK(0) != -1) {
3545 grount = lockresult;
3555 //isInterrupt = true;
3557 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3559 BAMBOO_DEBUGPRINT(0xf000);
3564 BAMBOO_DEBUGPRINT(0xe992);
3565 BAMBOO_DEBUGPRINT_REG(lock);
3567 // check if has the lock already
3568 // can not get the lock, try later
3569 // release all grabbed locks for previous parameters
3570 for(j = 0; j < i; ++j) {
3571 lock = (int*)(runtime_locks[j].redirectlock);
3572 releasewritelock(lock);
3574 genputtable(activetasks, currtpd, currtpd);
3575 if(hashsize(activetasks) == 1) {
3576 // only one task right now, wait a little while before next try
3582 #ifdef ACCURATEPROFILE
3583 // fail, set the end of the checkTaskInfo
3590 } // line 2752: for(i = 0; i < runtime_locklen; i++)
3593 clock3 = BAMBOO_GET_EXE_TIME();
3594 //tprintf("sort: %d, grab: %d \n", clock2-clock1, clock3-clock2);*/
3597 BAMBOO_DEBUGPRINT(0xe993);
3599 /* Make sure that the parameters are still in the queues */
3600 for(i=0; i<numparams; i++) {
3601 void * parameter=currtpd->parameterArray[i];
3605 BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
3606 classsize[((struct ___Object___ *)parameter)->type]);
3608 tmpparam = (struct ___Object___ *)parameter;
3609 pd=currtpd->task->descriptorarray[i];
3610 pw=(struct parameterwrapper *) pd->queue;
3611 /* Check that object is still in queue */
3613 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
3615 BAMBOO_DEBUGPRINT(0xe994);
3616 BAMBOO_DEBUGPRINT_REG(parameter);
3618 // release grabbed locks
3619 for(j = 0; j < runtime_locklen; ++j) {
3620 int * lock = (int *)(runtime_locks[j].redirectlock);
3621 releasewritelock(lock);
3623 RUNFREE(currtpd->parameterArray);
3629 /* Check if the object's flags still meets requirements */
3633 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
3634 andmask=pw->intarray[tmpi*2];
3635 checkmask=pw->intarray[tmpi*2+1];
3636 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
3642 // flags are never suitable
3643 // remove this obj from the queue
3645 int UNUSED, UNUSED2;
3648 BAMBOO_DEBUGPRINT(0xe995);
3649 BAMBOO_DEBUGPRINT_REG(parameter);
3651 ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
3652 (int *) &enterflags, &UNUSED, &UNUSED2);
3653 ObjectHashremove(pw->objectset, (int)parameter);
3654 if (enterflags!=NULL)
3655 RUNFREE(enterflags);
3656 // release grabbed locks
3657 for(j = 0; j < runtime_locklen; ++j) {
3658 int * lock = (int *)(runtime_locks[j].redirectlock);
3659 releasewritelock(lock);
3661 RUNFREE(currtpd->parameterArray);
3665 #ifdef ACCURATEPROFILE
3666 // fail, set the end of the checkTaskInfo
3671 } // line 2878: if (!ismet)
3675 /* Check that object still has necessary tags */
3676 for(j=0; j<pd->numbertags; j++) {
3677 int slotid=pd->tagarray[2*j]+numparams;
3678 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
3679 if (!containstag(parameter, tagd)) {
3681 BAMBOO_DEBUGPRINT(0xe996);
3684 // release grabbed locks
3686 for(tmpj = 0; tmpj < runtime_locklen; ++tmpj) {
3687 int * lock = (int *)(runtime_locks[tmpj].redirectlock);
3688 releasewritelock(lock);
3691 RUNFREE(currtpd->parameterArray);
3695 } // line2911: if (!containstag(parameter, tagd))
3696 } // line 2808: for(j=0; j<pd->numbertags; j++)
3698 taskpointerarray[i+OFFSET]=parameter;
3699 } // line 2824: for(i=0; i<numparams; i++)
3701 for(; i<numtotal; i++) {
3702 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
3707 /* Actually call task */
3709 ((int *)taskpointerarray)[0]=currtpd->numParameters;
3710 taskpointerarray[1]=NULL;
3713 #ifdef ACCURATEPROFILE
3714 // check finish, set the end of the checkTaskInfo
3717 profileTaskStart(currtpd->task->name);
3721 //clock4 = BAMBOO_GET_EXE_TIME();
3722 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3725 BAMBOO_DEBUGPRINT(0xe997);
3727 ((void (*)(void **))currtpd->task->taskptr)(taskpointerarray);
3730 //clock5 = BAMBOO_GET_EXE_TIME();
3731 // tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3734 #ifdef ACCURATEPROFILE
3735 // task finish, set the end of the checkTaskInfo
3737 // new a PostTaskInfo for the post-task execution
3738 profileTaskStart("post task execution");
3742 BAMBOO_DEBUGPRINT(0xe998);
3743 BAMBOO_DEBUGPRINT_REG(islock);
3748 BAMBOO_DEBUGPRINT(0xe999);
3750 for(i = 0; i < runtime_locklen; ++i) {
3751 void * ptr = (void *)(runtime_locks[i].redirectlock);
3752 int * lock = (int *)(runtime_locks[i].value);
3754 BAMBOO_DEBUGPRINT_REG((int)ptr);
3755 BAMBOO_DEBUGPRINT_REG((int)lock);
3756 BAMBOO_DEBUGPRINT_REG(*((int*)lock+5));
3758 #ifndef MULTICORE_GC
3759 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
3761 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
3762 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
3763 releasewritelock_r(lock, (int *)redirectlock);
3768 releasewritelock(ptr);
3771 } // line 3015: if(islock)
3774 //clock6 = BAMBOO_GET_EXE_TIME();
3775 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3778 // post task execution finish, set the end of the postTaskInfo
3782 // Free up task parameter descriptor
3783 RUNFREE(currtpd->parameterArray);
3787 BAMBOO_DEBUGPRINT(0xe99a);
3790 //clock7 = BAMBOO_GET_EXE_TIME();
3791 //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));
3794 //} // if (hashsize(activetasks)>0)
3795 } // while(hashsize(activetasks)>0)
3797 BAMBOO_DEBUGPRINT(0xe99b);
3801 /* This function processes an objects tags */
3802 void processtags(struct parameterdescriptor *pd,
3804 struct parameterwrapper *parameter,
3805 int * iteratorcount,
3810 for(i=0; i<pd->numbertags; i++) {
3811 int slotid=pd->tagarray[2*i];
3812 int tagid=pd->tagarray[2*i+1];
3814 if (statusarray[slotid+numparams]==0) {
3815 parameter->iterators[*iteratorcount].istag=1;
3816 parameter->iterators[*iteratorcount].tagid=tagid;
3817 parameter->iterators[*iteratorcount].slot=slotid+numparams;
3818 parameter->iterators[*iteratorcount].tagobjectslot=index;
3819 statusarray[slotid+numparams]=1;
3826 void processobject(struct parameterwrapper *parameter,
3828 struct parameterdescriptor *pd,
3834 struct ObjectHash * objectset=
3835 ((struct parameterwrapper *)pd->queue)->objectset;
3837 parameter->iterators[*iteratorcount].istag=0;
3838 parameter->iterators[*iteratorcount].slot=index;
3839 parameter->iterators[*iteratorcount].objectset=objectset;
3840 statusarray[index]=1;
3842 for(i=0; i<pd->numbertags; i++) {
3843 int slotid=pd->tagarray[2*i];
3844 //int tagid=pd->tagarray[2*i+1];
3845 if (statusarray[slotid+numparams]!=0) {
3846 /* This tag has already been enqueued, use it to narrow search */
3847 parameter->iterators[*iteratorcount].tagbindings[tagcount]=
3852 parameter->iterators[*iteratorcount].numtags=tagcount;
3857 /* This function builds the iterators for a task & parameter */
3859 void builditerators(struct taskdescriptor * task,
3861 struct parameterwrapper * parameter) {
3862 int statusarray[MAXTASKPARAMS];
3864 int numparams=task->numParameters;
3865 int iteratorcount=0;
3866 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
3868 statusarray[index]=1; /* Initial parameter */
3869 /* Process tags for initial iterator */
3871 processtags(task->descriptorarray[index], index, parameter,
3872 &iteratorcount, statusarray, numparams);
3876 /* Check for objects with existing tags */
3877 for(i=0; i<numparams; i++) {
3878 if (statusarray[i]==0) {
3879 struct parameterdescriptor *pd=task->descriptorarray[i];
3881 for(j=0; j<pd->numbertags; j++) {
3882 int slotid=pd->tagarray[2*j];
3883 if(statusarray[slotid+numparams]!=0) {
3884 processobject(parameter, i, pd, &iteratorcount, statusarray,
3886 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3893 /* Next do objects w/ unbound tags*/
3895 for(i=0; i<numparams; i++) {
3896 if (statusarray[i]==0) {
3897 struct parameterdescriptor *pd=task->descriptorarray[i];
3898 if (pd->numbertags>0) {
3899 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3900 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3906 /* Nothing with a tag enqueued */
3908 for(i=0; i<numparams; i++) {
3909 if (statusarray[i]==0) {
3910 struct parameterdescriptor *pd=task->descriptorarray[i];
3911 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3912 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3925 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3928 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3929 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3931 printf("%s\n", task->name);
3933 for(j=0; j<task->numParameters; j++) {
3934 struct parameterdescriptor *param=task->descriptorarray[j];
3935 struct parameterwrapper *parameter=param->queue;
3936 struct ObjectHash * set=parameter->objectset;
3937 struct ObjectIterator objit;
3939 printf(" Parameter %d\n", j);
3941 ObjectHashiterator(set, &objit);
3942 while(ObjhasNext(&objit)) {
3943 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
3944 struct ___Object___ * tagptr=obj->___tags___;
3945 int nonfailed=Objdata4(&objit);
3946 int numflags=Objdata3(&objit);
3947 int flags=Objdata2(&objit);
3950 printf(" Contains %lx\n", obj);
3951 printf(" flag=%d\n", obj->flag);
3954 } else if (tagptr->type==TAGTYPE) {
3956 printf(" tag=%lx\n",tagptr);
3962 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
3963 for(; tagindex<ao->___cachedCode___; tagindex++) {
3965 printf(" tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*,
3978 /* This function processes the task information to create queues for
3979 each parameter type. */
3981 void processtasks() {
3983 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3986 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3987 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3990 /* Build objectsets */
3991 for(j=0; j<task->numParameters; j++) {
3992 struct parameterdescriptor *param=task->descriptorarray[j];
3993 struct parameterwrapper *parameter=param->queue;
3994 parameter->objectset=allocateObjectHash(10);
3995 parameter->task=task;
3998 /* Build iterators for parameters */
3999 for(j=0; j<task->numParameters; j++) {
4000 struct parameterdescriptor *param=task->descriptorarray[j];
4001 struct parameterwrapper *parameter=param->queue;
4002 builditerators(task, j, parameter);
4007 void toiReset(struct tagobjectiterator * it) {
4010 } else if (it->numtags>0) {
4013 ObjectHashiterator(it->objectset, &it->it);
4017 int toiHasNext(struct tagobjectiterator *it,
4018 void ** objectarray OPTARG(int * failed)) {
4021 /* Get object with tags */
4022 struct ___Object___ *obj=objectarray[it->tagobjectslot];
4023 struct ___Object___ *tagptr=obj->___tags___;
4024 if (tagptr->type==TAGTYPE) {
4025 if ((it->tagobjindex==0)&& /* First object */
4026 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
4031 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
4032 int tagindex=it->tagobjindex;
4033 for(; tagindex<ao->___cachedCode___; tagindex++) {
4034 struct ___TagDescriptor___ *td=
4035 ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
4036 if (td->flag==it->tagid) {
4037 it->tagobjindex=tagindex; /* Found right type of tag */
4043 } else if (it->numtags>0) {
4044 /* Use tags to locate appropriate objects */
4045 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
4046 struct ___Object___ *objptr=tag->flagptr;
4048 if (objptr->type!=OBJECTARRAYTYPE) {
4049 if (it->tagobjindex>0)
4051 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
4053 for(i=1; i<it->numtags; i++) {
4054 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
4055 if (!containstag(objptr,tag2))
4060 struct ArrayObject *ao=(struct ArrayObject *) objptr;
4063 for(tagindex=it->tagobjindex; tagindex<ao->___cachedCode___; tagindex++) {
4064 struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
4065 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
4067 for(i=1; i<it->numtags; i++) {
4068 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
4069 if (!containstag(objptr,tag2))
4072 it->tagobjindex=tagindex;
4077 it->tagobjindex=tagindex;
4081 return ObjhasNext(&it->it);
4085 int containstag(struct ___Object___ *ptr,
4086 struct ___TagDescriptor___ *tag) {
4088 struct ___Object___ * objptr=tag->flagptr;
4089 if (objptr->type==OBJECTARRAYTYPE) {
4090 struct ArrayObject *ao=(struct ArrayObject *)objptr;
4091 for(j=0; j<ao->___cachedCode___; j++) {
4092 if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
4102 void toiNext(struct tagobjectiterator *it,
4103 void ** objectarray OPTARG(int * failed)) {
4104 /* hasNext has all of the intelligence */
4107 /* Get object with tags */
4108 struct ___Object___ *obj=objectarray[it->tagobjectslot];
4109 struct ___Object___ *tagptr=obj->___tags___;
4110 if (tagptr->type==TAGTYPE) {
4112 objectarray[it->slot]=tagptr;
4114 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
4115 objectarray[it->slot]=
4116 ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
4118 } else if (it->numtags>0) {
4119 /* Use tags to locate appropriate objects */
4120 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
4121 struct ___Object___ *objptr=tag->flagptr;
4122 if (objptr->type!=OBJECTARRAYTYPE) {
4124 objectarray[it->slot]=objptr;
4126 struct ArrayObject *ao=(struct ArrayObject *) objptr;
4127 objectarray[it->slot]=
4128 ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
4131 /* Iterate object */
4132 objectarray[it->slot]=(void *)Objkey(&it->it);
4138 inline void profileTaskStart(char * taskname) {
4139 if(!taskInfoOverflow) {
4140 TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
4141 taskInfoArray[taskInfoIndex] = taskInfo;
4142 taskInfo->taskName = taskname;
4143 taskInfo->startTime = BAMBOO_GET_EXE_TIME();
4144 taskInfo->endTime = -1;
4145 taskInfo->exitIndex = -1;
4146 taskInfo->newObjs = NULL;
4150 inline void profileTaskEnd() {
4151 if(!taskInfoOverflow) {
4152 taskInfoArray[taskInfoIndex]->endTime = BAMBOO_GET_EXE_TIME();
4154 if(taskInfoIndex == TASKINFOLENGTH) {
4155 taskInfoOverflow = true;
4156 //taskInfoIndex = 0;
4161 // output the profiling data
4162 void outputProfileData() {
4165 unsigned long long totaltasktime = 0;
4166 unsigned long long preprocessingtime = 0;
4167 unsigned long long objqueuecheckingtime = 0;
4168 unsigned long long postprocessingtime = 0;
4169 //int interruptiontime = 0;
4170 unsigned long long other = 0;
4171 unsigned long long averagetasktime = 0;
4174 printf("Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
4175 // output task related info
4176 for(i = 0; i < taskInfoIndex; i++) {
4177 TaskInfo* tmpTInfo = taskInfoArray[i];
4178 unsigned long long duration = tmpTInfo->endTime - tmpTInfo->startTime;
4179 printf("%s, %lld, %lld, %lld, %lld",
4180 tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime,
4181 duration, tmpTInfo->exitIndex);
4182 // summarize new obj info
4183 if(tmpTInfo->newObjs != NULL) {
4184 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
4185 struct RuntimeIterator * iter = NULL;
4186 while(0 == isEmpty(tmpTInfo->newObjs)) {
4187 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
4188 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
4190 RuntimeHashget(nobjtbl, (int)objtype, &num);
4191 RuntimeHashremovekey(nobjtbl, (int)objtype);
4193 RuntimeHashadd(nobjtbl, (int)objtype, num);
4195 RuntimeHashadd(nobjtbl, (int)objtype, 1);
4197 //printf(stderr, "new obj!\n");
4200 // output all new obj info
4201 iter = RuntimeHashcreateiterator(nobjtbl);
4202 while(RunhasNext(iter)) {
4203 char * objtype = (char *)Runkey(iter);
4204 int num = Runnext(iter);
4205 printf(", %s, %d", objtype, num);
4209 if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
4210 preprocessingtime += duration;
4211 } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
4212 postprocessingtime += duration;
4213 } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
4214 objqueuecheckingtime += duration;
4216 totaltasktime += duration;
4217 averagetasktime += duration;
4222 if(taskInfoOverflow) {
4223 printf("Caution: task info overflow!\n");
4226 other = totalexetime-totaltasktime-preprocessingtime-postprocessingtime;
4227 averagetasktime /= tasknum;
4229 printf("\nTotal time: %lld\n", totalexetime);
4230 printf("Total task execution time: %lld (%d%%)\n", totaltasktime,
4231 (int)(((double)totaltasktime/(double)totalexetime)*100));
4232 printf("Total objqueue checking time: %lld (%d%%)\n",
4233 objqueuecheckingtime,
4234 (int)(((double)objqueuecheckingtime/(double)totalexetime)*100));
4235 printf("Total pre-processing time: %lld (%d%%)\n", preprocessingtime,
4236 (int)(((double)preprocessingtime/(double)totalexetime)*100));
4237 printf("Total post-processing time: %lld (%d%%)\n", postprocessingtime,
4238 (int)(((double)postprocessingtime/(double)totalexetime)*100));
4239 printf("Other time: %lld (%d%%)\n", other,
4240 (int)(((double)other/(double)totalexetime)*100));
4243 printf("\nAverage task execution time: %lld\n", averagetasktime);
4245 //printf("\nTotal time spent for interruptions: %lld\n", interrupttime);
4250 BAMBOO_DEBUGPRINT(0xdddd);
4251 // output task related info
4252 for(i= 0; i < taskInfoIndex; i++) {
4253 TaskInfo* tmpTInfo = taskInfoArray[i];
4254 char* tmpName = tmpTInfo->taskName;
4255 int nameLen = strlen(tmpName);
4256 BAMBOO_DEBUGPRINT(0xddda);
4257 for(j = 0; j < nameLen; j++) {
4258 BAMBOO_DEBUGPRINT_REG(tmpName[j]);
4260 BAMBOO_DEBUGPRINT(0xdddb);
4261 BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
4262 BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
4263 BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
4264 if(tmpTInfo->newObjs != NULL) {
4265 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
4266 struct RuntimeIterator * iter = NULL;
4267 while(0 == isEmpty(tmpTInfo->newObjs)) {
4268 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
4269 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
4271 RuntimeHashget(nobjtbl, (int)objtype, &num);
4272 RuntimeHashremovekey(nobjtbl, (int)objtype);
4274 RuntimeHashadd(nobjtbl, (int)objtype, num);
4276 RuntimeHashadd(nobjtbl, (int)objtype, 1);
4280 // ouput all new obj info
4281 iter = RuntimeHashcreateiterator(nobjtbl);
4282 while(RunhasNext(iter)) {
4283 char * objtype = (char *)Runkey(iter);
4284 int num = Runnext(iter);
4285 int nameLen = strlen(objtype);
4286 BAMBOO_DEBUGPRINT(0xddda);
4287 for(j = 0; j < nameLen; j++) {
4288 BAMBOO_DEBUGPRINT_REG(objtype[j]);
4290 BAMBOO_DEBUGPRINT(0xdddb);
4291 BAMBOO_DEBUGPRINT_REG(num);
4294 BAMBOO_DEBUGPRINT(0xdddc);
4297 if(taskInfoOverflow) {
4298 BAMBOO_DEBUGPRINT(0xefee);
4301 // output interrupt related info
4302 for(i = 0; i < interruptInfoIndex; i++) {
4303 InterruptInfo* tmpIInfo = interruptInfoArray[i];
4304 BAMBOO_DEBUGPRINT(0xddde);
4305 BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
4306 BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
4307 BAMBOO_DEBUGPRINT(0xdddf);
4310 if(interruptInfoOverflow) {
4311 BAMBOO_DEBUGPRINT(0xefef);
4314 BAMBOO_DEBUGPRINT(0xeeee);
4317 #endif // #ifdef PROFILE