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