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