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