3 #include "multicoreruntime.h"
4 #include "runtime_arch.h"
6 __attribute__((always_inline)) inline void initialization() {
9 __attribute__((always_inline)) inline void initCommunication() {
11 if (corenum < NUMCORES) {
14 raw_user_interrupts_on();
19 __attribute__((always_inline)) inline void fakeExecution() {
20 // handle communications
30 #endif // #ifdef USEIO
34 __attribute__((always_inline)) inline void terminate() {
38 // helper function to compute the coordinates of a core from the core number
39 #define calCoords(core_num, coordX, coordY) \
40 *(coordX) = (core_num) % raw_get_array_size_x();\
41 *(coordY) = core_num / raw_get_array_size_x();
43 // transfer an object to targetcore
45 inline void transferObject(struct transObjInfo * transObj) {// __attribute__((always_inline)){
46 void * obj = transObj->objptr;
47 int type=((int *)obj)[0];
48 int targetcore = transObj->targetcore;
51 int self_y, self_x, target_y, target_x;
52 // for 32 bit machine, the size of fixed part is always 3 words
53 int msgsize = 3 + transObj->length * 2;
56 struct ___Object___ * newobj = (struct ___Object___ *)obj;
58 calCoords(corenum, &self_x, &self_y);
59 calCoords(targetcore, &target_x, &target_y);
61 // Build the message header
62 msgHdr = construct_dyn_hdr(0, msgsize, 0, // msgsize word sent.
65 // start sending msg, set sand msg flag
68 BAMBOO_DEBUGPRINT(0xbbbb);
69 BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
77 BAMBOO_DEBUGPRINT_REG(msgsize);
81 BAMBOO_DEBUGPRINT_REG(obj);
83 for(i = 0; i < transObj->length; ++i) {
84 int taskindex = transObj->queues[2*i];
85 int paramindex = transObj->queues[2*i+1];
88 BAMBOO_DEBUGPRINT_REG(taskindex);
92 BAMBOO_DEBUGPRINT_REG(paramindex);
96 BAMBOO_DEBUGPRINT(0xffff);
98 // end of sending this msg, set sand msg flag false
100 ++(self_numsendobjs);
101 // check if there are pending msgs
102 while(isMsgHanging) {
103 // get the msg from outmsgdata[]
104 // length + target + msg
105 outmsgleft = outmsgdata[outmsgindex++];
106 int target = outmsgdata[outmsgindex++];
107 calCoords(target, &target_x, &target_y);
108 // mark to start sending the msg
110 // Build the message header
111 msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
116 BAMBOO_DEBUGPRINT(0xbbbb);
117 BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
119 while(outmsgleft-- > 0) {
120 gdn_send(outmsgdata[outmsgindex++]);
122 BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
126 BAMBOO_DEBUGPRINT(0xffff);
128 // mark to end sending the msg
129 isMsgSending = false;
130 BAMBOO_START_CRITICAL_SECTION_MSG();
131 // check if there are still msg hanging
132 if(outmsgindex == outmsglast) {
134 outmsgindex = outmsglast = 0;
135 isMsgHanging = false;
137 BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
141 __attribute__((always_inline)) inline void send_msg_1 (int targetcore,
145 int self_y, self_x, target_y, target_x;
148 // get the x-coord and y-coord of the target core
149 calCoords(corenum, &self_x, &self_y);
150 calCoords(targetcore, &target_x, &target_y);
152 // mark to start sending the msg
154 // Build the message header
155 msgHdr = construct_dyn_hdr(0, msglength, 0, // msgsize word sent.
158 gdn_send(msgHdr); // Send the message header
160 BAMBOO_DEBUGPRINT(0xbbbb);
161 BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
165 BAMBOO_DEBUGPRINT(n0);
166 BAMBOO_DEBUGPRINT(0xffff);
168 // mark to end sending the msg
169 isMsgSending = false;
170 // check if there are pending msgs
171 while(isMsgHanging) {
172 // get the msg from outmsgdata[]
173 // length + target + msg
174 outmsgleft = outmsgdata[outmsgindex++];
175 int target = outmsgdata[outmsgindex++];
176 calCoords(target, &target_x, &target_y);
177 // mark to start sending the msg
179 // Build the message header
180 msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
185 BAMBOO_DEBUGPRINT(0xbbbb);
186 BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
188 while(outmsgleft-- > 0) {
189 gdn_send(outmsgdata[outmsgindex++]);
191 BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
195 BAMBOO_DEBUGPRINT(0xffff);
197 // mark to end sending the msg
198 isMsgSending = false;
199 BAMBOO_START_CRITICAL_SECTION_MSG();
200 // check if there are still msg hanging
201 if(outmsgindex == outmsglast) {
203 outmsgindex = outmsglast = 0;
204 isMsgHanging = false;
206 BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
210 __attribute__((always_inline)) inline void send_msg_2 (int targetcore,
215 int self_y, self_x, target_y, target_x;
218 // get the x-coord and y-coord of the target core
219 calCoords(corenum, &self_x, &self_y);
220 calCoords(targetcore, &target_x, &target_y);
222 // mark to start sending the msg
224 // Build the message header
225 msgHdr = construct_dyn_hdr(0, msglength, 0, // msgsize word sent.
228 gdn_send(msgHdr); // Send the message header
230 BAMBOO_DEBUGPRINT(0xbbbb);
231 BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
235 BAMBOO_DEBUGPRINT(n0);
239 BAMBOO_DEBUGPRINT(n1);
240 BAMBOO_DEBUGPRINT(0xffff);
242 // mark to end sending the msg
243 isMsgSending = false;
244 // check if there are pending msgs
245 while(isMsgHanging) {
246 // get the msg from outmsgdata[]
247 // length + target + msg
248 outmsgleft = outmsgdata[outmsgindex++];
249 int target = outmsgdata[outmsgindex++];
250 calCoords(target, &target_x, &target_y);
251 // mark to start sending the msg
253 // Build the message header
254 msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
259 BAMBOO_DEBUGPRINT(0xbbbb);
260 BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
262 while(outmsgleft-- > 0) {
263 gdn_send(outmsgdata[outmsgindex++]);
265 BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
269 BAMBOO_DEBUGPRINT(0xffff);
271 // mark to end sending the msg
272 isMsgSending = false;
273 BAMBOO_START_CRITICAL_SECTION_MSG();
274 // check if there are still msg hanging
275 if(outmsgindex == outmsglast) {
277 outmsgindex = outmsglast = 0;
278 isMsgHanging = false;
280 BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
284 __attribute__((always_inline)) inline void send_msg_3 (int targetcore,
290 int self_y, self_x, target_y, target_x;
293 // get the x-coord and y-coord of the target core
294 calCoords(corenum, &self_x, &self_y);
295 calCoords(targetcore, &target_x, &target_y);
297 // mark to start sending the msg
299 // Build the message header
300 msgHdr = construct_dyn_hdr(0, msglength, 0, // msgsize word sent.
303 gdn_send(msgHdr); // Send the message header
305 BAMBOO_DEBUGPRINT(0xbbbb);
306 BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
310 BAMBOO_DEBUGPRINT(n0);
314 BAMBOO_DEBUGPRINT(n1);
318 BAMBOO_DEBUGPRINT(n2);
319 BAMBOO_DEBUGPRINT(0xffff);
321 // mark to end sending the msg
322 isMsgSending = false;
323 // check if there are pending msgs
324 while(isMsgHanging) {
325 // get the msg from outmsgdata[]
326 // length + target + msg
327 outmsgleft = outmsgdata[outmsgindex++];
328 int target = outmsgdata[outmsgindex++];
329 calCoords(target, &target_x, &target_y);
330 // mark to start sending the msg
332 // Build the message header
333 msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
338 BAMBOO_DEBUGPRINT(0xbbbb);
339 BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
341 while(outmsgleft-- > 0) {
342 gdn_send(outmsgdata[outmsgindex++]);
344 BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
348 BAMBOO_DEBUGPRINT(0xffff);
350 // mark to end sending the msg
351 isMsgSending = false;
352 BAMBOO_START_CRITICAL_SECTION_MSG();
353 // check if there are still msg hanging
354 if(outmsgindex == outmsglast) {
356 outmsgindex = outmsglast = 0;
357 isMsgHanging = false;
359 BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
363 __attribute__((always_inline)) inline void send_msg_4 (int targetcore,
370 int self_y, self_x, target_y, target_x;
373 // get the x-coord and y-coord of the target core
374 calCoords(corenum, &self_x, &self_y);
375 calCoords(targetcore, &target_x, &target_y);
377 // mark to start sending the msg
379 // Build the message header
380 msgHdr = construct_dyn_hdr(0, msglength, 0, // msgsize word sent.
383 gdn_send(msgHdr); // Send the message header
385 BAMBOO_DEBUGPRINT(0xbbbb);
386 BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
390 BAMBOO_DEBUGPRINT(n0);
394 BAMBOO_DEBUGPRINT(n1);
398 BAMBOO_DEBUGPRINT(n2);
402 BAMBOO_DEBUGPRINT(n3);
403 BAMBOO_DEBUGPRINT(0xffff);
405 // mark to end sending the msg
406 isMsgSending = false;
407 // check if there are pending msgs
408 while(isMsgHanging) {
409 // get the msg from outmsgdata[]
410 // length + target + msg
411 outmsgleft = outmsgdata[outmsgindex++];
412 int target = outmsgdata[outmsgindex++];
413 calCoords(target, &target_x, &target_y);
414 // mark to start sending the msg
416 // Build the message header
417 msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
422 BAMBOO_DEBUGPRINT(0xbbbb);
423 BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
425 while(outmsgleft-- > 0) {
426 gdn_send(outmsgdata[outmsgindex++]);
428 BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
432 BAMBOO_DEBUGPRINT(0xffff);
434 // mark to end sending the msg
435 isMsgSending = false;
436 BAMBOO_START_CRITICAL_SECTION_MSG();
437 // check if there are still msg hanging
438 if(outmsgindex == outmsglast) {
440 outmsgindex = outmsglast = 0;
441 isMsgHanging = false;
443 BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
447 __attribute__((always_inline)) inline void send_msg_5 (int targetcore,
455 int self_y, self_x, target_y, target_x;
458 // get the x-coord and y-coord of the target core
459 calCoords(corenum, &self_x, &self_y);
460 calCoords(targetcore, &target_x, &target_y);
462 // mark to start sending the msg
464 // Build the message header
465 msgHdr = construct_dyn_hdr(0, msglength, 0, // msgsize word sent.
468 gdn_send(msgHdr); // Send the message header
470 BAMBOO_DEBUGPRINT(0xbbbb);
471 BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
475 BAMBOO_DEBUGPRINT(n0);
479 BAMBOO_DEBUGPRINT(n1);
483 BAMBOO_DEBUGPRINT(n2);
487 BAMBOO_DEBUGPRINT(n3);
491 BAMBOO_DEBUGPRINT(n4);
492 BAMBOO_DEBUGPRINT(0xffff);
494 // mark to end sending the msg
495 isMsgSending = false;
496 // check if there are pending msgs
497 while(isMsgHanging) {
498 // get the msg from outmsgdata[]
499 // length + target + msg
500 outmsgleft = outmsgdata[outmsgindex++];
501 int target = outmsgdata[outmsgindex++];
502 calCoords(target, &target_x, &target_y);
503 // mark to start sending the msg
505 // Build the message header
506 msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
511 BAMBOO_DEBUGPRINT(0xbbbb);
512 BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
514 while(outmsgleft-- > 0) {
515 gdn_send(outmsgdata[outmsgindex++]);
517 BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
521 BAMBOO_DEBUGPRINT(0xffff);
523 // mark to end sending the msg
524 isMsgSending = false;
525 BAMBOO_START_CRITICAL_SECTION_MSG();
526 // check if there are still msg hanging
527 if(outmsgindex == outmsglast) {
529 outmsgindex = outmsglast = 0;
530 isMsgHanging = false;
532 BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
536 __attribute__((always_inline)) inline void send_msg_6 (int targetcore,
545 int self_y, self_x, target_y, target_x;
548 // get the x-coord and y-coord of the target core
549 calCoords(corenum, &self_x, &self_y);
550 calCoords(targetcore, &target_x, &target_y);
552 // mark to start sending the msg
554 // Build the message header
555 msgHdr = construct_dyn_hdr(0, msglength, 0, // msgsize word sent.
558 gdn_send(msgHdr); // Send the message header
560 BAMBOO_DEBUGPRINT(0xbbbb);
561 BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
565 BAMBOO_DEBUGPRINT(n0);
569 BAMBOO_DEBUGPRINT(n1);
573 BAMBOO_DEBUGPRINT(n2);
577 BAMBOO_DEBUGPRINT(n3);
581 BAMBOO_DEBUGPRINT(n4);
585 BAMBOO_DEBUGPRINT(n5);
586 BAMBOO_DEBUGPRINT(0xffff);
588 // mark to end sending the msg
589 isMsgSending = false;
590 // check if there are pending msgs
591 while(isMsgHanging) {
592 // get the msg from outmsgdata[]
593 // length + target + msg
594 outmsgleft = outmsgdata[outmsgindex++];
595 int target = outmsgdata[outmsgindex++];
596 calCoords(target, &target_x, &target_y);
597 // mark to start sending the msg
599 // Build the message header
600 msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
605 BAMBOO_DEBUGPRINT(0xbbbb);
606 BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
608 while(outmsgleft-- > 0) {
609 gdn_send(outmsgdata[outmsgindex++]);
611 BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
615 BAMBOO_DEBUGPRINT(0xffff);
617 // mark to end sending the msg
618 isMsgSending = false;
619 BAMBOO_START_CRITICAL_SECTION_MSG();
620 // check if there are still msg hanging
621 if(outmsgindex == outmsglast) {
623 outmsgindex = outmsglast = 0;
624 isMsgHanging = false;
626 BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
630 __attribute__((always_inline)) inline void cache_msg_2 (int targetcore,
635 BAMBOO_DEBUGPRINT(0xdede);
638 // cache the msg in outmsgdata and send it later
639 // msglength + target core + msg
640 outmsgdata[outmsglast++] = 2;
641 outmsgdata[outmsglast++] = targetcore;
642 outmsgdata[outmsglast++] = n0;
643 outmsgdata[outmsglast++] = n1;
646 __attribute__((always_inline)) inline void cache_msg_3 (int targetcore,
652 BAMBOO_DEBUGPRINT(0xdede);
655 // cache the msg in outmsgdata and send it later
656 // msglength + target core + msg
657 outmsgdata[outmsglast++] = 3;
658 outmsgdata[outmsglast++] = targetcore;
659 outmsgdata[outmsglast++] = n0;
660 outmsgdata[outmsglast++] = n1;
661 outmsgdata[outmsglast++] = n2;
664 __attribute__((always_inline)) inline void cache_msg_4 (int targetcore,
671 BAMBOO_DEBUGPRINT(0xdede);
674 // cache the msg in outmsgdata and send it later
675 // msglength + target core + msg
676 outmsgdata[outmsglast++] = 4;
677 outmsgdata[outmsglast++] = targetcore;
678 outmsgdata[outmsglast++] = n0;
679 outmsgdata[outmsglast++] = n1;
680 outmsgdata[outmsglast++] = n2;
681 outmsgdata[outmsglast++] = n3;
684 __attribute__((always_inline)) inline void cache_msg_5 (int targetcore,
692 BAMBOO_DEBUGPRINT(0xdede);
695 // cache the msg in outmsgdata and send it later
696 // msglength + target core + msg
697 outmsgdata[outmsglast++] = 5;
698 outmsgdata[outmsglast++] = targetcore;
699 outmsgdata[outmsglast++] = n0;
700 outmsgdata[outmsglast++] = n1;
701 outmsgdata[outmsglast++] = n2;
702 outmsgdata[outmsglast++] = n3;
703 outmsgdata[outmsglast++] = n4;
707 __attribute__((always_inline)) inline void cache_msg_6 (int targetcore,
716 BAMBOO_DEBUGPRINT(0xdede);
719 // cache the msg in outmsgdata and send it later
720 // msglength + target core + msg
721 outmsgdata[outmsglast++] = 6;
722 outmsgdata[outmsglast++] = targetcore;
723 outmsgdata[outmsglast++] = n0;
724 outmsgdata[outmsglast++] = n1;
725 outmsgdata[outmsglast++] = n2;
726 outmsgdata[outmsglast++] = n3;
727 outmsgdata[outmsglast++] = n4;
728 outmsgdata[outmsglast++] = n5;
731 __attribute__((always_inline)) inline int receiveMsg() {
732 if(gdn_input_avail() == 0) {
734 if(corenum < NUMCORES) {
735 BAMBOO_DEBUGPRINT(0xd001);
741 /*if(isInterrupt && (!interruptInfoOverflow)) {
742 // BAMBOO_DEBUGPRINT(0xffff);
743 interruptInfoArray[interruptInfoIndex] = RUNMALLOC_I(sizeof(struct interrupt_info));
744 interruptInfoArray[interruptInfoIndex]->startTime = raw_get_cycle();
745 interruptInfoArray[interruptInfoIndex]->endTime = -1;
749 BAMBOO_DEBUGPRINT(0xcccc);
751 while((gdn_input_avail() != 0) && (msgdataindex < msglength)) {
752 msgdata[msgdataindex] = gdn_receive();
753 if(msgdataindex == 0) {
754 if(msgdata[0] > 0xc) {
756 } else if (msgdata[0] == 0xc) {
758 } else if(msgdata[0] > 8) {
760 } else if(msgdata[0] == 8) {
762 } else if(msgdata[0] > 5) {
764 } else if (msgdata[0] > 2) {
766 } else if (msgdata[0] == 2) {
768 } else if (msgdata[0] > 0) {
771 } else if((msgdataindex == 1) && (msgdata[0] == 0)) {
772 msglength = msgdata[msgdataindex];
775 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
780 BAMBOO_DEBUGPRINT(0xffff);
785 bool getreadlock(void * ptr) {
788 if(((struct ___Object___ *)ptr)->lock == NULL) {
789 lock2require = lockobj;
791 lock2require = (int)(((struct ___Object___ *)ptr)->lock);
793 targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
800 if(targetcore == BAMBOO_NUM_OF_CORE) {
801 // reside on this core
803 BAMBOO_START_CRITICAL_SECTION_LOCK();
805 BAMBOO_DEBUGPRINT(0xf001);
807 deny = processlockrequest(0, lock2require, (int)ptr, BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, false);
808 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
810 BAMBOO_DEBUGPRINT(0xf000);
816 if(lockobj == (int)ptr) {
827 // conflicts on lockresults
833 // send lock request msg
834 // for 32 bit machine, the size is always 5 words
835 send_msg_5(targetcore, LOCKREQUEST, 0, (int)ptr,
836 lock2require, BAMBOO_NUM_OF_CORE);
841 void releasewritelock_r(void * lock, void * redirectlock);
842 bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache);
844 bool getwritelock_I_r(void* lock, void* redirectlock, int core, bool cache);
846 void releasereadlock(void * ptr) {
849 if(((struct ___Object___ *)ptr)->lock == NULL) {
852 reallock = (int)(((struct ___Object___ *)ptr)->lock);
854 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
856 if(targetcore == BAMBOO_NUM_OF_CORE) {
857 BAMBOO_START_CRITICAL_SECTION_LOCK();
859 BAMBOO_DEBUGPRINT(0xf001);
861 // reside on this core
862 if(!RuntimeHashcontainskey(locktbl, reallock)) {
863 // no locks for this object, something is wrong
867 struct LockValue * lockvalue = NULL;
868 RuntimeHashget(locktbl, reallock, &rwlock_obj);
869 lockvalue = (struct LockValue *)rwlock_obj;
872 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
874 BAMBOO_DEBUGPRINT(0xf000);
878 // send lock release msg
879 // for 32 bit machine, the size is always 4 words
880 send_msg_4(targetcore, LOCKRELEASE, 0, (int)ptr, reallock);
884 // redirected lock request
885 bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
888 if(core == BAMBOO_NUM_OF_CORE) {
890 lock2require = (int)redirectlock;
897 targetcore = ((int)redirectlock >> 5) % BAMBOO_TOTALCORE;
899 if(targetcore == BAMBOO_NUM_OF_CORE) {
900 // reside on this core
901 int deny = processlockrequest(0, (int)redirectlock, (int)ptr, BAMBOO_NUM_OF_CORE, core, cache);
906 if(core == BAMBOO_NUM_OF_CORE) {
907 if(lockobj == (int)ptr) {
912 RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
919 // conflicts on lockresults
924 // send lock grant/deny request to the root requiring core
925 // check if there is still some msg on sending
926 if((!cache) || (cache && !isMsgSending)) {
927 send_msg_4(core, deny==1?REDIRECTDENY:REDIRECTGROUNT, 0,
928 (int)ptr, (int)redirectlock);
930 cache_msg_4(core, deny==1?REDIRECTDENY:REDIRECTGROUNT, 0,
931 (int)ptr, (int)redirectlock);
936 // redirect the lock request
937 // for 32 bit machine, the size is always 6 words
938 if((!cache) || (cache && !isMsgSending)) {
939 send_msg_6(targetcore, REDIRECTLOCK, 0, (int)ptr, lock2require,
940 core, BAMBOO_NUM_OF_CORE);
942 cache_msg_6(targetcore, REDIRECTLOCK, 0, (int)ptr, lock2require,
943 core, BAMBOO_NUM_OF_CORE);
950 bool getwritelock(void * ptr) {
953 // for 32 bit machine, the size is always 5 words
957 if(((struct ___Object___ *)ptr)->lock == NULL) {
958 lock2require = lockobj;
960 lock2require = (int)(((struct ___Object___ *)ptr)->lock);
962 targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
970 BAMBOO_DEBUGPRINT(0xe551);
971 BAMBOO_DEBUGPRINT_REG(lockobj);
972 BAMBOO_DEBUGPRINT_REG(lock2require);
973 BAMBOO_DEBUGPRINT_REG(targetcore);
976 if(targetcore == BAMBOO_NUM_OF_CORE) {
977 // reside on this core
979 BAMBOO_START_CRITICAL_SECTION_LOCK();
981 BAMBOO_DEBUGPRINT(0xf001);
983 deny = processlockrequest(1, lock2require, (int)ptr, BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, false);
984 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
986 BAMBOO_DEBUGPRINT(0xf000);
989 BAMBOO_DEBUGPRINT(0xe555);
990 BAMBOO_DEBUGPRINT_REG(lockresult);
996 if(lockobj == (int)ptr) {
1007 // conflicts on lockresults
1008 BAMBOO_EXIT(0xa01b);
1013 // send lock request msg
1014 // for 32 bit machine, the size is always 5 words
1015 send_msg_5(targetcore, LOCKREQUEST, 1, (int)ptr, lock2require,
1016 BAMBOO_NUM_OF_CORE);
1021 void releasewritelock(void * ptr) {
1024 if(((struct ___Object___ *)ptr)->lock == NULL) {
1025 reallock = (int)ptr;
1027 reallock = (int)(((struct ___Object___ *)ptr)->lock);
1029 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
1032 BAMBOO_DEBUGPRINT(0xe661);
1033 BAMBOO_DEBUGPRINT_REG((int)ptr);
1034 BAMBOO_DEBUGPRINT_REG(reallock);
1035 BAMBOO_DEBUGPRINT_REG(targetcore);
1038 if(targetcore == BAMBOO_NUM_OF_CORE) {
1039 BAMBOO_START_CRITICAL_SECTION_LOCK();
1041 BAMBOO_DEBUGPRINT(0xf001);
1043 // reside on this core
1044 if(!RuntimeHashcontainskey(locktbl, reallock)) {
1045 // no locks for this object, something is wrong
1046 BAMBOO_EXIT(0xa01c);
1049 struct LockValue * lockvalue = NULL;
1050 RuntimeHashget(locktbl, reallock, &rwlock_obj);
1051 lockvalue = (struct LockValue *)rwlock_obj;
1054 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
1056 BAMBOO_DEBUGPRINT(0xf000);
1060 // send lock release msg
1061 // for 32 bit machine, the size is always 4 words
1062 send_msg_4(targetcore, LOCKRELEASE, 1, (int)ptr, reallock);
1066 void releasewritelock_r(void * lock, void * redirectlock) {
1068 int reallock = (int)lock;
1069 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
1072 BAMBOO_DEBUGPRINT(0xe671);
1073 BAMBOO_DEBUGPRINT_REG((int)lock);
1074 BAMBOO_DEBUGPRINT_REG(reallock);
1075 BAMBOO_DEBUGPRINT_REG(targetcore);
1078 if(targetcore == BAMBOO_NUM_OF_CORE) {
1079 BAMBOO_START_CRITICAL_SECTION_LOCK();
1081 BAMBOO_DEBUGPRINT(0xf001);
1083 // reside on this core
1084 if(!RuntimeHashcontainskey(locktbl, reallock)) {
1085 // no locks for this object, something is wrong
1086 BAMBOO_EXIT(0xa01d);
1089 struct LockValue * lockvalue = NULL;
1091 BAMBOO_DEBUGPRINT(0xe672);
1093 RuntimeHashget(locktbl, reallock, &rwlock_obj);
1094 lockvalue = (struct LockValue *)rwlock_obj;
1096 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1099 lockvalue->redirectlock = (int)redirectlock;
1101 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1104 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
1106 BAMBOO_DEBUGPRINT(0xf000);
1110 // send lock release with redirect info msg
1111 // for 32 bit machine, the size is always 4 words
1112 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock, (int)redirectlock);
1116 bool getwritelock_I(void * ptr) {
1119 if(((struct ___Object___ *)ptr)->lock == NULL) {
1120 lock2require = lockobj;
1122 lock2require = (int)(((struct ___Object___ *)ptr)->lock);
1124 targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
1132 BAMBOO_DEBUGPRINT(0xe561);
1133 BAMBOO_DEBUGPRINT_REG(lockobj);
1134 BAMBOO_DEBUGPRINT_REG(lock2require);
1135 BAMBOO_DEBUGPRINT_REG(targetcore);
1138 if(targetcore == BAMBOO_NUM_OF_CORE) {
1139 // reside on this core
1140 int deny = processlockrequest(1, (int)lock2require, (int)ptr, BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, false);
1145 if(lockobj == (int)ptr) {
1149 BAMBOO_DEBUGPRINT(0);
1154 BAMBOO_DEBUGPRINT(1);
1162 // conflicts on lockresults
1163 BAMBOO_EXIT(0xa01e);
1168 // send lock request msg
1169 // for 32 bit machine, the size is always 5 words
1170 send_msg_5(targetcore, LOCKREQUEST, 1, (int)ptr, lock2require,
1171 BAMBOO_NUM_OF_CORE);
1176 // redirected lock request
1177 bool getwritelock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
1180 if(core == BAMBOO_NUM_OF_CORE) {
1182 lock2require = (int)redirectlock;
1189 targetcore = ((int)redirectlock >> 5) % BAMBOO_TOTALCORE;
1192 BAMBOO_DEBUGPRINT(0xe571);
1193 BAMBOO_DEBUGPRINT_REG((int)ptr);
1194 BAMBOO_DEBUGPRINT_REG((int)redirectlock);
1195 BAMBOO_DEBUGPRINT_REG(core);
1196 BAMBOO_DEBUGPRINT_REG((int)cache);
1197 BAMBOO_DEBUGPRINT_REG(targetcore);
1201 if(targetcore == BAMBOO_NUM_OF_CORE) {
1202 // reside on this core
1203 int deny = processlockrequest(1, (int)redirectlock, (int)ptr, BAMBOO_NUM_OF_CORE, core, cache);
1208 if(core == BAMBOO_NUM_OF_CORE) {
1209 if(lockobj == (int)ptr) {
1214 RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
1221 // conflicts on lockresults
1222 BAMBOO_EXIT(0xa01f);
1226 // send lock grant/deny request to the root requiring core
1227 // check if there is still some msg on sending
1228 if((!cache) || (cache && !isMsgSending)) {
1229 send_msg_4(core, deny==1?REDIRECTDENY:REDIRECTGROUNT, 1,
1230 (int)ptr, (int)redirectlock);
1232 cache_msg_4(core, deny==1?REDIRECTDENY:REDIRECTGROUNT, 1,
1233 (int)ptr, (int)redirectlock);
1238 // redirect the lock request
1239 // for 32 bit machine, the size is always 6 words
1240 if((!cache) || (cache && !isMsgSending)) {
1241 send_msg_6(targetcore, REDIRECTLOCK, 1, (int)ptr, (int)redirectlock,
1242 core, BAMBOO_NUM_OF_CORE);
1244 cache_msg_6(targetcore, REDIRECTLOCK, 1, (int)ptr, (int)redirectlock,
1245 core, BAMBOO_NUM_OF_CORE);
1251 void releasewritelock_I(void * ptr) {
1254 if(((struct ___Object___ *)ptr)->lock == NULL) {
1255 reallock = (int)ptr;
1257 reallock = (int)(((struct ___Object___ *)ptr)->lock);
1259 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
1262 BAMBOO_DEBUGPRINT(0xe681);
1263 BAMBOO_DEBUGPRINT_REG((int)ptr);
1264 BAMBOO_DEBUGPRINT_REG(reallock);
1265 BAMBOO_DEBUGPRINT_REG(targetcore);
1268 if(targetcore == BAMBOO_NUM_OF_CORE) {
1269 // reside on this core
1270 if(!RuntimeHashcontainskey(locktbl, reallock)) {
1271 // no locks for this object, something is wrong
1272 BAMBOO_EXIT(0xa020);
1275 struct LockValue * lockvalue = NULL;
1276 RuntimeHashget(locktbl, reallock, &rwlock_obj);
1277 lockvalue = (struct LockValue *)rwlock_obj;
1282 // send lock release msg
1283 // for 32 bit machine, the size is always 4 words
1284 send_msg_4(targetcore, LOCKRELEASE, 1, (int)ptr, reallock);
1288 void releasewritelock_I_r(void * lock, void * redirectlock) {
1290 int reallock = (int)lock;
1291 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
1294 BAMBOO_DEBUGPRINT(0xe691);
1295 BAMBOO_DEBUGPRINT_REG((int)lock);
1296 BAMBOO_DEBUGPRINT_REG(reallock);
1297 BAMBOO_DEBUGPRINT_REG(targetcore);
1300 if(targetcore == BAMBOO_NUM_OF_CORE) {
1301 // reside on this core
1302 if(!RuntimeHashcontainskey(locktbl, reallock)) {
1303 // no locks for this object, something is wrong
1304 BAMBOO_EXIT(0xa021);
1307 struct LockValue * lockvalue = NULL;
1309 BAMBOO_DEBUGPRINT(0xe692);
1311 RuntimeHashget(locktbl, reallock, &rwlock_obj);
1312 lockvalue = (struct LockValue *)rwlock_obj;
1314 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1317 lockvalue->redirectlock = (int)redirectlock;
1319 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1324 // send lock release msg
1325 // for 32 bit machine, the size is always 4 words
1326 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock, (int)redirectlock);
1330 /* this function is to process lock requests.
1331 * can only be invoked in receiveObject() */
1332 // if return -1: the lock request is redirected
1333 // 0: the lock request is approved
1334 // 1: the lock request is denied
1335 __attribute__((always_inline)) int processlockrequest(int locktype, int lock, int obj, int requestcore, int rootrequestcore, bool cache) {
1337 if( ((lock >> 5) % BAMBOO_TOTALCORE) != BAMBOO_NUM_OF_CORE ) {
1338 // the lock should not be on this core
1340 BAMBOO_DEBUGPRINT_REG(requestcore);
1341 BAMBOO_DEBUGPRINT_REG(lock);
1342 BAMBOO_DEBUGPRINT_REG(BAMBOO_NUM_OF_CORE);
1344 BAMBOO_EXIT(0xa017);
1346 if(!RuntimeHashcontainskey(locktbl, lock)) {
1347 // no locks for this object
1348 // first time to operate on this shared object
1349 // create a lock for it
1350 // the lock is an integer: 0 -- stall, >0 -- read lock, -1 -- write lock
1351 struct LockValue * lockvalue = (struct LockValue *)(RUNMALLOC_I(sizeof(struct LockValue)));
1352 lockvalue->redirectlock = 0;
1355 BAMBOO_DEBUGPRINT(0xe110);
1359 lockvalue->value = 1;
1361 lockvalue->value = -1;
1363 RuntimeHashadd_I(locktbl, lock, (int)lockvalue);
1366 struct LockValue * lockvalue = NULL;
1369 BAMBOO_DEBUGPRINT(0xe111);
1372 RuntimeHashget(locktbl, lock, &rwlock_obj);
1373 lockvalue = (struct LockValue *)(rwlock_obj);
1376 BAMBOO_DEBUGPRINT_REG(lockvalue->redirectlock);
1379 if(lockvalue->redirectlock != 0) {
1380 // this lock is redirected
1383 BAMBOO_DEBUGPRINT(0xe112);
1387 getreadlock_I_r((void *)obj, (void *)lockvalue->redirectlock, rootrequestcore, cache);
1389 getwritelock_I_r((void *)obj, (void *)lockvalue->redirectlock, rootrequestcore, cache);
1391 return -1; // redirected
1395 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1398 if(0 == lockvalue->value) {
1400 lockvalue->value = 1;
1402 lockvalue->value = -1;
1404 } else if((lockvalue->value > 0) && (locktype == 0)) {
1405 // read lock request and there are only read locks
1412 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1420 __attribute__((always_inline)) void processlockrelease(int locktype, int lock, int redirectlock, bool isredirect) {
1421 if(!RuntimeHashcontainskey(locktbl, lock)) {
1422 // no locks for this object, something is wrong
1424 BAMBOO_DEBUGPRINT_REG(lock);
1426 BAMBOO_EXIT(0xa00b);
1429 struct LockValue * lockvalue = NULL;
1430 RuntimeHashget(locktbl, lock, &rwlock_obj);
1431 lockvalue = (struct LockValue*)(rwlock_obj);
1433 BAMBOO_DEBUGPRINT(0xe884);
1434 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1442 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1445 lockvalue->redirectlock = redirectlock;
1451 __attribute__((always_inline)) inline void profileTaskStart(char * taskname) {
1452 if(!taskInfoOverflow) {
1453 TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
1454 taskInfoArray[taskInfoIndex] = taskInfo;
1455 taskInfo->taskName = taskname;
1456 taskInfo->startTime = raw_get_cycle();
1457 taskInfo->endTime = -1;
1458 taskInfo->exitIndex = -1;
1459 taskInfo->newObjs = NULL;
1463 __attribute__((always_inline)) inline void profileTaskEnd() {
1464 if(!taskInfoOverflow) {
1465 taskInfoArray[taskInfoIndex]->endTime = raw_get_cycle();
1467 if(taskInfoIndex == TASKINFOLENGTH) {
1468 taskInfoOverflow = true;
1473 // output the profiling data
1474 void outputProfileData() {
1481 int totaltasktime = 0;
1482 int preprocessingtime = 0;
1483 int objqueuecheckingtime = 0;
1484 int postprocessingtime = 0;
1485 //int interruptiontime = 0;
1487 int averagetasktime = 0;
1490 for(i = 0; i < 50; i++) {
1494 calCoords(corenum, &self_y, &self_x);
1495 c_y = (char)self_y + '0';
1496 c_x = (char)self_x + '0';
1497 strcat(fn, "profile_");
1503 if((fp = fopen(fn, "w+")) == NULL) {
1504 fprintf(stderr, "fopen error\n");
1508 fprintf(fp, "Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
1509 // output task related info
1510 for(i = 0; i < taskInfoIndex; i++) {
1511 TaskInfo* tmpTInfo = taskInfoArray[i];
1512 int duration = tmpTInfo->endTime - tmpTInfo->startTime;
1513 fprintf(fp, "%s, %d, %d, %d, %d", tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime, duration, tmpTInfo->exitIndex);
1514 // summarize new obj info
1515 if(tmpTInfo->newObjs != NULL) {
1516 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
1517 struct RuntimeIterator * iter = NULL;
1518 while(0 == isEmpty(tmpTInfo->newObjs)) {
1519 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
1520 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
1522 RuntimeHashget(nobjtbl, (int)objtype, &num);
1523 RuntimeHashremovekey(nobjtbl, (int)objtype);
1525 RuntimeHashadd(nobjtbl, (int)objtype, num);
1527 RuntimeHashadd(nobjtbl, (int)objtype, 1);
1529 //fprintf(stderr, "new obj!\n");
1532 // output all new obj info
1533 iter = RuntimeHashcreateiterator(nobjtbl);
1534 while(RunhasNext(iter)) {
1535 char * objtype = (char *)Runkey(iter);
1536 int num = Runnext(iter);
1537 fprintf(fp, ", %s, %d", objtype, num);
1541 if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
1542 preprocessingtime += duration;
1543 } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
1544 postprocessingtime += duration;
1545 } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
1546 objqueuecheckingtime += duration;
1548 totaltasktime += duration;
1549 averagetasktime += duration;
1554 if(taskInfoOverflow) {
1555 fprintf(stderr, "Caution: task info overflow!\n");
1558 other = totalexetime - totaltasktime - preprocessingtime - postprocessingtime;
1559 averagetasktime /= tasknum;
1561 fprintf(fp, "\nTotal time: %d\n", totalexetime);
1562 fprintf(fp, "Total task execution time: %d (%f%%)\n", totaltasktime, ((double)totaltasktime/(double)totalexetime)*100);
1563 fprintf(fp, "Total objqueue checking time: %d (%f%%)\n", objqueuecheckingtime, ((double)objqueuecheckingtime/(double)totalexetime)*100);
1564 fprintf(fp, "Total pre-processing time: %d (%f%%)\n", preprocessingtime, ((double)preprocessingtime/(double)totalexetime)*100);
1565 fprintf(fp, "Total post-processing time: %d (%f%%)\n", postprocessingtime, ((double)postprocessingtime/(double)totalexetime)*100);
1566 fprintf(fp, "Other time: %d (%f%%)\n", other, ((double)other/(double)totalexetime)*100);
1568 fprintf(fp, "\nAverage task execution time: %d\n", averagetasktime);
1575 BAMBOO_DEBUGPRINT(0xdddd);
1576 // output task related info
1577 for(i= 0; i < taskInfoIndex; i++) {
1578 TaskInfo* tmpTInfo = taskInfoArray[i];
1579 char* tmpName = tmpTInfo->taskName;
1580 int nameLen = strlen(tmpName);
1581 BAMBOO_DEBUGPRINT(0xddda);
1582 for(j = 0; j < nameLen; j++) {
1583 BAMBOO_DEBUGPRINT_REG(tmpName[j]);
1585 BAMBOO_DEBUGPRINT(0xdddb);
1586 BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
1587 BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
1588 BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
1589 if(tmpTInfo->newObjs != NULL) {
1590 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
1591 struct RuntimeIterator * iter = NULL;
1592 while(0 == isEmpty(tmpTInfo->newObjs)) {
1593 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
1594 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
1596 RuntimeHashget(nobjtbl, (int)objtype, &num);
1597 RuntimeHashremovekey(nobjtbl, (int)objtype);
1599 RuntimeHashadd(nobjtbl, (int)objtype, num);
1601 RuntimeHashadd(nobjtbl, (int)objtype, 1);
1605 // ouput all new obj info
1606 iter = RuntimeHashcreateiterator(nobjtbl);
1607 while(RunhasNext(iter)) {
1608 char * objtype = (char *)Runkey(iter);
1609 int num = Runnext(iter);
1610 int nameLen = strlen(objtype);
1611 BAMBOO_DEBUGPRINT(0xddda);
1612 for(j = 0; j < nameLen; j++) {
1613 BAMBOO_DEBUGPRINT_REG(objtype[j]);
1615 BAMBOO_DEBUGPRINT(0xdddb);
1616 BAMBOO_DEBUGPRINT_REG(num);
1619 BAMBOO_DEBUGPRINT(0xdddc);
1622 if(taskInfoOverflow) {
1623 BAMBOO_DEBUGPRINT(0xefee);
1626 // output interrupt related info
1627 /*for(i = 0; i < interruptInfoIndex; i++) {
1628 InterruptInfo* tmpIInfo = interruptInfoArray[i];
1629 BAMBOO_DEBUGPRINT(0xddde);
1630 BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
1631 BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
1632 BAMBOO_DEBUGPRINT(0xdddf);
1635 if(interruptInfoOverflow) {
1636 BAMBOO_DEBUGPRINT(0xefef);
1639 BAMBOO_DEBUGPRINT(0xeeee);
1642 #endif // #ifdef PROFILE
1644 #endif // #ifdef TASK