cb0c1e182f6a2135d2678f0d8221652a96d038d0
[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 // data structures for locking
7 struct RuntimeHash locktable;
8 static struct RuntimeHash* locktbl = &locktable;
9 struct LockValue {
10         int redirectlock;
11         int value;
12 };
13
14 __attribute__((always_inline)) inline void initialization() {
15 } // initialization()
16
17 __attribute__((always_inline)) inline void initCommunication() {
18 #ifdef INTERRUPT
19   if (corenum < NUMCORES) {
20     // set up interrupts
21     setup_ints();
22     raw_user_interrupts_on();
23   }
24 #endif
25 }
26
27 __attribute__((always_inline)) inline void fakeExecution()  {
28   // handle communications
29   while(true) {
30           receiveObject();
31   }
32 }
33
34 #ifdef USEIO
35 int main(void) {
36 #else
37 void begin() {
38 #endif // #ifdef USEIO
39   run(NULL);
40 }
41
42 __attribute__((always_inline)) inline void terminate()  {
43         raw_test_done(1);
44 }
45
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();
50
51 // transfer an object to targetcore
52 // format: object
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;  
57
58   unsigned msgHdr;
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;
62   int i = 0;
63
64   struct ___Object___ * newobj = (struct ___Object___ *)obj;
65
66   calCoords(corenum, &self_x, &self_y);
67   calCoords(targetcore, &target_x, &target_y);
68   isMsgSending = true;
69   // Build the message header
70   msgHdr = construct_dyn_hdr(0, msgsize, 0,             // msgsize word sent.
71                              self_y, self_x,
72                              target_y, target_x);
73   // start sending msg, set sand msg flag
74   gdn_send(msgHdr);                     
75 #ifdef DEBUG
76   BAMBOO_DEBUGPRINT(0xbbbb);
77   BAMBOO_DEBUGPRINT(0xb000 + targetcore);       // targetcore
78 #endif
79   gdn_send(0);
80 #ifdef DEBUG
81   BAMBOO_DEBUGPRINT(0);
82 #endif
83   gdn_send(msgsize);
84 #ifdef DEBUG
85   BAMBOO_DEBUGPRINT_REG(msgsize);
86 #endif
87   gdn_send((int)obj);
88 #ifdef DEBUG
89   BAMBOO_DEBUGPRINT_REG(obj);
90 #endif
91   for(i = 0; i < transObj->length; ++i) {
92     int taskindex = transObj->queues[2*i];
93     int paramindex = transObj->queues[2*i+1];
94     gdn_send(taskindex);
95 #ifdef DEBUG
96     BAMBOO_DEBUGPRINT_REG(taskindex);
97 #endif
98     gdn_send(paramindex);
99 #ifdef DEBUG
100     BAMBOO_DEBUGPRINT_REG(paramindex);
101 #endif
102   }
103 #ifdef DEBUG
104   BAMBOO_DEBUGPRINT(0xffff);
105 #endif
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
117           isMsgSending = true;
118           // Build the message header
119           msgHdr = construct_dyn_hdr(0, outmsgleft, 0,                        // msgsize word sent.
120                                  self_y, self_x,
121                                  target_y, target_x);
122           gdn_send(msgHdr);                           
123 #ifdef DEBUG
124           BAMBOO_DEBUGPRINT(0xbbbb);
125           BAMBOO_DEBUGPRINT(0xb000 + target);             // targetcore
126 #endif
127           while(outmsgleft-- > 0) {
128                   gdn_send(outmsgdata[outmsgindex++]);
129 #ifdef DEBUG
130                   BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
131 #endif
132           }
133 #ifdef DEBUG
134           BAMBOO_DEBUGPRINT(0xffff);
135 #endif
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) {
141                   // no more msgs
142                   outmsgindex = outmsglast = 0;
143                   isMsgHanging = false;
144           }
145           BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
146   }
147 }
148
149 __attribute__((always_inline)) inline void send_msg_1 (int targetcore, 
150                                                                    int n0) {
151   // send this msg
152   unsigned msgHdr;
153   int self_y, self_x, target_y, target_x;
154   msglength = 1;
155
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);
159
160   // mark to start sending the msg
161   isMsgSending = true;
162   // Build the message header
163   msgHdr = construct_dyn_hdr(0, msglength, 0,             // msgsize word sent.
164                              self_y, self_x,
165                              target_y, target_x);
166   gdn_send(msgHdr);                     // Send the message header
167 #ifdef DEBUG
168   BAMBOO_DEBUGPRINT(0xbbbb);
169   BAMBOO_DEBUGPRINT(0xb000 + targetcore);       // targetcore
170 #endif
171   gdn_send(n0);
172 #ifdef DEBUG
173   BAMBOO_DEBUGPRINT(n0);
174   BAMBOO_DEBUGPRINT(0xffff);
175 #endif
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
186           isMsgSending = true;
187           // Build the message header
188           msgHdr = construct_dyn_hdr(0, outmsgleft, 0,                        // msgsize word sent.
189                                  self_y, self_x,
190                                  target_y, target_x);
191           gdn_send(msgHdr);                           
192 #ifdef DEBUG
193           BAMBOO_DEBUGPRINT(0xbbbb);
194           BAMBOO_DEBUGPRINT(0xb000 + target);             // targetcore
195 #endif
196           while(outmsgleft-- > 0) {
197                   gdn_send(outmsgdata[outmsgindex++]);
198 #ifdef DEBUG
199                   BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
200 #endif
201           }
202 #ifdef DEBUG
203           BAMBOO_DEBUGPRINT(0xffff);
204 #endif
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) {
210                   // no more msgs
211                   outmsgindex = outmsglast = 0;
212                   isMsgHanging = false;
213           }
214           BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
215   }
216 }
217
218 __attribute__((always_inline)) inline void send_msg_2 (int targetcore, 
219                                                                    int n0, 
220                                                                                                                                                                                                                          int n1) {
221   // send this msg
222   unsigned msgHdr;
223   int self_y, self_x, target_y, target_x;
224   msglength = 2;
225
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);
229
230   // mark to start sending the msg
231   isMsgSending = true;
232   // Build the message header
233   msgHdr = construct_dyn_hdr(0, msglength, 0,             // msgsize word sent.
234                              self_y, self_x,
235                              target_y, target_x);
236   gdn_send(msgHdr);                     // Send the message header
237 #ifdef DEBUG
238   BAMBOO_DEBUGPRINT(0xbbbb);
239   BAMBOO_DEBUGPRINT(0xb000 + targetcore);       // targetcore
240 #endif
241   gdn_send(n0);
242 #ifdef DEBUG
243   BAMBOO_DEBUGPRINT(n0);
244 #endif
245   gdn_send(n1);
246 #ifdef DEBUG
247   BAMBOO_DEBUGPRINT(n1);
248   BAMBOO_DEBUGPRINT(0xffff);
249 #endif
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
260           isMsgSending = true;
261           // Build the message header
262           msgHdr = construct_dyn_hdr(0, outmsgleft, 0,                        // msgsize word sent.
263                                  self_y, self_x,
264                                  target_y, target_x);
265           gdn_send(msgHdr);                           
266 #ifdef DEBUG
267           BAMBOO_DEBUGPRINT(0xbbbb);
268           BAMBOO_DEBUGPRINT(0xb000 + target);             // targetcore
269 #endif
270           while(outmsgleft-- > 0) {
271                   gdn_send(outmsgdata[outmsgindex++]);
272 #ifdef DEBUG
273                   BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
274 #endif
275           }
276 #ifdef DEBUG
277           BAMBOO_DEBUGPRINT(0xffff);
278 #endif
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) {
284                   // no more msgs
285                   outmsgindex = outmsglast = 0;
286                   isMsgHanging = false;
287           }
288           BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
289   }
290 }
291
292 __attribute__((always_inline)) inline void send_msg_3 (int targetcore, 
293                                                                    int n0, 
294                                                                                                                                                                                                                          int n1, 
295                                                                                                                                                                                                                          int n2) {
296   // send this msg
297   unsigned msgHdr;
298   int self_y, self_x, target_y, target_x;
299   msglength = 3;
300
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);
304
305   // mark to start sending the msg
306   isMsgSending = true;
307   // Build the message header
308   msgHdr = construct_dyn_hdr(0, msglength, 0,             // msgsize word sent.
309                              self_y, self_x,
310                              target_y, target_x);
311   gdn_send(msgHdr);                     // Send the message header
312 #ifdef DEBUG
313   BAMBOO_DEBUGPRINT(0xbbbb);
314   BAMBOO_DEBUGPRINT(0xb000 + targetcore);       // targetcore
315 #endif
316   gdn_send(n0);
317 #ifdef DEBUG
318   BAMBOO_DEBUGPRINT(n0);
319 #endif
320   gdn_send(n1);
321 #ifdef DEBUG
322   BAMBOO_DEBUGPRINT(n1);
323 #endif
324   gdn_send(n2);
325 #ifdef DEBUG
326   BAMBOO_DEBUGPRINT(n2);
327   BAMBOO_DEBUGPRINT(0xffff);
328 #endif
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
339           isMsgSending = true;
340           // Build the message header
341           msgHdr = construct_dyn_hdr(0, outmsgleft, 0,                        // msgsize word sent.
342                                  self_y, self_x,
343                                  target_y, target_x);
344           gdn_send(msgHdr);                           
345 #ifdef DEBUG
346           BAMBOO_DEBUGPRINT(0xbbbb);
347           BAMBOO_DEBUGPRINT(0xb000 + target);             // targetcore
348 #endif
349           while(outmsgleft-- > 0) {
350                   gdn_send(outmsgdata[outmsgindex++]);
351 #ifdef DEBUG
352                   BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
353 #endif
354           }
355 #ifdef DEBUG
356           BAMBOO_DEBUGPRINT(0xffff);
357 #endif
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) {
363                   // no more msgs
364                   outmsgindex = outmsglast = 0;
365                   isMsgHanging = false;
366           }
367           BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
368   }
369 }
370
371 __attribute__((always_inline)) inline void send_msg_4 (int targetcore, 
372                                                                    int n0, 
373                                                                                                                                                                                                                          int n1, 
374                                                                                                                                                                                                                          int n2, 
375                                                                                                                                                                                                                          int n3) {
376   // send this msg
377   unsigned msgHdr;
378   int self_y, self_x, target_y, target_x;
379   msglength = 4;
380
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);
384
385   // mark to start sending the msg
386   isMsgSending = true;
387   // Build the message header
388   msgHdr = construct_dyn_hdr(0, msglength, 0,             // msgsize word sent.
389                              self_y, self_x,
390                              target_y, target_x);
391   gdn_send(msgHdr);                     // Send the message header
392 #ifdef DEBUG
393   BAMBOO_DEBUGPRINT(0xbbbb);
394   BAMBOO_DEBUGPRINT(0xb000 + targetcore);       // targetcore
395 #endif
396   gdn_send(n0);
397 #ifdef DEBUG
398   BAMBOO_DEBUGPRINT(n0);
399 #endif
400   gdn_send(n1);
401 #ifdef DEBUG
402   BAMBOO_DEBUGPRINT(n1);
403 #endif
404   gdn_send(n2);
405 #ifdef DEBUG
406   BAMBOO_DEBUGPRINT(n2);
407 #endif
408   gdn_send(n3);
409 #ifdef DEBUG
410   BAMBOO_DEBUGPRINT(n3);
411   BAMBOO_DEBUGPRINT(0xffff);
412 #endif
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
423           isMsgSending = true;
424           // Build the message header
425           msgHdr = construct_dyn_hdr(0, outmsgleft, 0,                        // msgsize word sent.
426                                  self_y, self_x,
427                                  target_y, target_x);
428           gdn_send(msgHdr);                           
429 #ifdef DEBUG
430           BAMBOO_DEBUGPRINT(0xbbbb);
431           BAMBOO_DEBUGPRINT(0xb000 + target);             // targetcore
432 #endif
433           while(outmsgleft-- > 0) {
434                   gdn_send(outmsgdata[outmsgindex++]);
435 #ifdef DEBUG
436                   BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
437 #endif
438           }
439 #ifdef DEBUG
440           BAMBOO_DEBUGPRINT(0xffff);
441 #endif
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) {
447                   // no more msgs
448                   outmsgindex = outmsglast = 0;
449                   isMsgHanging = false;
450           }
451           BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
452   }
453 }
454
455 __attribute__((always_inline)) inline void send_msg_5 (int targetcore, 
456                                                                    int n0, 
457                                                                                                                                                                                                                          int n1, 
458                                                                                                                                                                                                                          int n2, 
459                                                                                                                                                                                                                          int n3, 
460                                                                                                                                                                                                                          int n4) {
461   // send this msg
462   unsigned msgHdr;
463   int self_y, self_x, target_y, target_x;
464   msglength = 5;
465
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);
469
470   // mark to start sending the msg
471   isMsgSending = true;
472   // Build the message header
473   msgHdr = construct_dyn_hdr(0, msglength, 0,             // msgsize word sent.
474                              self_y, self_x,
475                              target_y, target_x);
476   gdn_send(msgHdr);                     // Send the message header
477 #ifdef DEBUG
478   BAMBOO_DEBUGPRINT(0xbbbb);
479   BAMBOO_DEBUGPRINT(0xb000 + targetcore);       // targetcore
480 #endif
481   gdn_send(n0);
482 #ifdef DEBUG
483   BAMBOO_DEBUGPRINT(n0);
484 #endif
485   gdn_send(n1);
486 #ifdef DEBUG
487   BAMBOO_DEBUGPRINT(n1);
488 #endif
489   gdn_send(n2);
490 #ifdef DEBUG
491   BAMBOO_DEBUGPRINT(n2);
492 #endif
493   gdn_send(n3);
494 #ifdef DEBUG
495   BAMBOO_DEBUGPRINT(n3);
496 #endif
497   gdn_send(n4);
498 #ifdef DEBUG
499   BAMBOO_DEBUGPRINT(n4);
500   BAMBOO_DEBUGPRINT(0xffff);
501 #endif
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
512           isMsgSending = true;
513           // Build the message header
514           msgHdr = construct_dyn_hdr(0, outmsgleft, 0,                        // msgsize word sent.
515                                  self_y, self_x,
516                                  target_y, target_x);
517           gdn_send(msgHdr);                           
518 #ifdef DEBUG
519           BAMBOO_DEBUGPRINT(0xbbbb);
520           BAMBOO_DEBUGPRINT(0xb000 + target);             // targetcore
521 #endif
522           while(outmsgleft-- > 0) {
523                   gdn_send(outmsgdata[outmsgindex++]);
524 #ifdef DEBUG
525                   BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
526 #endif
527           }
528 #ifdef DEBUG
529           BAMBOO_DEBUGPRINT(0xffff);
530 #endif
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) {
536                   // no more msgs
537                   outmsgindex = outmsglast = 0;
538                   isMsgHanging = false;
539           }
540           BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
541   }
542 }
543
544 __attribute__((always_inline)) inline void send_msg_6 (int targetcore, 
545                                                                    int n0, 
546                                                                                                                                                                                                                          int n1, 
547                                                                                                                                                                                                                          int n2, 
548                                                                                                                                                                                                                          int n3, 
549                                                                                                                                                                                                                          int n4, 
550                                                                                                                                                                                                                          int n5) {
551   // send this msg
552   unsigned msgHdr;
553   int self_y, self_x, target_y, target_x;
554   msglength = 6;
555
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);
559
560   // mark to start sending the msg
561   isMsgSending = true;
562   // Build the message header
563   msgHdr = construct_dyn_hdr(0, msglength, 0,             // msgsize word sent.
564                              self_y, self_x,
565                              target_y, target_x);
566   gdn_send(msgHdr);                     // Send the message header
567 #ifdef DEBUG
568   BAMBOO_DEBUGPRINT(0xbbbb);
569   BAMBOO_DEBUGPRINT(0xb000 + targetcore);       // targetcore
570 #endif
571   gdn_send(n0);
572 #ifdef DEBUG
573   BAMBOO_DEBUGPRINT(n0);
574 #endif
575   gdn_send(n1);
576 #ifdef DEBUG
577   BAMBOO_DEBUGPRINT(n1);
578 #endif
579   gdn_send(n2);
580 #ifdef DEBUG
581   BAMBOO_DEBUGPRINT(n2);
582 #endif
583   gdn_send(n3);
584 #ifdef DEBUG
585   BAMBOO_DEBUGPRINT(n3);
586 #endif
587   gdn_send(n4);
588 #ifdef DEBUG
589   BAMBOO_DEBUGPRINT(n4);
590 #endif
591   gdn_send(n5);
592 #ifdef DEBUG
593   BAMBOO_DEBUGPRINT(n5);
594   BAMBOO_DEBUGPRINT(0xffff);
595 #endif
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
606           isMsgSending = true;
607           // Build the message header
608           msgHdr = construct_dyn_hdr(0, outmsgleft, 0,                        // msgsize word sent.
609                                  self_y, self_x,
610                                  target_y, target_x);
611           gdn_send(msgHdr);                           
612 #ifdef DEBUG
613           BAMBOO_DEBUGPRINT(0xbbbb);
614           BAMBOO_DEBUGPRINT(0xb000 + target);             // targetcore
615 #endif
616           while(outmsgleft-- > 0) {
617                   gdn_send(outmsgdata[outmsgindex++]);
618 #ifdef DEBUG
619                   BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
620 #endif
621           }
622 #ifdef DEBUG
623           BAMBOO_DEBUGPRINT(0xffff);
624 #endif
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) {
630                   // no more msgs
631                   outmsgindex = outmsglast = 0;
632                   isMsgHanging = false;
633           }
634           BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
635   }
636 }
637
638 __attribute__((always_inline)) inline void cache_msg_2 (int targetcore, 
639                                                                     int n0, 
640                                                                                                                                                                                                                                 int n1) {
641   // cache this msg
642 #ifdef DEBUG
643   BAMBOO_DEBUGPRINT(0xdede);
644 #endif
645   isMsgHanging = true;
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;
652 }
653
654 __attribute__((always_inline)) inline void cache_msg_3 (int targetcore, 
655                                                                     int n0, 
656                                                                                                                                                                                                                                 int n1, 
657                                                                                                                                                                                                                                 int n2) {
658   // cache this msg
659 #ifdef DEBUG
660   BAMBOO_DEBUGPRINT(0xdede);
661 #endif
662   isMsgHanging = true;
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;
670 }
671
672 __attribute__((always_inline)) inline void cache_msg_4 (int targetcore, 
673                                                                     int n0, 
674                                                                                                                                                                                                                                 int n1, 
675                                                                                                                                                                                                                                 int n2, 
676                                                                                                                                                                                                                                 int n3) {
677   // cache this msg
678 #ifdef DEBUG
679   BAMBOO_DEBUGPRINT(0xdede);
680 #endif
681   isMsgHanging = true;
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;
690 }
691
692 __attribute__((always_inline)) inline void cache_msg_5 (int targetcore, 
693                                                                     int n0, 
694                                                                                                                                                                                                                                 int n1, 
695                                                                                                                                                                                                                                 int n2, 
696                                                                                                                                                                                                                                 int n3, 
697                                                                                                                                                                                                                                 int n4) {
698   // cache this msg
699 #ifdef DEBUG
700   BAMBOO_DEBUGPRINT(0xdede);
701 #endif
702   isMsgHanging = true;
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;
712 }
713
714
715 __attribute__((always_inline)) inline void cache_msg_6 (int targetcore, 
716                                                                     int n0, 
717                                                                                                                                                                                                                                 int n1, 
718                                                                                                                                                                                                                                 int n2, 
719                                                                                                                                                                                                                                 int n3, 
720                                                                                                                                                                                                                                 int n4, 
721                                                                                                                                                                                                                                 int n5) {
722   // cache this msg
723 #ifdef DEBUG
724   BAMBOO_DEBUGPRINT(0xdede);
725 #endif
726   isMsgHanging = true;
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;
737 }
738
739 __attribute__((always_inline)) inline int receiveMsg() {
740   if(gdn_input_avail() == 0) {
741 #ifdef DEBUG
742     if(corenum < NUMCORES) {
743       BAMBOO_DEBUGPRINT(0xd001);
744     }
745 #endif
746     return -1;
747   }
748 #ifdef PROFILE
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;
754      }*/
755 #endif
756 #ifdef DEBUG
757   BAMBOO_DEBUGPRINT(0xcccc);
758 #endif
759   while((gdn_input_avail() != 0) && (msgdataindex < msglength)) {
760     msgdata[msgdataindex] = gdn_receive();
761     if(msgdataindex == 0) {
762                 if(msgdata[0] > 0xc) {
763                         msglength = 3;
764                 } else if (msgdata[0] == 0xc) {
765                         msglength = 1;
766                 } else if(msgdata[0] > 8) {
767                         msglength = 4;
768                 } else if(msgdata[0] == 8) {
769                         msglength = 6;
770                 } else if(msgdata[0] > 5) {
771                         msglength = 2;
772                 } else if (msgdata[0] > 2) {
773                         msglength = 4;
774                 } else if (msgdata[0] == 2) {
775                         msglength = 5;
776                 } else if (msgdata[0] > 0) {
777                         msglength = 4;
778                 }
779     } else if((msgdataindex == 1) && (msgdata[0] == 0)) {
780       msglength = msgdata[msgdataindex];
781     }
782 #ifdef DEBUG
783     BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
784 #endif
785     msgdataindex++;
786   }
787 #ifdef DEBUG
788   BAMBOO_DEBUGPRINT(0xffff);
789 #endif
790   return msgdataindex;
791 }
792
793 bool getreadlock(void * ptr) {
794   int targetcore = 0;
795   lockobj = (int)ptr;
796   if(((struct ___Object___ *)ptr)->lock == NULL) {
797         lock2require = lockobj;
798   } else {
799         lock2require = (int)(((struct ___Object___ *)ptr)->lock);
800   }
801   targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
802   lockflag = false;
803 #ifndef INTERRUPT
804   reside = false;
805 #endif
806   lockresult = 0;
807
808   if(targetcore == BAMBOO_NUM_OF_CORE) {
809     // reside on this core
810     int deny = 0;
811         BAMBOO_START_CRITICAL_SECTION_LOCK();
812 #ifdef DEBUG
813         BAMBOO_DEBUGPRINT(0xf001);
814 #endif
815         deny = processlockrequest(0, lock2require, (int)ptr, BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, false);
816         BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
817 #ifdef DEBUG
818         BAMBOO_DEBUGPRINT(0xf000);
819 #endif
820     if(deny == -1) {
821                 // redirected
822                 return true;
823         } else {
824                 if(lockobj == (int)ptr) {
825                         if(deny) {
826                                 lockresult = 0;
827                         } else {
828                                 lockresult = 1;
829                         }
830                         lockflag = true;
831 #ifndef INTERRUPT
832                         reside = true;
833 #endif
834                 } else {
835                         // conflicts on lockresults
836                         BAMBOO_EXIT(0xa018);
837                 }
838         }
839     return true;
840   } else {
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);
845   }
846   return true;
847 }
848
849 void releasewritelock_r(void * lock, void * redirectlock);
850 bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache);
851
852 bool getwritelock_I_r(void* lock, void* redirectlock, int core, bool cache);
853
854 void releasereadlock(void * ptr) {
855   int targetcore = 0;
856   int reallock = 0;
857   if(((struct ___Object___ *)ptr)->lock == NULL) {
858         reallock = (int)ptr;
859   } else {
860         reallock = (int)(((struct ___Object___ *)ptr)->lock);
861   }
862   targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
863
864   if(targetcore == BAMBOO_NUM_OF_CORE) {
865         BAMBOO_START_CRITICAL_SECTION_LOCK();
866 #ifdef DEBUG
867         BAMBOO_DEBUGPRINT(0xf001);
868 #endif
869     // reside on this core
870     if(!RuntimeHashcontainskey(locktbl, reallock)) {
871       // no locks for this object, something is wrong
872       BAMBOO_EXIT(0xa019);
873     } else {
874       int rwlock_obj = 0;
875           struct LockValue * lockvalue = NULL;
876       RuntimeHashget(locktbl, reallock, &rwlock_obj);
877           lockvalue = (struct LockValue *)rwlock_obj;
878       lockvalue->value--;
879     }
880         BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
881 #ifdef DEBUG
882         BAMBOO_DEBUGPRINT(0xf000);
883 #endif
884     return;
885   } else {
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);
889   }
890 }
891
892 // redirected lock request
893 bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
894   int targetcore = 0;
895   
896   if(core == BAMBOO_NUM_OF_CORE) {
897           lockobj = (int)ptr;
898           lock2require = (int)redirectlock;
899           lockflag = false;
900 #ifndef INTERRUPT
901           reside = false;
902 #endif
903           lockresult = 0;
904   }  
905   targetcore = ((int)redirectlock >> 5) % BAMBOO_TOTALCORE;
906   
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);
910         if(deny == -1) {
911                 // redirected
912                 return true;
913         } else {
914                 if(core == BAMBOO_NUM_OF_CORE) {
915                         if(lockobj == (int)ptr) {
916                                 if(deny) {
917                                         lockresult = 0;
918                                 } else {
919                                         lockresult = 1;
920                                         RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
921                                 }
922                                 lockflag = true;
923 #ifndef INTERRUPT
924                                 reside = true;
925 #endif
926                         } else {
927                                 // conflicts on lockresults
928                                 BAMBOO_EXIT(0xa01a);
929                         }
930                         return true;
931                 } else {
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);
937                         } else {
938                                 cache_msg_4(core, deny==1?REDIRECTDENY:REDIRECTGROUNT, 0, 
939                                                         (int)ptr, (int)redirectlock);
940                         }
941                 }
942         }
943   } else {
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);
949         } else {
950                 cache_msg_6(targetcore, REDIRECTLOCK, 0, (int)ptr, lock2require, 
951                                         core, BAMBOO_NUM_OF_CORE);
952         }
953   }
954   return true;
955 }
956
957 // not reentrant
958 bool getwritelock(void * ptr) {
959   int targetcore = 0;
960
961   // for 32 bit machine, the size is always 5 words
962   //int msgsize = 5;
963
964   lockobj = (int)ptr;
965   if(((struct ___Object___ *)ptr)->lock == NULL) {
966         lock2require = lockobj;
967   } else {
968         lock2require = (int)(((struct ___Object___ *)ptr)->lock);
969   }
970   targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
971   lockflag = false;
972 #ifndef INTERRUPT
973   reside = false;
974 #endif
975   lockresult = 0;
976
977 #ifdef DEBUG
978   BAMBOO_DEBUGPRINT(0xe551);
979   BAMBOO_DEBUGPRINT_REG(lockobj);
980   BAMBOO_DEBUGPRINT_REG(lock2require);
981   BAMBOO_DEBUGPRINT_REG(targetcore);
982 #endif
983
984   if(targetcore == BAMBOO_NUM_OF_CORE) {
985     // reside on this core
986     int deny = 0;
987         BAMBOO_START_CRITICAL_SECTION_LOCK();
988 #ifdef DEBUG
989         BAMBOO_DEBUGPRINT(0xf001);
990 #endif
991         deny = processlockrequest(1, lock2require, (int)ptr, BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, false);
992         BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
993 #ifdef DEBUG
994         BAMBOO_DEBUGPRINT(0xf000);
995 #endif
996 #ifdef DEBUG
997     BAMBOO_DEBUGPRINT(0xe555);
998     BAMBOO_DEBUGPRINT_REG(lockresult);
999 #endif
1000     if(deny == -1) {
1001                 // redirected
1002                 return true;
1003         } else {
1004                 if(lockobj == (int)ptr) {
1005                         if(deny) {
1006                                 lockresult = 0;
1007                         } else {
1008                                 lockresult = 1;
1009                         }
1010                         lockflag = true;
1011 #ifndef INTERRUPT
1012                         reside = true;
1013 #endif
1014                 } else {
1015                         // conflicts on lockresults
1016                         BAMBOO_EXIT(0xa01b);
1017                 }
1018         }
1019     return true;
1020   } else {
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);
1025   }
1026   return true;
1027 }
1028
1029 void releasewritelock(void * ptr) {
1030   int targetcore = 0;
1031   int reallock = 0;
1032   if(((struct ___Object___ *)ptr)->lock == NULL) {
1033         reallock = (int)ptr;
1034   } else {
1035         reallock = (int)(((struct ___Object___ *)ptr)->lock);
1036   }
1037   targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
1038
1039 #ifdef DEBUG
1040   BAMBOO_DEBUGPRINT(0xe661);
1041   BAMBOO_DEBUGPRINT_REG((int)ptr);
1042   BAMBOO_DEBUGPRINT_REG(reallock);
1043   BAMBOO_DEBUGPRINT_REG(targetcore);
1044 #endif
1045
1046   if(targetcore == BAMBOO_NUM_OF_CORE) {
1047         BAMBOO_START_CRITICAL_SECTION_LOCK();
1048 #ifdef DEBUG
1049         BAMBOO_DEBUGPRINT(0xf001);
1050 #endif
1051     // reside on this core
1052     if(!RuntimeHashcontainskey(locktbl, reallock)) {
1053       // no locks for this object, something is wrong
1054       BAMBOO_EXIT(0xa01c);
1055     } else {
1056       int rwlock_obj = 0;
1057           struct LockValue * lockvalue = NULL;
1058       RuntimeHashget(locktbl, reallock, &rwlock_obj);
1059           lockvalue = (struct LockValue *)rwlock_obj;
1060       lockvalue->value++;
1061     }
1062         BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
1063 #ifdef DEBUG
1064         BAMBOO_DEBUGPRINT(0xf000);
1065 #endif
1066     return;
1067   } else {
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);
1071   }
1072 }
1073
1074 void releasewritelock_r(void * lock, void * redirectlock) {
1075   int targetcore = 0;
1076   int reallock = (int)lock;
1077   targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
1078
1079 #ifdef DEBUG
1080   BAMBOO_DEBUGPRINT(0xe671);
1081   BAMBOO_DEBUGPRINT_REG((int)lock);
1082   BAMBOO_DEBUGPRINT_REG(reallock);
1083   BAMBOO_DEBUGPRINT_REG(targetcore);
1084 #endif
1085
1086   if(targetcore == BAMBOO_NUM_OF_CORE) {
1087         BAMBOO_START_CRITICAL_SECTION_LOCK();
1088 #ifdef DEBUG
1089         BAMBOO_DEBUGPRINT(0xf001);
1090 #endif
1091     // reside on this core
1092     if(!RuntimeHashcontainskey(locktbl, reallock)) {
1093       // no locks for this object, something is wrong
1094       BAMBOO_EXIT(0xa01d);
1095     } else {
1096       int rwlock_obj = 0;
1097           struct LockValue * lockvalue = NULL;
1098 #ifdef DEBUG
1099       BAMBOO_DEBUGPRINT(0xe672);
1100 #endif
1101       RuntimeHashget(locktbl, reallock, &rwlock_obj);
1102           lockvalue = (struct LockValue *)rwlock_obj;
1103 #ifdef DEBUG
1104       BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1105 #endif
1106       lockvalue->value++;
1107           lockvalue->redirectlock = (int)redirectlock;
1108 #ifdef DEBUG
1109       BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1110 #endif
1111     }
1112         BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
1113 #ifdef DEBUG
1114         BAMBOO_DEBUGPRINT(0xf000);
1115 #endif
1116     return;
1117   } else {
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);
1121   }
1122 }
1123
1124 bool getwritelock_I(void * ptr) {
1125   int targetcore = 0;
1126   lockobj = (int)ptr;
1127   if(((struct ___Object___ *)ptr)->lock == NULL) {
1128         lock2require = lockobj;
1129   } else {
1130         lock2require = (int)(((struct ___Object___ *)ptr)->lock);
1131   }
1132   targetcore = (lock2require >> 5) % BAMBOO_TOTALCORE;
1133   lockflag = false;
1134 #ifndef INTERRUPT
1135   reside = false;
1136 #endif
1137   lockresult = 0;
1138
1139 #ifdef DEBUG
1140   BAMBOO_DEBUGPRINT(0xe561);
1141   BAMBOO_DEBUGPRINT_REG(lockobj);
1142   BAMBOO_DEBUGPRINT_REG(lock2require);
1143   BAMBOO_DEBUGPRINT_REG(targetcore);
1144 #endif
1145
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);
1149         if(deny == -1) {
1150                 // redirected
1151                 return true;
1152         } else {
1153                 if(lockobj == (int)ptr) {
1154                         if(deny) {
1155                                 lockresult = 0;
1156 #ifdef DEBUG
1157                                 BAMBOO_DEBUGPRINT(0);
1158 #endif
1159                         } else {
1160                                 lockresult = 1;
1161 #ifdef DEBUG
1162                                 BAMBOO_DEBUGPRINT(1);
1163 #endif
1164                         }
1165                         lockflag = true;
1166 #ifndef INTERRUPT
1167                         reside = true;
1168 #endif
1169                 } else {
1170                         // conflicts on lockresults
1171                         BAMBOO_EXIT(0xa01e);
1172                 }
1173                 return true;
1174         }
1175   } else {
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);
1180   }
1181   return true;
1182 }
1183
1184 // redirected lock request
1185 bool getwritelock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
1186   int targetcore = 0;
1187
1188   if(core == BAMBOO_NUM_OF_CORE) {
1189           lockobj = (int)ptr;
1190           lock2require = (int)redirectlock;
1191           lockflag = false;
1192 #ifndef INTERRUPT
1193           reside = false;
1194 #endif
1195           lockresult = 0;
1196   }
1197   targetcore = ((int)redirectlock >> 5) % BAMBOO_TOTALCORE;
1198
1199 #ifdef DEBUG
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);
1206 #endif
1207
1208
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);
1212         if(deny == -1) {
1213                 // redirected
1214                 return true;
1215         } else {
1216                 if(core == BAMBOO_NUM_OF_CORE) {
1217                         if(lockobj == (int)ptr) {
1218                                 if(deny) {
1219                                         lockresult = 0;
1220                                 } else {
1221                                         lockresult = 1;
1222                                         RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
1223                                 }
1224                                 lockflag = true;
1225 #ifndef INTERRUPT
1226                                 reside = true;
1227 #endif
1228                         } else {
1229                                 // conflicts on lockresults
1230                                 BAMBOO_EXIT(0xa01f);
1231                         }
1232                         return true;
1233                 } else {
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);
1239                         } else {
1240                                 cache_msg_4(core, deny==1?REDIRECTDENY:REDIRECTGROUNT, 1, 
1241                                                         (int)ptr, (int)redirectlock);
1242                         }
1243                 }
1244         }
1245   } else {
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);
1251         } else {
1252                 cache_msg_6(targetcore, REDIRECTLOCK, 1, (int)ptr, (int)redirectlock, 
1253                                         core, BAMBOO_NUM_OF_CORE);
1254         }
1255   }
1256   return true;
1257 }
1258
1259 void releasewritelock_I(void * ptr) {
1260   int targetcore = 0;
1261   int reallock = 0;
1262   if(((struct ___Object___ *)ptr)->lock == NULL) {
1263         reallock = (int)ptr;
1264   } else {
1265         reallock = (int)(((struct ___Object___ *)ptr)->lock);
1266   }
1267   targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
1268
1269 #ifdef DEBUG
1270   BAMBOO_DEBUGPRINT(0xe681);
1271   BAMBOO_DEBUGPRINT_REG((int)ptr);
1272   BAMBOO_DEBUGPRINT_REG(reallock);
1273   BAMBOO_DEBUGPRINT_REG(targetcore);
1274 #endif
1275
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);
1281     } else {
1282       int rwlock_obj = 0;
1283           struct LockValue * lockvalue = NULL;
1284       RuntimeHashget(locktbl, reallock, &rwlock_obj);
1285           lockvalue = (struct LockValue *)rwlock_obj;
1286       lockvalue->value++;
1287     }
1288     return;
1289   } else {
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);
1293   }
1294 }
1295
1296 void releasewritelock_I_r(void * lock, void * redirectlock) {
1297   int targetcore = 0;
1298   int reallock = (int)lock;
1299   targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
1300
1301 #ifdef DEBUG
1302   BAMBOO_DEBUGPRINT(0xe691);
1303   BAMBOO_DEBUGPRINT_REG((int)lock);
1304   BAMBOO_DEBUGPRINT_REG(reallock);
1305   BAMBOO_DEBUGPRINT_REG(targetcore);
1306 #endif
1307
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);
1313     } else {
1314       int rwlock_obj = 0;
1315           struct LockValue * lockvalue = NULL;
1316 #ifdef DEBUG
1317       BAMBOO_DEBUGPRINT(0xe692);
1318 #endif
1319       RuntimeHashget(locktbl, reallock, &rwlock_obj);
1320           lockvalue = (struct LockValue *)rwlock_obj;
1321 #ifdef DEBUG
1322       BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1323 #endif
1324       lockvalue->value++;
1325           lockvalue->redirectlock = (int)redirectlock;
1326 #ifdef DEBUG
1327       BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1328 #endif
1329     }
1330     return;
1331   } else {
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);
1335   }
1336 }
1337
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) {
1344   int deny = 0;
1345   if( ((lock >> 5) % BAMBOO_TOTALCORE) != BAMBOO_NUM_OF_CORE ) {
1346           // the lock should not be on this core
1347 #ifndef TILERA
1348           BAMBOO_DEBUGPRINT_REG(requestcore);
1349           BAMBOO_DEBUGPRINT_REG(lock);
1350           BAMBOO_DEBUGPRINT_REG(BAMBOO_NUM_OF_CORE);
1351 #endif
1352           BAMBOO_EXIT(0xa017);
1353   }
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;
1361 #ifdef DEBUG
1362 #ifndef TILERA
1363           BAMBOO_DEBUGPRINT(0xe110);
1364 #endif
1365 #endif
1366           if(locktype == 0) {
1367                   lockvalue->value = 1;
1368           } else {
1369                   lockvalue->value = -1;
1370           }
1371           RuntimeHashadd_I(locktbl, lock, (int)lockvalue);
1372   } else {
1373           int rwlock_obj = 0;
1374           struct LockValue * lockvalue = NULL;
1375 #ifdef DEBUG
1376 #ifndef TILERA
1377           BAMBOO_DEBUGPRINT(0xe111);
1378 #endif
1379 #endif
1380           RuntimeHashget(locktbl, lock, &rwlock_obj);
1381           lockvalue = (struct LockValue *)(rwlock_obj);
1382 #ifdef DEBUG
1383 #ifndef TILERA
1384           BAMBOO_DEBUGPRINT_REG(lockvalue->redirectlock);
1385 #endif
1386 #endif
1387           if(lockvalue->redirectlock != 0) {
1388                   // this lock is redirected
1389 #ifdef DEBUG
1390 #ifndef TILERA
1391                   BAMBOO_DEBUGPRINT(0xe112);
1392 #endif
1393 #endif
1394                   if(locktype == 0) {
1395                           getreadlock_I_r((void *)obj, (void *)lockvalue->redirectlock, rootrequestcore, cache);
1396                   } else {
1397                           getwritelock_I_r((void *)obj, (void *)lockvalue->redirectlock, rootrequestcore, cache);
1398                   }
1399                   return -1;  // redirected
1400           } else {
1401 #ifdef DEBUG
1402 #ifndef TILERA
1403                   BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1404 #endif
1405 #endif
1406                   if(0 == lockvalue->value) {
1407                           if(locktype == 0) {
1408                                   lockvalue->value = 1;
1409                           } else {
1410                                   lockvalue->value = -1;
1411                           }
1412                   } else if((lockvalue->value > 0) && (locktype == 0)) {
1413                           // read lock request and there are only read locks
1414                           lockvalue->value++;
1415                   } else {
1416                           deny = 1;
1417                   }
1418 #ifdef DEBUG
1419 #ifndef TILERA
1420                   BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1421 #endif
1422 #endif
1423           }
1424   }
1425   return deny;
1426 }
1427
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
1431 #ifdef DEBUG
1432                 BAMBOO_DEBUGPRINT_REG(lock);
1433 #endif
1434                 BAMBOO_EXIT(0xa00b);
1435         } else {
1436                 int rwlock_obj = 0;
1437                 struct LockValue * lockvalue = NULL;
1438                 RuntimeHashget(locktbl, lock, &rwlock_obj);
1439                 lockvalue = (struct LockValue*)(rwlock_obj);
1440 #ifdef DEBUG
1441                 BAMBOO_DEBUGPRINT(0xe884);
1442                 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1443 #endif
1444                 if(locktype == 0) {
1445                         lockvalue->value--;
1446                 } else {
1447                         lockvalue->value++;
1448                 }
1449 #ifdef DEBUG
1450                 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
1451 #endif
1452                 if(isredirect) {
1453                         lockvalue->redirectlock = redirectlock;
1454                 }
1455         }
1456 }
1457
1458 #ifdef PROFILE
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;
1468   }
1469 }
1470
1471 __attribute__((always_inline)) inline void profileTaskEnd() {
1472   if(!taskInfoOverflow) {
1473           taskInfoArray[taskInfoIndex]->endTime = raw_get_cycle();
1474           taskInfoIndex++;
1475           if(taskInfoIndex == TASKINFOLENGTH) {
1476                   taskInfoOverflow = true;
1477           }
1478   }
1479 }
1480
1481 // output the profiling data
1482 void outputProfileData() {
1483 #ifdef USEIO
1484   FILE * fp;
1485   char fn[50];
1486   int self_y, self_x;
1487   char c_y, c_x;
1488   int i;
1489   int totaltasktime = 0;
1490   int preprocessingtime = 0;
1491   int objqueuecheckingtime = 0;
1492   int postprocessingtime = 0;
1493   //int interruptiontime = 0;
1494   int other = 0;
1495   int averagetasktime = 0;
1496   int tasknum = 0;
1497
1498   for(i = 0; i < 50; i++) {
1499     fn[i] = 0;
1500   }
1501
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_");
1506   strcat(fn, &c_x);
1507   strcat(fn, "_");
1508   strcat(fn, &c_y);
1509   strcat(fn, ".rst");
1510
1511   if((fp = fopen(fn, "w+")) == NULL) {
1512     fprintf(stderr, "fopen error\n");
1513     return;
1514   }
1515
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))) {
1529                                 int num = 0;
1530                                 RuntimeHashget(nobjtbl, (int)objtype, &num);
1531                                 RuntimeHashremovekey(nobjtbl, (int)objtype);
1532                                 num++;
1533                                 RuntimeHashadd(nobjtbl, (int)objtype, num);
1534                         } else {
1535                                 RuntimeHashadd(nobjtbl, (int)objtype, 1);
1536                         }
1537                         //fprintf(stderr, "new obj!\n");
1538                 }
1539
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);
1546                 }
1547         }
1548         fprintf(fp, "\n");
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;
1555     } else {
1556       totaltasktime += duration;
1557       averagetasktime += duration;
1558       tasknum++;
1559     }
1560   }
1561
1562   if(taskInfoOverflow) {
1563     fprintf(stderr, "Caution: task info overflow!\n");
1564   }
1565
1566   other = totalexetime - totaltasktime - preprocessingtime - postprocessingtime;
1567   averagetasktime /= tasknum;
1568
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);
1575
1576   fprintf(fp, "\nAverage task execution time: %d\n", averagetasktime);
1577
1578   fclose(fp);
1579 #else
1580   int i = 0;
1581   int j = 0;
1582
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]);
1592     }
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))) {
1603                                 int num = 0;
1604                                 RuntimeHashget(nobjtbl, (int)objtype, &num);
1605                                 RuntimeHashremovekey(nobjtbl, (int)objtype);
1606                                 num++;
1607                                 RuntimeHashadd(nobjtbl, (int)objtype, num);
1608                         } else {
1609                                 RuntimeHashadd(nobjtbl, (int)objtype, 1);
1610                         }
1611                 }
1612
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]);
1622                         }
1623                         BAMBOO_DEBUGPRINT(0xdddb);
1624                         BAMBOO_DEBUGPRINT_REG(num);
1625                 }
1626         }
1627     BAMBOO_DEBUGPRINT(0xdddc);
1628   }
1629
1630   if(taskInfoOverflow) {
1631     BAMBOO_DEBUGPRINT(0xefee);
1632   }
1633
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);
1641      }
1642
1643      if(interruptInfoOverflow) {
1644        BAMBOO_DEBUGPRINT(0xefef);
1645      }*/
1646
1647   BAMBOO_DEBUGPRINT(0xeeee);
1648 #endif
1649 }
1650 #endif  // #ifdef PROFILE
1651
1652 #endif // #ifdef TASK