3 #include "multicoreruntime.h"
4 #include "runtime_arch.h"
5 #include "GenericHashtable.h"
8 #define INLINE inline __attribute__((always_inline))
9 #endif // #ifndef INLINE
11 // data structures for task invocation
12 struct genhashtable * activetasks;
13 struct taskparamdescriptor * currtpd;
14 struct LockValue runtime_locks[MAXTASKPARAMS];
17 // specific functions used inside critical sections
18 void enqueueObject_I(void * ptr,
19 struct parameterwrapper ** queues,
21 int enqueuetasks_I(struct parameterwrapper *parameter,
22 struct parameterwrapper *prevptr,
23 struct ___Object___ *ptr,
29 #define NUM_CORES2TEST 5
31 int core2test[1][NUM_CORES2TEST] = {
35 int core2test[56][NUM_CORES2TEST] = {
36 { 0, -1, 7, -1, 1}, { 1, -1, 8, 0, 2}, { 2, -1, 9, 1, 3},
37 { 3, -1, 10, 2, 4}, { 4, -1, 11, 3, 5}, { 5, -1, 12, 4, 6},
38 { 6, -1, 13, 5, -1}, { 7, 0, 14, -1, 8}, { 8, 1, 15, 7, 9},
39 { 9, 2, 16, 8, 10}, {10, 3, 17, 9, 11}, {11, 4, 18, 10, 12},
40 {12, 5, 19, 11, 13}, {13, 6, 20, 12, -1}, {14, 7, 21, -1, 15},
41 {15, 8, 22, 14, 16}, {16, 9, 23, 15, 17}, {17, 10, 24, 16, 18},
42 {18, 11, 25, 17, 19}, {19, 12, 26, 18, 20}, {20, 13, 27, 19, -1},
43 {21, 14, 28, -1, 22}, {22, 15, 29, 21, 23}, {23, 16, 30, 22, 24},
44 {24, 17, 31, 23, 25}, {25, 18, 32, 24, 26}, {26, 19, 33, 25, 27},
45 {27, 20, 34, 26, -1}, {28, 21, 35, -1, 29}, {29, 22, 36, 28, 30},
46 {30, 23, 37, 29, 31}, {31, 24, 38, 30, 32}, {32, 25, 39, 31, 33},
47 {33, 26, 40, 32, 34}, {34, 27, 41, 33, -1}, {35, 28, 42, -1, 36},
48 {36, 29, 43, 35, 37}, {37, 30, 44, 36, 38}, {38, 31, 45, 37, 39},
49 {39, 32, 46, 38, 40}, {40, 33, 47, 39, 41}, {41, 34, 48, 40, -1},
50 {42, 35, 49, -1, 43}, {43, 36, 50, 42, 44}, {44, 37, 51, 43, 45},
51 {45, 38, 52, 44, 46}, {46, 39, 53, 45, 47}, {47, 40, 54, 46, 48},
52 {48, 41, 55, 47, -1}, {49, 42, -1, -1, 50}, {50, 43, -1, 49, 51},
53 {51, 44, -1, 50, 52}, {52, 45, -1, 51, 53}, {53, 46, -1, 52, 54},
54 {54, 47, -1, 53, 55}, {55, 48, -1, 54, -1}
57 int core2test[62][NUM_CORES2TEST] = {
58 { 0, -1, 6, -1, 1}, { 1, -1, 7, 0, 2}, { 2, -1, 8, 1, 3},
59 { 3, -1, 9, 2, 4}, { 4, -1, 10, 3, 5}, { 5, -1, 11, 4, -1},
60 { 6, 0, 14, -1, 7}, { 7, 1, 15, 6, 8}, { 8, 2, 16, 7, 9},
61 { 9, 3, 17, 8, 10}, {10, 4, 18, 9, 11}, {11, 5, 19, 10, 12},
62 {12, -1, 20, 11, 13}, {13, -1, 21, 12, -1}, {14, 6, 22, -1, 15},
63 {15, 7, 23, 14, 16}, {16, 8, 24, 15, 17}, {17, 9, 25, 16, 18},
64 {18, 10, 26, 17, 19}, {19, 11, 27, 18, 20}, {20, 12, 28, 19, 21},
65 {21, 13, 29, 28, -1}, {22, 14, 30, -1, 23}, {23, 15, 31, 22, 24},
66 {24, 16, 32, 23, 25}, {25, 17, 33, 24, 26}, {26, 18, 34, 25, 27},
67 {27, 19, 35, 26, 28}, {28, 20, 36, 27, 29}, {29, 21, 37, 28, -1},
68 {30, 22, 38, -1, 31}, {31, 23, 39, 30, 32}, {32, 24, 40, 31, 33},
69 {33, 25, 41, 32, 34}, {34, 26, 42, 33, 35}, {35, 27, 43, 34, 36},
70 {36, 28, 44, 35, 37}, {37, 29, 45, 36, -1}, {38, 30, 46, -1, 39},
71 {39, 31, 47, 38, 40}, {40, 32, 48, 39, 41}, {41, 33, 49, 40, 42},
72 {42, 34, 50, 41, 43}, {43, 35, 51, 42, 44}, {44, 36, 52, 43, 45},
73 {45, 37, 53, 44, -1}, {46, 38, 54, -1, 47}, {47, 39, 55, 46, 48},
74 {48, 40, 56, 47, 49}, {49, 41, 57, 48, 50}, {50, 42, 58, 49, 51},
75 {51, 43, 59, 50, 52}, {52, 44, 60, 51, 53}, {53, 45, 61, 52, -1},
76 {54, 46, -1, -1, 55}, {55, 47, -1, 54, 56}, {56, 48, -1, 55, 57},
77 {57, 49, -1, 56, 59}, {58, 50, -1, 57, 59}, {59, 51, -1, 58, 60},
78 {60, 52, -1, 59, 61}, {61, 53, -1, 60, -1}
82 unsigned int gcmem_mixed_threshold = 0;
83 unsigned int gcmem_mixed_usedmem = 0;
84 #define NUM_CORES2TEST 9
86 int core2test[1][NUM_CORES2TEST] = {
87 {0, -1, -1, -1, -1, -1, -1, -1, -1}
90 int core2test[56][NUM_CORES2TEST] = {
91 { 0, -1, 7, -1, 1, -1, 14, -1, 2}, { 1, -1, 8, 0, 2, -1, 15, -1, 3},
92 { 2, -1, 9, 1, 3, -1, 16, 0, 4}, { 3, -1, 10, 2, 4, -1, 17, 1, 5},
93 { 4, -1, 11, 3, 5, -1, 18, 2, 6}, { 5, -1, 12, 4, 6, -1, 19, 3, -1},
94 { 6, -1, 13, 5, -1, -1, 20, 4, -1}, { 7, 0, 14, -1, 8, -1, 21, -1, 9},
95 { 8, 1, 15, 7, 9, -1, 22, -1, 10}, { 9, 2, 16, 8, 10, -1, 23, 7, 11},
96 {10, 3, 17, 9, 11, -1, 24, 8, 12}, {11, 4, 18, 10, 12, -1, 25, 9, 13},
97 {12, 5, 19, 11, 13, -1, 26, 10, -1}, {13, 6, 20, 12, -1, -1, 27, 11, -1},
98 {14, 7, 21, -1, 15, 0, 28, -1, 16}, {15, 8, 22, 14, 16, 1, 29, -1, 17},
99 {16, 9, 23, 15, 17, 2, 30, 14, 18}, {17, 10, 24, 16, 18, 3, 31, 15, 19},
100 {18, 11, 25, 17, 19, 4, 32, 16, 20}, {19, 12, 26, 18, 20, 5, 33, 17, -1},
101 {20, 13, 27, 19, -1, 6, 34, 18, -1}, {21, 14, 28, -1, 22, 7, 35, -1, 23},
102 {22, 15, 29, 21, 23, 8, 36, -1, 24}, {23, 16, 30, 22, 24, 9, 37, 21, 25},
103 {24, 17, 31, 23, 25, 10, 38, 22, 26}, {25, 18, 32, 24, 26, 11, 39, 23, 27},
104 {26, 19, 33, 25, 27, 12, 40, 24, -1}, {27, 20, 34, 26, -1, 13, 41, 25, -1},
105 {28, 21, 35, -1, 29, 14, 42, -1, 30}, {29, 22, 36, 28, 30, 15, 43, -1, 31},
106 {30, 23, 37, 29, 31, 16, 44, 28, 32}, {31, 24, 38, 30, 32, 17, 45, 29, 33},
107 {32, 25, 39, 31, 33, 18, 46, 30, 34}, {33, 26, 40, 32, 34, 19, 47, 31, -1},
108 {34, 27, 41, 33, -1, 20, 48, 32, -1}, {35, 28, 42, -1, 36, 21, 49, -1, 37},
109 {36, 29, 43, 35, 37, 22, 50, -1, 38}, {37, 30, 44, 36, 38, 23, 51, 35, 39},
110 {38, 31, 45, 37, 39, 24, 52, 36, 40}, {39, 32, 46, 38, 40, 25, 53, 37, 41},
111 {40, 33, 47, 39, 41, 26, 54, 38, -1}, {41, 34, 48, 40, -1, 27, 55, 39, -1},
112 {42, 35, 49, -1, 43, 28, -1, -1, 44}, {43, 36, 50, 42, 44, 29, -1, -1, 45},
113 {44, 37, 51, 43, 45, 30, -1, 42, 46}, {45, 38, 52, 44, 46, 31, -1, 43, 47},
114 {46, 39, 53, 45, 47, 32, -1, 44, 48}, {47, 40, 54, 46, 48, 33, -1, 45, -1},
115 {48, 41, 55, 47, -1, 34, -1, 46, -1}, {49, 42, -1, -1, 50, 35, -1, -1, 51},
116 {50, 43, -1, 49, 51, 36, -1, -1, 52}, {51, 44, -1, 50, 52, 37, -1, 49, 53},
117 {52, 45, -1, 51, 53, 38, -1, 50, 54}, {53, 46, -1, 52, 54, 39, -1, 51, 55},
118 {54, 47, -1, 53, 55, 40, -1, 52, -1}, {55, 48, -1, 54, -1, 41, -1, 53, -1}
121 int core2test[62][NUM_CORES2TEST] = {
122 { 0, -1, 6, -1, 1, -1, 14, -1, 2}, { 1, -1, 7, 0, 2, -1, 15, -1, 3},
123 { 2, -1, 8, 1, 3, -1, 16, 0, 4}, { 3, -1, 9, 2, 4, -1, 17, 1, 5},
124 { 4, -1, 10, 3, 5, -1, 18, 2, -1}, { 5, -1, 11, 4, -1, -1, 19, 3, -1},
125 { 6, 0, 14, -1, 7, -1, 22, -1, 8}, { 7, 1, 15, 6, 8, -1, 23, -1, 9},
126 { 8, 2, 16, 7, 9, -1, 24, 6, 10}, { 9, 3, 17, 8, 10, -1, 25, 7, 11},
127 {10, 4, 18, 9, 11, -1, 26, 8, 12}, {11, 5, 19, 10, 12, -1, 27, 9, 13},
128 {12, -1, 20, 11, 13, -1, 28, 10, -1}, {13, -1, 21, 12, -1, -1, 29, 11, -1},
129 {14, 6, 22, -1, 15, 0, 30, -1, 16}, {15, 7, 23, 14, 16, 1, 31, -1, 17},
130 {16, 8, 24, 15, 17, 2, 32, 14, 18}, {17, 9, 25, 16, 18, 3, 33, 15, 19},
131 {18, 10, 26, 17, 19, 4, 34, 16, 20}, {19, 11, 27, 18, 20, 5, 35, 17, 21},
132 {20, 12, 28, 19, 21, -1, 36, 18, -1}, {21, 13, 29, 28, -1, -1, 37, 19, -1},
133 {22, 14, 30, -1, 23, 6, 38, -1, 24}, {23, 15, 31, 22, 24, 7, 39, -1, 25},
134 {24, 16, 32, 23, 25, 8, 40, 22, 26}, {25, 17, 33, 24, 26, 9, 41, 23, 27},
135 {26, 18, 34, 25, 27, 10, 42, 24, 28}, {27, 19, 35, 26, 28, 11, 43, 25, 29},
136 {28, 20, 36, 27, 29, 12, 44, 26, -1}, {29, 21, 37, 28, -1, 13, 45, 27, -1},
137 {30, 22, 38, -1, 31, 22, 46, -1, 32}, {31, 23, 39, 30, 32, 15, 47, -1, 33},
138 {32, 24, 40, 31, 33, 16, 48, 30, 34}, {33, 25, 41, 32, 34, 17, 49, 31, 35},
139 {34, 26, 42, 33, 35, 18, 50, 32, 36}, {35, 27, 43, 34, 36, 19, 51, 33, 37},
140 {36, 28, 44, 35, 37, 20, 52, 34, -1}, {37, 29, 45, 36, -1, 21, 53, 35, -1},
141 {38, 30, 46, -1, 39, 22, 54, -1, 40}, {39, 31, 47, 38, 40, 23, 55, -1, 41},
142 {40, 32, 48, 39, 41, 24, 56, 38, 42}, {41, 33, 49, 40, 42, 25, 57, 39, 43},
143 {42, 34, 50, 41, 43, 26, 58, 40, 44}, {43, 35, 51, 42, 44, 27, 59, 41, 45},
144 {44, 36, 52, 43, 45, 28, 60, 42, -1}, {45, 37, 53, 44, -1, 29, 61, 43, -1},
145 {46, 38, 54, -1, 47, 30, -1, -1, 48}, {47, 39, 55, 46, 48, 31, -1, -1, 49},
146 {48, 40, 56, 47, 49, 32, -1, 46, 50}, {49, 41, 57, 48, 50, 33, -1, 47, 51},
147 {50, 42, 58, 49, 51, 34, -1, 48, 52}, {51, 43, 59, 50, 52, 35, -1, 49, 53},
148 {52, 44, 60, 51, 53, 36, -1, 50, -1}, {53, 45, 61, 52, -1, 37, -1, 51, -1},
149 {54, 46, -1, -1, 55, 38, -1, -1, 56}, {55, 47, -1, 54, 56, 39, -1, -1, 57},
150 {56, 48, -1, 55, 57, 40, -1, 54, 58}, {57, 49, -1, 56, 59, 41, -1, 55, 59},
151 {58, 50, -1, 57, 59, 42, -1, 56, 60}, {59, 51, -1, 58, 60, 43, -1, 57, 61},
152 {60, 52, -1, 59, 61, 44, -1, 58, -1}, {61, 53, -1, 60, -1, 45, -1, 59, -1}
157 inline __attribute__((always_inline))
158 void setupsmemmode(void) {
160 // Only allocate local mem chunks to each core.
161 // If a core has used up its local shared memory, start gc.
162 bamboo_smem_mode = SMEMLOCAL;
164 // Allocate the local shared memory to each core with the highest priority,
165 // if a core has used up its local shared memory, try to allocate the
166 // shared memory that belong to its neighbours, if also failed, start gc.
167 bamboo_smem_mode = SMEMFIXED;
169 // Allocate the local shared memory to each core with the highest priority,
170 // if a core has used up its local shared memory, try to allocate the
171 // shared memory that belong to its neighbours first, if failed, check
172 // current memory allocation rate, if it has already reached the threshold,
173 // start gc, otherwise, allocate the shared memory globally. If all the
174 // shared memory has been used up, start gc.
175 bamboo_smem_mode = SMEMMIXED;
177 // Allocate all the memory chunks globally, do not consider the host cores
178 // When all the shared memory are used up, start gc.
179 bamboo_smem_mode = SMEMGLOBAL;
181 // defaultly using local mode
182 //bamboo_smem_mode = SMEMLOCAL;
183 //bamboo_smem_mode = SMEMGLOBAL;
184 //bamboo_smem_mode = SMEMFIXED;
186 } // void setupsmemmode(void)
189 inline __attribute__((always_inline))
190 void initruntimedata() {
192 // initialize the arrays
193 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
194 // startup core to initialize corestatus[]
195 for(i = 0; i < NUMCORESACTIVE; ++i) {
198 numreceiveobjs[i] = 0;
200 // initialize the profile data arrays
201 profilestatus[i] = 1;
205 gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
206 gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
208 } // for(i = 0; i < NUMCORESACTIVE; ++i)
210 for(i = 0; i < NUMCORES4GC; ++i) {
212 gcrequiredmems[i] = 0;
214 gcfilledblocks[i] = 0;
215 } // for(i = 0; i < NUMCORES4GC; ++i)
218 gc_infoOverflow = false;
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;
307 gc_num_forwardobj = 0;
310 // create the lock table, lockresult table and obj queue
313 (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
314 /* Set allocation blocks*/
315 locktable.listhead=NULL;
316 locktable.listtail=NULL;
318 locktable.numelements = 0;
323 lockRedirectTbl = allocateRuntimeHash_I(20);
324 objRedirectLockTbl = allocateRuntimeHash_I(20);
329 objqueue.head = NULL;
330 objqueue.tail = NULL;
336 //isInterrupt = true;
340 taskInfoOverflow = false;
342 interruptInfoIndex = 0;
343 interruptInfoOverflow = false;
346 for(i = 0; i < MAXTASKPARAMS; i++) {
347 runtime_locks[i].redirectlock = 0;
348 runtime_locks[i].value = 0;
353 inline __attribute__((always_inline))
354 void disruntimedata() {
356 #ifdef LOCALHASHTBL_TEST
357 freeRuntimeHash(gcpointertbl);
359 mgchashDelete(gcpointertbl);
361 //freeMGCHash(gcpointertbl);
362 freeMGCHash(gcforwardobjtbl);
363 // for mapping info structures
364 //freeRuntimeHash(gcrcoretbl);
366 freeRuntimeHash(lockRedirectTbl);
367 freeRuntimeHash(objRedirectLockTbl);
368 RUNFREE(locktable.bucket);
370 if(activetasks != NULL) {
371 genfreehashtable(activetasks);
373 if(currtpd != NULL) {
374 RUNFREE(currtpd->parameterArray);
378 BAMBOO_LOCAL_MEM_CLOSE();
379 BAMBOO_SHARE_MEM_CLOSE();
382 inline __attribute__((always_inline))
383 bool checkObjQueue() {
385 struct transObjInfo * objInfo = NULL;
389 #ifdef ACCURATEPROFILE
390 bool isChecking = false;
391 if(!isEmpty(&objqueue)) {
392 profileTaskStart("objqueue checking");
394 } // if(!isEmpty(&objqueue))
398 while(!isEmpty(&objqueue)) {
400 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
402 BAMBOO_DEBUGPRINT(0xf001);
405 //isInterrupt = false;
408 BAMBOO_DEBUGPRINT(0xeee1);
411 objInfo = (struct transObjInfo *)getItem(&objqueue);
412 obj = objInfo->objptr;
414 BAMBOO_DEBUGPRINT_REG((int)obj);
416 // grab lock and flush the obj
420 BAMBOO_WAITING_FOR_LOCK(0);
421 } // while(!lockflag)
424 BAMBOO_DEBUGPRINT_REG(grount);
439 BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
440 BAMBOO_CACHE_FLUSH_RANGE((int)obj,
441 classsize[((struct ___Object___ *)obj)->type]);
443 // enqueue the object
444 for(k = 0; k < objInfo->length; ++k) {
445 int taskindex = objInfo->queues[2 * k];
446 int paramindex = objInfo->queues[2 * k + 1];
447 struct parameterwrapper ** queues =
448 &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
450 BAMBOO_DEBUGPRINT_REG(taskindex);
451 BAMBOO_DEBUGPRINT_REG(paramindex);
452 struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
453 tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n",
454 BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj,
455 (long)obj, tmpptr->flag);
457 enqueueObject_I(obj, queues, 1);
459 BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
461 } // for(k = 0; k < objInfo->length; ++k)
462 releasewritelock_I(obj);
463 RUNFREE(objInfo->queues);
467 // put it at the end of the queue if no update version in the queue
468 struct QueueItem * qitem = getHead(&objqueue);
469 struct QueueItem * prev = NULL;
470 while(qitem != NULL) {
471 struct transObjInfo * tmpinfo =
472 (struct transObjInfo *)(qitem->objectptr);
473 if(tmpinfo->objptr == obj) {
474 // the same object in the queue, which should be enqueued
475 // recently. Current one is outdate, do not re-enqueue it
476 RUNFREE(objInfo->queues);
481 } // if(tmpinfo->objptr == obj)
482 qitem = getNextQueueItem(prev);
483 } // while(qitem != NULL)
484 // try to execute active tasks already enqueued first
485 addNewItem_I(&objqueue, objInfo);
487 //isInterrupt = true;
490 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
492 BAMBOO_DEBUGPRINT(0xf000);
496 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
498 BAMBOO_DEBUGPRINT(0xf000);
500 } // while(!isEmpty(&objqueue))
503 #ifdef ACCURATEPROFILE
511 BAMBOO_DEBUGPRINT(0xee02);
516 inline __attribute__((always_inline))
517 void checkCoreStatus() {
518 bool allStall = false;
522 (waitconfirm && (numconfirm == 0))) {
524 BAMBOO_DEBUGPRINT(0xee04);
525 BAMBOO_DEBUGPRINT_REG(waitconfirm);
527 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
529 BAMBOO_DEBUGPRINT(0xf001);
531 corestatus[BAMBOO_NUM_OF_CORE] = 0;
532 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
533 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
534 // check the status of all cores
537 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
539 for(i = 0; i < NUMCORESACTIVE; ++i) {
541 BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
543 if(corestatus[i] != 0) {
547 } // for(i = 0; i < NUMCORESACTIVE; ++i)
549 // check if the sum of send objs and receive obj are the same
550 // yes->check if the info is the latest; no->go on executing
552 for(i = 0; i < NUMCORESACTIVE; ++i) {
553 sumsendobj += numsendobjs[i];
555 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
557 } // for(i = 0; i < NUMCORESACTIVE; ++i)
558 for(i = 0; i < NUMCORESACTIVE; ++i) {
559 sumsendobj -= numreceiveobjs[i];
561 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
563 } // for(i = 0; i < NUMCORESACTIVE; ++i)
564 if(0 == sumsendobj) {
566 // the first time found all cores stall
567 // send out status confirm msg to all other cores
568 // reset the corestatus array too
570 BAMBOO_DEBUGPRINT(0xee05);
572 corestatus[BAMBOO_NUM_OF_CORE] = 1;
574 numconfirm = NUMCORESACTIVE - 1;
575 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
576 for(i = 1; i < NUMCORESACTIVE; ++i) {
578 // send status confirm msg to core i
579 send_msg_1(i, STATUSCONFIRM, false);
580 } // for(i = 1; i < NUMCORESACTIVE; ++i)
583 // all the core status info are the latest
584 // terminate; for profiling mode, send request to all
585 // other cores to pour out profiling data
587 BAMBOO_DEBUGPRINT(0xee06);
591 totalexetime = BAMBOO_GET_EXE_TIME() - bamboo_start_time;
594 //BAMBOO_DEBUGPRINT_REG(interrupttime);
597 BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME() - bamboo_start_time);
598 //BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
599 BAMBOO_DEBUGPRINT(0xbbbbbbbb);
601 // profile mode, send msgs to other cores to request pouring
602 // out progiling data
604 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
606 BAMBOO_DEBUGPRINT(0xf000);
608 for(i = 1; i < NUMCORESACTIVE; ++i) {
609 // send profile request msg to core i
610 send_msg_2(i, PROFILEOUTPUT, totalexetime, false);
611 } // for(i = 1; i < NUMCORESACTIVE; ++i)
612 // pour profiling data on startup core
615 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
617 BAMBOO_DEBUGPRINT(0xf001);
619 profilestatus[BAMBOO_NUM_OF_CORE] = 0;
620 // check the status of all cores
623 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
625 for(i = 0; i < NUMCORESACTIVE; ++i) {
627 BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
629 if(profilestatus[i] != 0) {
633 } // for(i = 0; i < NUMCORESACTIVE; ++i)
636 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
638 BAMBOO_DEBUGPRINT(0xf000);
643 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
649 // gc_profile mode, ourput gc prfiling data
652 gc_outputProfileData();
653 #endif // #ifdef GC_PROFILE
654 #endif // #ifdef MULTICORE_GC
656 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
657 terminate(); // All done.
658 } // if(!waitconfirm)
660 // still some objects on the fly on the network
661 // reset the waitconfirm and numconfirm
663 BAMBOO_DEBUGPRINT(0xee07);
667 } // if(0 == sumsendobj)
669 // not all cores are stall, keep on waiting
671 BAMBOO_DEBUGPRINT(0xee08);
676 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
678 BAMBOO_DEBUGPRINT(0xf000);
680 } // if((!waitconfirm) ||
683 // main function for each core
684 inline void run(void * arg) {
688 bool sendStall = false;
690 bool tocontinue = false;
692 corenum = BAMBOO_GET_NUM_OF_CORE();
694 BAMBOO_DEBUGPRINT(0xeeee);
695 BAMBOO_DEBUGPRINT_REG(corenum);
696 BAMBOO_DEBUGPRINT(STARTUPCORE);
699 // initialize runtime data structures
702 // other architecture related initialization
706 initializeexithandler();
708 // main process of the execution module
709 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
710 // non-executing cores, only processing communications
713 BAMBOO_DEBUGPRINT(0xee01);
714 BAMBOO_DEBUGPRINT_REG(taskInfoIndex);
715 BAMBOO_DEBUGPRINT_REG(taskInfoOverflow);
716 profileTaskStart("msg handling");
720 //isInterrupt = false;
724 /* Create queue of active tasks */
726 genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
727 (int (*)(void *,void *)) &comparetpd);
729 /* Process task information */
732 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
733 /* Create startup object */
734 createstartupobject(argc, argv);
738 BAMBOO_DEBUGPRINT(0xee00);
743 // check if need to do GC
747 // check if there are new active tasks can be executed
754 while(receiveObject() != -1) {
759 BAMBOO_DEBUGPRINT(0xee01);
762 // check if there are some pending objects,
763 // if yes, enqueue them and executetasks again
764 tocontinue = checkObjQueue();
768 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
771 BAMBOO_DEBUGPRINT(0xee03);
779 BAMBOO_DEBUGPRINT(0xee09);
785 // wait for some time
788 BAMBOO_DEBUGPRINT(0xee0a);
794 // send StallMsg to startup core
796 BAMBOO_DEBUGPRINT(0xee0b);
799 send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
800 self_numsendobjs, self_numreceiveobjs, false);
812 BAMBOO_DEBUGPRINT(0xee0c);
815 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
818 } // if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)
822 struct ___createstartupobject____I_locals {
825 struct ___StartupObject___ * ___startupobject___;
826 struct ArrayObject * ___stringarray___;
827 }; // struct ___createstartupobject____I_locals
829 void createstartupobject(int argc,
833 /* Allocate startup object */
835 struct ___createstartupobject____I_locals ___locals___={2, NULL, NULL, NULL};
836 struct ___StartupObject___ *startupobject=
837 (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
838 ___locals___.___startupobject___ = startupobject;
839 struct ArrayObject * stringarray=
840 allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
841 ___locals___.___stringarray___ = stringarray;
843 struct ___StartupObject___ *startupobject=
844 (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
845 struct ArrayObject * stringarray=
846 allocate_newarray(STRINGARRAYTYPE, argc-1);
848 /* Build array of strings */
849 startupobject->___parameters___=stringarray;
850 for(i=1; i<argc; i++) {
851 int length=strlen(argv[i]);
853 struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
855 struct ___String___ *newstring=NewString(argv[i],length);
857 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
861 startupobject->version = 0;
862 startupobject->lock = NULL;
864 /* Set initialized flag for startup object */
865 flagorandinit(startupobject,1,0xFFFFFFFF);
866 enqueueObject(startupobject, NULL, 0);
868 BAMBOO_CACHE_FLUSH_ALL();
872 int hashCodetpd(struct taskparamdescriptor *ftd) {
873 int hash=(int)ftd->task;
875 for(i=0; i<ftd->numParameters; i++) {
876 hash^=(int)ftd->parameterArray[i];
881 int comparetpd(struct taskparamdescriptor *ftd1,
882 struct taskparamdescriptor *ftd2) {
884 if (ftd1->task!=ftd2->task)
886 for(i=0; i<ftd1->numParameters; i++)
887 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
892 /* This function sets a tag. */
894 void tagset(void *ptr,
895 struct ___Object___ * obj,
896 struct ___TagDescriptor___ * tagd) {
898 void tagset(struct ___Object___ * obj,
899 struct ___TagDescriptor___ * tagd) {
901 struct ArrayObject * ao=NULL;
902 struct ___Object___ * tagptr=obj->___tags___;
904 obj->___tags___=(struct ___Object___ *)tagd;
906 /* Have to check if it is already set */
907 if (tagptr->type==TAGTYPE) {
908 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
913 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
914 struct ArrayObject * ao=
915 allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
916 obj=(struct ___Object___ *)ptrarray[2];
917 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
918 td=(struct ___TagDescriptor___ *) obj->___tags___;
920 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
923 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
924 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
925 obj->___tags___=(struct ___Object___ *) ao;
926 ao->___cachedCode___=2;
930 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
931 for(i=0; i<ao->___cachedCode___; i++) {
932 struct ___TagDescriptor___ * td=
933 ARRAYGET(ao, struct ___TagDescriptor___*, i);
938 if (ao->___cachedCode___<ao->___length___) {
939 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
940 ao->___cachedCode___++;
943 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
944 struct ArrayObject * aonew=
945 allocate_newarray(&ptrarray,TAGARRAYTYPE,
946 TAGARRAYINTERVAL+ao->___length___);
947 obj=(struct ___Object___ *)ptrarray[2];
948 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
949 ao=(struct ArrayObject *)obj->___tags___;
951 struct ArrayObject * aonew=
952 allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
955 aonew->___cachedCode___=ao->___length___+1;
956 for(i=0; i<ao->___length___; i++) {
957 ARRAYSET(aonew, struct ___TagDescriptor___*, i,
958 ARRAYGET(ao, struct ___TagDescriptor___*, i));
960 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
966 struct ___Object___ * tagset=tagd->flagptr;
969 } else if (tagset->type!=OBJECTARRAYTYPE) {
971 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
972 struct ArrayObject * ao=
973 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
974 obj=(struct ___Object___ *)ptrarray[2];
975 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
977 struct ArrayObject * ao=
978 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
980 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
981 ARRAYSET(ao, struct ___Object___ *, 1, obj);
982 ao->___cachedCode___=2;
983 tagd->flagptr=(struct ___Object___ *)ao;
985 struct ArrayObject *ao=(struct ArrayObject *) tagset;
986 if (ao->___cachedCode___<ao->___length___) {
987 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
991 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
992 struct ArrayObject * aonew=
993 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
994 OBJECTARRAYINTERVAL+ao->___length___);
995 obj=(struct ___Object___ *)ptrarray[2];
996 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
997 ao=(struct ArrayObject *)tagd->flagptr;
999 struct ArrayObject * aonew=
1000 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
1002 aonew->___cachedCode___=ao->___cachedCode___+1;
1003 for(i=0; i<ao->___length___; i++) {
1004 ARRAYSET(aonew, struct ___Object___*, i,
1005 ARRAYGET(ao, struct ___Object___*, i));
1007 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
1008 tagd->flagptr=(struct ___Object___ *) aonew;
1014 /* This function clears a tag. */
1016 void tagclear(void *ptr,
1017 struct ___Object___ * obj,
1018 struct ___TagDescriptor___ * tagd) {
1020 void tagclear(struct ___Object___ * obj,
1021 struct ___TagDescriptor___ * tagd) {
1023 /* We'll assume that tag is alway there.
1024 Need to statically check for this of course. */
1025 struct ___Object___ * tagptr=obj->___tags___;
1027 if (tagptr->type==TAGTYPE) {
1028 if ((struct ___TagDescriptor___ *)tagptr==tagd)
1029 obj->___tags___=NULL;
1031 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
1033 for(i=0; i<ao->___cachedCode___; i++) {
1034 struct ___TagDescriptor___ * td=
1035 ARRAYGET(ao, struct ___TagDescriptor___ *, i);
1037 ao->___cachedCode___--;
1038 if (i<ao->___cachedCode___)
1039 ARRAYSET(ao, struct ___TagDescriptor___ *, i,
1040 ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
1041 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
1042 if (ao->___cachedCode___==0)
1043 obj->___tags___=NULL;
1050 struct ___Object___ *tagset=tagd->flagptr;
1051 if (tagset->type!=OBJECTARRAYTYPE) {
1055 struct ArrayObject *ao=(struct ArrayObject *) tagset;
1057 for(i=0; i<ao->___cachedCode___; i++) {
1058 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
1060 ao->___cachedCode___--;
1061 if (i<ao->___cachedCode___)
1062 ARRAYSET(ao, struct ___Object___ *, i,
1063 ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
1064 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
1065 if (ao->___cachedCode___==0)
1076 /* This function allocates a new tag. */
1078 struct ___TagDescriptor___ * allocate_tag(void *ptr,
1080 struct ___TagDescriptor___ * v=
1081 (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
1082 classsize[TAGTYPE]);
1084 struct ___TagDescriptor___ * allocate_tag(int index) {
1085 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
1094 /* This function updates the flag for object ptr. It or's the flag
1095 with the or mask and and's it with the andmask. */
1097 void flagbody(struct ___Object___ *ptr,
1099 struct parameterwrapper ** queues,
1103 int flagcomp(const int *val1, const int *val2) {
1104 return (*val1)-(*val2);
1107 void flagorand(void * ptr,
1110 struct parameterwrapper ** queues,
1113 int oldflag=((int *)ptr)[1];
1114 int flag=ormask|oldflag;
1116 flagbody(ptr, flag, queues, length, false);
1120 bool intflagorand(void * ptr,
1124 int oldflag=((int *)ptr)[1];
1125 int flag=ormask|oldflag;
1127 if (flag==oldflag) /* Don't do anything */
1130 flagbody(ptr, flag, NULL, 0, false);
1136 void flagorandinit(void * ptr,
1139 int oldflag=((int *)ptr)[1];
1140 int flag=ormask|oldflag;
1142 flagbody(ptr,flag,NULL,0,true);
1145 void flagbody(struct ___Object___ *ptr,
1147 struct parameterwrapper ** vqueues,
1150 struct parameterwrapper * flagptr = NULL;
1152 struct parameterwrapper ** queues = vqueues;
1153 int length = vlength;
1155 int UNUSED, UNUSED2;
1156 int * enterflags = NULL;
1157 if((!isnew) && (queues == NULL)) {
1158 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
1159 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1160 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1167 /*Remove object from all queues */
1168 for(i = 0; i < length; ++i) {
1169 flagptr = queues[i];
1170 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
1171 (int *) &enterflags, &UNUSED, &UNUSED2);
1172 ObjectHashremove(flagptr->objectset, (int)ptr);
1173 if (enterflags!=NULL)
1174 RUNFREE(enterflags);
1178 void enqueueObject(void * vptr,
1179 struct parameterwrapper ** vqueues,
1181 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1184 //struct QueueItem *tmpptr;
1185 struct parameterwrapper * parameter=NULL;
1188 struct parameterwrapper * prevptr=NULL;
1189 struct ___Object___ *tagptr=NULL;
1190 struct parameterwrapper ** queues = vqueues;
1191 int length = vlength;
1192 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1195 if(queues == NULL) {
1196 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1197 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1199 tagptr=ptr->___tags___;
1201 /* Outer loop iterates through all parameter queues an object of
1202 this type could be in. */
1203 for(j = 0; j < length; ++j) {
1204 parameter = queues[j];
1206 if (parameter->numbertags>0) {
1208 goto nextloop; //that means the object has no tag
1209 //but that param needs tag
1210 else if(tagptr->type==TAGTYPE) { //one tag
1211 //struct ___TagDescriptor___ * tag=
1212 //(struct ___TagDescriptor___*) tagptr;
1213 for(i=0; i<parameter->numbertags; i++) {
1214 //slotid is parameter->tagarray[2*i];
1215 int tagid=parameter->tagarray[2*i+1];
1216 if (tagid!=tagptr->flag)
1217 goto nextloop; /*We don't have this tag */
1219 } else { //multiple tags
1220 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1221 for(i=0; i<parameter->numbertags; i++) {
1222 //slotid is parameter->tagarray[2*i];
1223 int tagid=parameter->tagarray[2*i+1];
1225 for(j=0; j<ao->___cachedCode___; j++) {
1226 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1237 for(i=0; i<parameter->numberofterms; i++) {
1238 int andmask=parameter->intarray[i*2];
1239 int checkmask=parameter->intarray[i*2+1];
1240 if ((ptr->flag&andmask)==checkmask) {
1241 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
1252 void enqueueObject_I(void * vptr,
1253 struct parameterwrapper ** vqueues,
1255 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1258 //struct QueueItem *tmpptr;
1259 struct parameterwrapper * parameter=NULL;
1262 struct parameterwrapper * prevptr=NULL;
1263 struct ___Object___ *tagptr=NULL;
1264 struct parameterwrapper ** queues = vqueues;
1265 int length = vlength;
1266 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1269 if(queues == NULL) {
1270 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1271 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1273 tagptr=ptr->___tags___;
1275 /* Outer loop iterates through all parameter queues an object of
1276 this type could be in. */
1277 for(j = 0; j < length; ++j) {
1278 parameter = queues[j];
1280 if (parameter->numbertags>0) {
1282 goto nextloop; //that means the object has no tag
1283 //but that param needs tag
1284 else if(tagptr->type==TAGTYPE) { //one tag
1285 //struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
1286 for(i=0; i<parameter->numbertags; i++) {
1287 //slotid is parameter->tagarray[2*i];
1288 int tagid=parameter->tagarray[2*i+1];
1289 if (tagid!=tagptr->flag)
1290 goto nextloop; /*We don't have this tag */
1292 } else { //multiple tags
1293 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1294 for(i=0; i<parameter->numbertags; i++) {
1295 //slotid is parameter->tagarray[2*i];
1296 int tagid=parameter->tagarray[2*i+1];
1298 for(j=0; j<ao->___cachedCode___; j++) {
1299 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1310 for(i=0; i<parameter->numberofterms; i++) {
1311 int andmask=parameter->intarray[i*2];
1312 int checkmask=parameter->intarray[i*2+1];
1313 if ((ptr->flag&andmask)==checkmask) {
1314 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1326 int * getAliasLock(void ** ptrs,
1328 struct RuntimeHash * tbl) {
1330 return (int*)(RUNMALLOC(sizeof(int)));
1335 bool redirect = false;
1336 int redirectlock = 0;
1337 for(; i < length; i++) {
1338 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1341 if(ptr->lock == NULL) {
1344 lock = (int)(ptr->lock);
1347 if(lock != redirectlock) {
1348 RuntimeHashadd(tbl, lock, redirectlock);
1351 if(RuntimeHashcontainskey(tbl, lock)) {
1352 // already redirected
1354 RuntimeHashget(tbl, lock, &redirectlock);
1355 for(; j < locklen; j++) {
1356 if(locks[j] != redirectlock) {
1357 RuntimeHashadd(tbl, locks[j], redirectlock);
1362 for(j = 0; j < locklen; j++) {
1363 if(locks[j] == lock) {
1366 } else if(locks[j] > lock) {
1373 locks[h] = locks[h-1];
1382 return (int *)redirectlock;
1384 return (int *)(locks[0]);
1389 void addAliasLock(void * ptr,
1391 struct ___Object___ * obj = (struct ___Object___ *)ptr;
1392 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1393 // originally no alias lock associated or have a different alias lock
1394 // flush it as the new one
1395 obj->lock = (int *)lock;
1400 inline void setTaskExitIndex(int index) {
1401 taskInfoArray[taskInfoIndex]->exitIndex = index;
1404 inline void addNewObjInfo(void * nobj) {
1405 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1406 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1408 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1413 // Only allocate local mem chunks to each core.
1414 // If a core has used up its local shared memory, start gc.
1415 void * localmalloc_I(int coren,
1419 int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
1422 int tofindb = gc_core2block[2*gccorenum+i]+(NUMCORES4GC*2)*j;
1423 int totest = tofindb;
1424 int bound = BAMBOO_SMEM_SIZE_L;
1428 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1429 int nsize = bamboo_smemtbl[totest];
1430 bool islocal = true;
1432 bool tocheck = true;
1433 // have some space in the block
1434 if(totest == tofindb) {
1435 // the first partition
1436 size = bound - nsize;
1437 } else if(nsize == 0) {
1438 // an empty partition, can be appended
1441 // not an empty partition, can not be appended
1442 // the last continuous block is not big enough, go to check the next
1446 } // if(totest == tofindb) else if(nsize == 0) else ...
1449 // have enough space in the block, malloc
1453 // no enough space yet, try to append next continuous block
1455 } // if(size > isize) else ...
1457 } // if(nsize < bound)
1459 // no space in the block, go to check the next block
1465 tofindb = totest = gc_core2block[2*gccorenum+i]+(NUMCORES4GC*2)*j;
1468 } // if(islocal) else ...
1469 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1470 // no more local mem, do not find suitable block
1473 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1476 if(foundsmem == 1) {
1477 // find suitable block
1478 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1479 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1480 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1482 // set bamboo_smemtbl
1483 for(i = tofindb; i <= totest; i++) {
1484 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1486 } else if(foundsmem == 2) {
1487 // no suitable block
1492 } // void * localmalloc_I(int, int, int *)
1495 // Allocate the local shared memory to each core with the highest priority,
1496 // if a core has used up its local shared memory, try to allocate the
1497 // shared memory that belong to its neighbours, if also failed, start gc.
1498 void * fixedmalloc_I(int coren,
1505 int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
1506 int coords_x = bamboo_cpu2coords[gccorenum*2];
1507 int coords_y = bamboo_cpu2coords[gccorenum*2+1];
1509 int tofindb = gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1510 int totest = tofindb;
1511 int bound = BAMBOO_SMEM_SIZE_L;
1515 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1516 int nsize = bamboo_smemtbl[totest];
1517 bool islocal = true;
1519 bool tocheck = true;
1520 // have some space in the block
1521 if(totest == tofindb) {
1522 // the first partition
1523 size = bound - nsize;
1524 } else if(nsize == 0) {
1525 // an empty partition, can be appended
1528 // not an empty partition, can not be appended
1529 // the last continuous block is not big enough, go to check the next
1533 } // if(totest == tofindb) else if(nsize == 0) else ...
1536 // have enough space in the block, malloc
1540 // no enough space yet, try to append next continuous block
1541 // TODO may consider to go to next local block?
1543 } // if(size > isize) else ...
1545 } // if(nsize < bound)
1547 // no space in the block, go to check the next block
1554 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1557 } // if(islocal) else ...
1558 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1559 // no more local mem, do not find suitable block on local mem
1560 // try to malloc shared memory assigned to the neighbour cores
1563 if(k >= NUM_CORES2TEST) {
1564 // no more memory available on either coren or its neighbour cores
1566 goto memsearchresult;
1568 } while(core2test[gccorenum][k] == -1);
1571 tofindb=totest=gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1572 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1576 if(foundsmem == 1) {
1577 // find suitable block
1578 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1579 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1580 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1582 // set bamboo_smemtbl
1583 for(i = tofindb; i <= totest; i++) {
1584 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1586 } else if(foundsmem == 2) {
1587 // no suitable block
1592 } // void * fixedmalloc_I(int, int, int *)
1593 #endif // #ifdef SMEMF
1596 // Allocate the local shared memory to each core with the highest priority,
1597 // if a core has used up its local shared memory, try to allocate the
1598 // shared memory that belong to its neighbours first, if failed, check
1599 // current memory allocation rate, if it has already reached the threshold,
1600 // start gc, otherwise, allocate the shared memory globally. If all the
1601 // shared memory has been used up, start gc.
1602 void * mixedmalloc_I(int coren,
1609 int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
1611 int tofindb = gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1612 int totest = tofindb;
1613 int bound = BAMBOO_SMEM_SIZE_L;
1617 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1618 int nsize = bamboo_smemtbl[totest];
1619 bool islocal = true;
1621 bool tocheck = true;
1622 // have some space in the block
1623 if(totest == tofindb) {
1624 // the first partition
1625 size = bound - nsize;
1626 } else if(nsize == 0) {
1627 // an empty partition, can be appended
1630 // not an empty partition, can not be appended
1631 // the last continuous block is not big enough, go to check the next
1635 } // if(totest == tofindb) else if(nsize == 0) else ...
1638 // have enough space in the block, malloc
1642 // no enough space yet, try to append next continuous block
1643 // TODO may consider to go to next local block?
1645 } // if(size > isize) else ...
1647 } // if(nsize < bound)
1649 // no space in the block, go to check the next block
1656 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1659 } // if(islocal) else ...
1660 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1661 // no more local mem, do not find suitable block on local mem
1662 // try to malloc shared memory assigned to the neighbour cores
1665 if(k >= NUM_CORES2TEST) {
1666 if(gcmem_mixed_usedmem >= gcmem_mixed_threshold) {
1667 // no more memory available on either coren or its neighbour cores
1669 goto memmixedsearchresult;
1671 // try allocate globally
1672 mem = globalmalloc_I(coren, isize, allocsize);
1676 } while(core2test[gccorenum][k] == -1);
1680 gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
1681 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1684 memmixedsearchresult:
1685 if(foundsmem == 1) {
1686 // find suitable block
1687 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1688 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1689 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1691 // set bamboo_smemtbl
1692 for(i = tofindb; i <= totest; i++) {
1693 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1695 gcmem_mixed_usedmem += size;
1696 if(tofindb == bamboo_free_block) {
1697 bamboo_free_block = totest+1;
1699 } else if(foundsmem == 2) {
1700 // no suitable block
1705 } // void * mixedmalloc_I(int, int, int *)
1706 #endif // #ifdef SMEMM
1708 // Allocate all the memory chunks globally, do not consider the host cores
1709 // When all the shared memory are used up, start gc.
1710 void * globalmalloc_I(int coren,
1714 int tofindb = bamboo_free_block; //0;
1715 int totest = tofindb;
1716 int bound = BAMBOO_SMEM_SIZE_L;
1719 if(tofindb > gcnumblock-1-bamboo_reserved_smem) {
1720 // Out of shared memory
1725 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1726 int nsize = bamboo_smemtbl[totest];
1727 bool isnext = false;
1729 bool tocheck = true;
1730 // have some space in the block
1731 if(totest == tofindb) {
1732 // the first partition
1733 size = bound - nsize;
1734 } else if(nsize == 0) {
1735 // an empty partition, can be appended
1738 // not an empty partition, can not be appended
1739 // the last continuous block is not big enough, start another block
1742 } // if(totest == tofindb) else if(nsize == 0) else ...
1745 // have enough space in the block, malloc
1748 } // if(size > isize)
1752 } // if(nsize < bound) else ...
1754 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1755 // no more local mem, do not find suitable block
1758 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1760 // start another block
1765 if(foundsmem == 1) {
1766 // find suitable block
1767 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1768 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1769 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1771 // set bamboo_smemtbl
1772 for(int i = tofindb; i <= totest; i++) {
1773 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1775 if(tofindb == bamboo_free_block) {
1776 bamboo_free_block = totest+1;
1778 } else if(foundsmem == 2) {
1779 // no suitable block
1785 } // void * globalmalloc_I(int, int, int *)
1786 #endif // #ifdef MULTICORE_GC
1788 // malloc from the shared memory
1789 void * smemalloc_I(int coren,
1794 int isize = size+(BAMBOO_CACHE_LINE_SIZE);
1796 // go through the bamboo_smemtbl for suitable partitions
1797 switch(bamboo_smem_mode) {
1799 mem = localmalloc_I(coren, isize, allocsize);
1805 mem = fixedmalloc_I(coren, isize, allocsize);
1807 // not supported yet
1808 BAMBOO_EXIT(0xe001);
1815 mem = mixedmalloc_I(coren, isize, allocsize);
1817 // not supported yet
1818 BAMBOO_EXIT(0xe002);
1824 mem = globalmalloc_I(coren, isize, allocsize);
1836 /*if(!interruptInfoOverflow) {
1837 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
1838 interruptInfoArray[interruptInfoIndex] = intInfo;
1839 intInfo->startTime = BAMBOO_GET_EXE_TIME();
1840 intInfo->endTime = -1;
1843 int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size) : (BAMBOO_SMEM_SIZE);
1844 //mem = mspace_calloc(bamboo_free_msp, 1, toallocate);
1845 if(toallocate > bamboo_free_smem_size) {
1849 mem = (void *)bamboo_free_smemp;
1850 bamboo_free_smemp = ((void*)bamboo_free_smemp) + toallocate;
1851 bamboo_free_smem_size -= toallocate;
1852 //BAMBOO_MEMSET_WH(mem, '\0', toallocate);
1854 *allocsize = toallocate;
1856 /*if(!interruptInfoOverflow) {
1857 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
1858 interruptInfoIndex++;
1859 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
1860 interruptInfoOverflow = true;
1865 #endif // MULTICORE_GC
1866 // no enough shared global memory
1872 BAMBOO_DEBUGPRINT(0xa001);
1873 BAMBOO_EXIT(0xa001);
1877 } // void * smemalloc_I(int, int, int)
1879 INLINE int checkMsgLength_I(int size) {
1882 BAMBOO_DEBUGPRINT(0xcccc);
1885 int type = msgdata[msgdataindex];
1892 case GCSTARTMAPINFO:
1906 case GCSTARTCOMPACT:
1909 case GCFINISHMAPINFO:
1934 case REDIRECTGROUNT:
1936 case REDIRECTRELEASE:
1949 case GCFINISHCOMPACT:
1963 case TRANSOBJ: // nonfixed size
1969 msglength = msgdata[msgdataindex+1];
1978 BAMBOO_DEBUGPRINT_REG(type);
1979 BAMBOO_DEBUGPRINT_REG(size);
1980 BAMBOO_DEBUGPRINT_REG(msgdataindex);
1981 BAMBOO_DEBUGPRINT_REG(msgdatalast);
1982 BAMBOO_DEBUGPRINT_REG(msgdatafull);
1985 BAMBOO_DEBUGPRINT(msgdata[msgdataindex+i]);
1987 BAMBOO_EXIT(0xd005);
1993 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
1998 BAMBOO_DEBUGPRINT(0xffff);
2004 INLINE void processmsg_transobj_I() {
2006 struct transObjInfo * transObj=RUNMALLOC_I(sizeof(struct transObjInfo));
2010 BAMBOO_DEBUGPRINT(0xe880);
2013 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2015 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
2017 BAMBOO_EXIT(0xa002);
2019 // store the object and its corresponding queue info, enqueue it later
2020 transObj->objptr = (void *)msgdata[msgdataindex]; //[2]
2022 transObj->length = (msglength - 3) / 2;
2023 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
2024 for(k = 0; k < transObj->length; ++k) {
2025 transObj->queues[2*k] = msgdata[msgdataindex]; //[3+2*k];
2029 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
2032 transObj->queues[2*k+1] = msgdata[msgdataindex]; //[3+2*k+1];
2036 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
2040 // check if there is an existing duplicate item
2042 struct QueueItem * qitem = getHead(&objqueue);
2043 struct QueueItem * prev = NULL;
2044 while(qitem != NULL) {
2045 struct transObjInfo * tmpinfo =
2046 (struct transObjInfo *)(qitem->objectptr);
2047 if(tmpinfo->objptr == transObj->objptr) {
2048 // the same object, remove outdate one
2049 RUNFREE(tmpinfo->queues);
2051 removeItem(&objqueue, qitem);
2057 qitem = getHead(&objqueue);
2059 qitem = getNextQueueItem(prev);
2062 addNewItem_I(&objqueue, (void *)transObj);
2064 ++(self_numreceiveobjs);
2067 INLINE void processmsg_transtall_I() {
2068 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2069 // non startup core can not receive stall msg
2071 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
2073 BAMBOO_EXIT(0xa003);
2075 int num_core = msgdata[msgdataindex]; //[1]
2077 if(num_core < NUMCORESACTIVE) {
2080 BAMBOO_DEBUGPRINT(0xe881);
2083 corestatus[num_core] = 0;
2084 numsendobjs[num_core] = msgdata[msgdataindex]; //[2];
2086 numreceiveobjs[num_core] = msgdata[msgdataindex]; //[3];
2091 #ifndef MULTICORE_GC
2092 INLINE void processmsg_lockrequest_I() {
2093 // check to see if there is a lock exist for the required obj
2094 // msgdata[1] -> lock type
2095 int locktype = msgdata[msgdataindex]; //[1];
2097 int data2 = msgdata[msgdataindex]; // obj pointer
2099 int data3 = msgdata[msgdataindex]; // lock
2101 int data4 = msgdata[msgdataindex]; // request core
2103 // -1: redirected, 0: approved, 1: denied
2104 int deny=processlockrequest(locktype, data3, data2, data4, data4, true);
2106 // this lock request is redirected
2109 // send response msg
2110 // for 32 bit machine, the size is always 4 words, cache the msg first
2111 int tmp = deny==1 ? LOCKDENY : LOCKGROUNT;
2112 if(BAMBOO_CHECK_SEND_MODE()) {
2113 cache_msg_4(data4, tmp, locktype, data2, data3);
2115 send_msg_4(data4, tmp, locktype, data2, data3, true);
2120 INLINE void processmsg_lockgrount_I() {
2122 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2124 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
2126 BAMBOO_EXIT(0xa004);
2128 int data2 = msgdata[msgdataindex];
2130 int data3 = msgdata[msgdataindex];
2132 if((lockobj == data2) && (lock2require == data3)) {
2135 BAMBOO_DEBUGPRINT(0xe882);
2144 // conflicts on lockresults
2146 BAMBOO_DEBUGPRINT_REG(data2);
2148 BAMBOO_EXIT(0xa005);
2152 INLINE void processmsg_lockdeny_I() {
2154 int data2 = msgdata[msgdataindex];
2156 int data3 = msgdata[msgdataindex];
2158 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2160 BAMBOO_DEBUGPRINT_REG(data2);
2162 BAMBOO_EXIT(0xa006);
2164 if((lockobj == data2) && (lock2require == data3)) {
2167 BAMBOO_DEBUGPRINT(0xe883);
2176 // conflicts on lockresults
2178 BAMBOO_DEBUGPRINT_REG(data2);
2180 BAMBOO_EXIT(0xa007);
2184 INLINE void processmsg_lockrelease_I() {
2185 int data1 = msgdata[msgdataindex];
2187 int data2 = msgdata[msgdataindex];
2189 // receive lock release msg
2190 processlockrelease(data1, data2, 0, false);
2193 INLINE void processmsg_redirectlock_I() {
2194 // check to see if there is a lock exist for the required obj
2195 int data1 = msgdata[msgdataindex];
2196 MSG_INDEXINC_I(); //msgdata[1]; // lock type
2197 int data2 = msgdata[msgdataindex];
2198 MSG_INDEXINC_I(); //msgdata[2]; // obj pointer
2199 int data3 = msgdata[msgdataindex];
2200 MSG_INDEXINC_I(); //msgdata[3]; // redirect lock
2201 int data4 = msgdata[msgdataindex];
2202 MSG_INDEXINC_I(); //msgdata[4]; // root request core
2203 int data5 = msgdata[msgdataindex];
2204 MSG_INDEXINC_I(); //msgdata[5]; // request core
2205 int deny = processlockrequest(data1, data3, data2, data5, data4, true);
2207 // this lock request is redirected
2210 // send response msg
2211 // for 32 bit machine, the size is always 4 words, cache the msg first
2212 if(BAMBOO_CHECK_SEND_MODE()) {
2213 cache_msg_4(data4, deny==1 ? REDIRECTDENY : REDIRECTGROUNT,
2214 data1, data2, data3);
2216 send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
2217 data1, data2, data3, true);
2222 INLINE void processmsg_redirectgrount_I() {
2224 int data2 = msgdata[msgdataindex];
2226 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2228 BAMBOO_DEBUGPRINT_REG(data2);
2230 BAMBOO_EXIT(0xa00a);
2232 if(lockobj == data2) {
2235 BAMBOO_DEBUGPRINT(0xe891);
2238 int data3 = msgdata[msgdataindex];
2242 RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
2247 // conflicts on lockresults
2249 BAMBOO_DEBUGPRINT_REG(data2);
2251 BAMBOO_EXIT(0xa00b);
2255 INLINE void processmsg_redirectdeny_I() {
2257 int data2 = msgdata[msgdataindex];
2259 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2261 BAMBOO_DEBUGPRINT_REG(data2);
2263 BAMBOO_EXIT(0xa00c);
2265 if(lockobj == data2) {
2268 BAMBOO_DEBUGPRINT(0xe892);
2277 // conflicts on lockresults
2279 BAMBOO_DEBUGPRINT_REG(data2);
2281 BAMBOO_EXIT(0xa00d);
2285 INLINE void processmsg_redirectrelease_I() {
2286 int data1 = msgdata[msgdataindex];
2288 int data2 = msgdata[msgdataindex];
2290 int data3 = msgdata[msgdataindex];
2292 processlockrelease(data1, data2, data3, true);
2294 #endif // #ifndef MULTICORE_GC
2297 INLINE void processmsg_profileoutput_I() {
2298 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
2299 // startup core can not receive profile output finish msg
2300 BAMBOO_EXIT(0xa008);
2304 BAMBOO_DEBUGPRINT(0xe885);
2308 totalexetime = msgdata[msgdataindex]; //[1]
2310 outputProfileData();
2311 // cache the msg first
2312 if(BAMBOO_CHECK_SEND_MODE()) {
2313 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
2315 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE, true);
2319 INLINE void processmsg_profilefinish_I() {
2320 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2321 // non startup core can not receive profile output finish msg
2323 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex /*1*/]);
2325 BAMBOO_EXIT(0xa009);
2329 BAMBOO_DEBUGPRINT(0xe886);
2332 int data1 = msgdata[msgdataindex];
2334 profilestatus[data1] = 0;
2336 #endif // #ifdef PROFILE
2338 INLINE void processmsg_statusconfirm_I() {
2339 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2340 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2341 // wrong core to receive such msg
2342 BAMBOO_EXIT(0xa00e);
2344 // send response msg
2347 BAMBOO_DEBUGPRINT(0xe887);
2350 // cache the msg first
2351 if(BAMBOO_CHECK_SEND_MODE()) {
2352 cache_msg_5(STARTUPCORE, STATUSREPORT,
2353 busystatus ? 1 : 0, BAMBOO_NUM_OF_CORE,
2354 self_numsendobjs, self_numreceiveobjs);
2356 send_msg_5(STARTUPCORE, STATUSREPORT, busystatus?1:0,
2357 BAMBOO_NUM_OF_CORE, self_numsendobjs,
2358 self_numreceiveobjs, true);
2363 INLINE void processmsg_statusreport_I() {
2364 int data1 = msgdata[msgdataindex];
2366 int data2 = msgdata[msgdataindex];
2368 int data3 = msgdata[msgdataindex];
2370 int data4 = msgdata[msgdataindex];
2372 // receive a status confirm info
2373 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2374 // wrong core to receive such msg
2376 BAMBOO_DEBUGPRINT_REG(data2);
2378 BAMBOO_EXIT(0xa00f);
2382 BAMBOO_DEBUGPRINT(0xe888);
2388 corestatus[data2] = data1;
2389 numsendobjs[data2] = data3;
2390 numreceiveobjs[data2] = data4;
2394 INLINE void processmsg_terminate_I() {
2397 BAMBOO_DEBUGPRINT(0xe889);
2404 INLINE void processmsg_memrequest_I() {
2406 if(!interruptInfoOverflow) {
2407 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
2408 interruptInfoArray[interruptInfoIndex] = intInfo;
2409 intInfo->startTime = BAMBOO_GET_EXE_TIME();
2410 intInfo->endTime = -1;
2413 int data1 = msgdata[msgdataindex];
2415 int data2 = msgdata[msgdataindex];
2417 // receive a shared memory request msg
2418 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2419 // wrong core to receive such msg
2421 BAMBOO_DEBUGPRINT_REG(data2);
2423 BAMBOO_EXIT(0xa010);
2427 BAMBOO_DEBUGPRINT(0xe88a);
2434 // is currently doing gc, dump this msg
2435 if(INITPHASE == gcphase) {
2436 // if still in the initphase of gc, send a startinit msg again,
2437 // cache the msg first
2438 if(BAMBOO_CHECK_SEND_MODE()) {
2439 cache_msg_1(data2, GCSTARTINIT);
2441 send_msg_1(data2, GCSTARTINIT, true);
2446 mem = smemalloc_I(data2, data1, &allocsize);
2448 // send the start_va to request core, cache the msg first
2449 if(BAMBOO_CHECK_SEND_MODE()) {
2450 cache_msg_3(data2, MEMRESPONSE, mem, allocsize);
2452 send_msg_3(data2, MEMRESPONSE, mem, allocsize, true);
2454 } // if mem == NULL, the gcflag of the startup core has been set
2455 // and the gc should be started later, then a GCSTARTINIT msg
2456 // will be sent to the requesting core to notice it to start gc
2457 // and try malloc again
2463 if(!interruptInfoOverflow) {
2464 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
2465 interruptInfoIndex++;
2466 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
2467 interruptInfoOverflow = true;
2473 INLINE void processmsg_memresponse_I() {
2474 int data1 = msgdata[msgdataindex];
2476 int data2 = msgdata[msgdataindex];
2478 // receive a shared memory response msg
2481 BAMBOO_DEBUGPRINT(0xe88b);
2485 // if is currently doing gc, dump this msg
2489 bamboo_smem_size = 0;
2492 bamboo_smem_zero_top = 0;
2496 // fill header to store the size of this mem block
2497 BAMBOO_MEMSET_WH(data1, '\0', BAMBOO_CACHE_LINE_SIZE);
2498 //memset(data1, 0, BAMBOO_CACHE_LINE_SIZE);
2499 (*((int*)data1)) = data2;
2500 bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
2501 bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
2502 bamboo_smem_zero_top = bamboo_cur_msp;
2504 bamboo_smem_size = data2;
2505 bamboo_cur_msp =(void*)(data1);
2515 INLINE void processmsg_gcstartinit_I() {
2517 gcphase = INITPHASE;
2519 // is waiting for response of mem request
2520 // let it return NULL and start gc
2521 bamboo_smem_size = 0;
2522 bamboo_cur_msp = NULL;
2524 bamboo_smem_zero_top = NULL;
2528 INLINE void processmsg_gcstart_I() {
2531 BAMBOO_DEBUGPRINT(0xe88c);
2535 gcphase = MARKPHASE;
2538 INLINE void processmsg_gcstartcompact_I() {
2539 gcblock2fill = msgdata[msgdataindex];
2540 MSG_INDEXINC_I(); //msgdata[1];
2541 gcphase = COMPACTPHASE;
2544 INLINE void processmsg_gcstartmapinfo_I() {
2548 INLINE void processmsg_gcstartflush_I() {
2549 gcphase = FLUSHPHASE;
2552 INLINE void processmsg_gcfinishinit_I() {
2553 int data1 = msgdata[msgdataindex];
2555 // received a init phase finish msg
2556 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2557 // non startup core can not receive this msg
2559 BAMBOO_DEBUGPRINT_REG(data1);
2561 BAMBOO_EXIT(0xb001);
2564 BAMBOO_DEBUGPRINT(0xe88c);
2565 BAMBOO_DEBUGPRINT_REG(data1);
2567 // All cores should do init GC
2568 if(data1 < NUMCORESACTIVE) {
2569 gccorestatus[data1] = 0;
2573 INLINE void processmsg_gcfinishmark_I() {
2574 int data1 = msgdata[msgdataindex];
2576 int data2 = msgdata[msgdataindex];
2578 int data3 = msgdata[msgdataindex];
2580 // received a mark phase finish msg
2581 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2582 // non startup core can not receive this msg
2584 BAMBOO_DEBUGPRINT_REG(data1);
2586 BAMBOO_EXIT(0xb002);
2588 // all cores should do mark
2589 if(data1 < NUMCORESACTIVE) {
2590 gccorestatus[data1] = 0;
2591 int entry_index = 0;
2594 entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
2597 entry_index = gcnumsrobjs_index;
2599 gcnumsendobjs[entry_index][data1] = data2;
2600 gcnumreceiveobjs[entry_index][data1] = data3;
2604 INLINE void processmsg_gcfinishcompact_I() {
2605 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2606 // non startup core can not receive this msg
2609 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
2611 BAMBOO_EXIT(0xb003);
2613 int cnum = msgdata[msgdataindex];
2614 MSG_INDEXINC_I(); //msgdata[1];
2615 int filledblocks = msgdata[msgdataindex];
2616 MSG_INDEXINC_I(); //msgdata[2];
2617 int heaptop = msgdata[msgdataindex];
2618 MSG_INDEXINC_I(); //msgdata[3];
2619 int data4 = msgdata[msgdataindex];
2620 MSG_INDEXINC_I(); //msgdata[4];
2621 // only gc cores need to do compact
2622 if(cnum < NUMCORES4GC) {
2623 if(COMPACTPHASE == gcphase) {
2624 gcfilledblocks[cnum] = filledblocks;
2625 gcloads[cnum] = heaptop;
2632 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
2633 // cache the msg first
2634 if(BAMBOO_CHECK_SEND_MODE()) {
2635 cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
2637 send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove, true);
2641 gccorestatus[cnum] = 0;
2643 } // if(cnum < NUMCORES4GC)
2646 INLINE void processmsg_gcfinishmapinfo_I() {
2647 int data1 = msgdata[msgdataindex];
2649 // received a map phase finish msg
2650 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2651 // non startup core can not receive this msg
2654 BAMBOO_DEBUGPRINT_REG(data1);
2656 BAMBOO_EXIT(0xb004);
2658 // all cores should do flush
2659 if(data1 < NUMCORES4GC) {
2660 gccorestatus[data1] = 0;
2665 INLINE void processmsg_gcfinishflush_I() {
2666 int data1 = msgdata[msgdataindex];
2668 // received a flush phase finish msg
2669 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2670 // non startup core can not receive this msg
2673 BAMBOO_DEBUGPRINT_REG(data1);
2675 BAMBOO_EXIT(0xb005);
2677 // all cores should do flush
2678 if(data1 < NUMCORESACTIVE) {
2679 gccorestatus[data1] = 0;
2683 INLINE void processmsg_gcmarkconfirm_I() {
2684 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2685 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2686 // wrong core to receive such msg
2687 BAMBOO_EXIT(0xb006);
2689 // send response msg, cahce the msg first
2690 if(BAMBOO_CHECK_SEND_MODE()) {
2691 cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2692 gcbusystatus, gcself_numsendobjs,
2693 gcself_numreceiveobjs);
2695 send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2696 gcbusystatus, gcself_numsendobjs,
2697 gcself_numreceiveobjs, true);
2702 INLINE void processmsg_gcmarkreport_I() {
2703 int data1 = msgdata[msgdataindex];
2705 int data2 = msgdata[msgdataindex];
2707 int data3 = msgdata[msgdataindex];
2709 int data4 = msgdata[msgdataindex];
2711 // received a marked phase finish confirm response msg
2712 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2713 // wrong core to receive such msg
2715 BAMBOO_DEBUGPRINT_REG(data2);
2717 BAMBOO_EXIT(0xb007);
2719 int entry_index = 0;
2723 entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
2725 // can never reach here
2727 entry_index = gcnumsrobjs_index;
2729 gccorestatus[data1] = data2;
2730 gcnumsendobjs[entry_index][data1] = data3;
2731 gcnumreceiveobjs[entry_index][data1] = data4;
2735 INLINE void processmsg_gcmarkedobj_I() {
2736 int data1 = msgdata[msgdataindex];
2738 // received a markedObj msg
2739 if(((int *)data1)[6] == INIT) {
2740 // this is the first time that this object is discovered,
2741 // set the flag as DISCOVERED
2742 ((int *)data1)[6] = DISCOVERED;
2743 gc_enqueue_I(data1);
2745 // set the remote flag
2746 ((int *)data1)[6] |= REMOTEM;
2747 gcself_numreceiveobjs++;
2748 gcbusystatus = true;
2751 INLINE void processmsg_gcmovestart_I() {
2753 gcdstcore = msgdata[msgdataindex];
2754 MSG_INDEXINC_I(); //msgdata[1];
2755 gcmovestartaddr = msgdata[msgdataindex];
2756 MSG_INDEXINC_I(); //msgdata[2];
2757 gcblock2fill = msgdata[msgdataindex];
2758 MSG_INDEXINC_I(); //msgdata[3];
2761 INLINE void processmsg_gcmaprequest_I() {
2763 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2765 void * dstptr = NULL;
2766 int data1 = msgdata[msgdataindex];
2769 // TODO unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2771 #ifdef LOCALHASHTBL_TEST
2772 RuntimeHashget(gcpointertbl, data1, &dstptr);
2774 dstptr = mgchashSearch(gcpointertbl, data1);
2776 //MGCHashget(gcpointertbl, data1, &dstptr);
2778 // TODO flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2780 int data2 = msgdata[msgdataindex];
2783 // TODO unsigned long long ttimei = BAMBOO_GET_EXE_TIME();
2785 if(NULL == dstptr) {
2786 // no such pointer in this core, something is wrong
2788 BAMBOO_DEBUGPRINT_REG(data1);
2789 BAMBOO_DEBUGPRINT_REG(data2);
2791 BAMBOO_EXIT(0xb009);
2792 //assume that the object was not moved, use the original address
2793 /*if(isMsgSending) {
2794 cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2796 send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2799 // send back the mapping info, cache the msg first
2800 if(BAMBOO_CHECK_SEND_MODE()) {
2801 cache_msg_3(data2, GCMAPINFO, data1, (int)dstptr);
2803 send_msg_3(data2, GCMAPINFO, data1, (int)dstptr, true);
2807 // TODO flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimei;
2808 //num_mapinforequest_i++;
2812 INLINE void processmsg_gcmapinfo_I() {
2814 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2816 int data1 = msgdata[msgdataindex];
2818 gcmappedobj = msgdata[msgdataindex]; // [2]
2820 #ifdef LOCALHASHTBL_TEST
2821 RuntimeHashadd_I(gcpointertbl, data1, gcmappedobj);
2823 mgchashInsert_I(gcpointertbl, data1, gcmappedobj);
2825 //MGCHashadd_I(gcpointertbl, data1, gcmappedobj);
2826 if(data1 == gcobj2map) {
2830 //flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2834 INLINE void processmsg_gcmaptbl_I() {
2835 int data1 = msgdata[msgdataindex];
2837 int data2 = msgdata[msgdataindex];
2839 gcrpointertbls[data2] = (mgcsharedhashtbl_t *)data1; //(struct GCSharedHash *)data1;
2842 INLINE void processmsg_gclobjinfo_I() {
2845 int data1 = msgdata[msgdataindex];
2847 int data2 = msgdata[msgdataindex];
2849 if(BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1) {
2851 BAMBOO_DEBUGPRINT_REG(data2);
2853 BAMBOO_EXIT(0xb00b);
2855 // store the mark result info
2857 gcloads[cnum] = msgdata[msgdataindex];
2858 MSG_INDEXINC_I(); // msgdata[3];
2859 int data4 = msgdata[msgdataindex];
2861 if(gcheaptop < data4) {
2864 // large obj info here
2865 for(int k = 5; k < data1; ) {
2866 int lobj = msgdata[msgdataindex];
2867 MSG_INDEXINC_I(); //msgdata[k++];
2868 int length = msgdata[msgdataindex];
2869 MSG_INDEXINC_I(); //msgdata[k++];
2870 gc_lobjenqueue_I(lobj, length, cnum);
2872 } // for(int k = 5; k < msgdata[1];)
2875 INLINE void processmsg_gclobjmapping_I() {
2876 int data1 = msgdata[msgdataindex];
2878 int data2 = msgdata[msgdataindex];
2880 #ifdef LOCALHASHTBL_TEST
2881 RuntimeHashadd_I(gcpointertbl, data1, data2);
2883 mgchashInsert_I(gcpointertbl, data1, data2);
2885 //MGCHashadd_I(gcpointertbl, data1, data2);
2886 mgcsharedhashInsert_I(gcsharedptbl, data1, data2);
2888 #endif // #ifdef MULTICORE_GC
2890 // receive object transferred from other cores
2891 // or the terminate message from other cores
2892 // Should be invoked in critical sections!!
2893 // NOTICE: following format is for threadsimulate version only
2894 // RAW version please see previous description
2895 // format: type + object
2896 // type: -1--stall msg
2898 // return value: 0--received an object
2899 // 1--received nothing
2900 // 2--received a Stall Msg
2901 // 3--received a lock Msg
2902 // RAW version: -1 -- received nothing
2903 // otherwise -- received msg type
2904 int receiveObject(int send_port_pending) {
2906 // get the incoming msgs
2907 if(receiveMsg(send_port_pending) == -1) {
2911 // processing received msgs
2913 MSG_REMAINSIZE_I(&size);
2914 if((size == 0) || (checkMsgLength_I(size) == -1)) {
2916 // have new coming msg
2917 if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
2924 if(msglength <= size) {
2925 // have some whole msg
2926 //if(msgdataindex == msglength) {
2927 // received a whole msg
2929 type = msgdata[msgdataindex]; //[0]
2931 msgdatafull = false;
2933 //tprintf("msg type: %x\n", type);
2936 // receive a object transfer msg
2937 processmsg_transobj_I();
2942 // receive a stall msg
2943 processmsg_transtall_I();
2947 // GC version have no lock msgs
2948 #ifndef MULTICORE_GC
2950 // receive lock request msg, handle it right now
2951 processmsg_lockrequest_I();
2953 } // case LOCKREQUEST
2956 // receive lock grount msg
2957 processmsg_lockgrount_I();
2959 } // case LOCKGROUNT
2962 // receive lock deny msg
2963 processmsg_lockdeny_I();
2968 processmsg_lockrelease_I();
2970 } // case LOCKRELEASE
2971 #endif // #ifndef MULTICORE_GC
2974 case PROFILEOUTPUT: {
2975 // receive an output profile data request msg
2976 processmsg_profileoutput_I();
2978 } // case PROFILEOUTPUT
2980 case PROFILEFINISH: {
2981 // receive a profile output finish msg
2982 processmsg_profilefinish_I();
2984 } // case PROFILEFINISH
2985 #endif // #ifdef PROFILE
2987 // GC version has no lock msgs
2988 #ifndef MULTICORE_GC
2989 case REDIRECTLOCK: {
2990 // receive a redirect lock request msg, handle it right now
2991 processmsg_redirectlock_I();
2993 } // case REDIRECTLOCK
2995 case REDIRECTGROUNT: {
2996 // receive a lock grant msg with redirect info
2997 processmsg_redirectgrount_I();
2999 } // case REDIRECTGROUNT
3001 case REDIRECTDENY: {
3002 // receive a lock deny msg with redirect info
3003 processmsg_redirectdeny_I();
3005 } // case REDIRECTDENY
3007 case REDIRECTRELEASE: {
3008 // receive a lock release msg with redirect info
3009 processmsg_redirectrelease_I();
3011 } // case REDIRECTRELEASE
3012 #endif // #ifndef MULTICORE_GC
3014 case STATUSCONFIRM: {
3015 // receive a status confirm info
3016 processmsg_statusconfirm_I();
3018 } // case STATUSCONFIRM
3020 case STATUSREPORT: {
3021 processmsg_statusreport_I();
3023 } // case STATUSREPORT
3026 // receive a terminate msg
3027 processmsg_terminate_I();
3032 processmsg_memrequest_I();
3034 } // case MEMREQUEST
3037 processmsg_memresponse_I();
3039 } // case MEMRESPONSE
3044 processmsg_gcstartinit_I();
3046 } // case GCSTARTINIT
3049 // receive a start GC msg
3050 processmsg_gcstart_I();
3054 case GCSTARTCOMPACT: {
3055 // a compact phase start msg
3056 processmsg_gcstartcompact_I();
3058 } // case GCSTARTCOMPACT
3060 case GCSTARTMAPINFO: {
3061 // received a flush phase start msg
3062 processmsg_gcstartmapinfo_I();
3064 } // case GCSTARTFLUSH
3066 case GCSTARTFLUSH: {
3067 // received a flush phase start msg
3068 processmsg_gcstartflush_I();
3070 } // case GCSTARTFLUSH
3072 case GCFINISHINIT: {
3073 processmsg_gcfinishinit_I();
3075 } // case GCFINISHINIT
3077 case GCFINISHMARK: {
3078 processmsg_gcfinishmark_I();
3080 } // case GCFINISHMARK
3082 case GCFINISHCOMPACT: {
3083 // received a compact phase finish msg
3084 processmsg_gcfinishcompact_I();
3086 } // case GCFINISHCOMPACT
3088 case GCFINISHMAPINFO: {
3089 processmsg_gcfinishmapinfo_I();
3091 } // case GCFINISHMAPINFO
3093 case GCFINISHFLUSH: {
3094 processmsg_gcfinishflush_I();
3096 } // case GCFINISHFLUSH
3099 // received a GC finish msg
3100 gcphase = FINISHPHASE;
3104 case GCMARKCONFIRM: {
3105 // received a marked phase finish confirm request msg
3106 // all cores should do mark
3107 processmsg_gcmarkconfirm_I();
3109 } // case GCMARKCONFIRM
3111 case GCMARKREPORT: {
3112 processmsg_gcmarkreport_I();
3114 } // case GCMARKREPORT
3117 processmsg_gcmarkedobj_I();
3119 } // case GCMARKEDOBJ
3122 // received a start moving objs msg
3123 processmsg_gcmovestart_I();
3125 } // case GCMOVESTART
3127 case GCMAPREQUEST: {
3128 // received a mapping info request msg
3129 processmsg_gcmaprequest_I();
3131 } // case GCMAPREQUEST
3134 // received a mapping info response msg
3135 processmsg_gcmapinfo_I();
3140 // received a mapping tbl response msg
3141 processmsg_gcmaptbl_I();
3145 case GCLOBJREQUEST: {
3146 // received a large objs info request msg
3147 transferMarkResults_I();
3149 } // case GCLOBJREQUEST
3152 // received a large objs info response msg
3153 processmsg_gclobjinfo_I();
3155 } // case GCLOBJINFO
3157 case GCLOBJMAPPING: {
3158 // received a large obj mapping info msg
3159 processmsg_gclobjmapping_I();
3161 } // case GCLOBJMAPPING
3163 #endif // #ifdef MULTICORE_GC
3168 //memset(msgdata, '\0', sizeof(int) * msgdataindex);
3170 msglength = BAMBOO_MSG_BUF_LENGTH;
3172 //printf("++ msg: %x \n", type);
3174 if(msgdataindex != msgdatalast) {
3175 // still have available msg
3180 BAMBOO_DEBUGPRINT(0xe88d);
3184 // have new coming msg
3185 if(BAMBOO_MSG_AVAIL() != 0) {
3199 BAMBOO_DEBUGPRINT(0xe88e);
3203 /* if(isInterrupt) {
3211 int enqueuetasks(struct parameterwrapper *parameter,
3212 struct parameterwrapper *prevptr,
3213 struct ___Object___ *ptr,
3215 int numenterflags) {
3216 void * taskpointerarray[MAXTASKPARAMS];
3218 //int numparams=parameter->task->numParameters;
3219 int numiterators=parameter->task->numTotal-1;
3222 struct taskdescriptor * task=parameter->task;
3224 //this add the object to parameterwrapper
3225 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
3226 numenterflags, enterflags==NULL);
3228 /* Add enqueued object to parameter vector */
3229 taskpointerarray[parameter->slot]=ptr;
3231 /* Reset iterators */
3232 for(j=0; j<numiterators; j++) {
3233 toiReset(¶meter->iterators[j]);
3236 /* Find initial state */
3237 for(j=0; j<numiterators; j++) {
3239 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3240 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3242 /* Need to backtrack */
3243 toiReset(¶meter->iterators[j]);
3247 /* Nothing to enqueue */
3253 /* Enqueue current state */
3255 struct taskparamdescriptor *tpd=
3256 RUNMALLOC(sizeof(struct taskparamdescriptor));
3258 tpd->numParameters=numiterators+1;
3259 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
3261 for(j=0; j<=numiterators; j++) {
3262 //store the actual parameters
3263 tpd->parameterArray[j]=taskpointerarray[j];
3266 if (( /*!gencontains(failedtasks, tpd)&&*/
3267 !gencontains(activetasks,tpd))) {
3268 genputtable(activetasks, tpd, tpd);
3270 RUNFREE(tpd->parameterArray);
3274 /* This loop iterates to the next parameter combination */
3275 if (numiterators==0)
3278 for(j=numiterators-1; j<numiterators; j++) {
3280 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3281 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3283 /* Need to backtrack */
3284 toiReset(¶meter->iterators[j]);
3288 /* Nothing more to enqueue */
3296 int enqueuetasks_I(struct parameterwrapper *parameter,
3297 struct parameterwrapper *prevptr,
3298 struct ___Object___ *ptr,
3300 int numenterflags) {
3301 void * taskpointerarray[MAXTASKPARAMS];
3303 //int numparams=parameter->task->numParameters;
3304 int numiterators=parameter->task->numTotal-1;
3309 struct taskdescriptor * task=parameter->task;
3311 //this add the object to parameterwrapper
3312 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
3313 numenterflags, enterflags==NULL);
3315 /* Add enqueued object to parameter vector */
3316 taskpointerarray[parameter->slot]=ptr;
3318 /* Reset iterators */
3319 for(j=0; j<numiterators; j++) {
3320 toiReset(¶meter->iterators[j]);
3323 /* Find initial state */
3324 for(j=0; j<numiterators; j++) {
3326 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3327 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3329 /* Need to backtrack */
3330 toiReset(¶meter->iterators[j]);
3334 /* Nothing to enqueue */
3340 /* Enqueue current state */
3342 struct taskparamdescriptor *tpd=
3343 RUNMALLOC_I(sizeof(struct taskparamdescriptor));
3345 tpd->numParameters=numiterators+1;
3346 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
3348 for(j=0; j<=numiterators; j++) {
3349 //store the actual parameters
3350 tpd->parameterArray[j]=taskpointerarray[j];
3353 if (( /*!gencontains(failedtasks, tpd)&&*/
3354 !gencontains(activetasks,tpd))) {
3355 genputtable_I(activetasks, tpd, tpd);
3357 RUNFREE(tpd->parameterArray);
3361 /* This loop iterates to the next parameter combination */
3362 if (numiterators==0)
3365 for(j=numiterators-1; j<numiterators; j++) {
3367 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
3368 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3370 /* Need to backtrack */
3371 toiReset(¶meter->iterators[j]);
3375 /* Nothing more to enqueue */
3389 int containstag(struct ___Object___ *ptr,
3390 struct ___TagDescriptor___ *tag);
3392 #ifndef MULTICORE_GC
3393 void releasewritelock_r(void * lock, void * redirectlock) {
3395 int reallock = (int)lock;
3396 targetcore = (reallock >> 5) % NUMCORES;
3399 BAMBOO_DEBUGPRINT(0xe671);
3400 BAMBOO_DEBUGPRINT_REG((int)lock);
3401 BAMBOO_DEBUGPRINT_REG(reallock);
3402 BAMBOO_DEBUGPRINT_REG(targetcore);
3405 if(targetcore == BAMBOO_NUM_OF_CORE) {
3406 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3408 BAMBOO_DEBUGPRINT(0xf001);
3410 // reside on this core
3411 if(!RuntimeHashcontainskey(locktbl, reallock)) {
3412 // no locks for this object, something is wrong
3413 BAMBOO_EXIT(0xa00b);
3416 struct LockValue * lockvalue = NULL;
3418 BAMBOO_DEBUGPRINT(0xe672);
3420 RuntimeHashget(locktbl, reallock, &rwlock_obj);
3421 lockvalue = (struct LockValue *)rwlock_obj;
3423 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
3426 lockvalue->redirectlock = (int)redirectlock;
3428 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
3431 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3433 BAMBOO_DEBUGPRINT(0xf000);
3437 // send lock release with redirect info msg
3438 // for 32 bit machine, the size is always 4 words
3439 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock,
3440 (int)redirectlock, false);
3445 void executetasks() {
3446 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
3449 struct ___Object___ * tmpparam = NULL;
3450 struct parameterdescriptor * pd=NULL;
3451 struct parameterwrapper *pw=NULL;
3461 while(hashsize(activetasks)>0) {
3466 BAMBOO_DEBUGPRINT(0xe990);
3469 /* See if there are any active tasks */
3470 //if (hashsize(activetasks)>0) {
3473 #ifdef ACCURATEPROFILE
3474 profileTaskStart("tpd checking");
3478 //clock1 = BAMBOO_GET_EXE_TIME();
3481 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
3482 genfreekey(activetasks, currtpd);
3484 numparams=currtpd->task->numParameters;
3485 numtotal=currtpd->task->numTotal;
3487 // clear the lockRedirectTbl
3488 // (TODO, this table should be empty after all locks are released)
3490 /*for(j = 0; j < MAXTASKPARAMS; j++) {
3491 runtime_locks[j].redirectlock = 0;
3492 runtime_locks[j].value = 0;
3494 // get all required locks
3495 runtime_locklen = 0;
3496 // check which locks are needed
3497 for(i = 0; i < numparams; i++) {
3498 void * param = currtpd->parameterArray[i];
3502 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
3504 taskpointerarray[i+OFFSET]=param;
3507 if(((struct ___Object___ *)param)->lock == NULL) {
3508 tmplock = (int)param;
3510 tmplock = (int)(((struct ___Object___ *)param)->lock);
3512 // insert into the locks array
3513 for(j = 0; j < runtime_locklen; j++) {
3514 if(runtime_locks[j].value == tmplock) {
3517 } else if(runtime_locks[j].value > tmplock) {
3522 int h = runtime_locklen;
3524 runtime_locks[h].redirectlock = runtime_locks[h-1].redirectlock;
3525 runtime_locks[h].value = runtime_locks[h-1].value;
3527 runtime_locks[j].value = tmplock;
3528 runtime_locks[j].redirectlock = (int)param;
3531 } // line 2713: for(i = 0; i < numparams; i++)
3532 // grab these required locks
3534 BAMBOO_DEBUGPRINT(0xe991);
3537 //clock2 = BAMBOO_GET_EXE_TIME();
3539 for(i = 0; i < runtime_locklen; i++) {
3540 int * lock = (int *)(runtime_locks[i].redirectlock);
3542 // require locks for this parameter if it is not a startup object
3544 BAMBOO_DEBUGPRINT_REG((int)lock);
3545 BAMBOO_DEBUGPRINT_REG((int)(runtime_locks[i].value));
3548 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3550 BAMBOO_DEBUGPRINT(0xf001);
3553 //isInterrupt = false;
3556 BAMBOO_WAITING_FOR_LOCK(0);
3560 while(BAMBOO_WAITING_FOR_LOCK(0) != -1) {
3564 grount = lockresult;
3574 //isInterrupt = true;
3576 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3578 BAMBOO_DEBUGPRINT(0xf000);
3583 BAMBOO_DEBUGPRINT(0xe992);
3584 BAMBOO_DEBUGPRINT_REG(lock);
3586 // check if has the lock already
3587 // can not get the lock, try later
3588 // release all grabbed locks for previous parameters
3589 for(j = 0; j < i; ++j) {
3590 lock = (int*)(runtime_locks[j].redirectlock);
3591 releasewritelock(lock);
3593 genputtable(activetasks, currtpd, currtpd);
3594 if(hashsize(activetasks) == 1) {
3595 // only one task right now, wait a little while before next try
3601 #ifdef ACCURATEPROFILE
3602 // fail, set the end of the checkTaskInfo
3609 } // line 2752: for(i = 0; i < runtime_locklen; i++)
3612 clock3 = BAMBOO_GET_EXE_TIME();
3613 //tprintf("sort: %d, grab: %d \n", clock2-clock1, clock3-clock2);*/
3616 BAMBOO_DEBUGPRINT(0xe993);
3618 /* Make sure that the parameters are still in the queues */
3619 for(i=0; i<numparams; i++) {
3620 void * parameter=currtpd->parameterArray[i];
3624 BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
3625 classsize[((struct ___Object___ *)parameter)->type]);
3627 tmpparam = (struct ___Object___ *)parameter;
3628 pd=currtpd->task->descriptorarray[i];
3629 pw=(struct parameterwrapper *) pd->queue;
3630 /* Check that object is still in queue */
3632 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
3634 BAMBOO_DEBUGPRINT(0xe994);
3635 BAMBOO_DEBUGPRINT_REG(parameter);
3637 // release grabbed locks
3638 for(j = 0; j < runtime_locklen; ++j) {
3639 int * lock = (int *)(runtime_locks[j].redirectlock);
3640 releasewritelock(lock);
3642 RUNFREE(currtpd->parameterArray);
3648 /* Check if the object's flags still meets requirements */
3652 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
3653 andmask=pw->intarray[tmpi*2];
3654 checkmask=pw->intarray[tmpi*2+1];
3655 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
3661 // flags are never suitable
3662 // remove this obj from the queue
3664 int UNUSED, UNUSED2;
3667 BAMBOO_DEBUGPRINT(0xe995);
3668 BAMBOO_DEBUGPRINT_REG(parameter);
3670 ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
3671 (int *) &enterflags, &UNUSED, &UNUSED2);
3672 ObjectHashremove(pw->objectset, (int)parameter);
3673 if (enterflags!=NULL)
3674 RUNFREE(enterflags);
3675 // release grabbed locks
3676 for(j = 0; j < runtime_locklen; ++j) {
3677 int * lock = (int *)(runtime_locks[j].redirectlock);
3678 releasewritelock(lock);
3680 RUNFREE(currtpd->parameterArray);
3684 #ifdef ACCURATEPROFILE
3685 // fail, set the end of the checkTaskInfo
3690 } // line 2878: if (!ismet)
3694 /* Check that object still has necessary tags */
3695 for(j=0; j<pd->numbertags; j++) {
3696 int slotid=pd->tagarray[2*j]+numparams;
3697 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
3698 if (!containstag(parameter, tagd)) {
3700 BAMBOO_DEBUGPRINT(0xe996);
3703 // release grabbed locks
3705 for(tmpj = 0; tmpj < runtime_locklen; ++tmpj) {
3706 int * lock = (int *)(runtime_locks[tmpj].redirectlock);
3707 releasewritelock(lock);
3710 RUNFREE(currtpd->parameterArray);
3714 } // line2911: if (!containstag(parameter, tagd))
3715 } // line 2808: for(j=0; j<pd->numbertags; j++)
3717 taskpointerarray[i+OFFSET]=parameter;
3718 } // line 2824: for(i=0; i<numparams; i++)
3720 for(; i<numtotal; i++) {
3721 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
3726 /* Actually call task */
3728 ((int *)taskpointerarray)[0]=currtpd->numParameters;
3729 taskpointerarray[1]=NULL;
3732 #ifdef ACCURATEPROFILE
3733 // check finish, set the end of the checkTaskInfo
3736 profileTaskStart(currtpd->task->name);
3740 //clock4 = BAMBOO_GET_EXE_TIME();
3741 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3744 BAMBOO_DEBUGPRINT(0xe997);
3746 ((void (*)(void **))currtpd->task->taskptr)(taskpointerarray);
3749 //clock5 = BAMBOO_GET_EXE_TIME();
3750 // tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3753 #ifdef ACCURATEPROFILE
3754 // task finish, set the end of the checkTaskInfo
3756 // new a PostTaskInfo for the post-task execution
3757 profileTaskStart("post task execution");
3761 BAMBOO_DEBUGPRINT(0xe998);
3762 BAMBOO_DEBUGPRINT_REG(islock);
3767 BAMBOO_DEBUGPRINT(0xe999);
3769 for(i = 0; i < runtime_locklen; ++i) {
3770 void * ptr = (void *)(runtime_locks[i].redirectlock);
3771 int * lock = (int *)(runtime_locks[i].value);
3773 BAMBOO_DEBUGPRINT_REG((int)ptr);
3774 BAMBOO_DEBUGPRINT_REG((int)lock);
3775 BAMBOO_DEBUGPRINT_REG(*((int*)lock+5));
3777 #ifndef MULTICORE_GC
3778 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
3780 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
3781 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
3782 releasewritelock_r(lock, (int *)redirectlock);
3787 releasewritelock(ptr);
3790 } // line 3015: if(islock)
3793 //clock6 = BAMBOO_GET_EXE_TIME();
3794 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3797 // post task execution finish, set the end of the postTaskInfo
3801 // Free up task parameter descriptor
3802 RUNFREE(currtpd->parameterArray);
3806 BAMBOO_DEBUGPRINT(0xe99a);
3809 //clock7 = BAMBOO_GET_EXE_TIME();
3810 //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));
3813 //} // if (hashsize(activetasks)>0)
3814 } // while(hashsize(activetasks)>0)
3816 BAMBOO_DEBUGPRINT(0xe99b);
3820 /* This function processes an objects tags */
3821 void processtags(struct parameterdescriptor *pd,
3823 struct parameterwrapper *parameter,
3824 int * iteratorcount,
3829 for(i=0; i<pd->numbertags; i++) {
3830 int slotid=pd->tagarray[2*i];
3831 int tagid=pd->tagarray[2*i+1];
3833 if (statusarray[slotid+numparams]==0) {
3834 parameter->iterators[*iteratorcount].istag=1;
3835 parameter->iterators[*iteratorcount].tagid=tagid;
3836 parameter->iterators[*iteratorcount].slot=slotid+numparams;
3837 parameter->iterators[*iteratorcount].tagobjectslot=index;
3838 statusarray[slotid+numparams]=1;
3845 void processobject(struct parameterwrapper *parameter,
3847 struct parameterdescriptor *pd,
3853 struct ObjectHash * objectset=
3854 ((struct parameterwrapper *)pd->queue)->objectset;
3856 parameter->iterators[*iteratorcount].istag=0;
3857 parameter->iterators[*iteratorcount].slot=index;
3858 parameter->iterators[*iteratorcount].objectset=objectset;
3859 statusarray[index]=1;
3861 for(i=0; i<pd->numbertags; i++) {
3862 int slotid=pd->tagarray[2*i];
3863 //int tagid=pd->tagarray[2*i+1];
3864 if (statusarray[slotid+numparams]!=0) {
3865 /* This tag has already been enqueued, use it to narrow search */
3866 parameter->iterators[*iteratorcount].tagbindings[tagcount]=
3871 parameter->iterators[*iteratorcount].numtags=tagcount;
3876 /* This function builds the iterators for a task & parameter */
3878 void builditerators(struct taskdescriptor * task,
3880 struct parameterwrapper * parameter) {
3881 int statusarray[MAXTASKPARAMS];
3883 int numparams=task->numParameters;
3884 int iteratorcount=0;
3885 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
3887 statusarray[index]=1; /* Initial parameter */
3888 /* Process tags for initial iterator */
3890 processtags(task->descriptorarray[index], index, parameter,
3891 &iteratorcount, statusarray, numparams);
3895 /* Check for objects with existing tags */
3896 for(i=0; i<numparams; i++) {
3897 if (statusarray[i]==0) {
3898 struct parameterdescriptor *pd=task->descriptorarray[i];
3900 for(j=0; j<pd->numbertags; j++) {
3901 int slotid=pd->tagarray[2*j];
3902 if(statusarray[slotid+numparams]!=0) {
3903 processobject(parameter, i, pd, &iteratorcount, statusarray,
3905 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3912 /* Next do objects w/ unbound tags*/
3914 for(i=0; i<numparams; i++) {
3915 if (statusarray[i]==0) {
3916 struct parameterdescriptor *pd=task->descriptorarray[i];
3917 if (pd->numbertags>0) {
3918 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3919 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3925 /* Nothing with a tag enqueued */
3927 for(i=0; i<numparams; i++) {
3928 if (statusarray[i]==0) {
3929 struct parameterdescriptor *pd=task->descriptorarray[i];
3930 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3931 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3944 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3947 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3948 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3950 printf("%s\n", task->name);
3952 for(j=0; j<task->numParameters; j++) {
3953 struct parameterdescriptor *param=task->descriptorarray[j];
3954 struct parameterwrapper *parameter=param->queue;
3955 struct ObjectHash * set=parameter->objectset;
3956 struct ObjectIterator objit;
3958 printf(" Parameter %d\n", j);
3960 ObjectHashiterator(set, &objit);
3961 while(ObjhasNext(&objit)) {
3962 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
3963 struct ___Object___ * tagptr=obj->___tags___;
3964 int nonfailed=Objdata4(&objit);
3965 int numflags=Objdata3(&objit);
3966 int flags=Objdata2(&objit);
3969 printf(" Contains %lx\n", obj);
3970 printf(" flag=%d\n", obj->flag);
3973 } else if (tagptr->type==TAGTYPE) {
3975 printf(" tag=%lx\n",tagptr);
3981 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
3982 for(; tagindex<ao->___cachedCode___; tagindex++) {
3984 printf(" tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*,
3997 /* This function processes the task information to create queues for
3998 each parameter type. */
4000 void processtasks() {
4002 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
4005 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
4006 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
4009 /* Build objectsets */
4010 for(j=0; j<task->numParameters; j++) {
4011 struct parameterdescriptor *param=task->descriptorarray[j];
4012 struct parameterwrapper *parameter=param->queue;
4013 parameter->objectset=allocateObjectHash(10);
4014 parameter->task=task;
4017 /* Build iterators for parameters */
4018 for(j=0; j<task->numParameters; j++) {
4019 struct parameterdescriptor *param=task->descriptorarray[j];
4020 struct parameterwrapper *parameter=param->queue;
4021 builditerators(task, j, parameter);
4026 void toiReset(struct tagobjectiterator * it) {
4029 } else if (it->numtags>0) {
4032 ObjectHashiterator(it->objectset, &it->it);
4036 int toiHasNext(struct tagobjectiterator *it,
4037 void ** objectarray OPTARG(int * failed)) {
4040 /* Get object with tags */
4041 struct ___Object___ *obj=objectarray[it->tagobjectslot];
4042 struct ___Object___ *tagptr=obj->___tags___;
4043 if (tagptr->type==TAGTYPE) {
4044 if ((it->tagobjindex==0)&& /* First object */
4045 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
4050 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
4051 int tagindex=it->tagobjindex;
4052 for(; tagindex<ao->___cachedCode___; tagindex++) {
4053 struct ___TagDescriptor___ *td=
4054 ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
4055 if (td->flag==it->tagid) {
4056 it->tagobjindex=tagindex; /* Found right type of tag */
4062 } else if (it->numtags>0) {
4063 /* Use tags to locate appropriate objects */
4064 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
4065 struct ___Object___ *objptr=tag->flagptr;
4067 if (objptr->type!=OBJECTARRAYTYPE) {
4068 if (it->tagobjindex>0)
4070 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
4072 for(i=1; i<it->numtags; i++) {
4073 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
4074 if (!containstag(objptr,tag2))
4079 struct ArrayObject *ao=(struct ArrayObject *) objptr;
4082 for(tagindex=it->tagobjindex; tagindex<ao->___cachedCode___; tagindex++) {
4083 struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
4084 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
4086 for(i=1; i<it->numtags; i++) {
4087 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
4088 if (!containstag(objptr,tag2))
4091 it->tagobjindex=tagindex;
4096 it->tagobjindex=tagindex;
4100 return ObjhasNext(&it->it);
4104 int containstag(struct ___Object___ *ptr,
4105 struct ___TagDescriptor___ *tag) {
4107 struct ___Object___ * objptr=tag->flagptr;
4108 if (objptr->type==OBJECTARRAYTYPE) {
4109 struct ArrayObject *ao=(struct ArrayObject *)objptr;
4110 for(j=0; j<ao->___cachedCode___; j++) {
4111 if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
4121 void toiNext(struct tagobjectiterator *it,
4122 void ** objectarray OPTARG(int * failed)) {
4123 /* hasNext has all of the intelligence */
4126 /* Get object with tags */
4127 struct ___Object___ *obj=objectarray[it->tagobjectslot];
4128 struct ___Object___ *tagptr=obj->___tags___;
4129 if (tagptr->type==TAGTYPE) {
4131 objectarray[it->slot]=tagptr;
4133 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
4134 objectarray[it->slot]=
4135 ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
4137 } else if (it->numtags>0) {
4138 /* Use tags to locate appropriate objects */
4139 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
4140 struct ___Object___ *objptr=tag->flagptr;
4141 if (objptr->type!=OBJECTARRAYTYPE) {
4143 objectarray[it->slot]=objptr;
4145 struct ArrayObject *ao=(struct ArrayObject *) objptr;
4146 objectarray[it->slot]=
4147 ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
4150 /* Iterate object */
4151 objectarray[it->slot]=(void *)Objkey(&it->it);
4157 inline void profileTaskStart(char * taskname) {
4158 if(!taskInfoOverflow) {
4159 TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
4160 taskInfoArray[taskInfoIndex] = taskInfo;
4161 taskInfo->taskName = taskname;
4162 taskInfo->startTime = BAMBOO_GET_EXE_TIME();
4163 taskInfo->endTime = -1;
4164 taskInfo->exitIndex = -1;
4165 taskInfo->newObjs = NULL;
4169 inline void profileTaskEnd() {
4170 if(!taskInfoOverflow) {
4171 taskInfoArray[taskInfoIndex]->endTime = BAMBOO_GET_EXE_TIME();
4173 if(taskInfoIndex == TASKINFOLENGTH) {
4174 taskInfoOverflow = true;
4175 //taskInfoIndex = 0;
4180 // output the profiling data
4181 void outputProfileData() {
4184 unsigned long long totaltasktime = 0;
4185 unsigned long long preprocessingtime = 0;
4186 unsigned long long objqueuecheckingtime = 0;
4187 unsigned long long postprocessingtime = 0;
4188 //int interruptiontime = 0;
4189 unsigned long long other = 0;
4190 unsigned long long averagetasktime = 0;
4193 printf("Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
4194 // output task related info
4195 for(i = 0; i < taskInfoIndex; i++) {
4196 TaskInfo* tmpTInfo = taskInfoArray[i];
4197 unsigned long long duration = tmpTInfo->endTime - tmpTInfo->startTime;
4198 printf("%s, %lld, %lld, %lld, %lld",
4199 tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime,
4200 duration, tmpTInfo->exitIndex);
4201 // summarize new obj info
4202 if(tmpTInfo->newObjs != NULL) {
4203 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
4204 struct RuntimeIterator * iter = NULL;
4205 while(0 == isEmpty(tmpTInfo->newObjs)) {
4206 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
4207 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
4209 RuntimeHashget(nobjtbl, (int)objtype, &num);
4210 RuntimeHashremovekey(nobjtbl, (int)objtype);
4212 RuntimeHashadd(nobjtbl, (int)objtype, num);
4214 RuntimeHashadd(nobjtbl, (int)objtype, 1);
4216 //printf(stderr, "new obj!\n");
4219 // output all new obj info
4220 iter = RuntimeHashcreateiterator(nobjtbl);
4221 while(RunhasNext(iter)) {
4222 char * objtype = (char *)Runkey(iter);
4223 int num = Runnext(iter);
4224 printf(", %s, %d", objtype, num);
4228 if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
4229 preprocessingtime += duration;
4230 } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
4231 postprocessingtime += duration;
4232 } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
4233 objqueuecheckingtime += duration;
4235 totaltasktime += duration;
4236 averagetasktime += duration;
4241 if(taskInfoOverflow) {
4242 printf("Caution: task info overflow!\n");
4245 other = totalexetime-totaltasktime-preprocessingtime-postprocessingtime;
4246 averagetasktime /= tasknum;
4248 printf("\nTotal time: %lld\n", totalexetime);
4249 printf("Total task execution time: %lld (%d%%)\n", totaltasktime,
4250 (int)(((double)totaltasktime/(double)totalexetime)*100));
4251 printf("Total objqueue checking time: %lld (%d%%)\n",
4252 objqueuecheckingtime,
4253 (int)(((double)objqueuecheckingtime/(double)totalexetime)*100));
4254 printf("Total pre-processing time: %lld (%d%%)\n", preprocessingtime,
4255 (int)(((double)preprocessingtime/(double)totalexetime)*100));
4256 printf("Total post-processing time: %lld (%d%%)\n", postprocessingtime,
4257 (int)(((double)postprocessingtime/(double)totalexetime)*100));
4258 printf("Other time: %lld (%d%%)\n", other,
4259 (int)(((double)other/(double)totalexetime)*100));
4262 printf("\nAverage task execution time: %lld\n", averagetasktime);
4264 //printf("\nTotal time spent for interruptions: %lld\n", interrupttime);
4269 BAMBOO_DEBUGPRINT(0xdddd);
4270 // output task related info
4271 for(i= 0; i < taskInfoIndex; i++) {
4272 TaskInfo* tmpTInfo = taskInfoArray[i];
4273 char* tmpName = tmpTInfo->taskName;
4274 int nameLen = strlen(tmpName);
4275 BAMBOO_DEBUGPRINT(0xddda);
4276 for(j = 0; j < nameLen; j++) {
4277 BAMBOO_DEBUGPRINT_REG(tmpName[j]);
4279 BAMBOO_DEBUGPRINT(0xdddb);
4280 BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
4281 BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
4282 BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
4283 if(tmpTInfo->newObjs != NULL) {
4284 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
4285 struct RuntimeIterator * iter = NULL;
4286 while(0 == isEmpty(tmpTInfo->newObjs)) {
4287 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
4288 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
4290 RuntimeHashget(nobjtbl, (int)objtype, &num);
4291 RuntimeHashremovekey(nobjtbl, (int)objtype);
4293 RuntimeHashadd(nobjtbl, (int)objtype, num);
4295 RuntimeHashadd(nobjtbl, (int)objtype, 1);
4299 // ouput all new obj info
4300 iter = RuntimeHashcreateiterator(nobjtbl);
4301 while(RunhasNext(iter)) {
4302 char * objtype = (char *)Runkey(iter);
4303 int num = Runnext(iter);
4304 int nameLen = strlen(objtype);
4305 BAMBOO_DEBUGPRINT(0xddda);
4306 for(j = 0; j < nameLen; j++) {
4307 BAMBOO_DEBUGPRINT_REG(objtype[j]);
4309 BAMBOO_DEBUGPRINT(0xdddb);
4310 BAMBOO_DEBUGPRINT_REG(num);
4313 BAMBOO_DEBUGPRINT(0xdddc);
4316 if(taskInfoOverflow) {
4317 BAMBOO_DEBUGPRINT(0xefee);
4320 // output interrupt related info
4321 for(i = 0; i < interruptInfoIndex; i++) {
4322 InterruptInfo* tmpIInfo = interruptInfoArray[i];
4323 BAMBOO_DEBUGPRINT(0xddde);
4324 BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
4325 BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
4326 BAMBOO_DEBUGPRINT(0xdddf);
4329 if(interruptInfoOverflow) {
4330 BAMBOO_DEBUGPRINT(0xefef);
4333 BAMBOO_DEBUGPRINT(0xeeee);
4336 #endif // #ifdef PROFILE