finish most parts, need to fix large objs handling and memory allocation(add free...
[IRC.git] / Robust / src / Runtime / RAW / task_arch.c
1 #ifdef TASK
2 #include "runtime.h"
3 #include "multicoreruntime.h"
4 #include "runtime_arch.h"
5
6 __attribute__((always_inline)) inline void initialization() {
7 } // initialization()
8
9 __attribute__((always_inline)) inline void initCommunication() {
10 #ifdef INTERRUPT
11   if (corenum < NUMCORES) {
12     // set up interrupts
13     setup_ints();
14     raw_user_interrupts_on();
15   }
16 #endif
17 }
18
19 __attribute__((always_inline)) inline void fakeExecution()  {
20   // handle communications
21   while(true) {
22           receiveObject();
23   }
24 }
25
26 #ifdef USEIO
27 int main(void) {
28 #else
29 void begin() {
30 #endif // #ifdef USEIO
31   run(NULL);
32 }
33
34 __attribute__((always_inline)) inline void terminate()  {
35         raw_test_done(1);
36 }
37
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();
42
43 // transfer an object to targetcore
44 // format: object
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;  
49
50   unsigned msgHdr;
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;
54   int i = 0;
55
56   struct ___Object___ * newobj = (struct ___Object___ *)obj;
57
58   calCoords(corenum, &self_x, &self_y);
59   calCoords(targetcore, &target_x, &target_y);
60   isMsgSending = true;
61   // Build the message header
62   msgHdr = construct_dyn_hdr(0, msgsize, 0,             // msgsize word sent.
63                              self_y, self_x,
64                              target_y, target_x);
65   // start sending msg, set sand msg flag
66   gdn_send(msgHdr);                     
67 #ifdef DEBUG
68   BAMBOO_DEBUGPRINT(0xbbbb);
69   BAMBOO_DEBUGPRINT(0xb000 + targetcore);       // targetcore
70 #endif
71   gdn_send(0);
72 #ifdef DEBUG
73   BAMBOO_DEBUGPRINT(0);
74 #endif
75   gdn_send(msgsize);
76 #ifdef DEBUG
77   BAMBOO_DEBUGPRINT_REG(msgsize);
78 #endif
79   gdn_send((int)obj);
80 #ifdef DEBUG
81   BAMBOO_DEBUGPRINT_REG(obj);
82 #endif
83   for(i = 0; i < transObj->length; ++i) {
84     int taskindex = transObj->queues[2*i];
85     int paramindex = transObj->queues[2*i+1];
86     gdn_send(taskindex);
87 #ifdef DEBUG
88     BAMBOO_DEBUGPRINT_REG(taskindex);
89 #endif
90     gdn_send(paramindex);
91 #ifdef DEBUG
92     BAMBOO_DEBUGPRINT_REG(paramindex);
93 #endif
94   }
95 #ifdef DEBUG
96   BAMBOO_DEBUGPRINT(0xffff);
97 #endif
98   // end of sending this msg, set sand msg flag false
99   isMsgSending = 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
109           isMsgSending = true;
110           // Build the message header
111           msgHdr = construct_dyn_hdr(0, outmsgleft, 0,                        // msgsize word sent.
112                                  self_y, self_x,
113                                  target_y, target_x);
114           gdn_send(msgHdr);                           
115 #ifdef DEBUG
116           BAMBOO_DEBUGPRINT(0xbbbb);
117           BAMBOO_DEBUGPRINT(0xb000 + target);             // targetcore
118 #endif
119           while(outmsgleft-- > 0) {
120                   gdn_send(outmsgdata[outmsgindex++]);
121 #ifdef DEBUG
122                   BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
123 #endif
124           }
125 #ifdef DEBUG
126           BAMBOO_DEBUGPRINT(0xffff);
127 #endif
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) {
133                   // no more msgs
134                   outmsgindex = outmsglast = 0;
135                   isMsgHanging = false;
136           }
137           BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
138   }
139 }
140
141 __attribute__((always_inline)) inline void send_msg_1 (int targetcore, 
142                                                                    int n0) {
143   // send this msg
144   unsigned msgHdr;
145   int self_y, self_x, target_y, target_x;
146   msglength = 1;
147
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);
151
152   // mark to start sending the msg
153   isMsgSending = true;
154   // Build the message header
155   msgHdr = construct_dyn_hdr(0, msglength, 0,             // msgsize word sent.
156                              self_y, self_x,
157                              target_y, target_x);
158   gdn_send(msgHdr);                     // Send the message header
159 #ifdef DEBUG
160   BAMBOO_DEBUGPRINT(0xbbbb);
161   BAMBOO_DEBUGPRINT(0xb000 + targetcore);       // targetcore
162 #endif
163   gdn_send(n0);
164 #ifdef DEBUG
165   BAMBOO_DEBUGPRINT(n0);
166   BAMBOO_DEBUGPRINT(0xffff);
167 #endif
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
178           isMsgSending = true;
179           // Build the message header
180           msgHdr = construct_dyn_hdr(0, outmsgleft, 0,                        // msgsize word sent.
181                                  self_y, self_x,
182                                  target_y, target_x);
183           gdn_send(msgHdr);                           
184 #ifdef DEBUG
185           BAMBOO_DEBUGPRINT(0xbbbb);
186           BAMBOO_DEBUGPRINT(0xb000 + target);             // targetcore
187 #endif
188           while(outmsgleft-- > 0) {
189                   gdn_send(outmsgdata[outmsgindex++]);
190 #ifdef DEBUG
191                   BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
192 #endif
193           }
194 #ifdef DEBUG
195           BAMBOO_DEBUGPRINT(0xffff);
196 #endif
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) {
202                   // no more msgs
203                   outmsgindex = outmsglast = 0;
204                   isMsgHanging = false;
205           }
206           BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
207   }
208 }
209
210 __attribute__((always_inline)) inline void send_msg_2 (int targetcore, 
211                                                                    int n0, 
212                                                                                                                                                                                                                          int n1) {
213   // send this msg
214   unsigned msgHdr;
215   int self_y, self_x, target_y, target_x;
216   msglength = 2;
217
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);
221
222   // mark to start sending the msg
223   isMsgSending = true;
224   // Build the message header
225   msgHdr = construct_dyn_hdr(0, msglength, 0,             // msgsize word sent.
226                              self_y, self_x,
227                              target_y, target_x);
228   gdn_send(msgHdr);                     // Send the message header
229 #ifdef DEBUG
230   BAMBOO_DEBUGPRINT(0xbbbb);
231   BAMBOO_DEBUGPRINT(0xb000 + targetcore);       // targetcore
232 #endif
233   gdn_send(n0);
234 #ifdef DEBUG
235   BAMBOO_DEBUGPRINT(n0);
236 #endif
237   gdn_send(n1);
238 #ifdef DEBUG
239   BAMBOO_DEBUGPRINT(n1);
240   BAMBOO_DEBUGPRINT(0xffff);
241 #endif
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
252           isMsgSending = true;
253           // Build the message header
254           msgHdr = construct_dyn_hdr(0, outmsgleft, 0,                        // msgsize word sent.
255                                  self_y, self_x,
256                                  target_y, target_x);
257           gdn_send(msgHdr);                           
258 #ifdef DEBUG
259           BAMBOO_DEBUGPRINT(0xbbbb);
260           BAMBOO_DEBUGPRINT(0xb000 + target);             // targetcore
261 #endif
262           while(outmsgleft-- > 0) {
263                   gdn_send(outmsgdata[outmsgindex++]);
264 #ifdef DEBUG
265                   BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
266 #endif
267           }
268 #ifdef DEBUG
269           BAMBOO_DEBUGPRINT(0xffff);
270 #endif
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) {
276                   // no more msgs
277                   outmsgindex = outmsglast = 0;
278                   isMsgHanging = false;
279           }
280           BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
281   }
282 }
283
284 __attribute__((always_inline)) inline void send_msg_3 (int targetcore, 
285                                                                    int n0, 
286                                                                                                                                                                                                                          int n1, 
287                                                                                                                                                                                                                          int n2) {
288   // send this msg
289   unsigned msgHdr;
290   int self_y, self_x, target_y, target_x;
291   msglength = 3;
292
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);
296
297   // mark to start sending the msg
298   isMsgSending = true;
299   // Build the message header
300   msgHdr = construct_dyn_hdr(0, msglength, 0,             // msgsize word sent.
301                              self_y, self_x,
302                              target_y, target_x);
303   gdn_send(msgHdr);                     // Send the message header
304 #ifdef DEBUG
305   BAMBOO_DEBUGPRINT(0xbbbb);
306   BAMBOO_DEBUGPRINT(0xb000 + targetcore);       // targetcore
307 #endif
308   gdn_send(n0);
309 #ifdef DEBUG
310   BAMBOO_DEBUGPRINT(n0);
311 #endif
312   gdn_send(n1);
313 #ifdef DEBUG
314   BAMBOO_DEBUGPRINT(n1);
315 #endif
316   gdn_send(n2);
317 #ifdef DEBUG
318   BAMBOO_DEBUGPRINT(n2);
319   BAMBOO_DEBUGPRINT(0xffff);
320 #endif
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
331           isMsgSending = true;
332           // Build the message header
333           msgHdr = construct_dyn_hdr(0, outmsgleft, 0,                        // msgsize word sent.
334                                  self_y, self_x,
335                                  target_y, target_x);
336           gdn_send(msgHdr);                           
337 #ifdef DEBUG
338           BAMBOO_DEBUGPRINT(0xbbbb);
339           BAMBOO_DEBUGPRINT(0xb000 + target);             // targetcore
340 #endif
341           while(outmsgleft-- > 0) {
342                   gdn_send(outmsgdata[outmsgindex++]);
343 #ifdef DEBUG
344                   BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
345 #endif
346           }
347 #ifdef DEBUG
348           BAMBOO_DEBUGPRINT(0xffff);
349 #endif
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) {
355                   // no more msgs
356                   outmsgindex = outmsglast = 0;
357                   isMsgHanging = false;
358           }
359           BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
360   }
361 }
362
363 __attribute__((always_inline)) inline void send_msg_4 (int targetcore, 
364                                                                    int n0, 
365                                                                                                                                                                                                                          int n1, 
366                                                                                                                                                                                                                          int n2, 
367                                                                                                                                                                                                                          int n3) {
368   // send this msg
369   unsigned msgHdr;
370   int self_y, self_x, target_y, target_x;
371   msglength = 4;
372
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);
376
377   // mark to start sending the msg
378   isMsgSending = true;
379   // Build the message header
380   msgHdr = construct_dyn_hdr(0, msglength, 0,             // msgsize word sent.
381                              self_y, self_x,
382                              target_y, target_x);
383   gdn_send(msgHdr);                     // Send the message header
384 #ifdef DEBUG
385   BAMBOO_DEBUGPRINT(0xbbbb);
386   BAMBOO_DEBUGPRINT(0xb000 + targetcore);       // targetcore
387 #endif
388   gdn_send(n0);
389 #ifdef DEBUG
390   BAMBOO_DEBUGPRINT(n0);
391 #endif
392   gdn_send(n1);
393 #ifdef DEBUG
394   BAMBOO_DEBUGPRINT(n1);
395 #endif
396   gdn_send(n2);
397 #ifdef DEBUG
398   BAMBOO_DEBUGPRINT(n2);
399 #endif
400   gdn_send(n3);
401 #ifdef DEBUG
402   BAMBOO_DEBUGPRINT(n3);
403   BAMBOO_DEBUGPRINT(0xffff);
404 #endif
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
415           isMsgSending = true;
416           // Build the message header
417           msgHdr = construct_dyn_hdr(0, outmsgleft, 0,                        // msgsize word sent.
418                                  self_y, self_x,
419                                  target_y, target_x);
420           gdn_send(msgHdr);                           
421 #ifdef DEBUG
422           BAMBOO_DEBUGPRINT(0xbbbb);
423           BAMBOO_DEBUGPRINT(0xb000 + target);             // targetcore
424 #endif
425           while(outmsgleft-- > 0) {
426                   gdn_send(outmsgdata[outmsgindex++]);
427 #ifdef DEBUG
428                   BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
429 #endif
430           }
431 #ifdef DEBUG
432           BAMBOO_DEBUGPRINT(0xffff);
433 #endif
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) {
439                   // no more msgs
440                   outmsgindex = outmsglast = 0;
441                   isMsgHanging = false;
442           }
443           BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
444   }
445 }
446
447 __attribute__((always_inline)) inline void send_msg_5 (int targetcore, 
448                                                                    int n0, 
449                                                                                                                                                                                                                          int n1, 
450                                                                                                                                                                                                                          int n2, 
451                                                                                                                                                                                                                          int n3, 
452                                                                                                                                                                                                                          int n4) {
453   // send this msg
454   unsigned msgHdr;
455   int self_y, self_x, target_y, target_x;
456   msglength = 5;
457
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);
461
462   // mark to start sending the msg
463   isMsgSending = true;
464   // Build the message header
465   msgHdr = construct_dyn_hdr(0, msglength, 0,             // msgsize word sent.
466                              self_y, self_x,
467                              target_y, target_x);
468   gdn_send(msgHdr);                     // Send the message header
469 #ifdef DEBUG
470   BAMBOO_DEBUGPRINT(0xbbbb);
471   BAMBOO_DEBUGPRINT(0xb000 + targetcore);       // targetcore
472 #endif
473   gdn_send(n0);
474 #ifdef DEBUG
475   BAMBOO_DEBUGPRINT(n0);
476 #endif
477   gdn_send(n1);
478 #ifdef DEBUG
479   BAMBOO_DEBUGPRINT(n1);
480 #endif
481   gdn_send(n2);
482 #ifdef DEBUG
483   BAMBOO_DEBUGPRINT(n2);
484 #endif
485   gdn_send(n3);
486 #ifdef DEBUG
487   BAMBOO_DEBUGPRINT(n3);
488 #endif
489   gdn_send(n4);
490 #ifdef DEBUG
491   BAMBOO_DEBUGPRINT(n4);
492   BAMBOO_DEBUGPRINT(0xffff);
493 #endif
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
504           isMsgSending = true;
505           // Build the message header
506           msgHdr = construct_dyn_hdr(0, outmsgleft, 0,                        // msgsize word sent.
507                                  self_y, self_x,
508                                  target_y, target_x);
509           gdn_send(msgHdr);                           
510 #ifdef DEBUG
511           BAMBOO_DEBUGPRINT(0xbbbb);
512           BAMBOO_DEBUGPRINT(0xb000 + target);             // targetcore
513 #endif
514           while(outmsgleft-- > 0) {
515                   gdn_send(outmsgdata[outmsgindex++]);
516 #ifdef DEBUG
517                   BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
518 #endif
519           }
520 #ifdef DEBUG
521           BAMBOO_DEBUGPRINT(0xffff);
522 #endif
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) {
528                   // no more msgs
529                   outmsgindex = outmsglast = 0;
530                   isMsgHanging = false;
531           }
532           BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
533   }
534 }
535
536 __attribute__((always_inline)) inline void send_msg_6 (int targetcore, 
537                                                                    int n0, 
538                                                                                                                                                                                                                          int n1, 
539                                                                                                                                                                                                                          int n2, 
540                                                                                                                                                                                                                          int n3, 
541                                                                                                                                                                                                                          int n4, 
542                                                                                                                                                                                                                          int n5) {
543   // send this msg
544   unsigned msgHdr;
545   int self_y, self_x, target_y, target_x;
546   msglength = 6;
547
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);
551
552   // mark to start sending the msg
553   isMsgSending = true;
554   // Build the message header
555   msgHdr = construct_dyn_hdr(0, msglength, 0,             // msgsize word sent.
556                              self_y, self_x,
557                              target_y, target_x);
558   gdn_send(msgHdr);                     // Send the message header
559 #ifdef DEBUG
560   BAMBOO_DEBUGPRINT(0xbbbb);
561   BAMBOO_DEBUGPRINT(0xb000 + targetcore);       // targetcore
562 #endif
563   gdn_send(n0);
564 #ifdef DEBUG
565   BAMBOO_DEBUGPRINT(n0);
566 #endif
567   gdn_send(n1);
568 #ifdef DEBUG
569   BAMBOO_DEBUGPRINT(n1);
570 #endif
571   gdn_send(n2);
572 #ifdef DEBUG
573   BAMBOO_DEBUGPRINT(n2);
574 #endif
575   gdn_send(n3);
576 #ifdef DEBUG
577   BAMBOO_DEBUGPRINT(n3);
578 #endif
579   gdn_send(n4);
580 #ifdef DEBUG
581   BAMBOO_DEBUGPRINT(n4);
582 #endif
583   gdn_send(n5);
584 #ifdef DEBUG
585   BAMBOO_DEBUGPRINT(n5);
586   BAMBOO_DEBUGPRINT(0xffff);
587 #endif
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
598           isMsgSending = true;
599           // Build the message header
600           msgHdr = construct_dyn_hdr(0, outmsgleft, 0,                        // msgsize word sent.
601                                  self_y, self_x,
602                                  target_y, target_x);
603           gdn_send(msgHdr);                           
604 #ifdef DEBUG
605           BAMBOO_DEBUGPRINT(0xbbbb);
606           BAMBOO_DEBUGPRINT(0xb000 + target);             // targetcore
607 #endif
608           while(outmsgleft-- > 0) {
609                   gdn_send(outmsgdata[outmsgindex++]);
610 #ifdef DEBUG
611                   BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
612 #endif
613           }
614 #ifdef DEBUG
615           BAMBOO_DEBUGPRINT(0xffff);
616 #endif
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) {
622                   // no more msgs
623                   outmsgindex = outmsglast = 0;
624                   isMsgHanging = false;
625           }
626           BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
627   }
628 }
629
630 __attribute__((always_inline)) inline void cache_msg_2 (int targetcore, 
631                                                                     int n0, 
632                                                                                                                                                                                                                                 int n1) {
633   // cache this msg
634 #ifdef DEBUG
635   BAMBOO_DEBUGPRINT(0xdede);
636 #endif
637   isMsgHanging = true;
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;
644 }
645
646 __attribute__((always_inline)) inline void cache_msg_3 (int targetcore, 
647                                                                     int n0, 
648                                                                                                                                                                                                                                 int n1, 
649                                                                                                                                                                                                                                 int n2) {
650   // cache this msg
651 #ifdef DEBUG
652   BAMBOO_DEBUGPRINT(0xdede);
653 #endif
654   isMsgHanging = true;
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;
662 }
663
664 __attribute__((always_inline)) inline void cache_msg_4 (int targetcore, 
665                                                                     int n0, 
666                                                                                                                                                                                                                                 int n1, 
667                                                                                                                                                                                                                                 int n2, 
668                                                                                                                                                                                                                                 int n3) {
669   // cache this msg
670 #ifdef DEBUG
671   BAMBOO_DEBUGPRINT(0xdede);
672 #endif
673   isMsgHanging = true;
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;
682 }
683
684 __attribute__((always_inline)) inline void cache_msg_5 (int targetcore, 
685                                                                     int n0, 
686                                                                                                                                                                                                                                 int n1, 
687                                                                                                                                                                                                                                 int n2, 
688                                                                                                                                                                                                                                 int n3, 
689                                                                                                                                                                                                                                 int n4) {
690   // cache this msg
691 #ifdef DEBUG
692   BAMBOO_DEBUGPRINT(0xdede);
693 #endif
694   isMsgHanging = true;
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;
704 }
705
706
707 __attribute__((always_inline)) inline void cache_msg_6 (int targetcore, 
708                                                                     int n0, 
709                                                                                                                                                                                                                                 int n1, 
710                                                                                                                                                                                                                                 int n2, 
711                                                                                                                                                                                                                                 int n3, 
712                                                                                                                                                                                                                                 int n4, 
713                                                                                                                                                                                                                                 int n5) {
714   // cache this msg
715 #ifdef DEBUG
716   BAMBOO_DEBUGPRINT(0xdede);
717 #endif
718   isMsgHanging = true;
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;
729 }
730
731 __attribute__((always_inline)) inline int receiveMsg() {
732   if(gdn_input_avail() == 0) {
733 #ifdef DEBUG
734     if(corenum < NUMCORES) {
735       BAMBOO_DEBUGPRINT(0xd001);
736     }
737 #endif
738     return -1;
739   }
740 #ifdef PROFILE
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;
746      }*/
747 #endif
748 #ifdef DEBUG
749   BAMBOO_DEBUGPRINT(0xcccc);
750 #endif
751   while((gdn_input_avail() != 0) && (msgdataindex < msglength)) {
752     msgdata[msgdataindex] = gdn_receive();
753     if(msgdataindex == 0) {
754                 if(msgdata[0] > 0xc) {
755                         msglength = 3;
756                 } else if (msgdata[0] == 0xc) {
757                         msglength = 1;
758                 } else if(msgdata[0] > 8) {
759                         msglength = 4;
760                 } else if(msgdata[0] == 8) {
761                         msglength = 6;
762                 } else if(msgdata[0] > 5) {
763                         msglength = 2;
764                 } else if (msgdata[0] > 2) {
765                         msglength = 4;
766                 } else if (msgdata[0] == 2) {
767                         msglength = 5;
768                 } else if (msgdata[0] > 0) {
769                         msglength = 4;
770                 }
771     } else if((msgdataindex == 1) && (msgdata[0] == 0)) {
772       msglength = msgdata[msgdataindex];
773     }
774 #ifdef DEBUG
775     BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
776 #endif
777     msgdataindex++;
778   }
779 #ifdef DEBUG
780   BAMBOO_DEBUGPRINT(0xffff);
781 #endif
782   return msgdataindex;
783 }
784
785 bool getreadlock(void * ptr) {
786   int targetcore = 0;
787   lockobj = (int)ptr;
788   if(((struct ___Object___ *)ptr)->lock == NULL) {
789         lock2require = lockobj;
790   } else {
791         lock2require = (int)(((struct ___Object___ *)ptr)->lock);
792   }
793   targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
794   lockflag = false;
795 #ifndef INTERRUPT
796   reside = false;
797 #endif
798   lockresult = 0;
799
800   if(targetcore == BAMBOO_NUM_OF_CORE) {
801     // reside on this core
802     int deny = 0;
803         BAMBOO_START_CRITICAL_SECTION_LOCK();
804 #ifdef DEBUG
805         BAMBOO_DEBUGPRINT(0xf001);
806 #endif
807         deny = processlockrequest(0, lock2require, (int)ptr, BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, false);
808         BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
809 #ifdef DEBUG
810         BAMBOO_DEBUGPRINT(0xf000);
811 #endif
812     if(deny == -1) {
813                 // redirected
814                 return true;
815         } else {
816                 if(lockobj == (int)ptr) {
817                         if(deny) {
818                                 lockresult = 0;
819                         } else {
820                                 lockresult = 1;
821                         }
822                         lockflag = true;
823 #ifndef INTERRUPT
824                         reside = true;
825 #endif
826                 } else {
827                         // conflicts on lockresults
828                         BAMBOO_EXIT(0xa018);
829                 }
830         }
831     return true;
832   } else {
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);
837   }
838   return true;
839 }
840
841 void releasewritelock_r(void * lock, void * redirectlock);
842 bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache);
843
844 bool getwritelock_I_r(void* lock, void* redirectlock, int core, bool cache);
845
846 void releasereadlock(void * ptr) {
847   int targetcore = 0;
848   int reallock = 0;
849   if(((struct ___Object___ *)ptr)->lock == NULL) {
850         reallock = (int)ptr;
851   } else {
852         reallock = (int)(((struct ___Object___ *)ptr)->lock);
853   }
854   targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
855
856   if(targetcore == BAMBOO_NUM_OF_CORE) {
857         BAMBOO_START_CRITICAL_SECTION_LOCK();
858 #ifdef DEBUG
859         BAMBOO_DEBUGPRINT(0xf001);
860 #endif
861     // reside on this core
862     if(!RuntimeHashcontainskey(locktbl, reallock)) {
863       // no locks for this object, something is wrong
864       BAMBOO_EXIT(0xa019);
865     } else {
866       int rwlock_obj = 0;
867           struct LockValue * lockvalue = NULL;
868       RuntimeHashget(locktbl, reallock, &rwlock_obj);
869           lockvalue = (struct LockValue *)rwlock_obj;
870       lockvalue->value--;
871     }
872         BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
873 #ifdef DEBUG
874         BAMBOO_DEBUGPRINT(0xf000);
875 #endif
876     return;
877   } else {
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);
881   }
882 }
883
884 // redirected lock request
885 bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
886   int targetcore = 0;
887   
888   if(core == BAMBOO_NUM_OF_CORE) {
889           lockobj = (int)ptr;
890           lock2require = (int)redirectlock;
891           lockflag = false;
892 #ifndef INTERRUPT
893           reside = false;
894 #endif
895           lockresult = 0;
896   }  
897   targetcore = ((int)redirectlock >> 5) % BAMBOO_TOTALCORE;
898   
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);
902         if(deny == -1) {
903                 // redirected
904                 return true;
905         } else {
906                 if(core == BAMBOO_NUM_OF_CORE) {
907                         if(lockobj == (int)ptr) {
908                                 if(deny) {
909                                         lockresult = 0;
910                                 } else {
911                                         lockresult = 1;
912                                         RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
913                                 }
914                                 lockflag = true;
915 #ifndef INTERRUPT
916                                 reside = true;
917 #endif
918                         } else {
919                                 // conflicts on lockresults
920                                 BAMBOO_EXIT(0xa01a);
921                         }
922                         return true;
923                 } else {
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);
929                         } else {
930                                 cache_msg_4(core, deny==1?REDIRECTDENY:REDIRECTGROUNT, 0, 
931                                                         (int)ptr, (int)redirectlock);
932                         }
933                 }
934         }
935   } else {
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);
941         } else {
942                 cache_msg_6(targetcore, REDIRECTLOCK, 0, (int)ptr, lock2require, 
943                                         core, BAMBOO_NUM_OF_CORE);
944         }
945   }
946   return true;
947 }
948
949 // not reentrant
950 bool getwritelock(void * ptr) {
951   int targetcore = 0;
952
953   // for 32 bit machine, the size is always 5 words
954   //int msgsize = 5;
955
956   lockobj = (int)ptr;
957   if(((struct ___Object___ *)ptr)->lock == NULL) {
958         lock2require = lockobj;
959   } else {
960         lock2require = (int)(((struct ___Object___ *)ptr)->lock);
961   }
962   targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
963   lockflag = false;
964 #ifndef INTERRUPT
965   reside = false;
966 #endif
967   lockresult = 0;
968
969 #ifdef DEBUG
970   BAMBOO_DEBUGPRINT(0xe551);
971   BAMBOO_DEBUGPRINT_REG(lockobj);
972   BAMBOO_DEBUGPRINT_REG(lock2require);
973   BAMBOO_DEBUGPRINT_REG(targetcore);
974 #endif
975
976   if(targetcore == BAMBOO_NUM_OF_CORE) {
977     // reside on this core
978     int deny = 0;
979         BAMBOO_START_CRITICAL_SECTION_LOCK();
980 #ifdef DEBUG
981         BAMBOO_DEBUGPRINT(0xf001);
982 #endif
983         deny = processlockrequest(1, lock2require, (int)ptr, BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, false);
984         BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
985 #ifdef DEBUG
986         BAMBOO_DEBUGPRINT(0xf000);
987 #endif
988 #ifdef DEBUG
989     BAMBOO_DEBUGPRINT(0xe555);
990     BAMBOO_DEBUGPRINT_REG(lockresult);
991 #endif
992     if(deny == -1) {
993                 // redirected
994                 return true;
995         } else {
996                 if(lockobj == (int)ptr) {
997                         if(deny) {
998                                 lockresult = 0;
999                         } else {
1000                                 lockresult = 1;
1001                         }
1002                         lockflag = true;
1003 #ifndef INTERRUPT
1004                         reside = true;
1005 #endif
1006                 } else {
1007                         // conflicts on lockresults
1008                         BAMBOO_EXIT(0xa01b);
1009                 }
1010         }
1011     return true;
1012   } else {
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);
1017   }
1018   return true;
1019 }
1020
1021 void releasewritelock(void * ptr) {
1022   int targetcore = 0;
1023   int reallock = 0;
1024   if(((struct ___Object___ *)ptr)->lock == NULL) {
1025         reallock = (int)ptr;
1026   } else {
1027         reallock = (int)(((struct ___Object___ *)ptr)->lock);
1028   }
1029   targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
1030
1031 #ifdef DEBUG
1032   BAMBOO_DEBUGPRINT(0xe661);
1033   BAMBOO_DEBUGPRINT_REG((int)ptr);
1034   BAMBOO_DEBUGPRINT_REG(reallock);
1035   BAMBOO_DEBUGPRINT_REG(targetcore);
1036 #endif
1037
1038   if(targetcore == BAMBOO_NUM_OF_CORE) {
1039         BAMBOO_START_CRITICAL_SECTION_LOCK();
1040 #ifdef DEBUG
1041         BAMBOO_DEBUGPRINT(0xf001);
1042 #endif
1043     // reside on this core
1044     if(!RuntimeHashcontainskey(locktbl, reallock)) {
1045       // no locks for this object, something is wrong
1046       BAMBOO_EXIT(0xa01c);
1047     } else {
1048       int rwlock_obj = 0;
1049           struct LockValue * lockvalue = NULL;
1050       RuntimeHashget(locktbl, reallock, &rwlock_obj);
1051           lockvalue = (struct LockValue *)rwlock_obj;
1052       lockvalue->value++;
1053     }
1054         BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
1055 #ifdef DEBUG
1056         BAMBOO_DEBUGPRINT(0xf000);
1057 #endif
1058     return;
1059   } else {
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);
1063   }
1064 }
1065
1066 void releasewritelock_r(void * lock, void * redirectlock) {
1067   int targetcore = 0;
1068   int reallock = (int)lock;
1069   targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
1070
1071 #ifdef DEBUG
1072   BAMBOO_DEBUGPRINT(0xe671);
1073   BAMBOO_DEBUGPRINT_REG((int)lock);
1074   BAMBOO_DEBUGPRINT_REG(reallock);
1075   BAMBOO_DEBUGPRINT_REG(targetcore);
1076 #endif
1077
1078   if(targetcore == BAMBOO_NUM_OF_CORE) {
1079         BAMBOO_START_CRITICAL_SECTION_LOCK();
1080 #ifdef DEBUG
1081         BAMBOO_DEBUGPRINT(0xf001);
1082 #endif
1083     // reside on this core
1084     if(!RuntimeHashcontainskey(locktbl, reallock)) {
1085       // no locks for this object, something is wrong
1086       BAMBOO_EXIT(0xa01d);
1087     } else {
1088       int rwlock_obj = 0;
1089           struct LockValue * lockvalue = NULL;
1090 #ifdef DEBUG
1091       BAMBOO_DEBUGPRINT(0xe672);
1092 #endif
1093       RuntimeHashget(locktbl, reallock, &rwlock_obj);
1094           lockvalue = (struct LockValue *)rwlock_obj;
1095 #ifdef DEBUG
1096       BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1097 #endif
1098       lockvalue->value++;
1099           lockvalue->redirectlock = (int)redirectlock;
1100 #ifdef DEBUG
1101       BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1102 #endif
1103     }
1104         BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
1105 #ifdef DEBUG
1106         BAMBOO_DEBUGPRINT(0xf000);
1107 #endif
1108     return;
1109   } else {
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);
1113   }
1114 }
1115
1116 bool getwritelock_I(void * ptr) {
1117   int targetcore = 0;
1118   lockobj = (int)ptr;
1119   if(((struct ___Object___ *)ptr)->lock == NULL) {
1120         lock2require = lockobj;
1121   } else {
1122         lock2require = (int)(((struct ___Object___ *)ptr)->lock);
1123   }
1124   targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
1125   lockflag = false;
1126 #ifndef INTERRUPT
1127   reside = false;
1128 #endif
1129   lockresult = 0;
1130
1131 #ifdef DEBUG
1132   BAMBOO_DEBUGPRINT(0xe561);
1133   BAMBOO_DEBUGPRINT_REG(lockobj);
1134   BAMBOO_DEBUGPRINT_REG(lock2require);
1135   BAMBOO_DEBUGPRINT_REG(targetcore);
1136 #endif
1137
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);
1141         if(deny == -1) {
1142                 // redirected
1143                 return true;
1144         } else {
1145                 if(lockobj == (int)ptr) {
1146                         if(deny) {
1147                                 lockresult = 0;
1148 #ifdef DEBUG
1149                                 BAMBOO_DEBUGPRINT(0);
1150 #endif
1151                         } else {
1152                                 lockresult = 1;
1153 #ifdef DEBUG
1154                                 BAMBOO_DEBUGPRINT(1);
1155 #endif
1156                         }
1157                         lockflag = true;
1158 #ifndef INTERRUPT
1159                         reside = true;
1160 #endif
1161                 } else {
1162                         // conflicts on lockresults
1163                         BAMBOO_EXIT(0xa01e);
1164                 }
1165                 return true;
1166         }
1167   } else {
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);
1172   }
1173   return true;
1174 }
1175
1176 // redirected lock request
1177 bool getwritelock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
1178   int targetcore = 0;
1179
1180   if(core == BAMBOO_NUM_OF_CORE) {
1181           lockobj = (int)ptr;
1182           lock2require = (int)redirectlock;
1183           lockflag = false;
1184 #ifndef INTERRUPT
1185           reside = false;
1186 #endif
1187           lockresult = 0;
1188   }
1189   targetcore = ((int)redirectlock >> 5) % BAMBOO_TOTALCORE;
1190
1191 #ifdef DEBUG
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);
1198 #endif
1199
1200
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);
1204         if(deny == -1) {
1205                 // redirected
1206                 return true;
1207         } else {
1208                 if(core == BAMBOO_NUM_OF_CORE) {
1209                         if(lockobj == (int)ptr) {
1210                                 if(deny) {
1211                                         lockresult = 0;
1212                                 } else {
1213                                         lockresult = 1;
1214                                         RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
1215                                 }
1216                                 lockflag = true;
1217 #ifndef INTERRUPT
1218                                 reside = true;
1219 #endif
1220                         } else {
1221                                 // conflicts on lockresults
1222                                 BAMBOO_EXIT(0xa01f);
1223                         }
1224                         return true;
1225                 } else {
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);
1231                         } else {
1232                                 cache_msg_4(core, deny==1?REDIRECTDENY:REDIRECTGROUNT, 1, 
1233                                                         (int)ptr, (int)redirectlock);
1234                         }
1235                 }
1236         }
1237   } else {
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);
1243         } else {
1244                 cache_msg_6(targetcore, REDIRECTLOCK, 1, (int)ptr, (int)redirectlock, 
1245                                         core, BAMBOO_NUM_OF_CORE);
1246         }
1247   }
1248   return true;
1249 }
1250
1251 void releasewritelock_I(void * ptr) {
1252   int targetcore = 0;
1253   int reallock = 0;
1254   if(((struct ___Object___ *)ptr)->lock == NULL) {
1255         reallock = (int)ptr;
1256   } else {
1257         reallock = (int)(((struct ___Object___ *)ptr)->lock);
1258   }
1259   targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
1260
1261 #ifdef DEBUG
1262   BAMBOO_DEBUGPRINT(0xe681);
1263   BAMBOO_DEBUGPRINT_REG((int)ptr);
1264   BAMBOO_DEBUGPRINT_REG(reallock);
1265   BAMBOO_DEBUGPRINT_REG(targetcore);
1266 #endif
1267
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);
1273     } else {
1274       int rwlock_obj = 0;
1275           struct LockValue * lockvalue = NULL;
1276       RuntimeHashget(locktbl, reallock, &rwlock_obj);
1277           lockvalue = (struct LockValue *)rwlock_obj;
1278       lockvalue->value++;
1279     }
1280     return;
1281   } else {
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);
1285   }
1286 }
1287
1288 void releasewritelock_I_r(void * lock, void * redirectlock) {
1289   int targetcore = 0;
1290   int reallock = (int)lock;
1291   targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
1292
1293 #ifdef DEBUG
1294   BAMBOO_DEBUGPRINT(0xe691);
1295   BAMBOO_DEBUGPRINT_REG((int)lock);
1296   BAMBOO_DEBUGPRINT_REG(reallock);
1297   BAMBOO_DEBUGPRINT_REG(targetcore);
1298 #endif
1299
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);
1305     } else {
1306       int rwlock_obj = 0;
1307           struct LockValue * lockvalue = NULL;
1308 #ifdef DEBUG
1309       BAMBOO_DEBUGPRINT(0xe692);
1310 #endif
1311       RuntimeHashget(locktbl, reallock, &rwlock_obj);
1312           lockvalue = (struct LockValue *)rwlock_obj;
1313 #ifdef DEBUG
1314       BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1315 #endif
1316       lockvalue->value++;
1317           lockvalue->redirectlock = (int)redirectlock;
1318 #ifdef DEBUG
1319       BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1320 #endif
1321     }
1322     return;
1323   } else {
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);
1327   }
1328 }
1329
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) {
1336   int deny = 0;
1337   if( ((lock >> 5) % BAMBOO_TOTALCORE) != BAMBOO_NUM_OF_CORE ) {
1338           // the lock should not be on this core
1339 #ifndef TILERA
1340           BAMBOO_DEBUGPRINT_REG(requestcore);
1341           BAMBOO_DEBUGPRINT_REG(lock);
1342           BAMBOO_DEBUGPRINT_REG(BAMBOO_NUM_OF_CORE);
1343 #endif
1344           BAMBOO_EXIT(0xa017);
1345   }
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;
1353 #ifdef DEBUG
1354 #ifndef TILERA
1355           BAMBOO_DEBUGPRINT(0xe110);
1356 #endif
1357 #endif
1358           if(locktype == 0) {
1359                   lockvalue->value = 1;
1360           } else {
1361                   lockvalue->value = -1;
1362           }
1363           RuntimeHashadd_I(locktbl, lock, (int)lockvalue);
1364   } else {
1365           int rwlock_obj = 0;
1366           struct LockValue * lockvalue = NULL;
1367 #ifdef DEBUG
1368 #ifndef TILERA
1369           BAMBOO_DEBUGPRINT(0xe111);
1370 #endif
1371 #endif
1372           RuntimeHashget(locktbl, lock, &rwlock_obj);
1373           lockvalue = (struct LockValue *)(rwlock_obj);
1374 #ifdef DEBUG
1375 #ifndef TILERA
1376           BAMBOO_DEBUGPRINT_REG(lockvalue->redirectlock);
1377 #endif
1378 #endif
1379           if(lockvalue->redirectlock != 0) {
1380                   // this lock is redirected
1381 #ifdef DEBUG
1382 #ifndef TILERA
1383                   BAMBOO_DEBUGPRINT(0xe112);
1384 #endif
1385 #endif
1386                   if(locktype == 0) {
1387                           getreadlock_I_r((void *)obj, (void *)lockvalue->redirectlock, rootrequestcore, cache);
1388                   } else {
1389                           getwritelock_I_r((void *)obj, (void *)lockvalue->redirectlock, rootrequestcore, cache);
1390                   }
1391                   return -1;  // redirected
1392           } else {
1393 #ifdef DEBUG
1394 #ifndef TILERA
1395                   BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1396 #endif
1397 #endif
1398                   if(0 == lockvalue->value) {
1399                           if(locktype == 0) {
1400                                   lockvalue->value = 1;
1401                           } else {
1402                                   lockvalue->value = -1;
1403                           }
1404                   } else if((lockvalue->value > 0) && (locktype == 0)) {
1405                           // read lock request and there are only read locks
1406                           lockvalue->value++;
1407                   } else {
1408                           deny = 1;
1409                   }
1410 #ifdef DEBUG
1411 #ifndef TILERA
1412                   BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1413 #endif
1414 #endif
1415           }
1416   }
1417   return deny;
1418 }
1419
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
1423 #ifdef DEBUG
1424                 BAMBOO_DEBUGPRINT_REG(lock);
1425 #endif
1426                 BAMBOO_EXIT(0xa00b);
1427         } else {
1428                 int rwlock_obj = 0;
1429                 struct LockValue * lockvalue = NULL;
1430                 RuntimeHashget(locktbl, lock, &rwlock_obj);
1431                 lockvalue = (struct LockValue*)(rwlock_obj);
1432 #ifdef DEBUG
1433                 BAMBOO_DEBUGPRINT(0xe884);
1434                 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1435 #endif
1436                 if(locktype == 0) {
1437                         lockvalue->value--;
1438                 } else {
1439                         lockvalue->value++;
1440                 }
1441 #ifdef DEBUG
1442                 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1443 #endif
1444                 if(isredirect) {
1445                         lockvalue->redirectlock = redirectlock;
1446                 }
1447         }
1448 }
1449
1450 #ifdef PROFILE
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;
1460   }
1461 }
1462
1463 __attribute__((always_inline)) inline void profileTaskEnd() {
1464   if(!taskInfoOverflow) {
1465           taskInfoArray[taskInfoIndex]->endTime = raw_get_cycle();
1466           taskInfoIndex++;
1467           if(taskInfoIndex == TASKINFOLENGTH) {
1468                   taskInfoOverflow = true;
1469           }
1470   }
1471 }
1472
1473 // output the profiling data
1474 void outputProfileData() {
1475 #ifdef USEIO
1476   FILE * fp;
1477   char fn[50];
1478   int self_y, self_x;
1479   char c_y, c_x;
1480   int i;
1481   int totaltasktime = 0;
1482   int preprocessingtime = 0;
1483   int objqueuecheckingtime = 0;
1484   int postprocessingtime = 0;
1485   //int interruptiontime = 0;
1486   int other = 0;
1487   int averagetasktime = 0;
1488   int tasknum = 0;
1489
1490   for(i = 0; i < 50; i++) {
1491     fn[i] = 0;
1492   }
1493
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_");
1498   strcat(fn, &c_x);
1499   strcat(fn, "_");
1500   strcat(fn, &c_y);
1501   strcat(fn, ".rst");
1502
1503   if((fp = fopen(fn, "w+")) == NULL) {
1504     fprintf(stderr, "fopen error\n");
1505     return;
1506   }
1507
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))) {
1521                                 int num = 0;
1522                                 RuntimeHashget(nobjtbl, (int)objtype, &num);
1523                                 RuntimeHashremovekey(nobjtbl, (int)objtype);
1524                                 num++;
1525                                 RuntimeHashadd(nobjtbl, (int)objtype, num);
1526                         } else {
1527                                 RuntimeHashadd(nobjtbl, (int)objtype, 1);
1528                         }
1529                         //fprintf(stderr, "new obj!\n");
1530                 }
1531
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);
1538                 }
1539         }
1540         fprintf(fp, "\n");
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;
1547     } else {
1548       totaltasktime += duration;
1549       averagetasktime += duration;
1550       tasknum++;
1551     }
1552   }
1553
1554   if(taskInfoOverflow) {
1555     fprintf(stderr, "Caution: task info overflow!\n");
1556   }
1557
1558   other = totalexetime - totaltasktime - preprocessingtime - postprocessingtime;
1559   averagetasktime /= tasknum;
1560
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);
1567
1568   fprintf(fp, "\nAverage task execution time: %d\n", averagetasktime);
1569
1570   fclose(fp);
1571 #else
1572   int i = 0;
1573   int j = 0;
1574
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]);
1584     }
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))) {
1595                                 int num = 0;
1596                                 RuntimeHashget(nobjtbl, (int)objtype, &num);
1597                                 RuntimeHashremovekey(nobjtbl, (int)objtype);
1598                                 num++;
1599                                 RuntimeHashadd(nobjtbl, (int)objtype, num);
1600                         } else {
1601                                 RuntimeHashadd(nobjtbl, (int)objtype, 1);
1602                         }
1603                 }
1604
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]);
1614                         }
1615                         BAMBOO_DEBUGPRINT(0xdddb);
1616                         BAMBOO_DEBUGPRINT_REG(num);
1617                 }
1618         }
1619     BAMBOO_DEBUGPRINT(0xdddc);
1620   }
1621
1622   if(taskInfoOverflow) {
1623     BAMBOO_DEBUGPRINT(0xefee);
1624   }
1625
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);
1633      }
1634
1635      if(interruptInfoOverflow) {
1636        BAMBOO_DEBUGPRINT(0xefef);
1637      }*/
1638
1639   BAMBOO_DEBUGPRINT(0xeeee);
1640 #endif
1641 }
1642 #endif  // #ifdef PROFILE
1643
1644 #endif // #ifdef TASK