Add support for 'static' fields in multicore gc version w/o tasks. Now we can have...
[IRC.git] / Robust / src / Runtime / bamboo / multicoreruntime.h
1 #ifndef MULTICORE_RUNTIME
2 #define MULTICORE_RUNTIME
3 #include "structdefs.h"
4
5 #ifndef INLINE
6 #define INLINE    inline __attribute__((always_inline))
7 #endif
8
9 #ifndef bool
10 #define bool int
11 #define true 1
12 #define false 0
13 #endif
14
15 ////////////////////////////////////////////////////////////////
16 // global variables                                          //
17 ///////////////////////////////////////////////////////////////
18
19 // record the starting time
20 unsigned long long bamboo_start_time;
21 bool stall;
22 int totalexetime;
23 #ifndef INTERRUPT
24 bool reside;
25 #endif
26
27 #ifdef MGC
28 // shared memory pointer for global thread queue
29 // In MGC version, this block of memory is located at the very bottom of the 
30 // shared memory with the base address as BAMBOO_BASE_VA.
31 // The bottom of the shared memory = global thread queue + sbstart tbl 
32 //                                  + smemtbl + NUMCORES4GC bamboo_rmsp
33 // This queue is always reside at the bottom of the shared memory.  It is 
34 // considered as runtime structure, during gc, it is scanned for mark and flush 
35 // phase but never been compacted.
36 //
37 // This is a loop array and the first 4 int fields of the queue are:
38 //     mutex + thread counter + start pointer + end pointer
39 #ifdef GC_SMALLPAGESIZE
40 #define BAMBOO_THREAD_QUEUE_SIZE (1024 * 1024)
41 #define BAMBOO_GLOBAL_DEFS_SIZE (1024 * 1024)
42 #else
43 #define BAMBOO_THREAD_QUEUE_SIZE (BAMBOO_SMEM_SIZE) // (45 * 16 * 1024)
44 #define BAMBOO_GLOBAL_DEFS_SIZE (BAMBOO_SMEM_SIZE)
45 #endif
46 // data structures for threads
47 INTPTR * bamboo_thread_queue;
48 unsigned int bamboo_max_thread_num_mask;
49 INTPTR bamboo_current_thread;
50
51 extern int corenum;
52 #endif // MGC
53
54 // data structures for msgs
55 #define BAMBOO_OUT_BUF_LENGTH 2048
56 #define BAMBOO_OUT_BUF_MASK (0x7FF)
57 #define BAMBOO_MSG_BUF_LENGTH 2048
58 #define BAMBOO_MSG_BUF_MASK (0x7FF)
59 int msgdata[BAMBOO_MSG_BUF_LENGTH];
60 volatile int msgdataindex;
61 volatile int msgdatalast;
62 int msglength;
63 volatile bool msgdatafull;
64 int outmsgdata[BAMBOO_OUT_BUF_LENGTH];
65 int outmsgindex;
66 int outmsglast;
67 int outmsgleft;
68 volatile bool isMsgHanging;
69
70 #define MSG_INDEXINC_I() \
71   msgdataindex = (msgdataindex + 1) & (BAMBOO_MSG_BUF_MASK) 
72
73 #define MSG_LASTINDEXINC_I() \
74   msgdatalast = (msgdatalast + 1) & (BAMBOO_MSG_BUF_MASK)
75
76 #define MSG_CACHE_I(n) \
77   msgdata[msgdatalast] = (n); \
78   MSG_LASTINDEXINC_I()
79
80 // NOTE: if msgdataindex == msgdatalast, it always means that the buffer if
81 //       full. In the case that the buffer is empty, should never call this
82 //       MACRO
83 #define MSG_REMAINSIZE_I(s) \
84   if(msgdataindex < msgdatalast) { \
85     (*(int*)s) = msgdatalast - msgdataindex; \
86   } else if((msgdataindex == msgdatalast) && (!msgdatafull)) { \
87     (*(int*)s) = 0; \
88   } else { \
89     (*(int*)s) = (BAMBOO_MSG_BUF_LENGTH) - msgdataindex + msgdatalast; \
90   }
91
92 #define OUTMSG_INDEXINC() \
93   outmsgindex = (outmsgindex + 1) & (BAMBOO_OUT_BUF_MASK)
94
95 #define OUTMSG_LASTINDEXINC() \
96   outmsglast = (outmsglast + 1) & (BAMBOO_OUT_BUF_MASK); \
97   if(outmsglast == outmsgindex) { \
98     BAMBOO_EXIT(0xd101); \
99   }
100
101 #define OUTMSG_CACHE(n) \
102   outmsgdata[outmsglast] = (n); \
103   OUTMSG_LASTINDEXINC();
104
105 #define MAX_PACKET_WORDS 5
106
107 /* Message format:
108  *      type + Msgbody
109  * type: 1 -- transfer object
110  *       2 -- transfer stall msg
111  *       3 -- lock request
112  *       4 -- lock grount
113  *       5 -- lock deny
114  *       6 -- lock release
115  *       // add for profile info
116  *       7 -- transfer profile output msg
117  *       8 -- transfer profile output finish msg
118  *       // add for alias lock strategy
119  *       9 -- redirect lock request
120  *       a -- lock grant with redirect info
121  *       b -- lock deny with redirect info
122  *       c -- lock release with redirect info
123  *       d -- status confirm request
124  *       e -- status report msg
125  *       f -- terminate
126  *      10 -- requiring for new memory
127  *      11 -- response for new memory request
128  *      12 -- GC init phase start
129  *      13 -- GC start
130  *      14 -- compact phase start
131  *      15 -- flush phase start
132  *      16 -- init phase finish
133  *      17 -- mark phase finish
134  *      18 -- compact phase finish
135  *      19 -- flush phase finish
136  *      1a -- GC finish
137  *      1b -- marked phase finish confirm request
138  *      1c -- marked phase finish confirm response
139  *      1d -- markedObj msg
140  *      1e -- start moving objs msg
141  *      1f -- ask for mapping info of a markedObj
142  *      20 -- mapping info of a markedObj
143  *      21 -- large objs info request
144  *      22 -- large objs info response
145  *      23 -- large objs mapping info
146  *
147  * ObjMsg: 1 + size of msg + obj's address + (task index + param index)+
148  * StallMsg: 2 + corenum + sendobjs + receiveobjs
149  *             (size is always 4 * sizeof(int))
150  * LockMsg: 3 + lock type + obj pointer + lock + request core
151  *            (size is always 5 * sizeof(int))
152  *          4/5/6 + lock type + obj pointer + lock
153  *            (size is always 4 * sizeof(int))
154  *          9 + lock type + obj pointer +  redirect lock + root request core
155  *            + request core
156  *            (size is always 6 * sizeof(int))
157  *          a/b + lock type + obj pointer + redirect lock
158  *              (size is always 4 * sizeof(int))
159  *          c + lock type + lock + redirect lock
160  *            (size is always 4 * sizeof(int))
161  *          lock type: 0 -- read; 1 -- write
162  * ProfileMsg: 7 + totalexetime
163  *               (size is always 2 * sizeof(int))
164  *             8 + corenum
165  *               (size is always 2 * sizeof(int))
166  * StatusMsg: d (size is always 1 * sizeof(int))
167  *            e + status + corenum + sendobjs + receiveobjs
168  *              (size is always 5 * sizeof(int))
169  *            status: 0 -- stall; 1 -- busy
170  * TerminateMsg: f (size is always 1 * sizeof(int)
171  * MemoryMsg: 10 + size + corenum
172  *              (size is always 3 * sizeof(int))
173  *           11 + base_va + size
174  *              (size is always 3 * sizeof(int))
175  * GCMsg: 12/13 (size is always 1 * sizeof(int))
176  *        14 + size of msg + (num of objs to move + (start address
177  *           + end address + dst core + start dst)+)?
178  *           + (num of incoming objs + (start dst + orig core)+)?
179  *           + (num of large obj lists + (start address + lenght
180  *           + start dst)+)?
181  *        15 (size is always 1 * sizeof(int))
182  *        16 + corenum
183  *           (size is always 2 * sizeof(int))
184  *        17 + corenum + gcsendobjs + gcreceiveobjs
185  *           (size if always 4 * sizeof(int))
186  *        18 + corenum + fulfilled blocks num + (finish compact(1) + current
187  *           heap top)/(need mem(0) + mem need)
188  *           size is always 5 * sizeof(int))
189  *        19 + corenum
190  *              (size is always 2 * sizeof(int))
191  *        1a (size is always 1 * sizeof(int))
192  *        1b (size if always 1 * sizeof(int))
193  *        1c + size of msg + corenum + gcsendobjs + gcreceiveobjs
194  *           (size is always 5 * sizeof(int))
195  *        1d + obj's address + request core
196  *           (size is always 3 * sizeof(int))
197  *        1e + corenum + start addr + end addr
198  *           (size if always 4 * sizeof(int))
199  *        1f + obj's address + corenum
200  *           (size is always 3 * sizeof(int))
201  *        20 + obj's address + dst address
202  *           (size if always 3 * sizeof(int))
203  *        21 (size is always 1 * sizeof(int))
204  *        22 + size of msg + corenum + current heap size
205  *           + (num of large obj lists + (start address + length)+)?
206  *        23 + orig large obj ptr + new large obj ptr
207  *            (size is always 3 * sizeof(int))
208  */
209 typedef enum {
210   MSGSTART = 0xD0,       // 0xD0
211   TRANSOBJ,              // 0xD1
212   TRANSTALL,             // 0xD2
213   LOCKREQUEST,           // 0xD3
214   LOCKGROUNT,            // 0xD4
215   LOCKDENY,              // 0xD5
216   LOCKRELEASE,           // 0xD6
217   PROFILEOUTPUT,         // 0xD7
218   PROFILEFINISH,         // 0xD8
219   REDIRECTLOCK,          // 0xD9
220   REDIRECTGROUNT,        // 0xDa
221   REDIRECTDENY,          // 0xDb
222   REDIRECTRELEASE,       // 0xDc
223   STATUSCONFIRM,         // 0xDd
224   STATUSREPORT,          // 0xDe
225   TERMINATE,             // 0xDf
226   MEMREQUEST,            // 0xE0
227   MEMRESPONSE,           // 0xE1
228 #ifdef MULTICORE_GC
229   GCSTARTPRE,            // 0xE2
230   GCSTARTINIT,           // 0xE3
231   GCSTART,               // 0xE4
232   GCSTARTCOMPACT,        // 0xE5
233   GCSTARTMAPINFO,        // 0xE6
234   GCSTARTFLUSH,          // 0xE7
235   GCFINISHPRE,           // 0xE8
236   GCFINISHINIT,          // 0xE9
237   GCFINISHMARK,          // 0xEa
238   GCFINISHCOMPACT,       // 0xEb
239   GCFINISHMAPINFO,       // 0xEc
240   GCFINISHFLUSH,         // 0xEd
241   GCFINISH,              // 0xEe
242   GCMARKCONFIRM,         // 0xEf
243   GCMARKREPORT,          // 0xF0
244   GCMARKEDOBJ,           // 0xF1
245   GCMOVESTART,           // 0xF2
246   GCMAPREQUEST,          // 0xF3
247   GCMAPINFO,             // 0xF4
248   GCMAPTBL,              // 0xF5
249   GCLOBJREQUEST,         // 0xF6
250   GCLOBJINFO,            // 0xF7
251   GCLOBJMAPPING,         // 0xF8
252 #ifdef GC_PROFILE
253   GCPROFILES,            // 0xF9
254 #endif // GC_PROFILE
255 #ifdef GC_CACHE_ADAPT
256   GCSTARTPOSTINIT,       // 0xFa
257   GCSTARTPREF,           // 0xFb
258   GCFINISHPOSTINIT,      // 0xFc
259   GCFINISHPREF,          // 0xFd
260 #endif // GC_CACHE_ADAPT
261 #endif // MULTICORE_GC
262   MSGEND
263 } MSGTYPE;
264
265 /////////////////////////////////////////////////////////////////////////////////
266 // NOTE: BAMBOO_TOTALCORE -- number of the available cores in the processor.
267 //                           No greater than the number of all the cores in
268 //                           the processor
269 //       NUMCORES -- number of cores chosen to deploy the application. It can
270 //                   be greater than that required to fully parallelize the
271 //                   application. The same as NUMCORES.
272 //       NUMCORESACTIVE -- number of cores that really execute the
273 //                         application. No greater than NUMCORES
274 //       NUMCORES4GC -- number of cores for gc. No greater than NUMCORES.
275 //                      NOTE: currently only support ontinuous cores as gc
276 //                            cores, i.e. 0~NUMCORES4GC-1
277 ////////////////////////////////////////////////////////////////////////////////
278 // data structures of status for termination
279 // only check working cores
280 volatile int corestatus[NUMCORESACTIVE]; // records status of each core
281                                          // 1: running tasks
282                                          // 0: stall
283 volatile int numsendobjs[NUMCORESACTIVE]; // records how many objects a core
284                                           // has sent out
285 volatile int numreceiveobjs[NUMCORESACTIVE]; // records how many objects a
286                                              // core has received
287 volatile int numconfirm;
288 volatile bool waitconfirm;
289 bool busystatus;
290 int self_numsendobjs;
291 int self_numreceiveobjs;
292
293 // TASK specific data structures
294 #ifdef TASK
295 // get rid of lock msgs for GC version
296 #ifndef MULTICORE_GC
297 // data structures for locking
298 struct RuntimeHash locktable;
299 static struct RuntimeHash* locktbl = &locktable;
300 struct RuntimeHash * lockRedirectTbl;
301 struct RuntimeHash * objRedirectLockTbl;
302 #endif // ifndef MULTICORE_GC
303 struct LockValue {
304   int redirectlock;
305   int value;
306 };
307 int lockobj;
308 int lock2require;
309 int lockresult;
310 bool lockflag;
311
312 // data structures for waiting objs
313 struct Queue objqueue;
314 struct Queue * totransobjqueue; // queue to hold objs to be transferred
315                                 // should be cleared whenever enter a task
316                                         
317 // for test TODO
318 int total_num_t6;
319
320 // data structures for profile mode
321 #ifdef PROFILE
322 #define TASKINFOLENGTH 3000 // 0
323 #ifdef PROFILE_INTERRUPT
324 #define INTERRUPTINFOLENGTH 50 //0
325 #endif // PROFILE_INTERRUPT
326
327 typedef struct task_info {
328   char* taskName;
329   unsigned long long startTime;
330   unsigned long long endTime;
331   unsigned long long exitIndex;
332   struct Queue * newObjs;
333 } TaskInfo;
334
335 TaskInfo * taskInfoArray[TASKINFOLENGTH];
336 int taskInfoIndex;
337 bool taskInfoOverflow;
338 #ifdef PROFILE_INTERRUPT
339 typedef struct interrupt_info {
340   unsigned long long startTime;
341   unsigned long long endTime;
342 } InterruptInfo;
343
344 InterruptInfo * interruptInfoArray[INTERRUPTINFOLENGTH];
345 int interruptInfoIndex;
346 bool interruptInfoOverflow;
347 #endif // PROFILE_INTERUPT
348 volatile int profilestatus[NUMCORESACTIVE]; // records status of each core
349                                             // 1: running tasks
350                                             // 0: stall
351 #endif // #ifdef PROFILE
352 #endif // TASK
353
354 #include "multicoremem.h"
355
356 /////////////////////////////////////////////////////////////
357
358 ////////////////////////////////////////////////////////////
359 // these are functions should be implemented in           //
360 // multicore runtime for any multicore processors         //
361 ////////////////////////////////////////////////////////////
362 #ifdef MULTICORE
363 INLINE void initialization(void);
364 INLINE void initCommunication(void);
365 INLINE void fakeExecution(void);
366 INLINE void terminate(void);
367 INLINE void initlock(struct ___Object___ * v);
368 #ifdef BAMBOO_MEMPROF
369 INLINE void terminatememprof(void);
370 #endif // BAMBOO_MEMPROF
371
372 // msg related functions
373 INLINE void send_hanging_msg(bool isInterrupt);
374 INLINE void send_msg_1(int targetcore,
375                        unsigned long n0,
376                                            bool isInterrupt);
377 INLINE void send_msg_2(int targetcore,
378                        unsigned long n0,
379                        unsigned long n1,
380                                            bool isInterrupt);
381 INLINE void send_msg_3(int targetcore,
382                        unsigned long n0,
383                        unsigned long n1,
384                        unsigned long n2,
385                                            bool isInterrupt);
386 INLINE void send_msg_4(int targetcore,
387                        unsigned long n0,
388                        unsigned long n1,
389                        unsigned long n2,
390                        unsigned long n3,
391                                            bool isInterrupt);
392 INLINE void send_msg_5(int targetcore,
393                        unsigned long n0,
394                        unsigned long n1,
395                        unsigned long n2,
396                        unsigned long n3,
397                        unsigned long n4,
398                                            bool isInterrupt);
399 INLINE void send_msg_6(int targetcore,
400                        unsigned long n0,
401                        unsigned long n1,
402                        unsigned long n2,
403                        unsigned long n3,
404                        unsigned long n4,
405                        unsigned long n5,
406                                            bool isInterrupt);
407 INLINE void cache_msg_1(int targetcore,
408                         unsigned long n0);
409 INLINE void cache_msg_2(int targetcore,
410                         unsigned long n0,
411                         unsigned long n1);
412 INLINE void cache_msg_3(int targetcore,
413                         unsigned long n0,
414                         unsigned long n1,
415                         unsigned long n2);
416 INLINE void cache_msg_4(int targetcore,
417                         unsigned long n0,
418                         unsigned long n1,
419                         unsigned long n2,
420                         unsigned long n3);
421 INLINE void cache_msg_5(int targetcore,
422                         unsigned long n0,
423                         unsigned long n1,
424                         unsigned long n2,
425                         unsigned long n3,
426                         unsigned long n4);
427 INLINE void cache_msg_6(int targetcore,
428                         unsigned long n0,
429                         unsigned long n1,
430                         unsigned long n2,
431                         unsigned long n3,
432                         unsigned long n4,
433                         unsigned long n5);
434 INLINE int receiveMsg(unsigned int send_port_pending);
435
436 #ifdef MULTICORE_GC
437 INLINE void transferMarkResults();
438 #endif // MULTICORE_GC
439
440 #ifdef TASK
441 // lock related functions
442 bool getreadlock(void* ptr);
443 void releasereadlock(void* ptr);
444 bool getwritelock(void* ptr);
445 void releasewritelock(void* ptr);
446 bool getwritelock_I(void* ptr);
447 void releasewritelock_I(void * ptr);
448 #ifndef MULTICORE_GC
449 void releasewritelock_r(void * lock, void * redirectlock);
450 #endif // ifndef MULTICORE_GC
451 /* this function is to process lock requests.
452  * can only be invoked in receiveObject() */
453 // if return -1: the lock request is redirected
454 //            0: the lock request is approved
455 //            1: the lock request is denied
456 INLINE int processlockrequest(int locktype,
457                               int lock,
458                               int obj,
459                               int requestcore,
460                               int rootrequestcore,
461                               bool cache);
462 INLINE void processlockrelease(int locktype,
463                                int lock,
464                                int redirectlock,
465                                bool redirect);
466
467 // msg related functions
468 INLINE void transferObject(struct transObjInfo * transObj);
469
470 #ifdef PROFILE
471 INLINE void profileTaskStart(char * taskname);
472 INLINE void profileTaskEnd(void);
473 void outputProfileData();
474 #endif  // #ifdef PROFILE
475 ///////////////////////////////////////////////////////////
476
477 /////////////////////////////////////////////////////////////////////////////
478 // For each version of BAMBOO runtime, there should be a header file named //
479 // runtim_arch.h defining following MARCOS:                                //
480 // BAMBOO_NUM_OF_CORE: the # of current residing core                      //
481 // BAMBOO_GET_NUM_OF_CORE(): compute the # of current residing core        //
482 // BAMBOO_COORDS(c, x, y): convert the cpu # to coords (*x, *y)            //
483 // BAMBOO_DEBUGPRINT(x): print out integer x                               //
484 // BAMBOO_DEBUGPRINT_REG(x): print out value of variable x                 //
485 // BAMBOO_EXIT_APP(x): exit the whole application                          //
486 // BAMBOO_EXIT(x): error exit routine with error #                         //
487 // BAMBOO_DIE(x): error exit routine with error msg                        //
488 // BAMBOO_GET_EXE_TIME(): rountine to get current clock cycle number       //
489 // BAMBOO_MSG_AVAIL(): checking if there are msgs coming in                //
490 // BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT(): change to runtime mode from    //
491 //                                          client mode                    //
492 // BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME(): change to client mode from     //
493 //                                          runtime mode                   //
494 // BAMBOO_ENTER_SEND_MODE_FROM_CLIENT(): change to send mode from          //
495 //                                       client mode                       //
496 // BAMBOO_ENTER_CLIENT_MODE_FROM_SEND(): change to client mode from        //
497 //                                       send mode                         //
498 // BAMBOO_ENTER_RUNTIME_MODE_FROM_SEND(): change to runtime mode from      //
499 //                                        send mode                        //
500 // BAMBOO_ENTER_SEND_MODE_FROM_RUNTIME(): change to send mode from         //
501 //                                        runtime mode                     //
502 // BAMBOO_WAITING_FOR_LOCK(): routine executed while waiting for lock      //
503 //                            request response                             //
504 // BAMBOO_LOCAL_MEM_CALLOC(x, y): allocate an array of x elements each of  //
505 //                                whose size in bytes is y on local memory //
506 //                                which is given by the hypervisor         //
507 // BAMBOO_LOCAL_MEM_FREE(x): free space with ptr x on local memory         //
508 // BAMBOO_LOCAL_MEM_CLOSE(): close the local heap                          //
509 // BAMBOO_LOCAL_MEM_CALLOC_S(x, y): allocate an array of x elements each of//
510 //                                  whose size in bytes is y on local      //
511 //                                  memory which is not from the hypervisor//
512 //                                  but is allocated from the free memory  //
513 // BAMBOO_LOCAL_MEM_FREE_S(x): free space with ptr x on self-allocated     //
514 //                             local memory                                //
515 // BAMBOO_LOCAL_MEM_CLOSE_S(): close the self-allocated local heap        //
516 // BAMBOO_SHARE_MEM_CALLOC_I(x, y): allocate an array of x elements each of//
517 //                                whose size in bytes is y on shared memory//
518 // BAMBOO_SHARE_MEM_CLOSE(): close the shared heap                         //
519 // BAMBOO_CACHE_LINE_SIZE: the cache line size                             //
520 // BAMBOO_CACHE_LINE_MASK: mask for a cache line                           //
521 // BAMBOO_CACHE_FLUSH_RANGE(x, y): flush cache lines started at x with     //
522 //                                 length y                                //
523 // BAMBOO_CACHE_FLUSH_ALL(): flush the whole cache of a core if necessary  //
524 // BAMBOO_MEMSET_WH(x, y, z): memset the specified region of memory (start //
525 //                            address x, size z) to value y with write     //
526 //                            hint, the processor will not fetch the       //
527 //                            current content of the memory and directly   //
528 //                            write                                        //
529 // BAMBOO_CLEAN_DTLB(): zero-out all the dtlb entries                      //
530 // BAMBOO_CACHE_FLUSH_L2(): Flush the contents of this tile's L2 back to   //
531 //                          main memory                                    //
532 // BAMBOO_CACHE_FLUSH_RANGE_NO_FENCE(x, y): flush a range of mem without   //
533 //                                          mem fence                      //
534 // BAMBOO_CACHE_MEM_FENCE_INCOHERENT(): fence to guarantee visibility of   //
535 //                                      stores to incoherent memory        //
536 /////////////////////////////////////////////////////////////////////////////
537
538 #endif  // #ifdef TASK
539 #endif  // #ifdef MULTICORE
540 #endif  // #ifndef MULTICORE_RUNTIME