3 #include "multicoreruntime.h"
4 #include "runtime_arch.h"
6 // data structures for locking
7 struct RuntimeHash locktable;
8 static struct RuntimeHash* locktbl = &locktable;
14 __attribute__((always_inline)) inline void initialization() {
17 __attribute__((always_inline)) inline void initCommunication() {
19 if (corenum < NUMCORES) {
22 raw_user_interrupts_on();
27 __attribute__((always_inline)) inline void fakeExecution() {
28 // handle communications
38 #endif // #ifdef USEIO
42 __attribute__((always_inline)) inline void terminate() {
46 // helper function to compute the coordinates of a core from the core number
47 #define calCoords(core_num, coordX, coordY) \
48 *(coordX) = (core_num) % raw_get_array_size_x();\
49 *(coordY) = core_num / raw_get_array_size_x();
51 // transfer an object to targetcore
53 inline void transferObject(struct transObjInfo * transObj) {// __attribute__((always_inline)){
54 void * obj = transObj->objptr;
55 int type=((int *)obj)[0];
56 int targetcore = transObj->targetcore;
59 int self_y, self_x, target_y, target_x;
60 // for 32 bit machine, the size of fixed part is always 3 words
61 int msgsize = 3 + transObj->length * 2;
64 struct ___Object___ * newobj = (struct ___Object___ *)obj;
66 calCoords(corenum, &self_x, &self_y);
67 calCoords(targetcore, &target_x, &target_y);
69 // Build the message header
70 msgHdr = construct_dyn_hdr(0, msgsize, 0, // msgsize word sent.
73 // start sending msg, set sand msg flag
76 BAMBOO_DEBUGPRINT(0xbbbb);
77 BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
85 BAMBOO_DEBUGPRINT_REG(msgsize);
89 BAMBOO_DEBUGPRINT_REG(obj);
91 for(i = 0; i < transObj->length; ++i) {
92 int taskindex = transObj->queues[2*i];
93 int paramindex = transObj->queues[2*i+1];
96 BAMBOO_DEBUGPRINT_REG(taskindex);
100 BAMBOO_DEBUGPRINT_REG(paramindex);
104 BAMBOO_DEBUGPRINT(0xffff);
106 // end of sending this msg, set sand msg flag false
107 isMsgSending = false;
108 ++(self_numsendobjs);
109 // check if there are pending msgs
110 while(isMsgHanging) {
111 // get the msg from outmsgdata[]
112 // length + target + msg
113 outmsgleft = outmsgdata[outmsgindex++];
114 int target = outmsgdata[outmsgindex++];
115 calCoords(target, &target_x, &target_y);
116 // mark to start sending the msg
118 // Build the message header
119 msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
124 BAMBOO_DEBUGPRINT(0xbbbb);
125 BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
127 while(outmsgleft-- > 0) {
128 gdn_send(outmsgdata[outmsgindex++]);
130 BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
134 BAMBOO_DEBUGPRINT(0xffff);
136 // mark to end sending the msg
137 isMsgSending = false;
138 BAMBOO_START_CRITICAL_SECTION_MSG();
139 // check if there are still msg hanging
140 if(outmsgindex == outmsglast) {
142 outmsgindex = outmsglast = 0;
143 isMsgHanging = false;
145 BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
149 __attribute__((always_inline)) inline void send_msg_1 (int targetcore,
153 int self_y, self_x, target_y, target_x;
156 // get the x-coord and y-coord of the target core
157 calCoords(corenum, &self_x, &self_y);
158 calCoords(targetcore, &target_x, &target_y);
160 // mark to start sending the msg
162 // Build the message header
163 msgHdr = construct_dyn_hdr(0, msglength, 0, // msgsize word sent.
166 gdn_send(msgHdr); // Send the message header
168 BAMBOO_DEBUGPRINT(0xbbbb);
169 BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
173 BAMBOO_DEBUGPRINT(n0);
174 BAMBOO_DEBUGPRINT(0xffff);
176 // mark to end sending the msg
177 isMsgSending = false;
178 // check if there are pending msgs
179 while(isMsgHanging) {
180 // get the msg from outmsgdata[]
181 // length + target + msg
182 outmsgleft = outmsgdata[outmsgindex++];
183 int target = outmsgdata[outmsgindex++];
184 calCoords(target, &target_x, &target_y);
185 // mark to start sending the msg
187 // Build the message header
188 msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
193 BAMBOO_DEBUGPRINT(0xbbbb);
194 BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
196 while(outmsgleft-- > 0) {
197 gdn_send(outmsgdata[outmsgindex++]);
199 BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
203 BAMBOO_DEBUGPRINT(0xffff);
205 // mark to end sending the msg
206 isMsgSending = false;
207 BAMBOO_START_CRITICAL_SECTION_MSG();
208 // check if there are still msg hanging
209 if(outmsgindex == outmsglast) {
211 outmsgindex = outmsglast = 0;
212 isMsgHanging = false;
214 BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
218 __attribute__((always_inline)) inline void send_msg_2 (int targetcore,
223 int self_y, self_x, target_y, target_x;
226 // get the x-coord and y-coord of the target core
227 calCoords(corenum, &self_x, &self_y);
228 calCoords(targetcore, &target_x, &target_y);
230 // mark to start sending the msg
232 // Build the message header
233 msgHdr = construct_dyn_hdr(0, msglength, 0, // msgsize word sent.
236 gdn_send(msgHdr); // Send the message header
238 BAMBOO_DEBUGPRINT(0xbbbb);
239 BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
243 BAMBOO_DEBUGPRINT(n0);
247 BAMBOO_DEBUGPRINT(n1);
248 BAMBOO_DEBUGPRINT(0xffff);
250 // mark to end sending the msg
251 isMsgSending = false;
252 // check if there are pending msgs
253 while(isMsgHanging) {
254 // get the msg from outmsgdata[]
255 // length + target + msg
256 outmsgleft = outmsgdata[outmsgindex++];
257 int target = outmsgdata[outmsgindex++];
258 calCoords(target, &target_x, &target_y);
259 // mark to start sending the msg
261 // Build the message header
262 msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
267 BAMBOO_DEBUGPRINT(0xbbbb);
268 BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
270 while(outmsgleft-- > 0) {
271 gdn_send(outmsgdata[outmsgindex++]);
273 BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
277 BAMBOO_DEBUGPRINT(0xffff);
279 // mark to end sending the msg
280 isMsgSending = false;
281 BAMBOO_START_CRITICAL_SECTION_MSG();
282 // check if there are still msg hanging
283 if(outmsgindex == outmsglast) {
285 outmsgindex = outmsglast = 0;
286 isMsgHanging = false;
288 BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
292 __attribute__((always_inline)) inline void send_msg_3 (int targetcore,
298 int self_y, self_x, target_y, target_x;
301 // get the x-coord and y-coord of the target core
302 calCoords(corenum, &self_x, &self_y);
303 calCoords(targetcore, &target_x, &target_y);
305 // mark to start sending the msg
307 // Build the message header
308 msgHdr = construct_dyn_hdr(0, msglength, 0, // msgsize word sent.
311 gdn_send(msgHdr); // Send the message header
313 BAMBOO_DEBUGPRINT(0xbbbb);
314 BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
318 BAMBOO_DEBUGPRINT(n0);
322 BAMBOO_DEBUGPRINT(n1);
326 BAMBOO_DEBUGPRINT(n2);
327 BAMBOO_DEBUGPRINT(0xffff);
329 // mark to end sending the msg
330 isMsgSending = false;
331 // check if there are pending msgs
332 while(isMsgHanging) {
333 // get the msg from outmsgdata[]
334 // length + target + msg
335 outmsgleft = outmsgdata[outmsgindex++];
336 int target = outmsgdata[outmsgindex++];
337 calCoords(target, &target_x, &target_y);
338 // mark to start sending the msg
340 // Build the message header
341 msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
346 BAMBOO_DEBUGPRINT(0xbbbb);
347 BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
349 while(outmsgleft-- > 0) {
350 gdn_send(outmsgdata[outmsgindex++]);
352 BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
356 BAMBOO_DEBUGPRINT(0xffff);
358 // mark to end sending the msg
359 isMsgSending = false;
360 BAMBOO_START_CRITICAL_SECTION_MSG();
361 // check if there are still msg hanging
362 if(outmsgindex == outmsglast) {
364 outmsgindex = outmsglast = 0;
365 isMsgHanging = false;
367 BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
371 __attribute__((always_inline)) inline void send_msg_4 (int targetcore,
378 int self_y, self_x, target_y, target_x;
381 // get the x-coord and y-coord of the target core
382 calCoords(corenum, &self_x, &self_y);
383 calCoords(targetcore, &target_x, &target_y);
385 // mark to start sending the msg
387 // Build the message header
388 msgHdr = construct_dyn_hdr(0, msglength, 0, // msgsize word sent.
391 gdn_send(msgHdr); // Send the message header
393 BAMBOO_DEBUGPRINT(0xbbbb);
394 BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
398 BAMBOO_DEBUGPRINT(n0);
402 BAMBOO_DEBUGPRINT(n1);
406 BAMBOO_DEBUGPRINT(n2);
410 BAMBOO_DEBUGPRINT(n3);
411 BAMBOO_DEBUGPRINT(0xffff);
413 // mark to end sending the msg
414 isMsgSending = false;
415 // check if there are pending msgs
416 while(isMsgHanging) {
417 // get the msg from outmsgdata[]
418 // length + target + msg
419 outmsgleft = outmsgdata[outmsgindex++];
420 int target = outmsgdata[outmsgindex++];
421 calCoords(target, &target_x, &target_y);
422 // mark to start sending the msg
424 // Build the message header
425 msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
430 BAMBOO_DEBUGPRINT(0xbbbb);
431 BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
433 while(outmsgleft-- > 0) {
434 gdn_send(outmsgdata[outmsgindex++]);
436 BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
440 BAMBOO_DEBUGPRINT(0xffff);
442 // mark to end sending the msg
443 isMsgSending = false;
444 BAMBOO_START_CRITICAL_SECTION_MSG();
445 // check if there are still msg hanging
446 if(outmsgindex == outmsglast) {
448 outmsgindex = outmsglast = 0;
449 isMsgHanging = false;
451 BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
455 __attribute__((always_inline)) inline void send_msg_5 (int targetcore,
463 int self_y, self_x, target_y, target_x;
466 // get the x-coord and y-coord of the target core
467 calCoords(corenum, &self_x, &self_y);
468 calCoords(targetcore, &target_x, &target_y);
470 // mark to start sending the msg
472 // Build the message header
473 msgHdr = construct_dyn_hdr(0, msglength, 0, // msgsize word sent.
476 gdn_send(msgHdr); // Send the message header
478 BAMBOO_DEBUGPRINT(0xbbbb);
479 BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
483 BAMBOO_DEBUGPRINT(n0);
487 BAMBOO_DEBUGPRINT(n1);
491 BAMBOO_DEBUGPRINT(n2);
495 BAMBOO_DEBUGPRINT(n3);
499 BAMBOO_DEBUGPRINT(n4);
500 BAMBOO_DEBUGPRINT(0xffff);
502 // mark to end sending the msg
503 isMsgSending = false;
504 // check if there are pending msgs
505 while(isMsgHanging) {
506 // get the msg from outmsgdata[]
507 // length + target + msg
508 outmsgleft = outmsgdata[outmsgindex++];
509 int target = outmsgdata[outmsgindex++];
510 calCoords(target, &target_x, &target_y);
511 // mark to start sending the msg
513 // Build the message header
514 msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
519 BAMBOO_DEBUGPRINT(0xbbbb);
520 BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
522 while(outmsgleft-- > 0) {
523 gdn_send(outmsgdata[outmsgindex++]);
525 BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
529 BAMBOO_DEBUGPRINT(0xffff);
531 // mark to end sending the msg
532 isMsgSending = false;
533 BAMBOO_START_CRITICAL_SECTION_MSG();
534 // check if there are still msg hanging
535 if(outmsgindex == outmsglast) {
537 outmsgindex = outmsglast = 0;
538 isMsgHanging = false;
540 BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
544 __attribute__((always_inline)) inline void send_msg_6 (int targetcore,
553 int self_y, self_x, target_y, target_x;
556 // get the x-coord and y-coord of the target core
557 calCoords(corenum, &self_x, &self_y);
558 calCoords(targetcore, &target_x, &target_y);
560 // mark to start sending the msg
562 // Build the message header
563 msgHdr = construct_dyn_hdr(0, msglength, 0, // msgsize word sent.
566 gdn_send(msgHdr); // Send the message header
568 BAMBOO_DEBUGPRINT(0xbbbb);
569 BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
573 BAMBOO_DEBUGPRINT(n0);
577 BAMBOO_DEBUGPRINT(n1);
581 BAMBOO_DEBUGPRINT(n2);
585 BAMBOO_DEBUGPRINT(n3);
589 BAMBOO_DEBUGPRINT(n4);
593 BAMBOO_DEBUGPRINT(n5);
594 BAMBOO_DEBUGPRINT(0xffff);
596 // mark to end sending the msg
597 isMsgSending = false;
598 // check if there are pending msgs
599 while(isMsgHanging) {
600 // get the msg from outmsgdata[]
601 // length + target + msg
602 outmsgleft = outmsgdata[outmsgindex++];
603 int target = outmsgdata[outmsgindex++];
604 calCoords(target, &target_x, &target_y);
605 // mark to start sending the msg
607 // Build the message header
608 msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
613 BAMBOO_DEBUGPRINT(0xbbbb);
614 BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
616 while(outmsgleft-- > 0) {
617 gdn_send(outmsgdata[outmsgindex++]);
619 BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
623 BAMBOO_DEBUGPRINT(0xffff);
625 // mark to end sending the msg
626 isMsgSending = false;
627 BAMBOO_START_CRITICAL_SECTION_MSG();
628 // check if there are still msg hanging
629 if(outmsgindex == outmsglast) {
631 outmsgindex = outmsglast = 0;
632 isMsgHanging = false;
634 BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
638 __attribute__((always_inline)) inline void cache_msg_2 (int targetcore,
643 BAMBOO_DEBUGPRINT(0xdede);
646 // cache the msg in outmsgdata and send it later
647 // msglength + target core + msg
648 outmsgdata[outmsglast++] = 2;
649 outmsgdata[outmsglast++] = targetcore;
650 outmsgdata[outmsglast++] = n0;
651 outmsgdata[outmsglast++] = n1;
654 __attribute__((always_inline)) inline void cache_msg_3 (int targetcore,
660 BAMBOO_DEBUGPRINT(0xdede);
663 // cache the msg in outmsgdata and send it later
664 // msglength + target core + msg
665 outmsgdata[outmsglast++] = 3;
666 outmsgdata[outmsglast++] = targetcore;
667 outmsgdata[outmsglast++] = n0;
668 outmsgdata[outmsglast++] = n1;
669 outmsgdata[outmsglast++] = n2;
672 __attribute__((always_inline)) inline void cache_msg_4 (int targetcore,
679 BAMBOO_DEBUGPRINT(0xdede);
682 // cache the msg in outmsgdata and send it later
683 // msglength + target core + msg
684 outmsgdata[outmsglast++] = 4;
685 outmsgdata[outmsglast++] = targetcore;
686 outmsgdata[outmsglast++] = n0;
687 outmsgdata[outmsglast++] = n1;
688 outmsgdata[outmsglast++] = n2;
689 outmsgdata[outmsglast++] = n3;
692 __attribute__((always_inline)) inline void cache_msg_5 (int targetcore,
700 BAMBOO_DEBUGPRINT(0xdede);
703 // cache the msg in outmsgdata and send it later
704 // msglength + target core + msg
705 outmsgdata[outmsglast++] = 5;
706 outmsgdata[outmsglast++] = targetcore;
707 outmsgdata[outmsglast++] = n0;
708 outmsgdata[outmsglast++] = n1;
709 outmsgdata[outmsglast++] = n2;
710 outmsgdata[outmsglast++] = n3;
711 outmsgdata[outmsglast++] = n4;
715 __attribute__((always_inline)) inline void cache_msg_6 (int targetcore,
724 BAMBOO_DEBUGPRINT(0xdede);
727 // cache the msg in outmsgdata and send it later
728 // msglength + target core + msg
729 outmsgdata[outmsglast++] = 6;
730 outmsgdata[outmsglast++] = targetcore;
731 outmsgdata[outmsglast++] = n0;
732 outmsgdata[outmsglast++] = n1;
733 outmsgdata[outmsglast++] = n2;
734 outmsgdata[outmsglast++] = n3;
735 outmsgdata[outmsglast++] = n4;
736 outmsgdata[outmsglast++] = n5;
739 __attribute__((always_inline)) inline int receiveMsg() {
740 if(gdn_input_avail() == 0) {
742 if(corenum < NUMCORES) {
743 BAMBOO_DEBUGPRINT(0xd001);
749 /*if(isInterrupt && (!interruptInfoOverflow)) {
750 // BAMBOO_DEBUGPRINT(0xffff);
751 interruptInfoArray[interruptInfoIndex] = RUNMALLOC_I(sizeof(struct interrupt_info));
752 interruptInfoArray[interruptInfoIndex]->startTime = raw_get_cycle();
753 interruptInfoArray[interruptInfoIndex]->endTime = -1;
757 BAMBOO_DEBUGPRINT(0xcccc);
759 while((gdn_input_avail() != 0) && (msgdataindex < msglength)) {
760 msgdata[msgdataindex] = gdn_receive();
761 if(msgdataindex == 0) {
762 if(msgdata[0] > 0xc) {
764 } else if (msgdata[0] == 0xc) {
766 } else if(msgdata[0] > 8) {
768 } else if(msgdata[0] == 8) {
770 } else if(msgdata[0] > 5) {
772 } else if (msgdata[0] > 2) {
774 } else if (msgdata[0] == 2) {
776 } else if (msgdata[0] > 0) {
779 } else if((msgdataindex == 1) && (msgdata[0] == 0)) {
780 msglength = msgdata[msgdataindex];
783 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
788 BAMBOO_DEBUGPRINT(0xffff);
793 bool getreadlock(void * ptr) {
796 if(((struct ___Object___ *)ptr)->lock == NULL) {
797 lock2require = lockobj;
799 lock2require = (int)(((struct ___Object___ *)ptr)->lock);
801 targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
808 if(targetcore == BAMBOO_NUM_OF_CORE) {
809 // reside on this core
811 BAMBOO_START_CRITICAL_SECTION_LOCK();
813 BAMBOO_DEBUGPRINT(0xf001);
815 deny = processlockrequest(0, lock2require, (int)ptr, BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, false);
816 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
818 BAMBOO_DEBUGPRINT(0xf000);
824 if(lockobj == (int)ptr) {
835 // conflicts on lockresults
841 // send lock request msg
842 // for 32 bit machine, the size is always 5 words
843 send_msg_5(targetcore, LOCKREQUEST, 0, (int)ptr,
844 lock2require, BAMBOO_NUM_OF_CORE);
849 void releasewritelock_r(void * lock, void * redirectlock);
850 bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache);
852 bool getwritelock_I_r(void* lock, void* redirectlock, int core, bool cache);
854 void releasereadlock(void * ptr) {
857 if(((struct ___Object___ *)ptr)->lock == NULL) {
860 reallock = (int)(((struct ___Object___ *)ptr)->lock);
862 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
864 if(targetcore == BAMBOO_NUM_OF_CORE) {
865 BAMBOO_START_CRITICAL_SECTION_LOCK();
867 BAMBOO_DEBUGPRINT(0xf001);
869 // reside on this core
870 if(!RuntimeHashcontainskey(locktbl, reallock)) {
871 // no locks for this object, something is wrong
875 struct LockValue * lockvalue = NULL;
876 RuntimeHashget(locktbl, reallock, &rwlock_obj);
877 lockvalue = (struct LockValue *)rwlock_obj;
880 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
882 BAMBOO_DEBUGPRINT(0xf000);
886 // send lock release msg
887 // for 32 bit machine, the size is always 4 words
888 send_msg_4(targetcore, LOCKRELEASE, 0, (int)ptr, reallock);
892 // redirected lock request
893 bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
896 if(core == BAMBOO_NUM_OF_CORE) {
898 lock2require = (int)redirectlock;
905 targetcore = ((int)redirectlock >> 5) % BAMBOO_TOTALCORE;
907 if(targetcore == BAMBOO_NUM_OF_CORE) {
908 // reside on this core
909 int deny = processlockrequest(0, (int)redirectlock, (int)ptr, BAMBOO_NUM_OF_CORE, core, cache);
914 if(core == BAMBOO_NUM_OF_CORE) {
915 if(lockobj == (int)ptr) {
920 RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
927 // conflicts on lockresults
932 // send lock grant/deny request to the root requiring core
933 // check if there is still some msg on sending
934 if((!cache) || (cache && !isMsgSending)) {
935 send_msg_4(core, deny==1?REDIRECTDENY:REDIRECTGROUNT, 0,
936 (int)ptr, (int)redirectlock);
938 cache_msg_4(core, deny==1?REDIRECTDENY:REDIRECTGROUNT, 0,
939 (int)ptr, (int)redirectlock);
944 // redirect the lock request
945 // for 32 bit machine, the size is always 6 words
946 if((!cache) || (cache && !isMsgSending)) {
947 send_msg_6(targetcore, REDIRECTLOCK, 0, (int)ptr, lock2require,
948 core, BAMBOO_NUM_OF_CORE);
950 cache_msg_6(targetcore, REDIRECTLOCK, 0, (int)ptr, lock2require,
951 core, BAMBOO_NUM_OF_CORE);
958 bool getwritelock(void * ptr) {
961 // for 32 bit machine, the size is always 5 words
965 if(((struct ___Object___ *)ptr)->lock == NULL) {
966 lock2require = lockobj;
968 lock2require = (int)(((struct ___Object___ *)ptr)->lock);
970 targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
978 BAMBOO_DEBUGPRINT(0xe551);
979 BAMBOO_DEBUGPRINT_REG(lockobj);
980 BAMBOO_DEBUGPRINT_REG(lock2require);
981 BAMBOO_DEBUGPRINT_REG(targetcore);
984 if(targetcore == BAMBOO_NUM_OF_CORE) {
985 // reside on this core
987 BAMBOO_START_CRITICAL_SECTION_LOCK();
989 BAMBOO_DEBUGPRINT(0xf001);
991 deny = processlockrequest(1, lock2require, (int)ptr, BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, false);
992 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
994 BAMBOO_DEBUGPRINT(0xf000);
997 BAMBOO_DEBUGPRINT(0xe555);
998 BAMBOO_DEBUGPRINT_REG(lockresult);
1004 if(lockobj == (int)ptr) {
1015 // conflicts on lockresults
1016 BAMBOO_EXIT(0xa01b);
1021 // send lock request msg
1022 // for 32 bit machine, the size is always 5 words
1023 send_msg_5(targetcore, LOCKREQUEST, 1, (int)ptr, lock2require,
1024 BAMBOO_NUM_OF_CORE);
1029 void releasewritelock(void * ptr) {
1032 if(((struct ___Object___ *)ptr)->lock == NULL) {
1033 reallock = (int)ptr;
1035 reallock = (int)(((struct ___Object___ *)ptr)->lock);
1037 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
1040 BAMBOO_DEBUGPRINT(0xe661);
1041 BAMBOO_DEBUGPRINT_REG((int)ptr);
1042 BAMBOO_DEBUGPRINT_REG(reallock);
1043 BAMBOO_DEBUGPRINT_REG(targetcore);
1046 if(targetcore == BAMBOO_NUM_OF_CORE) {
1047 BAMBOO_START_CRITICAL_SECTION_LOCK();
1049 BAMBOO_DEBUGPRINT(0xf001);
1051 // reside on this core
1052 if(!RuntimeHashcontainskey(locktbl, reallock)) {
1053 // no locks for this object, something is wrong
1054 BAMBOO_EXIT(0xa01c);
1057 struct LockValue * lockvalue = NULL;
1058 RuntimeHashget(locktbl, reallock, &rwlock_obj);
1059 lockvalue = (struct LockValue *)rwlock_obj;
1062 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
1064 BAMBOO_DEBUGPRINT(0xf000);
1068 // send lock release msg
1069 // for 32 bit machine, the size is always 4 words
1070 send_msg_4(targetcore, LOCKRELEASE, 1, (int)ptr, reallock);
1074 void releasewritelock_r(void * lock, void * redirectlock) {
1076 int reallock = (int)lock;
1077 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
1080 BAMBOO_DEBUGPRINT(0xe671);
1081 BAMBOO_DEBUGPRINT_REG((int)lock);
1082 BAMBOO_DEBUGPRINT_REG(reallock);
1083 BAMBOO_DEBUGPRINT_REG(targetcore);
1086 if(targetcore == BAMBOO_NUM_OF_CORE) {
1087 BAMBOO_START_CRITICAL_SECTION_LOCK();
1089 BAMBOO_DEBUGPRINT(0xf001);
1091 // reside on this core
1092 if(!RuntimeHashcontainskey(locktbl, reallock)) {
1093 // no locks for this object, something is wrong
1094 BAMBOO_EXIT(0xa01d);
1097 struct LockValue * lockvalue = NULL;
1099 BAMBOO_DEBUGPRINT(0xe672);
1101 RuntimeHashget(locktbl, reallock, &rwlock_obj);
1102 lockvalue = (struct LockValue *)rwlock_obj;
1104 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1107 lockvalue->redirectlock = (int)redirectlock;
1109 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1112 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
1114 BAMBOO_DEBUGPRINT(0xf000);
1118 // send lock release with redirect info msg
1119 // for 32 bit machine, the size is always 4 words
1120 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock, (int)redirectlock);
1124 bool getwritelock_I(void * ptr) {
1127 if(((struct ___Object___ *)ptr)->lock == NULL) {
1128 lock2require = lockobj;
1130 lock2require = (int)(((struct ___Object___ *)ptr)->lock);
1132 targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
1140 BAMBOO_DEBUGPRINT(0xe561);
1141 BAMBOO_DEBUGPRINT_REG(lockobj);
1142 BAMBOO_DEBUGPRINT_REG(lock2require);
1143 BAMBOO_DEBUGPRINT_REG(targetcore);
1146 if(targetcore == BAMBOO_NUM_OF_CORE) {
1147 // reside on this core
1148 int deny = processlockrequest(1, (int)lock2require, (int)ptr, BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, false);
1153 if(lockobj == (int)ptr) {
1157 BAMBOO_DEBUGPRINT(0);
1162 BAMBOO_DEBUGPRINT(1);
1170 // conflicts on lockresults
1171 BAMBOO_EXIT(0xa01e);
1176 // send lock request msg
1177 // for 32 bit machine, the size is always 5 words
1178 send_msg_5(targetcore, LOCKREQUEST, 1, (int)ptr, lock2require,
1179 BAMBOO_NUM_OF_CORE);
1184 // redirected lock request
1185 bool getwritelock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
1188 if(core == BAMBOO_NUM_OF_CORE) {
1190 lock2require = (int)redirectlock;
1197 targetcore = ((int)redirectlock >> 5) % BAMBOO_TOTALCORE;
1200 BAMBOO_DEBUGPRINT(0xe571);
1201 BAMBOO_DEBUGPRINT_REG((int)ptr);
1202 BAMBOO_DEBUGPRINT_REG((int)redirectlock);
1203 BAMBOO_DEBUGPRINT_REG(core);
1204 BAMBOO_DEBUGPRINT_REG((int)cache);
1205 BAMBOO_DEBUGPRINT_REG(targetcore);
1209 if(targetcore == BAMBOO_NUM_OF_CORE) {
1210 // reside on this core
1211 int deny = processlockrequest(1, (int)redirectlock, (int)ptr, BAMBOO_NUM_OF_CORE, core, cache);
1216 if(core == BAMBOO_NUM_OF_CORE) {
1217 if(lockobj == (int)ptr) {
1222 RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
1229 // conflicts on lockresults
1230 BAMBOO_EXIT(0xa01f);
1234 // send lock grant/deny request to the root requiring core
1235 // check if there is still some msg on sending
1236 if((!cache) || (cache && !isMsgSending)) {
1237 send_msg_4(core, deny==1?REDIRECTDENY:REDIRECTGROUNT, 1,
1238 (int)ptr, (int)redirectlock);
1240 cache_msg_4(core, deny==1?REDIRECTDENY:REDIRECTGROUNT, 1,
1241 (int)ptr, (int)redirectlock);
1246 // redirect the lock request
1247 // for 32 bit machine, the size is always 6 words
1248 if((!cache) || (cache && !isMsgSending)) {
1249 send_msg_6(targetcore, REDIRECTLOCK, 1, (int)ptr, (int)redirectlock,
1250 core, BAMBOO_NUM_OF_CORE);
1252 cache_msg_6(targetcore, REDIRECTLOCK, 1, (int)ptr, (int)redirectlock,
1253 core, BAMBOO_NUM_OF_CORE);
1259 void releasewritelock_I(void * ptr) {
1262 if(((struct ___Object___ *)ptr)->lock == NULL) {
1263 reallock = (int)ptr;
1265 reallock = (int)(((struct ___Object___ *)ptr)->lock);
1267 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
1270 BAMBOO_DEBUGPRINT(0xe681);
1271 BAMBOO_DEBUGPRINT_REG((int)ptr);
1272 BAMBOO_DEBUGPRINT_REG(reallock);
1273 BAMBOO_DEBUGPRINT_REG(targetcore);
1276 if(targetcore == BAMBOO_NUM_OF_CORE) {
1277 // reside on this core
1278 if(!RuntimeHashcontainskey(locktbl, reallock)) {
1279 // no locks for this object, something is wrong
1280 BAMBOO_EXIT(0xa020);
1283 struct LockValue * lockvalue = NULL;
1284 RuntimeHashget(locktbl, reallock, &rwlock_obj);
1285 lockvalue = (struct LockValue *)rwlock_obj;
1290 // send lock release msg
1291 // for 32 bit machine, the size is always 4 words
1292 send_msg_4(targetcore, LOCKRELEASE, 1, (int)ptr, reallock);
1296 void releasewritelock_I_r(void * lock, void * redirectlock) {
1298 int reallock = (int)lock;
1299 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
1302 BAMBOO_DEBUGPRINT(0xe691);
1303 BAMBOO_DEBUGPRINT_REG((int)lock);
1304 BAMBOO_DEBUGPRINT_REG(reallock);
1305 BAMBOO_DEBUGPRINT_REG(targetcore);
1308 if(targetcore == BAMBOO_NUM_OF_CORE) {
1309 // reside on this core
1310 if(!RuntimeHashcontainskey(locktbl, reallock)) {
1311 // no locks for this object, something is wrong
1312 BAMBOO_EXIT(0xa021);
1315 struct LockValue * lockvalue = NULL;
1317 BAMBOO_DEBUGPRINT(0xe692);
1319 RuntimeHashget(locktbl, reallock, &rwlock_obj);
1320 lockvalue = (struct LockValue *)rwlock_obj;
1322 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1325 lockvalue->redirectlock = (int)redirectlock;
1327 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1332 // send lock release msg
1333 // for 32 bit machine, the size is always 4 words
1334 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock, (int)redirectlock);
1338 /* this function is to process lock requests.
1339 * can only be invoked in receiveObject() */
1340 // if return -1: the lock request is redirected
1341 // 0: the lock request is approved
1342 // 1: the lock request is denied
1343 __attribute__((always_inline)) int processlockrequest(int locktype, int lock, int obj, int requestcore, int rootrequestcore, bool cache) {
1345 if( ((lock >> 5) % BAMBOO_TOTALCORE) != BAMBOO_NUM_OF_CORE ) {
1346 // the lock should not be on this core
1348 BAMBOO_DEBUGPRINT_REG(requestcore);
1349 BAMBOO_DEBUGPRINT_REG(lock);
1350 BAMBOO_DEBUGPRINT_REG(BAMBOO_NUM_OF_CORE);
1352 BAMBOO_EXIT(0xa017);
1354 if(!RuntimeHashcontainskey(locktbl, lock)) {
1355 // no locks for this object
1356 // first time to operate on this shared object
1357 // create a lock for it
1358 // the lock is an integer: 0 -- stall, >0 -- read lock, -1 -- write lock
1359 struct LockValue * lockvalue = (struct LockValue *)(RUNMALLOC_I(sizeof(struct LockValue)));
1360 lockvalue->redirectlock = 0;
1363 BAMBOO_DEBUGPRINT(0xe110);
1367 lockvalue->value = 1;
1369 lockvalue->value = -1;
1371 RuntimeHashadd_I(locktbl, lock, (int)lockvalue);
1374 struct LockValue * lockvalue = NULL;
1377 BAMBOO_DEBUGPRINT(0xe111);
1380 RuntimeHashget(locktbl, lock, &rwlock_obj);
1381 lockvalue = (struct LockValue *)(rwlock_obj);
1384 BAMBOO_DEBUGPRINT_REG(lockvalue->redirectlock);
1387 if(lockvalue->redirectlock != 0) {
1388 // this lock is redirected
1391 BAMBOO_DEBUGPRINT(0xe112);
1395 getreadlock_I_r((void *)obj, (void *)lockvalue->redirectlock, rootrequestcore, cache);
1397 getwritelock_I_r((void *)obj, (void *)lockvalue->redirectlock, rootrequestcore, cache);
1399 return -1; // redirected
1403 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1406 if(0 == lockvalue->value) {
1408 lockvalue->value = 1;
1410 lockvalue->value = -1;
1412 } else if((lockvalue->value > 0) && (locktype == 0)) {
1413 // read lock request and there are only read locks
1420 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1428 __attribute__((always_inline)) void processlockrelease(int locktype, int lock, int redirectlock, bool isredirect) {
1429 if(!RuntimeHashcontainskey(locktbl, lock)) {
1430 // no locks for this object, something is wrong
1432 BAMBOO_DEBUGPRINT_REG(lock);
1434 BAMBOO_EXIT(0xa00b);
1437 struct LockValue * lockvalue = NULL;
1438 RuntimeHashget(locktbl, lock, &rwlock_obj);
1439 lockvalue = (struct LockValue*)(rwlock_obj);
1441 BAMBOO_DEBUGPRINT(0xe884);
1442 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1450 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1453 lockvalue->redirectlock = redirectlock;
1459 __attribute__((always_inline)) inline void profileTaskStart(char * taskname) {
1460 if(!taskInfoOverflow) {
1461 TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
1462 taskInfoArray[taskInfoIndex] = taskInfo;
1463 taskInfo->taskName = taskname;
1464 taskInfo->startTime = raw_get_cycle();
1465 taskInfo->endTime = -1;
1466 taskInfo->exitIndex = -1;
1467 taskInfo->newObjs = NULL;
1471 __attribute__((always_inline)) inline void profileTaskEnd() {
1472 if(!taskInfoOverflow) {
1473 taskInfoArray[taskInfoIndex]->endTime = raw_get_cycle();
1475 if(taskInfoIndex == TASKINFOLENGTH) {
1476 taskInfoOverflow = true;
1481 // output the profiling data
1482 void outputProfileData() {
1489 int totaltasktime = 0;
1490 int preprocessingtime = 0;
1491 int objqueuecheckingtime = 0;
1492 int postprocessingtime = 0;
1493 //int interruptiontime = 0;
1495 int averagetasktime = 0;
1498 for(i = 0; i < 50; i++) {
1502 calCoords(corenum, &self_y, &self_x);
1503 c_y = (char)self_y + '0';
1504 c_x = (char)self_x + '0';
1505 strcat(fn, "profile_");
1511 if((fp = fopen(fn, "w+")) == NULL) {
1512 fprintf(stderr, "fopen error\n");
1516 fprintf(fp, "Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
1517 // output task related info
1518 for(i = 0; i < taskInfoIndex; i++) {
1519 TaskInfo* tmpTInfo = taskInfoArray[i];
1520 int duration = tmpTInfo->endTime - tmpTInfo->startTime;
1521 fprintf(fp, "%s, %d, %d, %d, %d", tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime, duration, tmpTInfo->exitIndex);
1522 // summarize new obj info
1523 if(tmpTInfo->newObjs != NULL) {
1524 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
1525 struct RuntimeIterator * iter = NULL;
1526 while(0 == isEmpty(tmpTInfo->newObjs)) {
1527 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
1528 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
1530 RuntimeHashget(nobjtbl, (int)objtype, &num);
1531 RuntimeHashremovekey(nobjtbl, (int)objtype);
1533 RuntimeHashadd(nobjtbl, (int)objtype, num);
1535 RuntimeHashadd(nobjtbl, (int)objtype, 1);
1537 //fprintf(stderr, "new obj!\n");
1540 // output all new obj info
1541 iter = RuntimeHashcreateiterator(nobjtbl);
1542 while(RunhasNext(iter)) {
1543 char * objtype = (char *)Runkey(iter);
1544 int num = Runnext(iter);
1545 fprintf(fp, ", %s, %d", objtype, num);
1549 if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
1550 preprocessingtime += duration;
1551 } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
1552 postprocessingtime += duration;
1553 } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
1554 objqueuecheckingtime += duration;
1556 totaltasktime += duration;
1557 averagetasktime += duration;
1562 if(taskInfoOverflow) {
1563 fprintf(stderr, "Caution: task info overflow!\n");
1566 other = totalexetime - totaltasktime - preprocessingtime - postprocessingtime;
1567 averagetasktime /= tasknum;
1569 fprintf(fp, "\nTotal time: %d\n", totalexetime);
1570 fprintf(fp, "Total task execution time: %d (%f%%)\n", totaltasktime, ((double)totaltasktime/(double)totalexetime)*100);
1571 fprintf(fp, "Total objqueue checking time: %d (%f%%)\n", objqueuecheckingtime, ((double)objqueuecheckingtime/(double)totalexetime)*100);
1572 fprintf(fp, "Total pre-processing time: %d (%f%%)\n", preprocessingtime, ((double)preprocessingtime/(double)totalexetime)*100);
1573 fprintf(fp, "Total post-processing time: %d (%f%%)\n", postprocessingtime, ((double)postprocessingtime/(double)totalexetime)*100);
1574 fprintf(fp, "Other time: %d (%f%%)\n", other, ((double)other/(double)totalexetime)*100);
1576 fprintf(fp, "\nAverage task execution time: %d\n", averagetasktime);
1583 BAMBOO_DEBUGPRINT(0xdddd);
1584 // output task related info
1585 for(i= 0; i < taskInfoIndex; i++) {
1586 TaskInfo* tmpTInfo = taskInfoArray[i];
1587 char* tmpName = tmpTInfo->taskName;
1588 int nameLen = strlen(tmpName);
1589 BAMBOO_DEBUGPRINT(0xddda);
1590 for(j = 0; j < nameLen; j++) {
1591 BAMBOO_DEBUGPRINT_REG(tmpName[j]);
1593 BAMBOO_DEBUGPRINT(0xdddb);
1594 BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
1595 BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
1596 BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
1597 if(tmpTInfo->newObjs != NULL) {
1598 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
1599 struct RuntimeIterator * iter = NULL;
1600 while(0 == isEmpty(tmpTInfo->newObjs)) {
1601 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
1602 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
1604 RuntimeHashget(nobjtbl, (int)objtype, &num);
1605 RuntimeHashremovekey(nobjtbl, (int)objtype);
1607 RuntimeHashadd(nobjtbl, (int)objtype, num);
1609 RuntimeHashadd(nobjtbl, (int)objtype, 1);
1613 // ouput all new obj info
1614 iter = RuntimeHashcreateiterator(nobjtbl);
1615 while(RunhasNext(iter)) {
1616 char * objtype = (char *)Runkey(iter);
1617 int num = Runnext(iter);
1618 int nameLen = strlen(objtype);
1619 BAMBOO_DEBUGPRINT(0xddda);
1620 for(j = 0; j < nameLen; j++) {
1621 BAMBOO_DEBUGPRINT_REG(objtype[j]);
1623 BAMBOO_DEBUGPRINT(0xdddb);
1624 BAMBOO_DEBUGPRINT_REG(num);
1627 BAMBOO_DEBUGPRINT(0xdddc);
1630 if(taskInfoOverflow) {
1631 BAMBOO_DEBUGPRINT(0xefee);
1634 // output interrupt related info
1635 /*for(i = 0; i < interruptInfoIndex; i++) {
1636 InterruptInfo* tmpIInfo = interruptInfoArray[i];
1637 BAMBOO_DEBUGPRINT(0xddde);
1638 BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
1639 BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
1640 BAMBOO_DEBUGPRINT(0xdddf);
1643 if(interruptInfoOverflow) {
1644 BAMBOO_DEBUGPRINT(0xefef);
1647 BAMBOO_DEBUGPRINT(0xeeee);
1650 #endif // #ifdef PROFILE
1652 #endif // #ifdef TASK