3 #include "multicoreruntime.h"
4 #include "runtime_arch.h"
5 #include "GenericHashtable.h"
8 #define INLINE inline __attribute__((always_inline))
9 #endif // #ifndef INLINE
11 // data structures for task invocation
12 struct genhashtable * activetasks;
13 struct taskparamdescriptor * currtpd;
14 struct LockValue runtime_locks[MAXTASKPARAMS];
17 // specific functions used inside critical sections
18 void enqueueObject_I(void * ptr,
19 struct parameterwrapper ** queues,
21 int enqueuetasks_I(struct parameterwrapper *parameter,
22 struct parameterwrapper *prevptr,
23 struct ___Object___ *ptr,
29 #define NUM_CORES2TEST 5
31 int core2test[1][NUM_CORES2TEST] = {
35 int core2test[56][NUM_CORES2TEST] = {
36 { 0, -1, 7, -1, 1}, { 1, -1, 8, 0, 2}, { 2, -1, 9, 1, 3},
37 { 3, -1, 10, 2, 4}, { 4, -1, 11, 3, 5}, { 5, -1, 12, 4, 6},
38 { 6, -1, 13, 5, -1}, { 7, 0, 14, -1, 8}, { 8, 1, 15, 7, 9},
39 { 9, 2, 16, 8, 10}, {10, 3, 17, 9, 11}, {11, 4, 18, 10, 12},
40 {12, 5, 19, 11, 13}, {13, 6, 20, 12, -1}, {14, 7, 21, -1, 15},
41 {15, 8, 22, 14, 16}, {16, 9, 23, 15, 17}, {17, 10, 24, 16, 18},
42 {18, 11, 25, 17, 19}, {19, 12, 26, 18, 20}, {20, 13, 27, 19, -1},
43 {21, 14, 28, -1, 22}, {22, 15, 29, 21, 23}, {23, 16, 30, 22, 24},
44 {24, 17, 31, 23, 25}, {25, 18, 32, 24, 26}, {26, 19, 33, 25, 27},
45 {27, 20, 34, 26, -1}, {28, 21, 35, -1, 29}, {29, 22, 36, 28, 30},
46 {30, 23, 37, 29, 31}, {31, 24, 38, 30, 32}, {32, 25, 39, 31, 33},
47 {33, 26, 40, 32, 34}, {34, 27, 41, 33, -1}, {35, 28, 42, -1, 36},
48 {36, 29, 43, 35, 37}, {37, 30, 44, 36, 38}, {38, 31, 45, 37, 39},
49 {39, 32, 46, 38, 40}, {40, 33, 47, 39, 41}, {41, 34, 48, 40, -1},
50 {42, 35, 49, -1, 43}, {43, 36, 50, 42, 44}, {44, 37, 51, 43, 45},
51 {45, 38, 52, 44, 46}, {46, 39, 53, 45, 47}, {47, 40, 54, 46, 48},
52 {48, 41, 55, 47, -1}, {49, 42, -1, -1, 50}, {50, 43, -1, 49, 51},
53 {51, 44, -1, 50, 52}, {52, 45, -1, 51, 53}, {53, 46, -1, 52, 54},
54 {54, 47, -1, 53, 55}, {55, 48, -1, 54, -1}
57 int core2test[62][NUM_CORES2TEST] = {
58 { 0, -1, 6, -1, 1}, { 1, -1, 7, 0, 2}, { 2, -1, 8, 1, 3},
59 { 3, -1, 9, 2, 4}, { 4, -1, 10, 3, 5}, { 5, -1, 11, 4, -1},
60 { 6, 0, 14, -1, 7}, { 7, 1, 15, 6, 8}, { 8, 2, 16, 7, 9},
61 { 9, 3, 17, 8, 10}, {10, 4, 18, 9, 11}, {11, 5, 19, 10, 12},
62 {12, -1, 20, 11, 13}, {13, -1, 21, 12, -1}, {14, 6, 22, -1, 15},
63 {15, 7, 23, 14, 16}, {16, 8, 24, 15, 17}, {17, 9, 25, 16, 18},
64 {18, 10, 26, 17, 19}, {19, 11, 27, 18, 20}, {20, 12, 28, 19, 21},
65 {21, 13, 29, 28, -1}, {22, 14, 30, -1, 23}, {23, 15, 31, 22, 24},
66 {24, 16, 32, 23, 25}, {25, 17, 33, 24, 26}, {26, 18, 34, 25, 27},
67 {27, 19, 35, 26, 28}, {28, 20, 36, 27, 29}, {29, 21, 37, 28, -1},
68 {30, 22, 38, -1, 31}, {31, 23, 39, 30, 32}, {32, 24, 40, 31, 33},
69 {33, 25, 41, 32, 34}, {34, 26, 42, 33, 35}, {35, 27, 43, 34, 36},
70 {36, 28, 44, 35, 37}, {37, 29, 45, 36, -1}, {38, 30, 46, -1, 39},
71 {39, 31, 47, 38, 40}, {40, 32, 48, 39, 41}, {41, 33, 49, 40, 42},
72 {42, 34, 50, 41, 43}, {43, 35, 51, 42, 44}, {44, 36, 52, 43, 45},
73 {45, 37, 53, 44, -1}, {46, 38, 54, -1, 47}, {47, 39, 55, 46, 48},
74 {48, 40, 56, 47, 49}, {49, 41, 57, 48, 50}, {50, 42, 58, 49, 51},
75 {51, 43, 59, 50, 52}, {52, 44, 60, 51, 53}, {53, 45, 61, 52, -1},
76 {54, 46, -1, -1, 55}, {55, 47, -1, 54, 56}, {56, 48, -1, 55, 57},
77 {57, 49, -1, 56, 59}, {58, 50, -1, 57, 59}, {59, 51, -1, 58, 60},
78 {60, 52, -1, 59, 61}, {61, 53, -1, 60, -1}
82 unsigned int gcmem_mixed_threshold = 0;
83 unsigned int gcmem_mixed_usedmem = 0;
84 #define NUM_CORES2TEST 9
86 int core2test[1][NUM_CORES2TEST] = {
87 {0, -1, -1, -1, -1, -1, -1, -1, -1}
90 int core2test[56][5] = {
91 { 0, -1, 7, -1, 1, -1, 14, -1, 2}, { 1, -1, 8, 0, 2, -1, 15, -1, 3},
92 { 2, -1, 9, 1, 3, -1, 16, 0, 4}, { 3, -1, 10, 2, 4, -1, 17, 1, 5},
93 { 4, -1, 11, 3, 5, -1, 18, 2, 6}, { 5, -1, 12, 4, 6, -1, 19, 3, -1},
94 { 6, -1, 13, 5, -1, -1, 20, 4, -1}, { 7, 0, 14, -1, 8, -1, 21, -1, 9},
95 { 8, 1, 15, 7, 9, -1, 22, -1, 10}, { 9, 2, 16, 8, 10, -1, 23, 7, 11},
96 {10, 3, 17, 9, 11, -1, 24, 8, 12}, {11, 4, 18, 10, 12, -1, 25, 9, 13},
97 {12, 5, 19, 11, 13, -1, 26, 10, -1}, {13, 6, 20, 12, -1, -1, 27, 11, -1},
98 {14, 7, 21, -1, 15, 0, 28, -1, 16}, {15, 8, 22, 14, 16, 1, 29, -1, 17},
99 {16, 9, 23, 15, 17, 2, 30, 14, 18}, {17, 10, 24, 16, 18, 3, 31, 15, 19},
100 {18, 11, 25, 17, 19, 4, 32, 16, 20}, {19, 12, 26, 18, 20, 5, 33, 17, -1},
101 {20, 13, 27, 19, -1, 6, 34, 18, -1}, {21, 14, 28, -1, 22, 7, 35, -1, 23},
102 {22, 15, 29, 21, 23, 8, 36, -1, 24}, {23, 16, 30, 22, 24, 9, 37, 21, 25},
103 {24, 17, 31, 23, 25, 10, 38, 22, 26}, {25, 18, 32, 24, 26, 11, 39, 23, 27},
104 {26, 19, 33, 25, 27, 12, 40, 24, -1}, {27, 20, 34, 26, -1, 13, 41, 25, -1},
105 {28, 21, 35, -1, 29, 14, 42, -1, 30}, {29, 22, 36, 28, 30, 15, 43, -1, 31},
106 {30, 23, 37, 29, 31, 16, 44, 28, 32}, {31, 24, 38, 30, 32, 17, 45, 29, 33},
107 {32, 25, 39, 31, 33, 18, 46, 30, 34}, {33, 26, 40, 32, 34, 19, 47, 31, -1},
108 {34, 27, 41, 33, -1, 20, 48, 32, -1}, {35, 28, 42, -1, 36, 21, 49, -1, 37},
109 {36, 29, 43, 35, 37, 22, 50, -1, 38}, {37, 30, 44, 36, 38, 23, 51, 35, 39},
110 {38, 31, 45, 37, 39, 24, 52, 36, 40}, {39, 32, 46, 38, 40, 25, 53, 37, 41},
111 {40, 33, 47, 39, 41, 26, 54, 38, -1}, {41, 34, 48, 40, -1, 27, 55, 39, -1},
112 {42, 35, 49, -1, 43, 28, -1, -1, 44}, {43, 36, 50, 42, 44, 29, -1, -1, 45},
113 {44, 37, 51, 43, 45, 30, -1, 42, 46}, {45, 38, 52, 44, 46, 31, -1, 43, 47},
114 {46, 39, 53, 45, 47, 32, -1, 44, 48}, {47, 40, 54, 46, 48, 33, -1, 45, -1},
115 {48, 41, 55, 47, -1, 34, -1, 46, -1}, {49, 42, -1, -1, 50, 35, -1, -1, 51},
116 {50, 43, -1, 49, 51, 36, -1, -1, 52}, {51, 44, -1, 50, 52, 37, -1, 49, 53},
117 {52, 45, -1, 51, 53, 38, -1, 50, 54}, {53, 46, -1, 52, 54, 39, -1, 51, 55},
118 {54, 47, -1, 53, 55, 40, -1, 52, -1}, {55, 48, -1, 54, -1, 41, -1, 53, -1}
121 int core2test[62][5] = {
122 { 0, -1, 6, -1, 1, -1, 14, -1, 2}, { 1, -1, 7, 0, 2, -1, 15, -1, 3},
123 { 2, -1, 8, 1, 3, -1, 16, 0, 4}, { 3, -1, 9, 2, 4, -1, 17, 1, 5},
124 { 4, -1, 10, 3, 5, -1, 18, 2, -1}, { 5, -1, 11, 4, -1, -1, 19, 3, -1},
125 { 6, 0, 14, -1, 7, -1, 22, -1, 8}, { 7, 1, 15, 6, 8, -1, 23, -1, 9},
126 { 8, 2, 16, 7, 9, -1, 24, 6, 10}, { 9, 3, 17, 8, 10, -1, 25, 7, 11},
127 {10, 4, 18, 9, 11, -1, 26, 8, 12}, {11, 5, 19, 10, 12, -1, 27, 9, 13},
128 {12, -1, 20, 11, 13, -1, 28, 10, -1}, {13, -1, 21, 12, -1, -1, 29, 11, -1},
129 {14, 6, 22, -1, 15, 0, 30, -1, 16}, {15, 7, 23, 14, 16, 1, 31, -1, 17},
130 {16, 8, 24, 15, 17, 2, 32, 14, 18}, {17, 9, 25, 16, 18, 3, 33, 15, 19},
131 {18, 10, 26, 17, 19, 4, 34, 16, 20}, {19, 11, 27, 18, 20, 5, 35, 17, 21},
132 {20, 12, 28, 19, 21, -1, 36, 18, -1}, {21, 13, 29, 28, -1, -1, 37, 19, -1},
133 {22, 14, 30, -1, 23, 6, 38, -1, 24}, {23, 15, 31, 22, 24, 7, 39, -1, 25},
134 {24, 16, 32, 23, 25, 8, 40, 22, 26}, {25, 17, 33, 24, 26, 9, 41, 23, 27},
135 {26, 18, 34, 25, 27, 10, 42, 24, 28}, {27, 19, 35, 26, 28, 11, 43, 25, 29},
136 {28, 20, 36, 27, 29, 12, 44, 26, -1}, {29, 21, 37, 28, -1, 13, 45, 27, -1},
137 {30, 22, 38, -1, 31, 22, 46, -1, 32}, {31, 23, 39, 30, 32, 15, 47, -1, 33},
138 {32, 24, 40, 31, 33, 16, 48, 30, 34}, {33, 25, 41, 32, 34, 17, 49, 31, 35},
139 {34, 26, 42, 33, 35, 18, 50, 32, 36}, {35, 27, 43, 34, 36, 19, 51, 33, 37},
140 {36, 28, 44, 35, 37, 20, 52, 34, -1}, {37, 29, 45, 36, -1, 21, 53, 35, -1},
141 {38, 30, 46, -1, 39, 22, 54, -1, 40}, {39, 31, 47, 38, 40, 23, 55, -1, 41},
142 {40, 32, 48, 39, 41, 24, 56, 38, 42}, {41, 33, 49, 40, 42, 25, 57, 39, 43},
143 {42, 34, 50, 41, 43, 26, 58, 40, 44}, {43, 35, 51, 42, 44, 27, 59, 41, 45},
144 {44, 36, 52, 43, 45, 28, 60, 42, -1}, {45, 37, 53, 44, -1, 29, 61, 43, -1},
145 {46, 38, 54, -1, 47, 30, -1, -1, 48}, {47, 39, 55, 46, 48, 31, -1, -1, 49},
146 {48, 40, 56, 47, 49, 32, -1, 46, 50}, {49, 41, 57, 48, 50, 33, -1, 47, 51},
147 {50, 42, 58, 49, 51, 34, -1, 48, 52}, {51, 43, 59, 50, 52, 35, -1, 49, 53},
148 {52, 44, 60, 51, 53, 36, -1, 50, -1}, {53, 45, 61, 52, -1, 37, -1, 51, -1},
149 {54, 46, -1, -1, 55, 38, -1, -1, 56}, {55, 47, -1, 54, 56, 39, -1, -1, 57},
150 {56, 48, -1, 55, 57, 40, -1, 54, 58}, {57, 49, -1, 56, 59, 41, -1, 55, 59},
151 {58, 50, -1, 57, 59, 42, -1, 56, 60}, {59, 51, -1, 58, 60, 43, -1, 57, 61},
152 {60, 52, -1, 59, 61, 44, -1, 58, -1}, {61, 53, -1, 60, -1, 45, -1, 59, -1}
157 inline __attribute__((always_inline))
158 void setupsmemmode(void) {
160 // Only allocate local mem chunks to each core.
161 // If a core has used up its local shared memory, start gc.
162 bamboo_smem_mode = SMEMLOCAL;
164 // Allocate the local shared memory to each core with the highest priority,
165 // if a core has used up its local shared memory, try to allocate the
166 // shared memory that belong to its neighbours, if also failed, start gc.
167 bamboo_smem_mode = SMEMFIXED;
169 // Allocate the local shared memory to each core with the highest priority,
170 // if a core has used up its local shared memory, try to allocate the
171 // shared memory that belong to its neighbours first, if failed, check
172 // current memory allocation rate, if it has already reached the threshold,
173 // start gc, otherwise, allocate the shared memory globally. If all the
174 // shared memory has been used up, start gc.
175 bamboo_smem_mode = SMEMMIXED;
177 // Allocate all the memory chunks globally, do not consider the host cores
178 // When all the shared memory are used up, start gc.
179 bamboo_smem_mode = SMEMGLOBAL;
181 // defaultly using local mode
182 //bamboo_smem_mode = SMEMLOCAL;
183 //bamboo_smem_mode = SMEMGLOBAL;
184 //bamboo_smem_mode = SMEMFIXED;
186 } // void setupsmemmode(void)
189 inline __attribute__((always_inline))
190 void initruntimedata() {
192 // initialize the arrays
193 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
194 // startup core to initialize corestatus[]
195 for(i = 0; i < NUMCORESACTIVE; ++i) {
198 numreceiveobjs[i] = 0;
200 // initialize the profile data arrays
201 profilestatus[i] = 1;
205 gcnumsendobjs[i] = 0;
206 gcnumreceiveobjs[i] = 0;
208 } // for(i = 0; i < NUMCORESACTIVE; ++i)
210 for(i = 0; i < NUMCORES4GC; ++i) {
212 gcrequiredmems[i] = 0;
214 gcfilledblocks[i] = 0;
215 } // for(i = 0; i < NUMCORES4GC; ++i)
218 gc_infoOverflow = false;
229 self_numsendobjs = 0;
230 self_numreceiveobjs = 0;
232 for(i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
237 msglength = BAMBOO_MSG_BUF_LENGTH;
239 for(i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
245 isMsgHanging = false;
246 //isMsgSending = false;
249 bamboo_cur_msp = NULL;
250 bamboo_smem_size = 0;
251 totransobjqueue = createQueue_I();
255 gcprocessing = false;
256 gcphase = FINISHPHASE;
258 gcself_numsendobjs = 0;
259 gcself_numreceiveobjs = 0;
260 gcmarkedptrbound = 0;
261 //mgchashCreate(2000, 0.75);
262 gcpointertbl = allocateRuntimeHash_I(20);
263 //gcpointertbl = allocateMGCHash(20);
264 gcforwardobjtbl = allocateMGCHash_I(20, 3);
267 //gcismapped = false;
276 gcsbstarttbl = BAMBOO_BASE_VA;
277 bamboo_smemtbl = (void *)gcsbstarttbl
278 + (BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE)*sizeof(INTPTR);
279 if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
280 int t_size = ((BAMBOO_RMSP_SIZE)-sizeof(mgcsharedhashtbl_t)*2
281 -128*sizeof(size_t))/sizeof(mgcsharedhashlistnode_t)-2;
283 unsigned int tmp_k = 1 << (sizeof(int)*8 -1);
284 while(((t_size & tmp_k) == 0) && (kk < sizeof(int)*8)) {
285 t_size = t_size << 1;
288 t_size = tmp_k >> kk;
289 gcsharedptbl = mgcsharedhashCreate_I(t_size,0.30);//allocateGCSharedHash_I(20);
293 BAMBOO_MEMSET_WH(gcrpointertbls,0,sizeof(mgcsharedhashtbl_t *)*NUMCORES4GC);
294 //sizeof(struct RuntimeHash *)*NUMCORES4GC);
296 gcmem_mixed_threshold =
297 (unsigned int)((BAMBOO_SHARED_MEM_SIZE-(gcbaseva-BAMBOO_BASE_VA))*0.8);
298 gcmem_mixed_usedmem = 0;
301 // create the lock table, lockresult table and obj queue
304 (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
305 /* Set allocation blocks*/
306 locktable.listhead=NULL;
307 locktable.listtail=NULL;
309 locktable.numelements = 0;
314 lockRedirectTbl = allocateRuntimeHash_I(20);
315 objRedirectLockTbl = allocateRuntimeHash_I(20);
320 objqueue.head = NULL;
321 objqueue.tail = NULL;
327 //isInterrupt = true;
331 taskInfoOverflow = false;
333 interruptInfoIndex = 0;
334 interruptInfoOverflow = false;
337 for(i = 0; i < MAXTASKPARAMS; i++) {
338 runtime_locks[i].redirectlock = 0;
339 runtime_locks[i].value = 0;
344 inline __attribute__((always_inline))
345 void disruntimedata() {
348 freeRuntimeHash(gcpointertbl);
349 //freeMGCHash(gcpointertbl);
350 freeMGCHash(gcforwardobjtbl);
351 // for mapping info structures
352 //freeRuntimeHash(gcrcoretbl);
354 freeRuntimeHash(lockRedirectTbl);
355 freeRuntimeHash(objRedirectLockTbl);
356 RUNFREE(locktable.bucket);
358 if(activetasks != NULL) {
359 genfreehashtable(activetasks);
361 if(currtpd != NULL) {
362 RUNFREE(currtpd->parameterArray);
366 BAMBOO_LOCAL_MEM_CLOSE();
367 BAMBOO_SHARE_MEM_CLOSE();
370 inline __attribute__((always_inline))
371 bool checkObjQueue() {
373 struct transObjInfo * objInfo = NULL;
377 #ifdef ACCURATEPROFILE
378 bool isChecking = false;
379 if(!isEmpty(&objqueue)) {
380 profileTaskStart("objqueue checking");
382 } // if(!isEmpty(&objqueue))
386 while(!isEmpty(&objqueue)) {
388 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
390 BAMBOO_DEBUGPRINT(0xf001);
393 //isInterrupt = false;
396 BAMBOO_DEBUGPRINT(0xeee1);
399 objInfo = (struct transObjInfo *)getItem(&objqueue);
400 obj = objInfo->objptr;
402 BAMBOO_DEBUGPRINT_REG((int)obj);
404 // grab lock and flush the obj
408 BAMBOO_WAITING_FOR_LOCK(0);
409 // check for outgoing sends
410 /*if (isMsgHanging) {
411 extern inline void send_hanging_msg(bool);
412 send_hanging_msg(true);
414 } // while(!lockflag)
417 BAMBOO_DEBUGPRINT_REG(grount);
432 BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
433 BAMBOO_CACHE_FLUSH_RANGE((int)obj,
434 classsize[((struct ___Object___ *)obj)->type]);
436 // enqueue the object
437 for(k = 0; k < objInfo->length; ++k) {
438 int taskindex = objInfo->queues[2 * k];
439 int paramindex = objInfo->queues[2 * k + 1];
440 struct parameterwrapper ** queues =
441 &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
443 BAMBOO_DEBUGPRINT_REG(taskindex);
444 BAMBOO_DEBUGPRINT_REG(paramindex);
445 struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
446 tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n",
447 BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj,
448 (long)obj, tmpptr->flag);
450 enqueueObject_I(obj, queues, 1);
452 BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
454 } // for(k = 0; k < objInfo->length; ++k)
455 releasewritelock_I(obj);
456 RUNFREE(objInfo->queues);
460 // put it at the end of the queue if no update version in the queue
461 struct QueueItem * qitem = getHead(&objqueue);
462 struct QueueItem * prev = NULL;
463 while(qitem != NULL) {
464 struct transObjInfo * tmpinfo =
465 (struct transObjInfo *)(qitem->objectptr);
466 if(tmpinfo->objptr == obj) {
467 // the same object in the queue, which should be enqueued
468 // recently. Current one is outdate, do not re-enqueue it
469 RUNFREE(objInfo->queues);
474 } // if(tmpinfo->objptr == obj)
475 qitem = getNextQueueItem(prev);
476 } // while(qitem != NULL)
477 // try to execute active tasks already enqueued first
478 addNewItem_I(&objqueue, objInfo);
480 //isInterrupt = true;
483 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
485 BAMBOO_DEBUGPRINT(0xf000);
489 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
491 BAMBOO_DEBUGPRINT(0xf000);
493 } // while(!isEmpty(&objqueue))
496 #ifdef ACCURATEPROFILE
504 BAMBOO_DEBUGPRINT(0xee02);
509 inline __attribute__((always_inline))
510 void checkCoreStatus() {
511 bool allStall = false;
515 (waitconfirm && (numconfirm == 0))) {
517 BAMBOO_DEBUGPRINT(0xee04);
518 BAMBOO_DEBUGPRINT_REG(waitconfirm);
520 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
522 BAMBOO_DEBUGPRINT(0xf001);
524 corestatus[BAMBOO_NUM_OF_CORE] = 0;
525 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
526 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
527 // check the status of all cores
530 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
532 for(i = 0; i < NUMCORESACTIVE; ++i) {
534 BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
536 if(corestatus[i] != 0) {
540 } // for(i = 0; i < NUMCORESACTIVE; ++i)
542 // check if the sum of send objs and receive obj are the same
543 // yes->check if the info is the latest; no->go on executing
545 for(i = 0; i < NUMCORESACTIVE; ++i) {
546 sumsendobj += numsendobjs[i];
548 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
550 } // for(i = 0; i < NUMCORESACTIVE; ++i)
551 for(i = 0; i < NUMCORESACTIVE; ++i) {
552 sumsendobj -= numreceiveobjs[i];
554 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
556 } // for(i = 0; i < NUMCORESACTIVE; ++i)
557 if(0 == sumsendobj) {
559 // the first time found all cores stall
560 // send out status confirm msg to all other cores
561 // reset the corestatus array too
563 BAMBOO_DEBUGPRINT(0xee05);
565 corestatus[BAMBOO_NUM_OF_CORE] = 1;
567 numconfirm = NUMCORESACTIVE - 1;
568 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
569 for(i = 1; i < NUMCORESACTIVE; ++i) {
571 // send status confirm msg to core i
572 send_msg_1(i, STATUSCONFIRM, false);
573 } // for(i = 1; i < NUMCORESACTIVE; ++i)
576 // all the core status info are the latest
577 // terminate; for profiling mode, send request to all
578 // other cores to pour out profiling data
580 BAMBOO_DEBUGPRINT(0xee06);
584 totalexetime = BAMBOO_GET_EXE_TIME() - bamboo_start_time;
587 //BAMBOO_DEBUGPRINT_REG(interrupttime);
590 BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME() - bamboo_start_time);
591 //BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
592 BAMBOO_DEBUGPRINT(0xbbbbbbbb);
594 // profile mode, send msgs to other cores to request pouring
595 // out progiling data
597 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
599 BAMBOO_DEBUGPRINT(0xf000);
601 for(i = 1; i < NUMCORESACTIVE; ++i) {
602 // send profile request msg to core i
603 send_msg_2(i, PROFILEOUTPUT, totalexetime, false);
604 } // for(i = 1; i < NUMCORESACTIVE; ++i)
605 // pour profiling data on startup core
608 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
610 BAMBOO_DEBUGPRINT(0xf001);
612 profilestatus[BAMBOO_NUM_OF_CORE] = 0;
613 // check the status of all cores
616 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
618 for(i = 0; i < NUMCORESACTIVE; ++i) {
620 BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
622 if(profilestatus[i] != 0) {
626 } // for(i = 0; i < NUMCORESACTIVE; ++i)
629 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
631 BAMBOO_DEBUGPRINT(0xf000);
636 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
642 // gc_profile mode, ourput gc prfiling data
645 gc_outputProfileData();
646 #endif // #ifdef GC_PROFILE
647 #endif // #ifdef MULTICORE_GC
649 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
650 terminate(); // All done.
651 } // if(!waitconfirm)
653 // still some objects on the fly on the network
654 // reset the waitconfirm and numconfirm
656 BAMBOO_DEBUGPRINT(0xee07);
660 } // if(0 == sumsendobj)
662 // not all cores are stall, keep on waiting
664 BAMBOO_DEBUGPRINT(0xee08);
669 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
671 BAMBOO_DEBUGPRINT(0xf000);
673 } // if((!waitconfirm) ||
676 // main function for each core
677 inline void run(void * arg) {
681 bool sendStall = false;
683 bool tocontinue = false;
685 corenum = BAMBOO_GET_NUM_OF_CORE();
687 BAMBOO_DEBUGPRINT(0xeeee);
688 BAMBOO_DEBUGPRINT_REG(corenum);
689 BAMBOO_DEBUGPRINT(STARTUPCORE);
692 // initialize runtime data structures
695 // other architecture related initialization
699 initializeexithandler();
701 // main process of the execution module
702 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
703 // non-executing cores, only processing communications
706 BAMBOO_DEBUGPRINT(0xee01);
707 BAMBOO_DEBUGPRINT_REG(taskInfoIndex);
708 BAMBOO_DEBUGPRINT_REG(taskInfoOverflow);
709 profileTaskStart("msg handling");
713 //isInterrupt = false;
717 /* Create queue of active tasks */
719 genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
720 (int (*)(void *,void *)) &comparetpd);
722 /* Process task information */
725 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
726 /* Create startup object */
727 createstartupobject(argc, argv);
731 BAMBOO_DEBUGPRINT(0xee00);
736 // check if need to do GC
740 // check if there are new active tasks can be executed
747 while(receiveObject() != -1) {
752 BAMBOO_DEBUGPRINT(0xee01);
755 // check if there are some pending objects,
756 // if yes, enqueue them and executetasks again
757 tocontinue = checkObjQueue();
761 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
764 BAMBOO_DEBUGPRINT(0xee03);
772 BAMBOO_DEBUGPRINT(0xee09);
778 // wait for some time
781 BAMBOO_DEBUGPRINT(0xee0a);
787 // send StallMsg to startup core
789 BAMBOO_DEBUGPRINT(0xee0b);
792 send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
793 self_numsendobjs, self_numreceiveobjs, false);
805 BAMBOO_DEBUGPRINT(0xee0c);
808 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
811 } // if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)
815 struct ___createstartupobject____I_locals {
818 struct ___StartupObject___ * ___startupobject___;
819 struct ArrayObject * ___stringarray___;
820 }; // struct ___createstartupobject____I_locals
822 void createstartupobject(int argc,
826 /* Allocate startup object */
828 struct ___createstartupobject____I_locals ___locals___={2, NULL, NULL, NULL};
829 struct ___StartupObject___ *startupobject=
830 (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
831 ___locals___.___startupobject___ = startupobject;
832 struct ArrayObject * stringarray=
833 allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
834 ___locals___.___stringarray___ = stringarray;
836 struct ___StartupObject___ *startupobject=
837 (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
838 struct ArrayObject * stringarray=
839 allocate_newarray(STRINGARRAYTYPE, argc-1);
841 /* Build array of strings */
842 startupobject->___parameters___=stringarray;
843 for(i=1; i<argc; i++) {
844 int length=strlen(argv[i]);
846 struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
848 struct ___String___ *newstring=NewString(argv[i],length);
850 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
854 startupobject->version = 0;
855 startupobject->lock = NULL;
857 /* Set initialized flag for startup object */
858 flagorandinit(startupobject,1,0xFFFFFFFF);
859 enqueueObject(startupobject, NULL, 0);
861 BAMBOO_CACHE_FLUSH_ALL();
865 int hashCodetpd(struct taskparamdescriptor *ftd) {
866 int hash=(int)ftd->task;
868 for(i=0; i<ftd->numParameters; i++) {
869 hash^=(int)ftd->parameterArray[i];
874 int comparetpd(struct taskparamdescriptor *ftd1,
875 struct taskparamdescriptor *ftd2) {
877 if (ftd1->task!=ftd2->task)
879 for(i=0; i<ftd1->numParameters; i++)
880 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
885 /* This function sets a tag. */
887 void tagset(void *ptr,
888 struct ___Object___ * obj,
889 struct ___TagDescriptor___ * tagd) {
891 void tagset(struct ___Object___ * obj,
892 struct ___TagDescriptor___ * tagd) {
894 struct ArrayObject * ao=NULL;
895 struct ___Object___ * tagptr=obj->___tags___;
897 obj->___tags___=(struct ___Object___ *)tagd;
899 /* Have to check if it is already set */
900 if (tagptr->type==TAGTYPE) {
901 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
906 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
907 struct ArrayObject * ao=
908 allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
909 obj=(struct ___Object___ *)ptrarray[2];
910 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
911 td=(struct ___TagDescriptor___ *) obj->___tags___;
913 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
916 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
917 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
918 obj->___tags___=(struct ___Object___ *) ao;
919 ao->___cachedCode___=2;
923 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
924 for(i=0; i<ao->___cachedCode___; i++) {
925 struct ___TagDescriptor___ * td=
926 ARRAYGET(ao, struct ___TagDescriptor___*, i);
931 if (ao->___cachedCode___<ao->___length___) {
932 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
933 ao->___cachedCode___++;
936 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
937 struct ArrayObject * aonew=
938 allocate_newarray(&ptrarray,TAGARRAYTYPE,
939 TAGARRAYINTERVAL+ao->___length___);
940 obj=(struct ___Object___ *)ptrarray[2];
941 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
942 ao=(struct ArrayObject *)obj->___tags___;
944 struct ArrayObject * aonew=
945 allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
948 aonew->___cachedCode___=ao->___length___+1;
949 for(i=0; i<ao->___length___; i++) {
950 ARRAYSET(aonew, struct ___TagDescriptor___*, i,
951 ARRAYGET(ao, struct ___TagDescriptor___*, i));
953 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
959 struct ___Object___ * tagset=tagd->flagptr;
962 } else if (tagset->type!=OBJECTARRAYTYPE) {
964 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
965 struct ArrayObject * ao=
966 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
967 obj=(struct ___Object___ *)ptrarray[2];
968 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
970 struct ArrayObject * ao=
971 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
973 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
974 ARRAYSET(ao, struct ___Object___ *, 1, obj);
975 ao->___cachedCode___=2;
976 tagd->flagptr=(struct ___Object___ *)ao;
978 struct ArrayObject *ao=(struct ArrayObject *) tagset;
979 if (ao->___cachedCode___<ao->___length___) {
980 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
984 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
985 struct ArrayObject * aonew=
986 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
987 OBJECTARRAYINTERVAL+ao->___length___);
988 obj=(struct ___Object___ *)ptrarray[2];
989 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
990 ao=(struct ArrayObject *)tagd->flagptr;
992 struct ArrayObject * aonew=
993 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
995 aonew->___cachedCode___=ao->___cachedCode___+1;
996 for(i=0; i<ao->___length___; i++) {
997 ARRAYSET(aonew, struct ___Object___*, i,
998 ARRAYGET(ao, struct ___Object___*, i));
1000 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
1001 tagd->flagptr=(struct ___Object___ *) aonew;
1007 /* This function clears a tag. */
1009 void tagclear(void *ptr,
1010 struct ___Object___ * obj,
1011 struct ___TagDescriptor___ * tagd) {
1013 void tagclear(struct ___Object___ * obj,
1014 struct ___TagDescriptor___ * tagd) {
1016 /* We'll assume that tag is alway there.
1017 Need to statically check for this of course. */
1018 struct ___Object___ * tagptr=obj->___tags___;
1020 if (tagptr->type==TAGTYPE) {
1021 if ((struct ___TagDescriptor___ *)tagptr==tagd)
1022 obj->___tags___=NULL;
1024 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
1026 for(i=0; i<ao->___cachedCode___; i++) {
1027 struct ___TagDescriptor___ * td=
1028 ARRAYGET(ao, struct ___TagDescriptor___ *, i);
1030 ao->___cachedCode___--;
1031 if (i<ao->___cachedCode___)
1032 ARRAYSET(ao, struct ___TagDescriptor___ *, i,
1033 ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
1034 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
1035 if (ao->___cachedCode___==0)
1036 obj->___tags___=NULL;
1043 struct ___Object___ *tagset=tagd->flagptr;
1044 if (tagset->type!=OBJECTARRAYTYPE) {
1048 struct ArrayObject *ao=(struct ArrayObject *) tagset;
1050 for(i=0; i<ao->___cachedCode___; i++) {
1051 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
1053 ao->___cachedCode___--;
1054 if (i<ao->___cachedCode___)
1055 ARRAYSET(ao, struct ___Object___ *, i,
1056 ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
1057 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
1058 if (ao->___cachedCode___==0)
1069 /* This function allocates a new tag. */
1071 struct ___TagDescriptor___ * allocate_tag(void *ptr,
1073 struct ___TagDescriptor___ * v=
1074 (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
1075 classsize[TAGTYPE]);
1077 struct ___TagDescriptor___ * allocate_tag(int index) {
1078 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
1087 /* This function updates the flag for object ptr. It or's the flag
1088 with the or mask and and's it with the andmask. */
1090 void flagbody(struct ___Object___ *ptr,
1092 struct parameterwrapper ** queues,
1096 int flagcomp(const int *val1, const int *val2) {
1097 return (*val1)-(*val2);
1100 void flagorand(void * ptr,
1103 struct parameterwrapper ** queues,
1106 int oldflag=((int *)ptr)[1];
1107 int flag=ormask|oldflag;
1109 flagbody(ptr, flag, queues, length, false);
1113 bool intflagorand(void * ptr,
1117 int oldflag=((int *)ptr)[1];
1118 int flag=ormask|oldflag;
1120 if (flag==oldflag) /* Don't do anything */
1123 flagbody(ptr, flag, NULL, 0, false);
1129 void flagorandinit(void * ptr,
1132 int oldflag=((int *)ptr)[1];
1133 int flag=ormask|oldflag;
1135 flagbody(ptr,flag,NULL,0,true);
1138 void flagbody(struct ___Object___ *ptr,
1140 struct parameterwrapper ** vqueues,
1143 struct parameterwrapper * flagptr = NULL;
1145 struct parameterwrapper ** queues = vqueues;
1146 int length = vlength;
1148 int UNUSED, UNUSED2;
1149 int * enterflags = NULL;
1150 if((!isnew) && (queues == NULL)) {
1151 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
1152 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1153 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1160 /*Remove object from all queues */
1161 for(i = 0; i < length; ++i) {
1162 flagptr = queues[i];
1163 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
1164 (int *) &enterflags, &UNUSED, &UNUSED2);
1165 ObjectHashremove(flagptr->objectset, (int)ptr);
1166 if (enterflags!=NULL)
1167 RUNFREE(enterflags);
1171 void enqueueObject(void * vptr,
1172 struct parameterwrapper ** vqueues,
1174 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1177 //struct QueueItem *tmpptr;
1178 struct parameterwrapper * parameter=NULL;
1181 struct parameterwrapper * prevptr=NULL;
1182 struct ___Object___ *tagptr=NULL;
1183 struct parameterwrapper ** queues = vqueues;
1184 int length = vlength;
1185 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1188 if(queues == NULL) {
1189 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1190 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1192 tagptr=ptr->___tags___;
1194 /* Outer loop iterates through all parameter queues an object of
1195 this type could be in. */
1196 for(j = 0; j < length; ++j) {
1197 parameter = queues[j];
1199 if (parameter->numbertags>0) {
1201 goto nextloop; //that means the object has no tag
1202 //but that param needs tag
1203 else if(tagptr->type==TAGTYPE) { //one tag
1204 //struct ___TagDescriptor___ * tag=
1205 //(struct ___TagDescriptor___*) tagptr;
1206 for(i=0; i<parameter->numbertags; i++) {
1207 //slotid is parameter->tagarray[2*i];
1208 int tagid=parameter->tagarray[2*i+1];
1209 if (tagid!=tagptr->flag)
1210 goto nextloop; /*We don't have this tag */
1212 } else { //multiple tags
1213 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1214 for(i=0; i<parameter->numbertags; i++) {
1215 //slotid is parameter->tagarray[2*i];
1216 int tagid=parameter->tagarray[2*i+1];
1218 for(j=0; j<ao->___cachedCode___; j++) {
1219 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1230 for(i=0; i<parameter->numberofterms; i++) {
1231 int andmask=parameter->intarray[i*2];
1232 int checkmask=parameter->intarray[i*2+1];
1233 if ((ptr->flag&andmask)==checkmask) {
1234 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
1245 void enqueueObject_I(void * vptr,
1246 struct parameterwrapper ** vqueues,
1248 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1251 //struct QueueItem *tmpptr;
1252 struct parameterwrapper * parameter=NULL;
1255 struct parameterwrapper * prevptr=NULL;
1256 struct ___Object___ *tagptr=NULL;
1257 struct parameterwrapper ** queues = vqueues;
1258 int length = vlength;
1259 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1262 if(queues == NULL) {
1263 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1264 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1266 tagptr=ptr->___tags___;
1268 /* Outer loop iterates through all parameter queues an object of
1269 this type could be in. */
1270 for(j = 0; j < length; ++j) {
1271 parameter = queues[j];
1273 if (parameter->numbertags>0) {
1275 goto nextloop; //that means the object has no tag
1276 //but that param needs tag
1277 else if(tagptr->type==TAGTYPE) { //one tag
1278 //struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
1279 for(i=0; i<parameter->numbertags; i++) {
1280 //slotid is parameter->tagarray[2*i];
1281 int tagid=parameter->tagarray[2*i+1];
1282 if (tagid!=tagptr->flag)
1283 goto nextloop; /*We don't have this tag */
1285 } else { //multiple tags
1286 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1287 for(i=0; i<parameter->numbertags; i++) {
1288 //slotid is parameter->tagarray[2*i];
1289 int tagid=parameter->tagarray[2*i+1];
1291 for(j=0; j<ao->___cachedCode___; j++) {
1292 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1303 for(i=0; i<parameter->numberofterms; i++) {
1304 int andmask=parameter->intarray[i*2];
1305 int checkmask=parameter->intarray[i*2+1];
1306 if ((ptr->flag&andmask)==checkmask) {
1307 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1319 int * getAliasLock(void ** ptrs,
1321 struct RuntimeHash * tbl) {
1323 return (int*)(RUNMALLOC(sizeof(int)));
1328 bool redirect = false;
1329 int redirectlock = 0;
1330 for(; i < length; i++) {
1331 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1334 if(ptr->lock == NULL) {
1337 lock = (int)(ptr->lock);
1340 if(lock != redirectlock) {
1341 RuntimeHashadd(tbl, lock, redirectlock);
1344 if(RuntimeHashcontainskey(tbl, lock)) {
1345 // already redirected
1347 RuntimeHashget(tbl, lock, &redirectlock);
1348 for(; j < locklen; j++) {
1349 if(locks[j] != redirectlock) {
1350 RuntimeHashadd(tbl, locks[j], redirectlock);
1355 for(j = 0; j < locklen; j++) {
1356 if(locks[j] == lock) {
1359 } else if(locks[j] > lock) {
1366 locks[h] = locks[h-1];
1375 return (int *)redirectlock;
1377 return (int *)(locks[0]);
1382 void addAliasLock(void * ptr,
1384 struct ___Object___ * obj = (struct ___Object___ *)ptr;
1385 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1386 // originally no alias lock associated or have a different alias lock
1387 // flush it as the new one
1388 obj->lock = (int *)lock;
1393 inline void setTaskExitIndex(int index) {
1394 taskInfoArray[taskInfoIndex]->exitIndex = index;
1397 inline void addNewObjInfo(void * nobj) {
1398 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1399 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1401 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1406 // Only allocate local mem chunks to each core.
1407 // If a core has used up its local shared memory, start gc.
1408 void * localmalloc_I(int coren,
1414 int tofindb = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1415 int totest = tofindb;
1416 int bound = BAMBOO_SMEM_SIZE_L;
1420 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1421 int nsize = bamboo_smemtbl[totest];
1422 bool islocal = true;
1424 bool tocheck = true;
1425 // have some space in the block
1426 if(totest == tofindb) {
1427 // the first partition
1428 size = bound - nsize;
1429 } else if(nsize == 0) {
1430 // an empty partition, can be appended
1433 // not an empty partition, can not be appended
1434 // the last continuous block is not big enough, go to check the next
1438 } // if(totest == tofindb) else if(nsize == 0) else ...
1441 // have enough space in the block, malloc
1445 // no enough space yet, try to append next continuous block
1447 } // if(size > isize) else ...
1449 } // if(nsize < bound)
1451 // no space in the block, go to check the next block
1457 tofindb = totest = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1460 } // if(islocal) else ...
1461 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1462 // no more local mem, do not find suitable block
1465 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1468 if(foundsmem == 1) {
1469 // find suitable block
1470 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1471 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1472 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1474 // set bamboo_smemtbl
1475 for(i = tofindb; i <= totest; i++) {
1476 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1478 } else if(foundsmem == 2) {
1479 // no suitable block
1484 } // void * localmalloc_I(int, int, int *)
1487 // Allocate the local shared memory to each core with the highest priority,
1488 // if a core has used up its local shared memory, try to allocate the
1489 // shared memory that belong to its neighbours, if also failed, start gc.
1490 void * fixedmalloc_I(int coren,
1497 int coords_x = bamboo_cpu2coords[coren*2];
1498 int coords_y = bamboo_cpu2coords[coren*2+1];
1500 int tofindb = gc_core2block[2*core2test[coren][k]+i]+(NUMCORES4GC*2)*j;
1501 int totest = tofindb;
1502 int bound = BAMBOO_SMEM_SIZE_L;
1506 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1507 int nsize = bamboo_smemtbl[totest];
1508 bool islocal = true;
1510 bool tocheck = true;
1511 // have some space in the block
1512 if(totest == tofindb) {
1513 // the first partition
1514 size = bound - nsize;
1515 } else if(nsize == 0) {
1516 // an empty partition, can be appended
1519 // not an empty partition, can not be appended
1520 // the last continuous block is not big enough, go to check the next
1524 } // if(totest == tofindb) else if(nsize == 0) else ...
1527 // have enough space in the block, malloc
1531 // no enough space yet, try to append next continuous block
1532 // TODO may consider to go to next local block?
1534 } // if(size > isize) else ...
1536 } // if(nsize < bound)
1538 // no space in the block, go to check the next block
1544 tofindb=totest=gc_core2block[2*core2test[coren][k]+i]+(NUMCORES4GC*2)*j;
1547 } // if(islocal) else ...
1548 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1549 // no more local mem, do not find suitable block on local mem
1550 // try to malloc shared memory assigned to the neighbour cores
1553 if(k >= NUM_CORES2TEST) {
1554 // no more memory available on either coren or its neighbour cores
1556 goto memsearchresult;
1558 } while(core2test[coren][k] == -1);
1561 tofindb=totest=gc_core2block[2*core2test[coren][k]+i]+(NUMCORES4GC*2)*j;
1562 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1566 if(foundsmem == 1) {
1567 // find suitable block
1568 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1569 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1570 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1572 // set bamboo_smemtbl
1573 for(i = tofindb; i <= totest; i++) {
1574 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1576 } else if(foundsmem == 2) {
1577 // no suitable block
1582 } // void * fixedmalloc_I(int, int, int *)
1583 #endif // #ifdef SMEMF
1586 // Allocate the local shared memory to each core with the highest priority,
1587 // if a core has used up its local shared memory, try to allocate the
1588 // shared memory that belong to its neighbours first, if failed, check
1589 // current memory allocation rate, if it has already reached the threshold,
1590 // start gc, otherwise, allocate the shared memory globally. If all the
1591 // shared memory has been used up, start gc.
1592 void * mixedmalloc_I(int coren,
1599 int coords_x = bamboo_cpu2coords[coren*2];
1600 int coords_y = bamboo_cpu2coords[coren*2+1];
1602 int tofindb = gc_core2block[2*core2test[coren][k]+i]+(NUMCORES4GC*2)*j;
1603 int totest = tofindb;
1604 int bound = BAMBOO_SMEM_SIZE_L;
1608 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1609 int nsize = bamboo_smemtbl[totest];
1610 bool islocal = true;
1612 bool tocheck = true;
1613 // have some space in the block
1614 if(totest == tofindb) {
1615 // the first partition
1616 size = bound - nsize;
1617 } else if(nsize == 0) {
1618 // an empty partition, can be appended
1621 // not an empty partition, can not be appended
1622 // the last continuous block is not big enough, go to check the next
1626 } // if(totest == tofindb) else if(nsize == 0) else ...
1629 // have enough space in the block, malloc
1633 // no enough space yet, try to append next continuous block
1634 // TODO may consider to go to next local block?
1636 } // if(size > isize) else ...
1638 } // if(nsize < bound)
1640 // no space in the block, go to check the next block
1646 tofindb=totest=gc_core2block[2*core2test[coren][k]+i]+(NUMCORES4GC*2)*j;
1649 } // if(islocal) else ...
1650 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1651 // no more local mem, do not find suitable block on local mem
1652 // try to malloc shared memory assigned to the neighbour cores
1655 if(k >= NUM_CORES2TEST) {
1656 if(gcmem_mixed_usedmem >= gcmem_mixed_threshold) {
1657 // no more memory available on either coren or its neighbour cores
1659 goto memmixedsearchresult;
1661 // try allocate globally
1662 mem = globalmalloc_I(coren, isize, allocsize);
1666 } while(core2test[coren][k] == -1);
1669 tofindb=totest=gc_core2block[2*core2test[coren][k]+i]+(NUMCORES4GC*2)*j;
1670 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1673 memmixedsearchresult:
1674 if(foundsmem == 1) {
1675 // find suitable block
1676 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1677 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1678 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1680 // set bamboo_smemtbl
1681 for(i = tofindb; i <= totest; i++) {
1682 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1684 gcmem_mixed_usedmem += size;
1685 if(tofindb == bamboo_free_block) {
1686 bamboo_free_block = totest+1;
1688 } else if(foundsmem == 2) {
1689 // no suitable block
1694 } // void * mixedmalloc_I(int, int, int *)
1695 #endif // #ifdef SMEMM
1697 // Allocate all the memory chunks globally, do not consider the host cores
1698 // When all the shared memory are used up, start gc.
1699 void * globalmalloc_I(int coren,
1703 int tofindb = bamboo_free_block; //0;
1704 int totest = tofindb;
1705 int bound = BAMBOO_SMEM_SIZE_L;
1708 if(tofindb > gcnumblock-1-bamboo_reserved_smem) {
1709 // Out of shared memory
1714 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1715 int nsize = bamboo_smemtbl[totest];
1716 bool isnext = false;
1718 bool tocheck = true;
1719 // have some space in the block
1720 if(totest == tofindb) {
1721 // the first partition
1722 size = bound - nsize;
1723 } else if(nsize == 0) {
1724 // an empty partition, can be appended
1727 // not an empty partition, can not be appended
1728 // the last continuous block is not big enough, start another block
1731 } // if(totest == tofindb) else if(nsize == 0) else ...
1734 // have enough space in the block, malloc
1737 } // if(size > isize)
1741 } // if(nsize < bound) else ...
1743 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1744 // no more local mem, do not find suitable block
1747 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1749 // start another block
1754 if(foundsmem == 1) {
1755 // find suitable block
1756 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1757 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1758 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1760 // set bamboo_smemtbl
1761 for(int i = tofindb; i <= totest; i++) {
1762 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1764 if(tofindb == bamboo_free_block) {
1765 bamboo_free_block = totest+1;
1767 } else if(foundsmem == 2) {
1768 // no suitable block
1774 } // void * globalmalloc_I(int, int, int *)
1775 #endif // #ifdef MULTICORE_GC
1777 // malloc from the shared memory
1778 void * smemalloc_I(int coren,
1783 int isize = size+(BAMBOO_CACHE_LINE_SIZE);
1785 // go through the bamboo_smemtbl for suitable partitions
1786 switch(bamboo_smem_mode) {
1788 mem = localmalloc_I(coren, isize, allocsize);
1794 mem = fixedmalloc_I(coren, isize, allocsize);
1796 // not supported yet
1797 BAMBOO_EXIT(0xe001);
1804 mem = mixedmalloc_I(coren, isize, allocsize);
1806 // not supported yet
1807 BAMBOO_EXIT(0xe002);
1813 mem = globalmalloc_I(coren, isize, allocsize);
1825 /*if(!interruptInfoOverflow) {
1826 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
1827 interruptInfoArray[interruptInfoIndex] = intInfo;
1828 intInfo->startTime = BAMBOO_GET_EXE_TIME();
1829 intInfo->endTime = -1;
1832 int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size) : (BAMBOO_SMEM_SIZE);
1833 //mem = mspace_calloc(bamboo_free_msp, 1, toallocate);
1834 if(toallocate > bamboo_free_smem_size) {
1838 mem = (void *)bamboo_free_smemp;
1839 bamboo_free_smemp = ((void*)bamboo_free_smemp) + toallocate;
1840 bamboo_free_smem_size -= toallocate;
1841 //BAMBOO_MEMSET_WH(mem, '\0', toallocate);
1843 *allocsize = toallocate;
1845 /*if(!interruptInfoOverflow) {
1846 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
1847 interruptInfoIndex++;
1848 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
1849 interruptInfoOverflow = true;
1854 #endif // MULTICORE_GC
1855 // no enough shared global memory
1861 BAMBOO_DEBUGPRINT(0xa001);
1862 BAMBOO_EXIT(0xa001);
1866 } // void * smemalloc_I(int, int, int)
1868 INLINE int checkMsgLength_I(int size) {
1871 BAMBOO_DEBUGPRINT(0xcccc);
1874 int type = msgdata[msgdataindex];
1881 case GCSTARTMAPINFO:
1895 case GCSTARTCOMPACT:
1898 case GCFINISHMAPINFO:
1923 case REDIRECTGROUNT:
1925 case REDIRECTRELEASE:
1938 case GCFINISHCOMPACT:
1952 case TRANSOBJ: // nonfixed size
1958 msglength = msgdata[msgdataindex+1];
1967 BAMBOO_DEBUGPRINT_REG(type);
1968 BAMBOO_DEBUGPRINT_REG(size);
1969 BAMBOO_DEBUGPRINT_REG(msgdataindex);
1970 BAMBOO_DEBUGPRINT_REG(msgdatalast);
1971 BAMBOO_DEBUGPRINT_REG(msgdatafull);
1974 BAMBOO_DEBUGPRINT(msgdata[msgdataindex+i]);
1976 BAMBOO_EXIT(0xd005);
1982 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
1987 BAMBOO_DEBUGPRINT(0xffff);
1993 INLINE void processmsg_transobj_I() {
1995 struct transObjInfo * transObj=RUNMALLOC_I(sizeof(struct transObjInfo));
1999 BAMBOO_DEBUGPRINT(0xe880);
2002 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2004 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
2006 BAMBOO_EXIT(0xa002);
2008 // store the object and its corresponding queue info, enqueue it later
2009 transObj->objptr = (void *)msgdata[msgdataindex]; //[2]
2011 transObj->length = (msglength - 3) / 2;
2012 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
2013 for(k = 0; k < transObj->length; ++k) {
2014 transObj->queues[2*k] = msgdata[msgdataindex]; //[3+2*k];
2018 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
2021 transObj->queues[2*k+1] = msgdata[msgdataindex]; //[3+2*k+1];
2025 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
2029 // check if there is an existing duplicate item
2031 struct QueueItem * qitem = getHead(&objqueue);
2032 struct QueueItem * prev = NULL;
2033 while(qitem != NULL) {
2034 struct transObjInfo * tmpinfo =
2035 (struct transObjInfo *)(qitem->objectptr);
2036 if(tmpinfo->objptr == transObj->objptr) {
2037 // the same object, remove outdate one
2038 RUNFREE(tmpinfo->queues);
2040 removeItem(&objqueue, qitem);
2046 qitem = getHead(&objqueue);
2048 qitem = getNextQueueItem(prev);
2051 addNewItem_I(&objqueue, (void *)transObj);
2053 ++(self_numreceiveobjs);
2056 INLINE void processmsg_transtall_I() {
2057 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2058 // non startup core can not receive stall msg
2060 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
2062 BAMBOO_EXIT(0xa003);
2064 int num_core = msgdata[msgdataindex]; //[1]
2066 if(num_core < NUMCORESACTIVE) {
2069 BAMBOO_DEBUGPRINT(0xe881);
2072 corestatus[num_core] = 0;
2073 numsendobjs[num_core] = msgdata[msgdataindex]; //[2];
2075 numreceiveobjs[num_core] = msgdata[msgdataindex]; //[3];
2080 #ifndef MULTICORE_GC
2081 INLINE void processmsg_lockrequest_I() {
2082 // check to see if there is a lock exist for the required obj
2083 // msgdata[1] -> lock type
2084 int locktype = msgdata[msgdataindex]; //[1];
2086 int data2 = msgdata[msgdataindex]; // obj pointer
2088 int data3 = msgdata[msgdataindex]; // lock
2090 int data4 = msgdata[msgdataindex]; // request core
2092 // -1: redirected, 0: approved, 1: denied
2093 int deny=processlockrequest(locktype, data3, data2, data4, data4, true);
2095 // this lock request is redirected
2098 // send response msg
2099 // for 32 bit machine, the size is always 4 words, cache the msg first
2100 int tmp = deny==1 ? LOCKDENY : LOCKGROUNT;
2101 if(BAMBOO_CHECK_SEND_MODE()) {
2102 cache_msg_4(data4, tmp, locktype, data2, data3);
2104 send_msg_4(data4, tmp, locktype, data2, data3, true);
2109 INLINE void processmsg_lockgrount_I() {
2111 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2113 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
2115 BAMBOO_EXIT(0xa004);
2117 int data2 = msgdata[msgdataindex];
2119 int data3 = msgdata[msgdataindex];
2121 if((lockobj == data2) && (lock2require == data3)) {
2124 BAMBOO_DEBUGPRINT(0xe882);
2133 // conflicts on lockresults
2135 BAMBOO_DEBUGPRINT_REG(data2);
2137 BAMBOO_EXIT(0xa005);
2141 INLINE void processmsg_lockdeny_I() {
2143 int data2 = msgdata[msgdataindex];
2145 int data3 = msgdata[msgdataindex];
2147 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2149 BAMBOO_DEBUGPRINT_REG(data2);
2151 BAMBOO_EXIT(0xa006);
2153 if((lockobj == data2) && (lock2require == data3)) {
2156 BAMBOO_DEBUGPRINT(0xe883);
2165 // conflicts on lockresults
2167 BAMBOO_DEBUGPRINT_REG(data2);
2169 BAMBOO_EXIT(0xa007);
2173 INLINE void processmsg_lockrelease_I() {
2174 int data1 = msgdata[msgdataindex];
2176 int data2 = msgdata[msgdataindex];
2178 // receive lock release msg
2179 processlockrelease(data1, data2, 0, false);
2182 INLINE void processmsg_redirectlock_I() {
2183 // check to see if there is a lock exist for the required obj
2184 int data1 = msgdata[msgdataindex];
2185 MSG_INDEXINC_I(); //msgdata[1]; // lock type
2186 int data2 = msgdata[msgdataindex];
2187 MSG_INDEXINC_I(); //msgdata[2]; // obj pointer
2188 int data3 = msgdata[msgdataindex];
2189 MSG_INDEXINC_I(); //msgdata[3]; // redirect lock
2190 int data4 = msgdata[msgdataindex];
2191 MSG_INDEXINC_I(); //msgdata[4]; // root request core
2192 int data5 = msgdata[msgdataindex];
2193 MSG_INDEXINC_I(); //msgdata[5]; // request core
2194 int deny = processlockrequest(data1, data3, data2, data5, data4, true);
2196 // this lock request is redirected
2199 // send response msg
2200 // for 32 bit machine, the size is always 4 words, cache the msg first
2201 if(BAMBOO_CHECK_SEND_MODE()) {
2202 cache_msg_4(data4, deny==1 ? REDIRECTDENY : REDIRECTGROUNT,
2203 data1, data2, data3);
2205 send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
2206 data1, data2, data3, true);
2211 INLINE void processmsg_redirectgrount_I() {
2213 int data2 = msgdata[msgdataindex];
2215 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2217 BAMBOO_DEBUGPRINT_REG(data2);
2219 BAMBOO_EXIT(0xa00a);
2221 if(lockobj == data2) {
2224 BAMBOO_DEBUGPRINT(0xe891);
2227 int data3 = msgdata[msgdataindex];
2231 RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
2236 // conflicts on lockresults
2238 BAMBOO_DEBUGPRINT_REG(data2);
2240 BAMBOO_EXIT(0xa00b);
2244 INLINE void processmsg_redirectdeny_I() {
2246 int data2 = msgdata[msgdataindex];
2248 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2250 BAMBOO_DEBUGPRINT_REG(data2);
2252 BAMBOO_EXIT(0xa00c);
2254 if(lockobj == data2) {
2257 BAMBOO_DEBUGPRINT(0xe892);
2266 // conflicts on lockresults
2268 BAMBOO_DEBUGPRINT_REG(data2);
2270 BAMBOO_EXIT(0xa00d);
2274 INLINE void processmsg_redirectrelease_I() {
2275 int data1 = msgdata[msgdataindex];
2277 int data2 = msgdata[msgdataindex];
2279 int data3 = msgdata[msgdataindex];
2281 processlockrelease(data1, data2, data3, true);
2283 #endif // #ifndef MULTICORE_GC
2286 INLINE void processmsg_profileoutput_I() {
2287 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
2288 // startup core can not receive profile output finish msg
2289 BAMBOO_EXIT(0xa008);
2293 BAMBOO_DEBUGPRINT(0xe885);
2297 totalexetime = msgdata[msgdataindex]; //[1]
2299 outputProfileData();
2300 // cache the msg first
2301 if(BAMBOO_CHECK_SEND_MODE()) {
2302 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
2304 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE, true);
2308 INLINE void processmsg_profilefinish_I() {
2309 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2310 // non startup core can not receive profile output finish msg
2312 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex /*1*/]);
2314 BAMBOO_EXIT(0xa009);
2318 BAMBOO_DEBUGPRINT(0xe886);
2321 int data1 = msgdata[msgdataindex];
2323 profilestatus[data1] = 0;
2325 #endif // #ifdef PROFILE
2327 INLINE void processmsg_statusconfirm_I() {
2328 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2329 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2330 // wrong core to receive such msg
2331 BAMBOO_EXIT(0xa00e);
2333 // send response msg
2336 BAMBOO_DEBUGPRINT(0xe887);
2339 // cache the msg first
2340 if(BAMBOO_CHECK_SEND_MODE()) {
2341 cache_msg_5(STARTUPCORE, STATUSREPORT,
2342 busystatus ? 1 : 0, BAMBOO_NUM_OF_CORE,
2343 self_numsendobjs, self_numreceiveobjs);
2345 send_msg_5(STARTUPCORE, STATUSREPORT, busystatus?1:0,
2346 BAMBOO_NUM_OF_CORE, self_numsendobjs,
2347 self_numreceiveobjs, true);
2352 INLINE void processmsg_statusreport_I() {
2353 int data1 = msgdata[msgdataindex];
2355 int data2 = msgdata[msgdataindex];
2357 int data3 = msgdata[msgdataindex];
2359 int data4 = msgdata[msgdataindex];
2361 // receive a status confirm info
2362 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2363 // wrong core to receive such msg
2365 BAMBOO_DEBUGPRINT_REG(data2);
2367 BAMBOO_EXIT(0xa00f);
2371 BAMBOO_DEBUGPRINT(0xe888);
2377 corestatus[data2] = data1;
2378 numsendobjs[data2] = data3;
2379 numreceiveobjs[data2] = data4;
2383 INLINE void processmsg_terminate_I() {
2386 BAMBOO_DEBUGPRINT(0xe889);
2393 INLINE void processmsg_memrequest_I() {
2395 if(!interruptInfoOverflow) {
2396 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
2397 interruptInfoArray[interruptInfoIndex] = intInfo;
2398 intInfo->startTime = BAMBOO_GET_EXE_TIME();
2399 intInfo->endTime = -1;
2402 int data1 = msgdata[msgdataindex];
2404 int data2 = msgdata[msgdataindex];
2406 // receive a shared memory request msg
2407 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2408 // wrong core to receive such msg
2410 BAMBOO_DEBUGPRINT_REG(data2);
2412 BAMBOO_EXIT(0xa010);
2416 BAMBOO_DEBUGPRINT(0xe88a);
2423 // is currently doing gc, dump this msg
2424 if(INITPHASE == gcphase) {
2425 // if still in the initphase of gc, send a startinit msg again,
2426 // cache the msg first
2427 if(BAMBOO_CHECK_SEND_MODE()) {
2428 cache_msg_1(data2, GCSTARTINIT);
2430 send_msg_1(data2, GCSTARTINIT, true);
2435 mem = smemalloc_I(data2, data1, &allocsize);
2437 // send the start_va to request core, cache the msg first
2438 if(BAMBOO_CHECK_SEND_MODE()) {
2439 cache_msg_3(data2, MEMRESPONSE, mem, allocsize);
2441 send_msg_3(data2, MEMRESPONSE, mem, allocsize, true);
2443 } // if mem == NULL, the gcflag of the startup core has been set
2444 // and the gc should be started later, then a GCSTARTINIT msg
2445 // will be sent to the requesting core to notice it to start gc
2446 // and try malloc again
2452 if(!interruptInfoOverflow) {
2453 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
2454 interruptInfoIndex++;
2455 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
2456 interruptInfoOverflow = true;
2462 INLINE void processmsg_memresponse_I() {
2463 int data1 = msgdata[msgdataindex];
2465 int data2 = msgdata[msgdataindex];
2467 // receive a shared memory response msg
2470 BAMBOO_DEBUGPRINT(0xe88b);
2474 // if is currently doing gc, dump this msg
2478 bamboo_smem_size = 0;
2482 // fill header to store the size of this mem block
2483 BAMBOO_MEMSET_WH(data1, '\0', BAMBOO_CACHE_LINE_SIZE);
2484 //memset(data1, 0, BAMBOO_CACHE_LINE_SIZE);
2485 (*((int*)data1)) = data2;
2486 bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
2487 bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
2489 bamboo_smem_size = data2;
2490 bamboo_cur_msp =(void*)(data1);
2500 INLINE void processmsg_gcstartinit_I() {
2502 gcphase = INITPHASE;
2504 // is waiting for response of mem request
2505 // let it return NULL and start gc
2506 bamboo_smem_size = 0;
2507 bamboo_cur_msp = NULL;
2512 INLINE void processmsg_gcstart_I() {
2515 BAMBOO_DEBUGPRINT(0xe88c);
2519 gcphase = MARKPHASE;
2522 INLINE void processmsg_gcstartcompact_I() {
2523 gcblock2fill = msgdata[msgdataindex];
2524 MSG_INDEXINC_I(); //msgdata[1];
2525 gcphase = COMPACTPHASE;
2528 INLINE void processmsg_gcstartmapinfo_I() {
2532 INLINE void processmsg_gcstartflush_I() {
2533 gcphase = FLUSHPHASE;
2536 INLINE void processmsg_gcfinishinit_I() {
2537 int data1 = msgdata[msgdataindex];
2539 // received a init phase finish msg
2540 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2541 // non startup core can not receive this msg
2543 BAMBOO_DEBUGPRINT_REG(data1);
2545 BAMBOO_EXIT(0xb001);
2548 BAMBOO_DEBUGPRINT(0xe88c);
2549 BAMBOO_DEBUGPRINT_REG(data1);
2551 // All cores should do init GC
2552 if(data1 < NUMCORESACTIVE) {
2553 gccorestatus[data1] = 0;
2557 INLINE void processmsg_gcfinishmark_I() {
2558 int data1 = msgdata[msgdataindex];
2560 int data2 = msgdata[msgdataindex];
2562 int data3 = msgdata[msgdataindex];
2564 // received a mark phase finish msg
2565 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2566 // non startup core can not receive this msg
2568 BAMBOO_DEBUGPRINT_REG(data1);
2570 BAMBOO_EXIT(0xb002);
2572 // all cores should do mark
2573 if(data1 < NUMCORESACTIVE) {
2574 gccorestatus[data1] = 0;
2575 gcnumsendobjs[data1] = data2;
2576 gcnumreceiveobjs[data1] = data3;
2580 INLINE void processmsg_gcfinishcompact_I() {
2581 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2582 // non startup core can not receive this msg
2585 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
2587 BAMBOO_EXIT(0xb003);
2589 int cnum = msgdata[msgdataindex];
2590 MSG_INDEXINC_I(); //msgdata[1];
2591 int filledblocks = msgdata[msgdataindex];
2592 MSG_INDEXINC_I(); //msgdata[2];
2593 int heaptop = msgdata[msgdataindex];
2594 MSG_INDEXINC_I(); //msgdata[3];
2595 int data4 = msgdata[msgdataindex];
2596 MSG_INDEXINC_I(); //msgdata[4];
2597 // only gc cores need to do compact
2598 if(cnum < NUMCORES4GC) {
2599 if(COMPACTPHASE == gcphase) {
2600 gcfilledblocks[cnum] = filledblocks;
2601 gcloads[cnum] = heaptop;
2608 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
2609 // cache the msg first
2610 if(BAMBOO_CHECK_SEND_MODE()) {
2611 cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
2613 send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove, true);
2617 gccorestatus[cnum] = 0;
2619 } // if(cnum < NUMCORES4GC)
2622 INLINE void processmsg_gcfinishmapinfo_I() {
2623 int data1 = msgdata[msgdataindex];
2625 // received a map phase finish msg
2626 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2627 // non startup core can not receive this msg
2630 BAMBOO_DEBUGPRINT_REG(data1);
2632 BAMBOO_EXIT(0xb004);
2634 // all cores should do flush
2635 if(data1 < NUMCORES4GC) {
2636 gccorestatus[data1] = 0;
2641 INLINE void processmsg_gcfinishflush_I() {
2642 int data1 = msgdata[msgdataindex];
2644 // received a flush phase finish msg
2645 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2646 // non startup core can not receive this msg
2649 BAMBOO_DEBUGPRINT_REG(data1);
2651 BAMBOO_EXIT(0xb005);
2653 // all cores should do flush
2654 if(data1 < NUMCORESACTIVE) {
2655 gccorestatus[data1] = 0;
2659 INLINE void processmsg_gcmarkconfirm_I() {
2660 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2661 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2662 // wrong core to receive such msg
2663 BAMBOO_EXIT(0xb006);
2665 // send response msg, cahce the msg first
2666 if(BAMBOO_CHECK_SEND_MODE()) {
2667 cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2668 gcbusystatus, gcself_numsendobjs,
2669 gcself_numreceiveobjs);
2671 send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2672 gcbusystatus, gcself_numsendobjs,
2673 gcself_numreceiveobjs, true);
2678 INLINE void processmsg_gcmarkreport_I() {
2679 int data1 = msgdata[msgdataindex];
2681 int data2 = msgdata[msgdataindex];
2683 int data3 = msgdata[msgdataindex];
2685 int data4 = msgdata[msgdataindex];
2687 // received a marked phase finish confirm response msg
2688 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2689 // wrong core to receive such msg
2691 BAMBOO_DEBUGPRINT_REG(data2);
2693 BAMBOO_EXIT(0xb007);
2698 gccorestatus[data1] = data2;
2699 gcnumsendobjs[data1] = data3;
2700 gcnumreceiveobjs[data1] = data4;
2704 INLINE void processmsg_gcmarkedobj_I() {
2705 int data1 = msgdata[msgdataindex];
2707 // received a markedObj msg
2708 if(((int *)data1)[6] == INIT) {
2709 // this is the first time that this object is discovered,
2710 // set the flag as DISCOVERED
2711 ((int *)data1)[6] = DISCOVERED;
2712 gc_enqueue_I(data1);
2714 // set the remote flag
2715 ((int *)data1)[6] |= REMOTEM;
2716 gcself_numreceiveobjs++;
2717 gcbusystatus = true;
2720 INLINE void processmsg_gcmovestart_I() {
2722 gcdstcore = msgdata[msgdataindex];
2723 MSG_INDEXINC_I(); //msgdata[1];
2724 gcmovestartaddr = msgdata[msgdataindex];
2725 MSG_INDEXINC_I(); //msgdata[2];
2726 gcblock2fill = msgdata[msgdataindex];
2727 MSG_INDEXINC_I(); //msgdata[3];
2730 INLINE void processmsg_gcmaprequest_I() {
2732 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2734 void * dstptr = NULL;
2735 int data1 = msgdata[msgdataindex];
2737 //dstptr = mgchashSearch(msgdata[1]);
2739 // TODO unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2741 RuntimeHashget(gcpointertbl, data1, &dstptr);
2743 // TODO flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2745 int data2 = msgdata[msgdataindex];
2747 //MGCHashget(gcpointertbl, msgdata[1], &dstptr);
2749 // TODO unsigned long long ttimei = BAMBOO_GET_EXE_TIME();
2751 if(NULL == dstptr) {
2752 // no such pointer in this core, something is wrong
2754 BAMBOO_DEBUGPRINT_REG(data1);
2755 BAMBOO_DEBUGPRINT_REG(data2);
2757 BAMBOO_EXIT(0xb009);
2758 //assume that the object was not moved, use the original address
2759 /*if(isMsgSending) {
2760 cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2762 send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2765 // send back the mapping info, cache the msg first
2766 if(BAMBOO_CHECK_SEND_MODE()) {
2767 cache_msg_3(data2, GCMAPINFO, data1, (int)dstptr);
2769 send_msg_3(data2, GCMAPINFO, data1, (int)dstptr, true);
2773 // TODO flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimei;
2774 //num_mapinforequest_i++;
2778 INLINE void processmsg_gcmapinfo_I() {
2780 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2782 int data1 = msgdata[msgdataindex];
2785 if(data1 != gcobj2map) {
2786 // obj not matched, something is wrong
2788 BAMBOO_DEBUGPRINT_REG(gcobj2map);
2789 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
2791 BAMBOO_EXIT(0xb00a);
2794 gcmappedobj = msgdata[msgdataindex]; // [2]
2796 //mgchashReplace_I(msgdata[1], msgdata[2]);
2797 //mgchashInsert_I(gcobj2map, gcmappedobj);
2798 RuntimeHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2799 /*struct nodemappinginfo * nodeinfo =
2800 (struct nodemappinginfo *)RUNMALLOC_I(sizeof(struct nodemappinginfo));
2801 nodeinfo->ptr = (void *)gcmappedobj;
2802 nodeinfo->cores = NULL;
2803 RuntimeHashadd_I(gcpointertbl, data1, (int)nodeinfo);*/
2804 //MGCHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2806 if(data1 == gcobj2map) {
2810 //flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2814 INLINE void processmsg_gcmaptbl_I() {
2815 int data1 = msgdata[msgdataindex];
2817 int data2 = msgdata[msgdataindex];
2819 gcrpointertbls[data2] = (mgcsharedhashtbl_t *)data1; //(struct GCSharedHash *)data1;
2822 INLINE void processmsg_gclobjinfo_I() {
2825 int data1 = msgdata[msgdataindex];
2827 int data2 = msgdata[msgdataindex];
2829 if(BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1) {
2831 BAMBOO_DEBUGPRINT_REG(data2);
2833 BAMBOO_EXIT(0xb00b);
2835 // store the mark result info
2837 gcloads[cnum] = msgdata[msgdataindex];
2838 MSG_INDEXINC_I(); // msgdata[3];
2839 int data4 = msgdata[msgdataindex];
2841 if(gcheaptop < data4) {
2844 // large obj info here
2845 for(int k = 5; k < data1; ) {
2846 int lobj = msgdata[msgdataindex];
2847 MSG_INDEXINC_I(); //msgdata[k++];
2848 int length = msgdata[msgdataindex];
2849 MSG_INDEXINC_I(); //msgdata[k++];
2850 gc_lobjenqueue_I(lobj, length, cnum);
2852 } // for(int k = 5; k < msgdata[1];)
2855 INLINE void processmsg_gclobjmapping_I() {
2856 int data1 = msgdata[msgdataindex];
2858 int data2 = msgdata[msgdataindex];
2860 //mgchashInsert_I(msgdata[1], msgdata[2]);
2861 RuntimeHashadd_I(gcpointertbl, data1, data2);
2862 mgcsharedhashInsert_I(gcsharedptbl, data1, data2);
2863 //GCSharedHashadd_I(gcsharedptbl, data1, data2);
2864 //MGCHashadd_I(gcpointertbl, msgdata[1], msgdata[2]);
2866 #endif // #ifdef MULTICORE_GC
2868 // receive object transferred from other cores
2869 // or the terminate message from other cores
2870 // Should be invoked in critical sections!!
2871 // NOTICE: following format is for threadsimulate version only
2872 // RAW version please see previous description
2873 // format: type + object
2874 // type: -1--stall msg
2876 // return value: 0--received an object
2877 // 1--received nothing
2878 // 2--received a Stall Msg
2879 // 3--received a lock Msg
2880 // RAW version: -1 -- received nothing
2881 // otherwise -- received msg type
2882 int receiveObject(int send_port_pending) {
2884 // get the incoming msgs
2885 if(receiveMsg(send_port_pending) == -1) {
2889 // processing received msgs
2891 MSG_REMAINSIZE_I(&size);
2892 if((size == 0) || (checkMsgLength_I(size) == -1)) {
2894 // have new coming msg
2895 if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
2902 if(msglength <= size) {
2903 // have some whole msg
2904 //if(msgdataindex == msglength) {
2905 // received a whole msg
2907 type = msgdata[msgdataindex]; //[0]
2909 msgdatafull = false;
2911 //tprintf("msg type: %x\n", type);
2914 // receive a object transfer msg
2915 processmsg_transobj_I();
2920 // receive a stall msg
2921 processmsg_transtall_I();
2925 // GC version have no lock msgs
2926 #ifndef MULTICORE_GC
2928 // receive lock request msg, handle it right now
2929 processmsg_lockrequest_I();
2931 } // case LOCKREQUEST
2934 // receive lock grount msg
2935 processmsg_lockgrount_I();
2937 } // case LOCKGROUNT
2940 // receive lock deny msg
2941 processmsg_lockdeny_I();
2946 processmsg_lockrelease_I();
2948 } // case LOCKRELEASE
2949 #endif // #ifndef MULTICORE_GC
2952 case PROFILEOUTPUT: {
2953 // receive an output profile data request msg
2954 processmsg_profileoutput_I();
2956 } // case PROFILEOUTPUT
2958 case PROFILEFINISH: {
2959 // receive a profile output finish msg
2960 processmsg_profilefinish_I();
2962 } // case PROFILEFINISH
2963 #endif // #ifdef PROFILE
2965 // GC version has no lock msgs
2966 #ifndef MULTICORE_GC
2967 case REDIRECTLOCK: {
2968 // receive a redirect lock request msg, handle it right now
2969 processmsg_redirectlock_I();
2971 } // case REDIRECTLOCK
2973 case REDIRECTGROUNT: {
2974 // receive a lock grant msg with redirect info
2975 processmsg_redirectgrount_I();
2977 } // case REDIRECTGROUNT
2979 case REDIRECTDENY: {
2980 // receive a lock deny msg with redirect info
2981 processmsg_redirectdeny_I();
2983 } // case REDIRECTDENY
2985 case REDIRECTRELEASE: {
2986 // receive a lock release msg with redirect info
2987 processmsg_redirectrelease_I();
2989 } // case REDIRECTRELEASE
2990 #endif // #ifndef MULTICORE_GC
2992 case STATUSCONFIRM: {
2993 // receive a status confirm info
2994 processmsg_statusconfirm_I();
2996 } // case STATUSCONFIRM
2998 case STATUSREPORT: {
2999 processmsg_statusreport_I();
3001 } // case STATUSREPORT
3004 // receive a terminate msg
3005 processmsg_terminate_I();
3010 processmsg_memrequest_I();
3012 } // case MEMREQUEST
3015 processmsg_memresponse_I();
3017 } // case MEMRESPONSE
3022 processmsg_gcstartinit_I();
3024 } // case GCSTARTINIT
3027 // receive a start GC msg
3028 processmsg_gcstart_I();
3032 case GCSTARTCOMPACT: {
3033 // a compact phase start msg
3034 processmsg_gcstartcompact_I();
3036 } // case GCSTARTCOMPACT
3038 case GCSTARTMAPINFO: {
3039 // received a flush phase start msg
3040 processmsg_gcstartmapinfo_I();
3042 } // case GCSTARTFLUSH
3044 case GCSTARTFLUSH: {
3045 // received a flush phase start msg
3046 processmsg_gcstartflush_I();
3048 } // case GCSTARTFLUSH
3050 case GCFINISHINIT: {
3051 processmsg_gcfinishinit_I();
3053 } // case GCFINISHINIT
3055 case GCFINISHMARK: {
3056 processmsg_gcfinishmark_I();
3058 } // case GCFINISHMARK
3060 case GCFINISHCOMPACT: {
3061 // received a compact phase finish msg
3062 processmsg_gcfinishcompact_I();
3064 } // case GCFINISHCOMPACT
3066 case GCFINISHMAPINFO: {
3067 processmsg_gcfinishmapinfo_I();
3069 } // case GCFINISHMAPINFO
3071 case GCFINISHFLUSH: {
3072 processmsg_gcfinishflush_I();
3074 } // case GCFINISHFLUSH
3077 // received a GC finish msg
3078 gcphase = FINISHPHASE;
3082 case GCMARKCONFIRM: {
3083 // received a marked phase finish confirm request msg
3084 // all cores should do mark
3085 processmsg_gcmarkconfirm_I();
3087 } // case GCMARKCONFIRM
3089 case GCMARKREPORT: {
3090 processmsg_gcmarkreport_I();
3092 } // case GCMARKREPORT
3095 processmsg_gcmarkedobj_I();
3097 } // case GCMARKEDOBJ
3100 // received a start moving objs msg
3101 processmsg_gcmovestart_I();
3103 } // case GCMOVESTART
3105 case GCMAPREQUEST: {
3106 // received a mapping info request msg
3107 processmsg_gcmaprequest_I();
3109 } // case GCMAPREQUEST
3112 // received a mapping info response msg
3113 processmsg_gcmapinfo_I();
3118 // received a mapping tbl response msg
3119 processmsg_gcmaptbl_I();
3123 case GCLOBJREQUEST: {
3124 // received a large objs info request msg
3125 transferMarkResults_I();
3127 } // case GCLOBJREQUEST
3130 // received a large objs info response msg
3131 processmsg_gclobjinfo_I();
3133 } // case GCLOBJINFO
3135 case GCLOBJMAPPING: {
3136 // received a large obj mapping info msg
3137 processmsg_gclobjmapping_I();
3139 } // case GCLOBJMAPPING
3141 #endif // #ifdef MULTICORE_GC
3146 //memset(msgdata, '\0', sizeof(int) * msgdataindex);
3148 msglength = BAMBOO_MSG_BUF_LENGTH;
3150 //printf("++ msg: %x \n", type);
3152 if(msgdataindex != msgdatalast) {
3153 // still have available msg
3158 BAMBOO_DEBUGPRINT(0xe88d);
3162 // have new coming msg
3163 if(BAMBOO_MSG_AVAIL() != 0) {
3177 BAMBOO_DEBUGPRINT(0xe88e);
3181 /* if(isInterrupt) {
3189 int enqueuetasks(struct parameterwrapper *parameter,
3190 struct parameterwrapper *prevptr,
3191 struct ___Object___ *ptr,
3193 int numenterflags) {
3194 void * taskpointerarray[MAXTASKPARAMS];
3196 //int numparams=parameter->task->numParameters;
3197 int numiterators=parameter->task->numTotal-1;
3200 struct taskdescriptor * task=parameter->task;
3202 //this add the object to parameterwrapper
3203 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
3204 numenterflags, enterflags==NULL);
3206 /* Add enqueued object to parameter vector */
3207 taskpointerarray[parameter->slot]=ptr;
3209 /* Reset iterators */
3210 for(j=0; j<numiterators; j++) {
3211 toiReset(¶meter->iterators[j]);
3214 /* Find initial state */
3215 for(j=0; j<numiterators; j++) {
3217 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3218 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3220 /* Need to backtrack */
3221 toiReset(¶meter->iterators[j]);
3225 /* Nothing to enqueue */
3231 /* Enqueue current state */
3233 struct taskparamdescriptor *tpd=
3234 RUNMALLOC(sizeof(struct taskparamdescriptor));
3236 tpd->numParameters=numiterators+1;
3237 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
3239 for(j=0; j<=numiterators; j++) {
3240 //store the actual parameters
3241 tpd->parameterArray[j]=taskpointerarray[j];
3244 if (( /*!gencontains(failedtasks, tpd)&&*/
3245 !gencontains(activetasks,tpd))) {
3246 genputtable(activetasks, tpd, tpd);
3248 RUNFREE(tpd->parameterArray);
3252 /* This loop iterates to the next parameter combination */
3253 if (numiterators==0)
3256 for(j=numiterators-1; j<numiterators; j++) {
3258 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3259 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3261 /* Need to backtrack */
3262 toiReset(¶meter->iterators[j]);
3266 /* Nothing more to enqueue */
3274 int enqueuetasks_I(struct parameterwrapper *parameter,
3275 struct parameterwrapper *prevptr,
3276 struct ___Object___ *ptr,
3278 int numenterflags) {
3279 void * taskpointerarray[MAXTASKPARAMS];
3281 //int numparams=parameter->task->numParameters;
3282 int numiterators=parameter->task->numTotal-1;
3287 struct taskdescriptor * task=parameter->task;
3289 //this add the object to parameterwrapper
3290 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
3291 numenterflags, enterflags==NULL);
3293 /* Add enqueued object to parameter vector */
3294 taskpointerarray[parameter->slot]=ptr;
3296 /* Reset iterators */
3297 for(j=0; j<numiterators; j++) {
3298 toiReset(¶meter->iterators[j]);
3301 /* Find initial state */
3302 for(j=0; j<numiterators; j++) {
3304 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3305 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3307 /* Need to backtrack */
3308 toiReset(¶meter->iterators[j]);
3312 /* Nothing to enqueue */
3318 /* Enqueue current state */
3320 struct taskparamdescriptor *tpd=
3321 RUNMALLOC_I(sizeof(struct taskparamdescriptor));
3323 tpd->numParameters=numiterators+1;
3324 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
3326 for(j=0; j<=numiterators; j++) {
3327 //store the actual parameters
3328 tpd->parameterArray[j]=taskpointerarray[j];
3331 if (( /*!gencontains(failedtasks, tpd)&&*/
3332 !gencontains(activetasks,tpd))) {
3333 genputtable_I(activetasks, tpd, tpd);
3335 RUNFREE(tpd->parameterArray);
3339 /* This loop iterates to the next parameter combination */
3340 if (numiterators==0)
3343 for(j=numiterators-1; j<numiterators; j++) {
3345 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
3346 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3348 /* Need to backtrack */
3349 toiReset(¶meter->iterators[j]);
3353 /* Nothing more to enqueue */
3367 int containstag(struct ___Object___ *ptr,
3368 struct ___TagDescriptor___ *tag);
3370 #ifndef MULTICORE_GC
3371 void releasewritelock_r(void * lock, void * redirectlock) {
3373 int reallock = (int)lock;
3374 targetcore = (reallock >> 5) % NUMCORES;
3377 BAMBOO_DEBUGPRINT(0xe671);
3378 BAMBOO_DEBUGPRINT_REG((int)lock);
3379 BAMBOO_DEBUGPRINT_REG(reallock);
3380 BAMBOO_DEBUGPRINT_REG(targetcore);
3383 if(targetcore == BAMBOO_NUM_OF_CORE) {
3384 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3386 BAMBOO_DEBUGPRINT(0xf001);
3388 // reside on this core
3389 if(!RuntimeHashcontainskey(locktbl, reallock)) {
3390 // no locks for this object, something is wrong
3391 BAMBOO_EXIT(0xa00b);
3394 struct LockValue * lockvalue = NULL;
3396 BAMBOO_DEBUGPRINT(0xe672);
3398 RuntimeHashget(locktbl, reallock, &rwlock_obj);
3399 lockvalue = (struct LockValue *)rwlock_obj;
3401 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
3404 lockvalue->redirectlock = (int)redirectlock;
3406 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
3409 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3411 BAMBOO_DEBUGPRINT(0xf000);
3415 // send lock release with redirect info msg
3416 // for 32 bit machine, the size is always 4 words
3417 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock,
3418 (int)redirectlock, false);
3423 void executetasks() {
3424 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
3427 struct ___Object___ * tmpparam = NULL;
3428 struct parameterdescriptor * pd=NULL;
3429 struct parameterwrapper *pw=NULL;
3439 while(hashsize(activetasks)>0) {
3444 BAMBOO_DEBUGPRINT(0xe990);
3447 /* See if there are any active tasks */
3448 //if (hashsize(activetasks)>0) {
3451 #ifdef ACCURATEPROFILE
3452 profileTaskStart("tpd checking");
3456 //clock1 = BAMBOO_GET_EXE_TIME();
3459 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
3460 genfreekey(activetasks, currtpd);
3462 numparams=currtpd->task->numParameters;
3463 numtotal=currtpd->task->numTotal;
3465 // clear the lockRedirectTbl
3466 // (TODO, this table should be empty after all locks are released)
3468 /*for(j = 0; j < MAXTASKPARAMS; j++) {
3469 runtime_locks[j].redirectlock = 0;
3470 runtime_locks[j].value = 0;
3472 // get all required locks
3473 runtime_locklen = 0;
3474 // check which locks are needed
3475 for(i = 0; i < numparams; i++) {
3476 void * param = currtpd->parameterArray[i];
3480 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
3482 taskpointerarray[i+OFFSET]=param;
3485 if(((struct ___Object___ *)param)->lock == NULL) {
3486 tmplock = (int)param;
3488 tmplock = (int)(((struct ___Object___ *)param)->lock);
3490 // insert into the locks array
3491 for(j = 0; j < runtime_locklen; j++) {
3492 if(runtime_locks[j].value == tmplock) {
3495 } else if(runtime_locks[j].value > tmplock) {
3500 int h = runtime_locklen;
3502 runtime_locks[h].redirectlock = runtime_locks[h-1].redirectlock;
3503 runtime_locks[h].value = runtime_locks[h-1].value;
3505 runtime_locks[j].value = tmplock;
3506 runtime_locks[j].redirectlock = (int)param;
3509 } // line 2713: for(i = 0; i < numparams; i++)
3510 // grab these required locks
3512 BAMBOO_DEBUGPRINT(0xe991);
3515 //clock2 = BAMBOO_GET_EXE_TIME();
3517 for(i = 0; i < runtime_locklen; i++) {
3518 int * lock = (int *)(runtime_locks[i].redirectlock);
3520 // require locks for this parameter if it is not a startup object
3522 BAMBOO_DEBUGPRINT_REG((int)lock);
3523 BAMBOO_DEBUGPRINT_REG((int)(runtime_locks[i].value));
3526 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3528 BAMBOO_DEBUGPRINT(0xf001);
3531 //isInterrupt = false;
3534 BAMBOO_WAITING_FOR_LOCK(0);
3535 // check for outgoing sends
3536 /*if (isMsgHanging) {
3537 extern inline void send_hanging_msg(bool);
3538 send_hanging_msg(true);
3543 while(BAMBOO_WAITING_FOR_LOCK(0) != -1) {
3544 // check for outgoing sends
3545 /*if (isMsgHanging) {
3546 extern inline void send_hanging_msg(bool);
3547 send_hanging_msg(true);
3552 grount = lockresult;
3562 //isInterrupt = true;
3564 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3566 BAMBOO_DEBUGPRINT(0xf000);
3571 BAMBOO_DEBUGPRINT(0xe992);
3572 BAMBOO_DEBUGPRINT_REG(lock);
3574 // check if has the lock already
3575 // can not get the lock, try later
3576 // release all grabbed locks for previous parameters
3577 for(j = 0; j < i; ++j) {
3578 lock = (int*)(runtime_locks[j].redirectlock);
3579 releasewritelock(lock);
3581 genputtable(activetasks, currtpd, currtpd);
3582 if(hashsize(activetasks) == 1) {
3583 // only one task right now, wait a little while before next try
3589 #ifdef ACCURATEPROFILE
3590 // fail, set the end of the checkTaskInfo
3597 } // line 2752: for(i = 0; i < runtime_locklen; i++)
3600 clock3 = BAMBOO_GET_EXE_TIME();
3601 //tprintf("sort: %d, grab: %d \n", clock2-clock1, clock3-clock2);*/
3604 BAMBOO_DEBUGPRINT(0xe993);
3606 /* Make sure that the parameters are still in the queues */
3607 for(i=0; i<numparams; i++) {
3608 void * parameter=currtpd->parameterArray[i];
3612 BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
3613 classsize[((struct ___Object___ *)parameter)->type]);
3615 tmpparam = (struct ___Object___ *)parameter;
3616 pd=currtpd->task->descriptorarray[i];
3617 pw=(struct parameterwrapper *) pd->queue;
3618 /* Check that object is still in queue */
3620 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
3622 BAMBOO_DEBUGPRINT(0xe994);
3623 BAMBOO_DEBUGPRINT_REG(parameter);
3625 // release grabbed locks
3626 for(j = 0; j < runtime_locklen; ++j) {
3627 int * lock = (int *)(runtime_locks[j].redirectlock);
3628 releasewritelock(lock);
3630 RUNFREE(currtpd->parameterArray);
3636 /* Check if the object's flags still meets requirements */
3640 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
3641 andmask=pw->intarray[tmpi*2];
3642 checkmask=pw->intarray[tmpi*2+1];
3643 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
3649 // flags are never suitable
3650 // remove this obj from the queue
3652 int UNUSED, UNUSED2;
3655 BAMBOO_DEBUGPRINT(0xe995);
3656 BAMBOO_DEBUGPRINT_REG(parameter);
3658 ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
3659 (int *) &enterflags, &UNUSED, &UNUSED2);
3660 ObjectHashremove(pw->objectset, (int)parameter);
3661 if (enterflags!=NULL)
3662 RUNFREE(enterflags);
3663 // release grabbed locks
3664 for(j = 0; j < runtime_locklen; ++j) {
3665 int * lock = (int *)(runtime_locks[j].redirectlock);
3666 releasewritelock(lock);
3668 RUNFREE(currtpd->parameterArray);
3672 #ifdef ACCURATEPROFILE
3673 // fail, set the end of the checkTaskInfo
3678 } // line 2878: if (!ismet)
3682 /* Check that object still has necessary tags */
3683 for(j=0; j<pd->numbertags; j++) {
3684 int slotid=pd->tagarray[2*j]+numparams;
3685 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
3686 if (!containstag(parameter, tagd)) {
3688 BAMBOO_DEBUGPRINT(0xe996);
3691 // release grabbed locks
3693 for(tmpj = 0; tmpj < runtime_locklen; ++tmpj) {
3694 int * lock = (int *)(runtime_locks[tmpj].redirectlock);
3695 releasewritelock(lock);
3698 RUNFREE(currtpd->parameterArray);
3702 } // line2911: if (!containstag(parameter, tagd))
3703 } // line 2808: for(j=0; j<pd->numbertags; j++)
3705 taskpointerarray[i+OFFSET]=parameter;
3706 } // line 2824: for(i=0; i<numparams; i++)
3708 for(; i<numtotal; i++) {
3709 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
3714 /* Actually call task */
3716 ((int *)taskpointerarray)[0]=currtpd->numParameters;
3717 taskpointerarray[1]=NULL;
3720 #ifdef ACCURATEPROFILE
3721 // check finish, set the end of the checkTaskInfo
3724 profileTaskStart(currtpd->task->name);
3728 //clock4 = BAMBOO_GET_EXE_TIME();
3729 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3732 BAMBOO_DEBUGPRINT(0xe997);
3734 ((void (*)(void **))currtpd->task->taskptr)(taskpointerarray);
3737 //clock5 = BAMBOO_GET_EXE_TIME();
3738 // tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3741 #ifdef ACCURATEPROFILE
3742 // task finish, set the end of the checkTaskInfo
3744 // new a PostTaskInfo for the post-task execution
3745 profileTaskStart("post task execution");
3749 BAMBOO_DEBUGPRINT(0xe998);
3750 BAMBOO_DEBUGPRINT_REG(islock);
3755 BAMBOO_DEBUGPRINT(0xe999);
3757 for(i = 0; i < runtime_locklen; ++i) {
3758 void * ptr = (void *)(runtime_locks[i].redirectlock);
3759 int * lock = (int *)(runtime_locks[i].value);
3761 BAMBOO_DEBUGPRINT_REG((int)ptr);
3762 BAMBOO_DEBUGPRINT_REG((int)lock);
3763 BAMBOO_DEBUGPRINT_REG(*((int*)lock+5));
3765 #ifndef MULTICORE_GC
3766 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
3768 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
3769 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
3770 releasewritelock_r(lock, (int *)redirectlock);
3775 releasewritelock(ptr);
3778 } // line 3015: if(islock)
3781 //clock6 = BAMBOO_GET_EXE_TIME();
3782 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3785 // post task execution finish, set the end of the postTaskInfo
3789 // Free up task parameter descriptor
3790 RUNFREE(currtpd->parameterArray);
3794 BAMBOO_DEBUGPRINT(0xe99a);
3797 //clock7 = BAMBOO_GET_EXE_TIME();
3798 //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));
3801 //} // if (hashsize(activetasks)>0)
3802 } // while(hashsize(activetasks)>0)
3804 BAMBOO_DEBUGPRINT(0xe99b);
3808 /* This function processes an objects tags */
3809 void processtags(struct parameterdescriptor *pd,
3811 struct parameterwrapper *parameter,
3812 int * iteratorcount,
3817 for(i=0; i<pd->numbertags; i++) {
3818 int slotid=pd->tagarray[2*i];
3819 int tagid=pd->tagarray[2*i+1];
3821 if (statusarray[slotid+numparams]==0) {
3822 parameter->iterators[*iteratorcount].istag=1;
3823 parameter->iterators[*iteratorcount].tagid=tagid;
3824 parameter->iterators[*iteratorcount].slot=slotid+numparams;
3825 parameter->iterators[*iteratorcount].tagobjectslot=index;
3826 statusarray[slotid+numparams]=1;
3833 void processobject(struct parameterwrapper *parameter,
3835 struct parameterdescriptor *pd,
3841 struct ObjectHash * objectset=
3842 ((struct parameterwrapper *)pd->queue)->objectset;
3844 parameter->iterators[*iteratorcount].istag=0;
3845 parameter->iterators[*iteratorcount].slot=index;
3846 parameter->iterators[*iteratorcount].objectset=objectset;
3847 statusarray[index]=1;
3849 for(i=0; i<pd->numbertags; i++) {
3850 int slotid=pd->tagarray[2*i];
3851 //int tagid=pd->tagarray[2*i+1];
3852 if (statusarray[slotid+numparams]!=0) {
3853 /* This tag has already been enqueued, use it to narrow search */
3854 parameter->iterators[*iteratorcount].tagbindings[tagcount]=
3859 parameter->iterators[*iteratorcount].numtags=tagcount;
3864 /* This function builds the iterators for a task & parameter */
3866 void builditerators(struct taskdescriptor * task,
3868 struct parameterwrapper * parameter) {
3869 int statusarray[MAXTASKPARAMS];
3871 int numparams=task->numParameters;
3872 int iteratorcount=0;
3873 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
3875 statusarray[index]=1; /* Initial parameter */
3876 /* Process tags for initial iterator */
3878 processtags(task->descriptorarray[index], index, parameter,
3879 &iteratorcount, statusarray, numparams);
3883 /* Check for objects with existing tags */
3884 for(i=0; i<numparams; i++) {
3885 if (statusarray[i]==0) {
3886 struct parameterdescriptor *pd=task->descriptorarray[i];
3888 for(j=0; j<pd->numbertags; j++) {
3889 int slotid=pd->tagarray[2*j];
3890 if(statusarray[slotid+numparams]!=0) {
3891 processobject(parameter, i, pd, &iteratorcount, statusarray,
3893 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3900 /* Next do objects w/ unbound tags*/
3902 for(i=0; i<numparams; i++) {
3903 if (statusarray[i]==0) {
3904 struct parameterdescriptor *pd=task->descriptorarray[i];
3905 if (pd->numbertags>0) {
3906 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3907 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3913 /* Nothing with a tag enqueued */
3915 for(i=0; i<numparams; i++) {
3916 if (statusarray[i]==0) {
3917 struct parameterdescriptor *pd=task->descriptorarray[i];
3918 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3919 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3932 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3935 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3936 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3938 printf("%s\n", task->name);
3940 for(j=0; j<task->numParameters; j++) {
3941 struct parameterdescriptor *param=task->descriptorarray[j];
3942 struct parameterwrapper *parameter=param->queue;
3943 struct ObjectHash * set=parameter->objectset;
3944 struct ObjectIterator objit;
3946 printf(" Parameter %d\n", j);
3948 ObjectHashiterator(set, &objit);
3949 while(ObjhasNext(&objit)) {
3950 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
3951 struct ___Object___ * tagptr=obj->___tags___;
3952 int nonfailed=Objdata4(&objit);
3953 int numflags=Objdata3(&objit);
3954 int flags=Objdata2(&objit);
3957 printf(" Contains %lx\n", obj);
3958 printf(" flag=%d\n", obj->flag);
3961 } else if (tagptr->type==TAGTYPE) {
3963 printf(" tag=%lx\n",tagptr);
3969 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
3970 for(; tagindex<ao->___cachedCode___; tagindex++) {
3972 printf(" tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*,
3985 /* This function processes the task information to create queues for
3986 each parameter type. */
3988 void processtasks() {
3990 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3993 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3994 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3997 /* Build objectsets */
3998 for(j=0; j<task->numParameters; j++) {
3999 struct parameterdescriptor *param=task->descriptorarray[j];
4000 struct parameterwrapper *parameter=param->queue;
4001 parameter->objectset=allocateObjectHash(10);
4002 parameter->task=task;
4005 /* Build iterators for parameters */
4006 for(j=0; j<task->numParameters; j++) {
4007 struct parameterdescriptor *param=task->descriptorarray[j];
4008 struct parameterwrapper *parameter=param->queue;
4009 builditerators(task, j, parameter);
4014 void toiReset(struct tagobjectiterator * it) {
4017 } else if (it->numtags>0) {
4020 ObjectHashiterator(it->objectset, &it->it);
4024 int toiHasNext(struct tagobjectiterator *it,
4025 void ** objectarray OPTARG(int * failed)) {
4028 /* Get object with tags */
4029 struct ___Object___ *obj=objectarray[it->tagobjectslot];
4030 struct ___Object___ *tagptr=obj->___tags___;
4031 if (tagptr->type==TAGTYPE) {
4032 if ((it->tagobjindex==0)&& /* First object */
4033 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
4038 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
4039 int tagindex=it->tagobjindex;
4040 for(; tagindex<ao->___cachedCode___; tagindex++) {
4041 struct ___TagDescriptor___ *td=
4042 ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
4043 if (td->flag==it->tagid) {
4044 it->tagobjindex=tagindex; /* Found right type of tag */
4050 } else if (it->numtags>0) {
4051 /* Use tags to locate appropriate objects */
4052 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
4053 struct ___Object___ *objptr=tag->flagptr;
4055 if (objptr->type!=OBJECTARRAYTYPE) {
4056 if (it->tagobjindex>0)
4058 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
4060 for(i=1; i<it->numtags; i++) {
4061 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
4062 if (!containstag(objptr,tag2))
4067 struct ArrayObject *ao=(struct ArrayObject *) objptr;
4070 for(tagindex=it->tagobjindex; tagindex<ao->___cachedCode___; tagindex++) {
4071 struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
4072 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
4074 for(i=1; i<it->numtags; i++) {
4075 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
4076 if (!containstag(objptr,tag2))
4079 it->tagobjindex=tagindex;
4084 it->tagobjindex=tagindex;
4088 return ObjhasNext(&it->it);
4092 int containstag(struct ___Object___ *ptr,
4093 struct ___TagDescriptor___ *tag) {
4095 struct ___Object___ * objptr=tag->flagptr;
4096 if (objptr->type==OBJECTARRAYTYPE) {
4097 struct ArrayObject *ao=(struct ArrayObject *)objptr;
4098 for(j=0; j<ao->___cachedCode___; j++) {
4099 if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
4109 void toiNext(struct tagobjectiterator *it,
4110 void ** objectarray OPTARG(int * failed)) {
4111 /* hasNext has all of the intelligence */
4114 /* Get object with tags */
4115 struct ___Object___ *obj=objectarray[it->tagobjectslot];
4116 struct ___Object___ *tagptr=obj->___tags___;
4117 if (tagptr->type==TAGTYPE) {
4119 objectarray[it->slot]=tagptr;
4121 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
4122 objectarray[it->slot]=
4123 ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
4125 } else if (it->numtags>0) {
4126 /* Use tags to locate appropriate objects */
4127 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
4128 struct ___Object___ *objptr=tag->flagptr;
4129 if (objptr->type!=OBJECTARRAYTYPE) {
4131 objectarray[it->slot]=objptr;
4133 struct ArrayObject *ao=(struct ArrayObject *) objptr;
4134 objectarray[it->slot]=
4135 ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
4138 /* Iterate object */
4139 objectarray[it->slot]=(void *)Objkey(&it->it);
4145 inline void profileTaskStart(char * taskname) {
4146 if(!taskInfoOverflow) {
4147 TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
4148 taskInfoArray[taskInfoIndex] = taskInfo;
4149 taskInfo->taskName = taskname;
4150 taskInfo->startTime = BAMBOO_GET_EXE_TIME();
4151 taskInfo->endTime = -1;
4152 taskInfo->exitIndex = -1;
4153 taskInfo->newObjs = NULL;
4157 inline void profileTaskEnd() {
4158 if(!taskInfoOverflow) {
4159 taskInfoArray[taskInfoIndex]->endTime = BAMBOO_GET_EXE_TIME();
4161 if(taskInfoIndex == TASKINFOLENGTH) {
4162 taskInfoOverflow = true;
4163 //taskInfoIndex = 0;
4168 // output the profiling data
4169 void outputProfileData() {
4172 unsigned long long totaltasktime = 0;
4173 unsigned long long preprocessingtime = 0;
4174 unsigned long long objqueuecheckingtime = 0;
4175 unsigned long long postprocessingtime = 0;
4176 //int interruptiontime = 0;
4177 unsigned long long other = 0;
4178 unsigned long long averagetasktime = 0;
4181 printf("Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
4182 // output task related info
4183 for(i = 0; i < taskInfoIndex; i++) {
4184 TaskInfo* tmpTInfo = taskInfoArray[i];
4185 unsigned long long duration = tmpTInfo->endTime - tmpTInfo->startTime;
4186 printf("%s, %lld, %lld, %lld, %lld",
4187 tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime,
4188 duration, tmpTInfo->exitIndex);
4189 // summarize new obj info
4190 if(tmpTInfo->newObjs != NULL) {
4191 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
4192 struct RuntimeIterator * iter = NULL;
4193 while(0 == isEmpty(tmpTInfo->newObjs)) {
4194 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
4195 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
4197 RuntimeHashget(nobjtbl, (int)objtype, &num);
4198 RuntimeHashremovekey(nobjtbl, (int)objtype);
4200 RuntimeHashadd(nobjtbl, (int)objtype, num);
4202 RuntimeHashadd(nobjtbl, (int)objtype, 1);
4204 //printf(stderr, "new obj!\n");
4207 // output all new obj info
4208 iter = RuntimeHashcreateiterator(nobjtbl);
4209 while(RunhasNext(iter)) {
4210 char * objtype = (char *)Runkey(iter);
4211 int num = Runnext(iter);
4212 printf(", %s, %d", objtype, num);
4216 if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
4217 preprocessingtime += duration;
4218 } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
4219 postprocessingtime += duration;
4220 } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
4221 objqueuecheckingtime += duration;
4223 totaltasktime += duration;
4224 averagetasktime += duration;
4229 if(taskInfoOverflow) {
4230 printf("Caution: task info overflow!\n");
4233 other = totalexetime-totaltasktime-preprocessingtime-postprocessingtime;
4234 averagetasktime /= tasknum;
4236 printf("\nTotal time: %lld\n", totalexetime);
4237 printf("Total task execution time: %lld (%d%%)\n", totaltasktime,
4238 (int)(((double)totaltasktime/(double)totalexetime)*100));
4239 printf("Total objqueue checking time: %lld (%d%%)\n",
4240 objqueuecheckingtime,
4241 (int)(((double)objqueuecheckingtime/(double)totalexetime)*100));
4242 printf("Total pre-processing time: %lld (%d%%)\n", preprocessingtime,
4243 (int)(((double)preprocessingtime/(double)totalexetime)*100));
4244 printf("Total post-processing time: %lld (%d%%)\n", postprocessingtime,
4245 (int)(((double)postprocessingtime/(double)totalexetime)*100));
4246 printf("Other time: %lld (%d%%)\n", other,
4247 (int)(((double)other/(double)totalexetime)*100));
4250 printf("\nAverage task execution time: %lld\n", averagetasktime);
4252 //printf("\nTotal time spent for interruptions: %lld\n", interrupttime);
4257 BAMBOO_DEBUGPRINT(0xdddd);
4258 // output task related info
4259 for(i= 0; i < taskInfoIndex; i++) {
4260 TaskInfo* tmpTInfo = taskInfoArray[i];
4261 char* tmpName = tmpTInfo->taskName;
4262 int nameLen = strlen(tmpName);
4263 BAMBOO_DEBUGPRINT(0xddda);
4264 for(j = 0; j < nameLen; j++) {
4265 BAMBOO_DEBUGPRINT_REG(tmpName[j]);
4267 BAMBOO_DEBUGPRINT(0xdddb);
4268 BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
4269 BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
4270 BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
4271 if(tmpTInfo->newObjs != NULL) {
4272 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
4273 struct RuntimeIterator * iter = NULL;
4274 while(0 == isEmpty(tmpTInfo->newObjs)) {
4275 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
4276 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
4278 RuntimeHashget(nobjtbl, (int)objtype, &num);
4279 RuntimeHashremovekey(nobjtbl, (int)objtype);
4281 RuntimeHashadd(nobjtbl, (int)objtype, num);
4283 RuntimeHashadd(nobjtbl, (int)objtype, 1);
4287 // ouput all new obj info
4288 iter = RuntimeHashcreateiterator(nobjtbl);
4289 while(RunhasNext(iter)) {
4290 char * objtype = (char *)Runkey(iter);
4291 int num = Runnext(iter);
4292 int nameLen = strlen(objtype);
4293 BAMBOO_DEBUGPRINT(0xddda);
4294 for(j = 0; j < nameLen; j++) {
4295 BAMBOO_DEBUGPRINT_REG(objtype[j]);
4297 BAMBOO_DEBUGPRINT(0xdddb);
4298 BAMBOO_DEBUGPRINT_REG(num);
4301 BAMBOO_DEBUGPRINT(0xdddc);
4304 if(taskInfoOverflow) {
4305 BAMBOO_DEBUGPRINT(0xefee);
4308 // output interrupt related info
4309 for(i = 0; i < interruptInfoIndex; i++) {
4310 InterruptInfo* tmpIInfo = interruptInfoArray[i];
4311 BAMBOO_DEBUGPRINT(0xddde);
4312 BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
4313 BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
4314 BAMBOO_DEBUGPRINT(0xdddf);
4317 if(interruptInfoOverflow) {
4318 BAMBOO_DEBUGPRINT(0xefef);
4321 BAMBOO_DEBUGPRINT(0xeeee);
4324 #endif // #ifdef PROFILE