code clean: define TILERA_BME mode and TILERA_ZLINUX mode. TILERA_ZLINUX mode is...
[IRC.git] / Robust / src / Runtime / multicoreruntime.h
1 #ifndef MULTICORE_RUNTIME
2 #define MULTICORE_RUNTIME
3
4 #ifndef INLINE
5 #define INLINE    inline __attribute__((always_inline))
6 #endif
7
8 ////////////////////////////////////////////////////////////////
9 // global variables                                          //
10 ///////////////////////////////////////////////////////////////
11
12 // record the starting time
13 unsigned long long bamboo_start_time;
14
15 // data structures for msgs
16 #define BAMBOO_OUT_BUF_LENGTH 3000
17 #define BAMBOO_MSG_BUF_LENGTH 3000
18 int msgdata[BAMBOO_MSG_BUF_LENGTH];
19 int msgdataindex;
20 int msgdatalast;
21 int msglength;
22 volatile bool msgdatafull;
23 int outmsgdata[BAMBOO_OUT_BUF_LENGTH];
24 int outmsgindex;
25 int outmsglast;
26 int outmsgleft;
27 volatile bool isMsgHanging;
28 volatile bool isMsgSending;
29
30 #define MSG_INDEXINC_I() \
31         msgdataindex = (msgdataindex + 1) % (BAMBOO_MSG_BUF_LENGTH)
32
33 #define MSG_LASTINDEXINC_I() \
34         msgdatalast = (msgdatalast + 1) % (BAMBOO_MSG_BUF_LENGTH)
35
36 #define MSG_CACHE_I(n) \
37         msgdata[msgdatalast] = (n); \
38   MSG_LASTINDEXINC_I() 
39
40 // NOTE: if msgdataindex == msgdatalast, it always means that the buffer if 
41 //       full. In the case that the buffer is empty, should never call this
42 //       MACRO
43 #define MSG_REMAINSIZE_I(s) \
44         if(msgdataindex < msgdatalast) { \
45                 (*(int*)s) = msgdatalast - msgdataindex; \
46         } else if((msgdataindex == msgdatalast) && (!msgdatafull)) {\
47                 (*(int*)s) = 0; \
48         }       else { \
49                 (*(int*)s) = (BAMBOO_MSG_BUF_LENGTH) - msgdataindex + msgdatalast; \
50         } 
51
52 #define OUTMSG_INDEXINC() \
53         outmsgindex = (outmsgindex + 1) % (BAMBOO_OUT_BUF_LENGTH)
54
55 #define OUTMSG_LASTINDEXINC() \
56         outmsglast = (outmsglast + 1) % (BAMBOO_OUT_BUF_LENGTH); \
57         if(outmsglast == outmsgindex) { \
58                 BAMBOO_EXIT(0xdd01); \
59         } 
60
61 #define OUTMSG_CACHE(n) \
62         outmsgdata[outmsglast] = (n); \
63   OUTMSG_LASTINDEXINC(); 
64
65 #define MAX_PACKET_WORDS 5
66
67 /* Message format:
68  *      type + Msgbody
69  * type: 1 -- transfer object
70  *       2 -- transfer stall msg
71  *       3 -- lock request
72  *       4 -- lock grount
73  *       5 -- lock deny
74  *       6 -- lock release
75  *       // add for profile info
76  *       7 -- transfer profile output msg
77  *       8 -- transfer profile output finish msg
78  *       // add for alias lock strategy
79  *       9 -- redirect lock request
80  *       a -- lock grant with redirect info
81  *       b -- lock deny with redirect info
82  *       c -- lock release with redirect info
83  *       d -- status confirm request
84  *       e -- status report msg
85  *       f -- terminate
86  *      10 -- requiring for new memory
87  *      11 -- response for new memory request
88  *      12 -- GC init phase start
89  *      13 -- GC start
90  *      14 -- compact phase start
91  *      15 -- flush phase start
92  *      16 -- init phase finish
93  *      17 -- mark phase finish
94  *      18 -- compact phase finish
95  *      19 -- flush phase finish
96  *      1a -- GC finish
97  *      1b -- marked phase finish confirm request
98  *      1c -- marked phase finish confirm response
99  *      1d -- markedObj msg
100  *      1e -- start moving objs msg
101  *      1f -- ask for mapping info of a markedObj
102  *      20 -- mapping info of a markedObj
103  *      21 -- large objs info request
104  *      22 -- large objs info response
105  *      23 -- large objs mapping info
106  *
107  * ObjMsg: 1 + size of msg + obj's address + (task index + param index)+
108  * StallMsg: 2 + corenum + sendobjs + receiveobjs 
109  *             (size is always 4 * sizeof(int))
110  * LockMsg: 3 + lock type + obj pointer + lock + request core 
111  *            (size is always 5 * sizeof(int))
112  *          4/5/6 + lock type + obj pointer + lock 
113  *            (size is always 4 * sizeof(int))
114  *          9 + lock type + obj pointer +  redirect lock + root request core 
115  *            + request core 
116  *            (size is always 6 * sizeof(int))
117  *          a/b + lock type + obj pointer + redirect lock 
118  *              (size is always 4 * sizeof(int))
119  *          c + lock type + lock + redirect lock 
120  *            (size is always 4 * sizeof(int))
121  *          lock type: 0 -- read; 1 -- write
122  * ProfileMsg: 7 + totalexetime 
123  *               (size is always 2 * sizeof(int))
124  *             8 + corenum 
125  *               (size is always 2 * sizeof(int))
126  * StatusMsg: d (size is always 1 * sizeof(int))
127  *            e + status + corenum + sendobjs + receiveobjs 
128  *              (size is always 5 * sizeof(int))
129  *            status: 0 -- stall; 1 -- busy
130  * TerminateMsg: f (size is always 1 * sizeof(int)
131  * MemoryMsg: 10 + size + corenum 
132  *              (size is always 3 * sizeof(int))
133  *           11 + base_va + size 
134  *              (size is always 3 * sizeof(int))
135  * GCMsg: 12/13 (size is always 1 * sizeof(int))
136  *        14 + size of msg + (num of objs to move + (start address 
137  *           + end address + dst core + start dst)+)? 
138  *           + (num of incoming objs + (start dst + orig core)+)? 
139  *           + (num of large obj lists + (start address + lenght 
140  *           + start dst)+)?
141  *        15 (size is always 1 * sizeof(int))
142  *        16 + corenum 
143  *           (size is always 2 * sizeof(int))
144  *        17 + corenum + gcsendobjs + gcreceiveobjs     
145  *           (size if always 4 * sizeof(int))
146  *        18 + corenum + fulfilled blocks num + (finish compact(1) + current
147  *           heap top)/(need mem(0) + mem need) 
148  *           size is always 5 * sizeof(int))
149  *        19 + corenum 
150  *              (size is always 2 * sizeof(int))
151  *        1a (size is always 1 * sizeof(int))
152  *        1b (size if always 1 * sizeof(int))
153  *        1c + size of msg + corenum + gcsendobjs + gcreceiveobjs 
154  *           (size is always 5 * sizeof(int))
155  *        1d + obj's address 
156  *           (size is always 2 * sizeof(int))
157  *        1e + corenum + start addr + end addr
158  *           (size if always 4 * sizeof(int))
159  *        1f + obj's address + corenum 
160  *           (size is always 3 * sizeof(int))
161  *        20 + obj's address + dst address 
162  *           (size if always 3 * sizeof(int))
163  *        21 (size is always 1 * sizeof(int))
164  *        22 + size of msg + corenum + current heap size 
165  *           + (num of large obj lists + (start address + length)+)?
166  *        23 + orig large obj ptr + new large obj ptr 
167  *            (size is always 3 * sizeof(int))
168  */
169 typedef enum {
170         MSGSTART = 0xD0, // 0xD0
171         TRANSOBJ,        // 0xD1
172         TRANSTALL,       // 0xD2
173         LOCKREQUEST,     // 0xD3
174         LOCKGROUNT,      // 0xD4
175         LOCKDENY,        // 0xD5
176         LOCKRELEASE,     // 0xD6
177         PROFILEOUTPUT,   // 0xD7
178         PROFILEFINISH,   // 0xD8
179         REDIRECTLOCK,    // 0xD9
180         REDIRECTGROUNT,  // 0xDa
181         REDIRECTDENY,    // 0xDb
182         REDIRECTRELEASE, // 0xDc
183         STATUSCONFIRM,   // 0xDd
184         STATUSREPORT,    // 0xDe
185         TERMINATE,       // 0xDf
186         MEMREQUEST,      // 0xE0
187         MEMRESPONSE,     // 0xE1
188 #ifdef MULTICORE_GC
189         GCSTARTINIT,     // 0xE2
190         GCSTART,         // 0xE3
191         GCSTARTCOMPACT,  // 0xE4
192         GCSTARTFLUSH,    // 0xE5
193         GCFINISHINIT,    // 0xE6
194         GCFINISHMARK,    // 0xE7
195         GCFINISHCOMPACT, // 0xE8
196         GCFINISHFLUSH,   // 0xE9
197         GCFINISH,        // 0xEa
198         GCMARKCONFIRM,   // 0xEb
199         GCMARKREPORT,    // 0xEc
200         GCMARKEDOBJ,     // 0xEd
201         GCMOVESTART,     // 0xEe
202         GCMAPREQUEST,    // 0xEf
203         GCMAPINFO,       // 0xF0
204         GCLOBJREQUEST,   // 0xF1
205         GCLOBJINFO,      // 0xF2
206         GCLOBJMAPPING,   // 0xF3
207 #endif
208         MSGEND
209 } MSGTYPE;
210
211 /////////////////////////////////////////////////////////////////////////////////
212 // NOTE: BAMBOO_TOTALCORE -- number of the available cores in the processor. 
213 //                           No greater than the number of all the cores in 
214 //                           the processor
215 //       NUMCORES -- number of cores chosen to deploy the application. It can 
216 //                   be greater than that required to fully parallelize the 
217 //                   application. The same as NUMCORES.
218 //       NUMCORESACTIVE -- number of cores that really execute the 
219 //                         application. No greater than NUMCORES
220 //       NUMCORES4GC -- number of cores for gc. No greater than NUMCORES. 
221 //                      NOTE: currently only support ontinuous cores as gc 
222 //                            cores, i.e. 0~NUMCORES4GC-1
223 ////////////////////////////////////////////////////////////////////////////////
224 // data structures of status for termination
225 // only check working cores
226 volatile int corestatus[NUMCORESACTIVE]; // records status of each core
227                                          // 1: running tasks
228                                          // 0: stall
229 volatile int numsendobjs[NUMCORESACTIVE]; // records how many objects a core 
230                                           // has sent out
231 volatile int numreceiveobjs[NUMCORESACTIVE]; // records how many objects a 
232                                              // core has received
233 volatile int numconfirm;
234 volatile bool waitconfirm;
235 bool busystatus;
236 int self_numsendobjs;
237 int self_numreceiveobjs;
238
239 // get rid of lock msgs for GC version
240 #ifndef MULTICORE_GC
241 // data structures for locking
242 struct RuntimeHash locktable;
243 static struct RuntimeHash* locktbl = &locktable;
244 struct RuntimeHash * lockRedirectTbl;
245 struct RuntimeHash * objRedirectLockTbl;
246 #endif
247 struct LockValue {
248         int redirectlock;
249         int value;
250 };
251 int lockobj;
252 int lock2require;
253 int lockresult;
254 bool lockflag;
255
256 // data structures for waiting objs
257 struct Queue objqueue;
258 struct Queue * totransobjqueue; // queue to hold objs to be transferred
259                                 // should be cleared whenever enter a task
260
261 // data structures for shared memory allocation
262 #define BAMBOO_BASE_VA 0xd000000
263 #ifdef GC_DEBUG
264 #include "structdefs.h"
265 #define BAMBOO_NUM_PAGES (NUMCORES4GC*(2+1)+3)
266 #define BAMBOO_PAGE_SIZE (64 * 64)
267 #define BAMBOO_SMEM_SIZE (64 * 64) // (BAMBOO_PAGE_SIZE)
268 #define BAMBOO_SHARED_MEM_SIZE ((BAMBOO_PAGE_SIZE) * (BAMBOO_NUM_PAGES))
269 #else
270 #define BAMBOO_NUM_PAGES (15 * 1024) //(64 * 4 * 0.75) //(1024 * 1024 * 3.5)  3G
271 #define BAMBOO_PAGE_SIZE (16 * 1024)// * 1024)  // (4096)
272 #define BAMBOO_SMEM_SIZE (16 * 1024)
273 #define BAMBOO_SHARED_MEM_SIZE (1024 * 1024 * 240) //(1024 * 1024 * 1024)
274 //(3.0 * 1024 * 1024 * 1024) // 3G// ((BAMBOO_PAGE_SIZE) * (BAMBOO_NUM_PAGES))
275 #endif
276
277 #ifdef MULTICORE_GC
278 #include "multicoregarbage.h"
279
280 typedef enum {
281         SMEMLOCAL = 0x0, // 0x0, using local mem only
282         SMEMFIXED,       // 0x1, use local mem in lower address space(1 block only)
283                          //      and global mem in higher address space
284         SMEMMIXED,       // 0x2, like FIXED mode but use a threshold to control
285         SMEMGLOBAL,      // 0x3, using global mem only
286         SMEMEND
287 } SMEMSTRATEGY;
288
289 SMEMSTRATEGY bamboo_smem_mode; //-DSMEML: LOCAL; -DSMEMF: FIXED; 
290                               //-DSMEMM: MIXED; -DSMEMG: GLOBAL;
291
292 struct freeMemItem {
293         INTPTR ptr;
294         int size;
295         int startblock;  
296         int endblock;
297         struct freeMemItem * next;
298 };
299
300 struct freeMemList {
301         struct freeMemItem * head;
302         struct freeMemItem * backuplist;  // hold removed freeMemItem for reuse; 
303                                           // only maintain 1 fremmMemItem
304 };
305
306 // table recording the number of allocated bytes on each block
307 // Note: this table resides on the bottom of the shared heap for all cores
308 //       to access
309 volatile int * bamboo_smemtbl;
310 volatile int bamboo_free_block;
311 //bool bamboo_smem_flushed;
312 //struct freeMemList * bamboo_free_mem_list;
313 int bamboo_reserved_smem; // reserved blocks on the top of the shared heap
314                           // e.g. 20% of the heap and should not be allocated
315                                                                                                         // otherwise gc is invoked
316 #else
317 volatile mspace bamboo_free_msp;
318 #endif
319 volatile bool smemflag;
320 volatile INTPTR bamboo_cur_msp;
321 volatile int bamboo_smem_size;
322
323 // for test TODO
324 int total_num_t6;
325
326 // data structures for profile mode
327 #ifdef PROFILE
328
329 #define TASKINFOLENGTH 30000
330 //#define INTERRUPTINFOLENGTH 500
331
332 bool stall;
333 //bool isInterrupt;
334 int totalexetime;
335
336 typedef struct task_info {
337   char* taskName;
338   unsigned long long startTime;
339   unsigned long long endTime;
340   unsigned long long exitIndex;
341   struct Queue * newObjs; 
342 } TaskInfo;
343
344 /*typedef struct interrupt_info {
345    int startTime;
346    int endTime;
347    } InterruptInfo;*/
348
349 TaskInfo * taskInfoArray[TASKINFOLENGTH];
350 int taskInfoIndex;
351 bool taskInfoOverflow;
352 /*InterruptInfo * interruptInfoArray[INTERRUPTINFOLENGTH];
353    int interruptInfoIndex;
354    bool interruptInfoOverflow;*/
355 volatile int profilestatus[NUMCORESACTIVE]; // records status of each core
356                                             // 1: running tasks
357                                             // 0: stall
358 #endif // #ifdef PROFILE
359
360 #ifndef INTERRUPT
361 bool reside;
362 #endif
363 /////////////////////////////////////////////////////////////
364
365 ////////////////////////////////////////////////////////////
366 // these are functions should be implemented in           //
367 // multicore runtime for any multicore processors         //
368 ////////////////////////////////////////////////////////////
369 #ifdef TASK
370 #ifdef MULTICORE
371 INLINE void initialization(void);
372 INLINE void initCommunication(void);
373 INLINE void fakeExecution(void);
374 INLINE void terminate(void);
375 INLINE void initlock(struct ___Object___ * v);
376
377 // lock related functions
378 bool getreadlock(void* ptr);
379 void releasereadlock(void* ptr);
380 bool getwritelock(void* ptr);
381 void releasewritelock(void* ptr);
382 bool getwritelock_I(void* ptr);
383 void releasewritelock_I(void * ptr);
384 #ifndef MULTICORE_GC
385 void releasewritelock_r(void * lock, void * redirectlock);
386 #endif
387 /* this function is to process lock requests. 
388  * can only be invoked in receiveObject() */
389 // if return -1: the lock request is redirected
390 //            0: the lock request is approved
391 //            1: the lock request is denied
392 INLINE int processlockrequest(int locktype, 
393                                           int lock, 
394                                                                                                                         int obj, 
395                                                                                                                         int requestcore, 
396                                                                                                                         int rootrequestcore, 
397                                                                                                                         bool cache);
398 INLINE void processlockrelease(int locktype, 
399                                            int lock, 
400                                                                                                                          int redirectlock, 
401                                                                                                                          bool redirect);
402
403 // msg related functions
404 INLINE void send_hanging_msg();
405 INLINE void send_msg_1(int targetcore, 
406                                    unsigned long n0);
407 INLINE void send_msg_2(int targetcore, 
408                                    unsigned long n0, 
409                                                                                          unsigned long n1);
410 INLINE void send_msg_3(int targetcore, 
411                                    unsigned long n0, 
412                                                                                          unsigned long n1, 
413                                                                                          unsigned long n2);
414 INLINE void send_msg_4(int targetcore, 
415                                    unsigned long n0, 
416                                                                                          unsigned long n1, 
417                                                                                          unsigned long n2, 
418                                                                                          unsigned long n3);
419 INLINE void send_msg_5(int targetcore, 
420                                    unsigned long n0, 
421                                                                                          unsigned long n1, 
422                                                                                          unsigned long n2, 
423                                                                                          unsigned long n3, 
424                                                                                          unsigned long n4);
425 INLINE void send_msg_6(int targetcore, 
426                                    unsigned long n0, 
427                                                                                          unsigned long n1, 
428                                                                                          unsigned long n2, 
429                                                                                          unsigned long n3, 
430                                                                                          unsigned long n4, 
431                                                                                          unsigned long n5);
432 INLINE void send_msg_3_I(int targetcore, 
433                                    unsigned long n0, 
434                                                                                          unsigned long n1, 
435                                                                                          unsigned long n2);
436 INLINE void cache_msg_1(int targetcore, 
437                                                                                                 unsigned long n0);
438 INLINE void cache_msg_2(int targetcore, 
439                                     unsigned long n0, 
440                                                                                                 unsigned long n1);
441 INLINE void cache_msg_3(int targetcore, 
442                                     unsigned long n0, 
443                                                                                                 unsigned long n1, 
444                                                                                                 unsigned long n2);
445 INLINE void cache_msg_4(int targetcore, 
446                                     unsigned long n0, 
447                                                                                                 unsigned long n1, 
448                                                                                                 unsigned long n2, 
449                                                                                                 unsigned long n3);
450 INLINE void cache_msg_5(int targetcore, 
451                                     unsigned long n0, 
452                                                                                                 unsigned long n1, 
453                                                                                                 unsigned long n2, 
454                                                                                                 unsigned long n3, 
455                                                                                                 unsigned long n4);
456 INLINE void cache_msg_6(int targetcore, 
457                                     unsigned long n0, 
458                                                                                                 unsigned long n1, 
459                                                                                                 unsigned long n2, 
460                                                                                                 unsigned long n3, 
461                                                                                                 unsigned long n4, 
462                                                                                                 unsigned long n5);
463 INLINE void transferObject(struct transObjInfo * transObj);
464 INLINE int receiveMsg(uint32_t send_port_pending);
465
466 #ifdef MULTICORE_GC
467 INLINE void transferMarkResults();
468 #endif
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(x): exit routine                                            //
486 // BAMBOO_DIE(x): error exit routine                                       //
487 // BAMBOO_GET_EXE_TIME(): rountine to get current clock cycle number       //
488 // BAMBOO_MSG_AVAIL(): checking if there are msgs coming in                //
489 // BAMBOO_GCMSG_AVAIL(): checking if there are gcmsgs 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 // BAMBOO_LOCAL_MEM_FREE(x): free space with ptr x on local memory         //
507 // BAMBOO_LOCAL_MEM_CLOSE(): close the local heap                          //
508 // BAMBOO_SHARE_MEM_CALLOC_I(x, y): allocate an array of x elements each of//
509 //                                whose size in bytes is y on shared memory//
510 // BAMBOO_SHARE_MEM_CLOSE(): close the shared heap                        //
511 // BAMBOO_CACHE_LINE_SIZE: the cache line size                             //
512 // BAMBOO_CACHE_LINE_MASK: mask for a cache line                           //
513 // BAMBOO_CACHE_FLUSH_RANGE(x, y): flush cache lines started at x with     //
514 //                                 length y                                //
515 // BAMBOO_CACHE_FLUSH_ALL(): flush the whole cache of a core if necessary  //
516 // BAMBOO_MEMSET_WH(x, y, z): memset the specified region of memory (start //
517 //                            address x, size z) to value y with write     //
518 //                            hint, the processor will not fetch the       //
519 //                            current content of the memory and directly   //
520 //                            write                                        //
521 /////////////////////////////////////////////////////////////////////////////
522
523 #endif  // #ifdef MULTICORE
524 #endif  // #ifdef TASK
525 #endif  // #ifndef MULTICORE_RUNTIME