fix bugs in multicoregc
[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 // data structures for msgs
13 #define BAMBOO_OUT_BUF_LENGTH 300
14 #define BAMBOO_MSG_BUF_LENGTH 30
15 int msgdata[BAMBOO_MSG_BUF_LENGTH];
16 int msgdataindex;
17 int msglength;
18 int outmsgdata[BAMBOO_OUT_BUF_LENGTH];
19 int outmsgindex;
20 int outmsglast;
21 int outmsgleft;
22 bool isMsgHanging;
23 volatile bool isMsgSending;
24
25 #define OUTMSG_INDEXINC() \
26         outmsgindex = (outmsgindex + 1) % (BAMBOO_OUT_BUF_LENGTH)
27
28 #define OUTMSG_LASTINDEXINC() \
29         outmsglast = (outmsglast + 1) % (BAMBOO_OUT_BUF_LENGTH); \
30         if(outmsglast == outmsgindex) { \
31                 BAMBOO_EXIT(0xd001); \
32         } 
33
34 #define OUTMSG_CACHE(n) \
35         outmsgdata[outmsglast] = (n); \
36   OUTMSG_LASTINDEXINC(); 
37
38 /* Message format:
39  *      type + Msgbody
40  * type: 1 -- transfer object
41  *       2 -- transfer stall msg
42  *       3 -- lock request
43  *       4 -- lock grount
44  *       5 -- lock deny
45  *       6 -- lock release
46  *       // add for profile info
47  *       7 -- transfer profile output msg
48  *       8 -- transfer profile output finish msg
49  *       // add for alias lock strategy
50  *       9 -- redirect lock request
51  *       a -- lock grant with redirect info
52  *       b -- lock deny with redirect info
53  *       c -- lock release with redirect info
54  *       d -- status confirm request
55  *       e -- status report msg
56  *       f -- terminate
57  *      10 -- requiring for new memory
58  *      11 -- response for new memory request
59  *      12 -- GC init phase start
60  *      13 -- GC start
61  *      14 -- compact phase start
62  *      15 -- flush phase start
63  *      16 -- init phase finish
64  *      17 -- mark phase finish
65  *      18 -- compact phase finish
66  *      19 -- flush phase finish
67  *      1a -- GC finish
68  *      1b -- marked phase finish confirm request
69  *      1c -- marked phase finish confirm response
70  *      1d -- markedObj msg
71  *      1e -- start moving objs msg
72  *      1f -- ask for mapping info of a markedObj
73  *      20 -- mapping info of a markedObj
74  *      21 -- large objs info request
75  *      22 -- large objs info response
76  *      23 -- large objs mapping info
77  *
78  * ObjMsg: 1 + size of msg + obj's address + (task index + param index)+
79  * StallMsg: 2 + corenum + sendobjs + receiveobjs 
80  *             (size is always 4 * sizeof(int))
81  * LockMsg: 3 + lock type + obj pointer + lock + request core 
82  *            (size is always 5 * sizeof(int))
83  *          4/5/6 + lock type + obj pointer + lock 
84  *            (size is always 4 * sizeof(int))
85  *          9 + lock type + obj pointer +  redirect lock + root request core 
86  *            + request core 
87  *            (size is always 6 * sizeof(int))
88  *          a/b + lock type + obj pointer + redirect lock 
89  *              (size is always 4 * sizeof(int))
90  *          c + lock type + lock + redirect lock 
91  *            (size is always 4 * sizeof(int))
92  *          lock type: 0 -- read; 1 -- write
93  * ProfileMsg: 7 + totalexetime 
94  *               (size is always 2 * sizeof(int))
95  *             8 + corenum 
96  *               (size is always 2 * sizeof(int))
97  * StatusMsg: d (size is always 1 * sizeof(int))
98  *            e + status + corenum + sendobjs + receiveobjs 
99  *              (size is always 5 * sizeof(int))
100  *            status: 0 -- stall; 1 -- busy
101  * TerminateMsg: f (size is always 1 * sizeof(int)
102  * MemoryMsg: 10 + size + corenum 
103  *              (size is always 3 * sizeof(int))
104  *           11 + base_va + size 
105  *              (size is always 3 * sizeof(int))
106  * GCMsg: 12/13 (size is always 1 * sizeof(int))
107  *        14 + size of msg + (num of objs to move + (start address 
108  *           + end address + dst core + start dst)+)? 
109  *           + (num of incoming objs + (start dst + orig core)+)? 
110  *           + (num of large obj lists + (start address + lenght 
111  *           + start dst)+)?
112  *        15 (size is always 1 * sizeof(int))
113  *        16 + corenum 
114  *           (size is always 2 * sizeof(int))
115  *        17 + corenum + gcsendobjs + gcreceiveobjs     
116  *           (size if always 4 * sizeof(int))
117  *        18 + corenum + fulfilled blocks num + (finish compact(1) + current
118  *           heap top)/(need mem(0) + mem need) 
119  *           size is always 5 * sizeof(int))
120  *        19 + corenum 
121  *              (size is always 2 * sizeof(int))
122  *        1a (size is always 1 * sizeof(int))
123  *        1b (size if always 1 * sizeof(int))
124  *        1c + size of msg + corenum + gcsendobjs + gcreceiveobjs 
125  *           (size is always 5 * sizeof(int))
126  *        1d + obj's address 
127  *           (size is always 2 * sizeof(int))
128  *        1e + corenum + start addr + end addr
129  *           (size if always 4 * sizeof(int))
130  *        1f + obj's address + corenum 
131  *           (size is always 3 * sizeof(int))
132  *        20 + obj's address + dst address 
133  *           (size if always 3 * sizeof(int))
134  *        21 (size is always 1 * sizeof(int))
135  *        22 + size of msg + corenum + current heap size 
136  *           + (num of large obj lists + (start address + length)+)?
137  *        23 + orig large obj ptr + new large obj ptr 
138  *            (size is always 3 * sizeof(int))
139  */
140 typedef enum {
141         MSGSTART = 0x0,  // 0x0
142         TRANSOBJ,        // 0x1
143         TRANSTALL,       // 0x2
144         LOCKREQUEST,     // 0x3
145         LOCKGROUNT,      // 0x4
146         LOCKDENY,        // 0x5
147         LOCKRELEASE,     // 0x6
148         PROFILEOUTPUT,   // 0x7
149         PROFILEFINISH,   // 0x8
150         REDIRECTLOCK,    // 0x9
151         REDIRECTGROUNT,  // 0xa
152         REDIRECTDENY,    // 0xb
153         REDIRECTRELEASE, // 0xc
154         STATUSCONFIRM,   // 0xd
155         STATUSREPORT,    // 0xe
156         TERMINATE,       // 0xf
157         MEMREQUEST,      // 0x10
158         MEMRESPONSE,     // 0x11
159 #ifdef MULTICORE_GC
160         GCSTARTINIT,     // 0x12
161         GCSTART,         // 0x13
162         GCSTARTCOMPACT,  // 0x14
163         GCSTARTFLUSH,    // 0x15
164         GCFINISHINIT,    // 0x16
165         GCFINISHMARK,    // 0x17
166         GCFINISHCOMPACT, // 0x18
167         GCFINISHFLUSH,   // 0x19
168         GCFINISH,        // 0x1a
169         GCMARKCONFIRM,   // 0x1b
170         GCMARKREPORT,    // 0x1c
171         GCMARKEDOBJ,     // 0x1d
172         GCMOVESTART,     // 0x1e
173         GCMAPREQUEST,    // 0x1f
174         GCMAPINFO,       // 0x20
175         GCLOBJREQUEST,   // 0x21
176         GCLOBJINFO,      // 0x22
177         GCLOBJMAPPING,   // 0x23
178 #endif
179         MSGEND
180 } MSGTYPE;
181
182 // data structures of status for termination
183 // only check working cores
184 int corestatus[NUMCORESACTIVE]; // records status of each core
185                                 // 1: running tasks
186                                 // 0: stall
187 int numsendobjs[NUMCORESACTIVE]; // records how many objects a core has sent out
188 int numreceiveobjs[NUMCORESACTIVE]; // records how many objects a core has received
189 volatile int numconfirm;
190 volatile bool waitconfirm;
191 bool busystatus;
192 int self_numsendobjs;
193 int self_numreceiveobjs;
194
195 // get rid of lock msgs for GC version
196 #ifndef MULTICORE_GC
197 // data structures for locking
198 struct RuntimeHash locktable;
199 static struct RuntimeHash* locktbl = &locktable;
200 struct RuntimeHash * lockRedirectTbl;
201 struct RuntimeHash * objRedirectLockTbl;
202 #endif
203 struct LockValue {
204         int redirectlock;
205         int value;
206 };
207 int lockobj;
208 int lock2require;
209 int lockresult;
210 bool lockflag;
211
212 // data structures for waiting objs
213 struct Queue objqueue;
214 struct Queue * totransobjqueue; // queue to hold objs to be transferred
215                                 // should be cleared whenever enter a task
216
217 // data structures for shared memory allocation
218 #define BAMBOO_BASE_VA 0xd000000
219 #ifdef GC_DEBUG
220 #include "structdefs.h"
221 #define BAMBOO_NUM_PAGES (NUMCORES*(2+1)+3)
222 #define BAMBOO_PAGE_SIZE (64 * 64)
223 #define BAMBOO_SMEM_SIZE (64 * 64) // (BAMBOO_PAGE_SIZE)
224 #define BAMBOO_SHARED_MEM_SIZE ((BAMBOO_PAGE_SIZE) * (BAMBOO_NUM_PAGES))
225 #else
226 #define BAMBOO_NUM_PAGES (64 * 4 * 0.75) //(1024 * 1024 * 3.5)  3G
227 #define BAMBOO_PAGE_SIZE (16 * 1024 * 1024)  // (4096)
228 #define BAMBOO_SMEM_SIZE (16 * 1024)
229 #define BAMBOO_SHARED_MEM_SIZE (3.0 * 1024 * 1024 * 1024) // 3G// ((BAMBOO_PAGE_SIZE) * (BAMBOO_NUM_PAGES))
230 #endif
231
232 #ifdef MULTICORE_GC
233 #include "multicoregarbage.h"
234
235 typedef enum {
236         SMEMLOCAL = 0x0, // 0x0, using local mem only
237         SMEMFIXED,       // 0x1, use local mem in lower address space(1 block only)
238                          //      and global mem in higher address space
239         SMEMMIXED,        // 0x2, like FIXED mode but use a threshold to control
240         SMEMGLOBAL,       // 0x3, using global mem only
241         SMEMEND
242 } SMEMSTRATEGY;
243
244 SMEMSTRATEGY bamboo_smem_mode; //-DSMEML: LOCAL; -DSMEMF: FIXED; 
245                               //-DSMEMM: MIXED; -DSMEMG: GLOBAL;
246
247 struct freeMemItem {
248         INTPTR ptr;
249         int size;
250         int startblock;  
251         int endblock;
252         struct freeMemItem * next;
253 };
254
255 struct freeMemList {
256         struct freeMemItem * head;
257         struct freeMemItem * backuplist;  // hold removed freeMemItem for reuse
258 };
259
260 struct freeMemList * bamboo_free_mem_list;
261 #else
262 volatile mspace bamboo_free_msp;
263 #endif
264 volatile bool smemflag;
265 volatile INTPTR bamboo_cur_msp;
266 volatile int bamboo_smem_size;
267
268 // for test TODO
269 int total_num_t6;
270
271 // data structures for profile mode
272 #ifdef PROFILE
273
274 #define TASKINFOLENGTH 30000
275 //#define INTERRUPTINFOLENGTH 500
276
277 bool stall;
278 //bool isInterrupt;
279 int totalexetime;
280
281 typedef struct task_info {
282   char* taskName;
283   unsigned long long startTime;
284   unsigned long long endTime;
285   unsigned long long exitIndex;
286   struct Queue * newObjs; 
287 } TaskInfo;
288
289 /*typedef struct interrupt_info {
290    int startTime;
291    int endTime;
292    } InterruptInfo;*/
293
294 TaskInfo * taskInfoArray[TASKINFOLENGTH];
295 int taskInfoIndex;
296 bool taskInfoOverflow;
297 /*InterruptInfo * interruptInfoArray[INTERRUPTINFOLENGTH];
298    int interruptInfoIndex;
299    bool interruptInfoOverflow;*/
300 int profilestatus[NUMCORESACTIVE]; // records status of each core
301                              // 1: running tasks
302                              // 0: stall
303 #endif // #ifdef PROFILE
304
305 #ifndef INTERRUPT
306 bool reside;
307 #endif
308 /////////////////////////////////////////////////////////////
309
310 ////////////////////////////////////////////////////////////
311 // these are functions should be implemented in           //
312 // multicore runtime for any multicore processors         //
313 ////////////////////////////////////////////////////////////
314 #ifdef TASK
315 #ifdef MULTICORE
316 INLINE void initialization(void);
317 INLINE void initCommunication(void);
318 INLINE void fakeExecution(void);
319 INLINE void terminate(void);
320 INLINE void initlock(struct ___Object___ * v);
321
322 // lock related functions
323 bool getreadlock(void* ptr);
324 void releasereadlock(void* ptr);
325 bool getwritelock(void* ptr);
326 void releasewritelock(void* ptr);
327 bool getwritelock_I(void* ptr);
328 void releasewritelock_I(void * ptr);
329 #ifndef MULTICORE_GC
330 void releasewritelock_r(void * lock, void * redirectlock);
331 #endif
332 /* this function is to process lock requests. 
333  * can only be invoked in receiveObject() */
334 // if return -1: the lock request is redirected
335 //            0: the lock request is approved
336 //            1: the lock request is denied
337 INLINE int processlockrequest(int locktype, 
338                                           int lock, 
339                                                                                                                         int obj, 
340                                                                                                                         int requestcore, 
341                                                                                                                         int rootrequestcore, 
342                                                                                                                         bool cache);
343 INLINE void processlockrelease(int locktype, 
344                                            int lock, 
345                                                                                                                          int redirectlock, 
346                                                                                                                          bool redirect);
347
348 // msg related functions
349 INLINE void send_hanging_msg();
350 INLINE void send_msg_1(int targetcore, 
351                                    unsigned long n0);
352 INLINE void send_msg_2(int targetcore, 
353                                    unsigned long n0, 
354                                                                                          unsigned long n1);
355 INLINE void send_msg_3(int targetcore, 
356                                    unsigned long n0, 
357                                                                                          unsigned long n1, 
358                                                                                          unsigned long n2);
359 INLINE void send_msg_4(int targetcore, 
360                                    unsigned long n0, 
361                                                                                          unsigned long n1, 
362                                                                                          unsigned long n2, 
363                                                                                          unsigned long n3);
364 INLINE void send_msg_5(int targetcore, 
365                                    unsigned long n0, 
366                                                                                          unsigned long n1, 
367                                                                                          unsigned long n2, 
368                                                                                          unsigned long n3, 
369                                                                                          unsigned long n4);
370 INLINE void send_msg_6(int targetcore, 
371                                    unsigned long n0, 
372                                                                                          unsigned long n1, 
373                                                                                          unsigned long n2, 
374                                                                                          unsigned long n3, 
375                                                                                          unsigned long n4, 
376                                                                                          unsigned long n5);
377 INLINE void cache_msg_2(int targetcore, 
378                                     unsigned long n0, 
379                                                                                                 unsigned long n1);
380 INLINE void cache_msg_3(int targetcore, 
381                                     unsigned long n0, 
382                                                                                                 unsigned long n1, 
383                                                                                                 unsigned long n2);
384 INLINE void cache_msg_4(int targetcore, 
385                                     unsigned long n0, 
386                                                                                                 unsigned long n1, 
387                                                                                                 unsigned long n2, 
388                                                                                                 unsigned long n3);
389 INLINE void cache_msg_5(int targetcore, 
390                                     unsigned long n0, 
391                                                                                                 unsigned long n1, 
392                                                                                                 unsigned long n2, 
393                                                                                                 unsigned long n3, 
394                                                                                                 unsigned long n4);
395 INLINE void cache_msg_6(int targetcore, 
396                                     unsigned long n0, 
397                                                                                                 unsigned long n1, 
398                                                                                                 unsigned long n2, 
399                                                                                                 unsigned long n3, 
400                                                                                                 unsigned long n4, 
401                                                                                                 unsigned long n5);
402 INLINE void transferObject(struct transObjInfo * transObj);
403 INLINE int receiveMsg(void);
404
405 #ifdef MULTICORE_GC
406 INLINE void transferMarkResults();
407 #endif
408
409 #ifdef PROFILE
410 INLINE void profileTaskStart(char * taskname);
411 INLINE void profileTaskEnd(void);
412 void outputProfileData();
413 #endif  // #ifdef PROFILE
414 ///////////////////////////////////////////////////////////
415
416 /////////////////////////////////////////////////////////////////////////////
417 // For each version of BAMBOO runtime, there should be a header file named //
418 // runtim_arch.h defining following MARCOS:                                //
419 // BAMBOO_TOTALCORE: the total # of cores available in the processor       //
420 // BAMBOO_NUM_OF_CORE: the # of current residing core                      //
421 // BAMBOO_GET_NUM_OF_CORE(): compute the # of current residing core        //
422 // BAMBOO_DEBUGPRINT(x): print out integer x                               //
423 // BAMBOO_DEBUGPRINT_REG(x): print out value of variable x                 //
424 // BAMBOO_LOCAL_MEM_CALLOC(x, y): allocate an array of x elements each of  //
425 //                                whose size in bytes is y on local memory //
426 // BAMBOO_LOCAL_MEM_FREE(x): free space with ptr x on local memory         //
427 // BAMBOO_SHARE_MEM_CALLOC(x, y): allocate an array of x elements each of  //
428 //                                whose size in bytes is y on shared memory//
429 // BAMBOO_START_CRITICAL_SECTION_OBJ_QUEUE()                               //
430 // BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE(): locks for global data        //
431 //                                            structures related to obj    //
432 //                                            queue                        //
433 // BAMBOO_START_CRITICAL_SECTION_STATUS()                                  //
434 // BAMBOO_CLOSE_CRITICAL_SECTION_STATUS(): locks for global data structures//
435 //                                         related to status data          //
436 // BAMBOO_START_CRITICAL_SECTION_MSG()                                     //
437 // BAMBOO_CLOSE_CRITICAL_SECTION_MSG(): locks for global data structures   //
438 //                                      related to msg data                //
439 // BAMBOO_START_CRITICAL_SECTION_LOCK()                                    //
440 // BAMBOO_CLOSE_CRITICAL_SECTION_LOCK(): locks for global data structures  //
441 //                                       related to lock table             //
442 // BAMBOO_START_CRITICAL_SECTION_MEM()                                     //
443 // BAMBOO_CLOSE_CRITICAL_SECTION_MEM(): locks for allocating memory        //
444 // BAMBOO_START_CRITICAL_SECTION()                                         //
445 // BAMBOO_CLOSE_CRITICAL_SECTION(): locks for all global data structures   //
446 // BAMBOO_WAITING_FOR_LOCK(): routine executed while waiting for lock      //
447 //                            request response                             //
448 // BAMBOO_CACHE_LINE_SIZE: the cache line size                             //
449 // BAMBOO_CACHE_LINE_MASK: mask for a cache line                           //
450 // BAMBOO_CACHE_FLUSH_RANGE(x, y): flush cache lines started at x with     //
451 //                                 length y                                //
452 // BAMBOO_CACHE_FLUSH_ALL(): flush the whole cache of a core if necessary  //
453 // BAMBOO_EXIT(x): exit routine                                            //
454 // BAMBOO_MSG_AVAIL(): checking if there are msgs coming in                //
455 // BAMBOO_GCMSG_AVAIL(): checking if there are gcmsgs coming in            //
456 // BAMBOO_GET_EXE_TIME(): rountine to get current clock cycle number       //
457 /////////////////////////////////////////////////////////////////////////////
458
459 #endif  // #ifdef MULTICORE
460 #endif  // #ifdef TASK
461 #endif  // #ifndef MULTICORE_RUNTIME