]>
Commit | Line | Data |
---|---|---|
5f520819 | 1 | /* |
2eab9666 | 2 | Copyright (c) 2014-2015 Intel Corporation. All Rights Reserved. |
5f520819 KY |
3 | |
4 | Redistribution and use in source and binary forms, with or without | |
5 | modification, are permitted provided that the following conditions | |
6 | are met: | |
7 | ||
8 | * Redistributions of source code must retain the above copyright | |
9 | notice, this list of conditions and the following disclaimer. | |
10 | * Redistributions in binary form must reproduce the above copyright | |
11 | notice, this list of conditions and the following disclaimer in the | |
12 | documentation and/or other materials provided with the distribution. | |
13 | * Neither the name of Intel Corporation nor the names of its | |
14 | contributors may be used to endorse or promote products derived | |
15 | from this software without specific prior written permission. | |
16 | ||
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
21 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
28 | */ | |
29 | ||
30 | ||
31 | /*! \file | |
32 | \brief Function and Variable tables used by the runtime library | |
33 | */ | |
34 | ||
35 | #ifndef OFFLOAD_TABLE_H_INCLUDED | |
36 | #define OFFLOAD_TABLE_H_INCLUDED | |
37 | ||
5f520819 KY |
38 | #include "offload_util.h" |
39 | ||
40 | // Template representing double linked list of tables | |
41 | template <typename T> class TableList { | |
42 | public: | |
43 | // table type | |
44 | typedef T Table; | |
45 | ||
46 | // List node | |
47 | struct Node { | |
48 | Table table; | |
49 | Node* prev; | |
50 | Node* next; | |
51 | }; | |
52 | ||
53 | public: | |
54 | explicit TableList(Node *node = 0) : m_head(node) {} | |
55 | ||
56 | void add_table(Node *node) { | |
57 | m_lock.lock(); | |
5f520819 KY |
58 | if (m_head != 0) { |
59 | node->next = m_head; | |
60 | m_head->prev = node; | |
61 | } | |
62 | m_head = node; | |
63 | ||
64 | m_lock.unlock(); | |
65 | } | |
66 | ||
67 | void remove_table(Node *node) { | |
5f520819 KY |
68 | if (node->next != 0) { |
69 | node->next->prev = node->prev; | |
70 | } | |
71 | if (node->prev != 0) { | |
72 | node->prev->next = node->next; | |
73 | } | |
74 | if (m_head == node) { | |
75 | m_head = node->next; | |
76 | } | |
5f520819 KY |
77 | } |
78 | ||
79 | protected: | |
80 | Node* m_head; | |
81 | mutex_t m_lock; | |
82 | }; | |
83 | ||
84 | // Function lookup table. | |
85 | struct FuncTable { | |
86 | //! Function table entry | |
87 | /*! This table contains functions created from offload regions. */ | |
88 | /*! Each entry consists of a pointer to the function's "key" | |
89 | and the function address. */ | |
90 | /*! Each shared library or executable may contain one such table. */ | |
91 | /*! The end of the table is marked with an entry whose name field | |
92 | has value -1. */ | |
93 | struct Entry { | |
94 | const char* name; //!< Name of the function | |
95 | void* func; //!< Address of the function | |
96 | }; | |
97 | ||
98 | // entries | |
99 | const Entry *entries; | |
100 | ||
101 | // max name length | |
102 | int64_t max_name_len; | |
103 | }; | |
104 | ||
105 | // Function table | |
2eab9666 | 106 | class DLL_LOCAL FuncList : public TableList<FuncTable> { |
5f520819 KY |
107 | public: |
108 | explicit FuncList(Node *node = 0) : TableList<Table>(node), | |
109 | m_max_name_len(-1) | |
110 | {} | |
111 | ||
112 | // add table to the list | |
113 | void add_table(Node *node) { | |
114 | // recalculate max function name length | |
115 | m_max_name_len = -1; | |
116 | ||
117 | // add table | |
118 | TableList<Table>::add_table(node); | |
119 | } | |
120 | ||
121 | // find function address for the given name | |
122 | const void* find_addr(const char *name); | |
123 | ||
124 | // find function name for the given address | |
125 | const char* find_name(const void *addr); | |
126 | ||
127 | // max name length from all tables in the list | |
128 | int64_t max_name_length(void); | |
129 | ||
130 | // debug dump | |
131 | void dump(void); | |
132 | ||
133 | private: | |
134 | // max name length within from all tables | |
135 | int64_t m_max_name_len; | |
136 | }; | |
137 | ||
138 | // Table entry for static variables | |
139 | struct VarTable { | |
140 | //! Variable table entry | |
141 | /*! This table contains statically allocated variables marked with | |
142 | __declspec(target(mic) or #pragma omp declare target. */ | |
143 | /*! Each entry consists of a pointer to the variable's "key", | |
144 | the variable address and its size in bytes. */ | |
145 | /*! Because memory allocation is done from the host, | |
146 | the MIC table does not need the size of the variable. */ | |
147 | /*! Padding to make the table entry size a power of 2 is necessary | |
148 | to avoid "holes" between table contributions from different object | |
149 | files on Windows when debug information is specified with /Zi. */ | |
150 | struct Entry { | |
151 | const char* name; //!< Name of the variable | |
152 | void* addr; //!< Address of the variable | |
153 | ||
154 | #if HOST_LIBRARY | |
155 | uint64_t size; | |
156 | ||
157 | #ifdef TARGET_WINNT | |
158 | // padding to make entry size a power of 2 | |
159 | uint64_t padding; | |
160 | #endif // TARGET_WINNT | |
161 | #endif | |
162 | }; | |
163 | ||
164 | // Table terminated by an entry with name == -1 | |
165 | const Entry *entries; | |
166 | }; | |
167 | ||
168 | // List of var tables | |
2eab9666 | 169 | class DLL_LOCAL VarList : public TableList<VarTable> { |
5f520819 KY |
170 | public: |
171 | VarList() : TableList<Table>() | |
172 | {} | |
173 | ||
174 | // debug dump | |
175 | void dump(); | |
176 | ||
177 | public: | |
5f520819 | 178 | |
2eab9666 IV |
179 | Node * get_head() { |
180 | return m_head; | |
5f520819 KY |
181 | } |
182 | ||
183 | public: | |
184 | // Entry representation in a copy buffer | |
185 | struct BufEntry { | |
186 | intptr_t name; | |
187 | intptr_t addr; | |
188 | }; | |
189 | ||
190 | // Calculate the number of elements in the table and | |
191 | // returns the size of buffer for the table | |
192 | int64_t table_size(int64_t &nelems); | |
193 | ||
194 | // Copy table contents to given buffer. It is supposed to be large | |
195 | // enough to hold all elements as string table. | |
196 | void table_copy(void *buf, int64_t nelems); | |
197 | ||
198 | // Patch name offsets in a table after it's been copied to other side | |
199 | static void table_patch_names(void *buf, int64_t nelems); | |
200 | }; | |
201 | ||
2eab9666 IV |
202 | DLL_LOCAL extern FuncList __offload_entries; |
203 | DLL_LOCAL extern FuncList __offload_funcs; | |
204 | DLL_LOCAL extern VarList __offload_vars; | |
5f520819 KY |
205 | |
206 | // Section names where the lookup tables are stored | |
207 | #ifdef TARGET_WINNT | |
208 | #define OFFLOAD_ENTRY_TABLE_SECTION_START ".OffloadEntryTable$a" | |
209 | #define OFFLOAD_ENTRY_TABLE_SECTION_END ".OffloadEntryTable$z" | |
210 | ||
211 | #define OFFLOAD_FUNC_TABLE_SECTION_START ".OffloadFuncTable$a" | |
212 | #define OFFLOAD_FUNC_TABLE_SECTION_END ".OffloadFuncTable$z" | |
213 | ||
214 | #define OFFLOAD_VAR_TABLE_SECTION_START ".OffloadVarTable$a" | |
215 | #define OFFLOAD_VAR_TABLE_SECTION_END ".OffloadVarTable$z" | |
216 | ||
217 | #define OFFLOAD_CRTINIT_SECTION_START ".CRT$XCT" | |
218 | ||
219 | #pragma section(OFFLOAD_CRTINIT_SECTION_START, read) | |
220 | ||
221 | #else // TARGET_WINNT | |
222 | ||
223 | #define OFFLOAD_ENTRY_TABLE_SECTION_START ".OffloadEntryTable." | |
224 | #define OFFLOAD_ENTRY_TABLE_SECTION_END ".OffloadEntryTable." | |
225 | ||
226 | #define OFFLOAD_FUNC_TABLE_SECTION_START ".OffloadFuncTable." | |
227 | #define OFFLOAD_FUNC_TABLE_SECTION_END ".OffloadFuncTable." | |
228 | ||
229 | #define OFFLOAD_VAR_TABLE_SECTION_START ".OffloadVarTable." | |
230 | #define OFFLOAD_VAR_TABLE_SECTION_END ".OffloadVarTable." | |
231 | #endif // TARGET_WINNT | |
232 | ||
233 | #pragma section(OFFLOAD_ENTRY_TABLE_SECTION_START, read, write) | |
234 | #pragma section(OFFLOAD_ENTRY_TABLE_SECTION_END, read, write) | |
235 | ||
236 | #pragma section(OFFLOAD_FUNC_TABLE_SECTION_START, read, write) | |
237 | #pragma section(OFFLOAD_FUNC_TABLE_SECTION_END, read, write) | |
238 | ||
239 | #pragma section(OFFLOAD_VAR_TABLE_SECTION_START, read, write) | |
240 | #pragma section(OFFLOAD_VAR_TABLE_SECTION_END, read, write) | |
241 | ||
242 | ||
243 | // register/unregister given tables | |
244 | extern "C" void __offload_register_tables( | |
245 | FuncList::Node *entry_table, | |
246 | FuncList::Node *func_table, | |
247 | VarList::Node *var_table | |
248 | ); | |
249 | ||
250 | extern "C" void __offload_unregister_tables( | |
251 | FuncList::Node *entry_table, | |
252 | FuncList::Node *func_table, | |
253 | VarList::Node *var_table | |
254 | ); | |
2eab9666 IV |
255 | |
256 | ||
257 | #ifdef MYO_SUPPORT | |
258 | ||
259 | #include <myotypes.h> | |
260 | #include <myoimpl.h> | |
261 | #include <myo.h> | |
262 | ||
263 | #ifdef TARGET_WINNT | |
264 | #define MYO_TABLE_END_MARKER() reinterpret_cast<const char*>(-1) | |
265 | #else // TARGET_WINNT | |
266 | #define MYO_TABLE_END_MARKER() reinterpret_cast<const char*>(0) | |
267 | #endif // TARGET_WINNT | |
268 | ||
269 | // Host and Target-side MYO shared variable table entry layout | |
270 | typedef MyoiSharedVarEntry SharedTableEntry; | |
271 | ||
272 | #if HOST_LIBRARY | |
273 | ||
274 | // Host-side MYO function table entry layout | |
275 | typedef struct { | |
276 | //! Function Name | |
277 | const char *funcName; | |
278 | //! Function Address | |
279 | void *funcAddr; | |
280 | //! Local Thunk Address | |
281 | void *localThunkAddr; | |
282 | #ifdef TARGET_WINNT | |
283 | // Dummy to pad up to 32 bytes | |
284 | void *dummy; | |
285 | #endif // TARGET_WINNT | |
286 | } FptrTableEntry; | |
287 | ||
288 | // Host-side MYO init routine table entry layout | |
289 | typedef struct { | |
290 | #ifdef TARGET_WINNT | |
291 | // Dummy to pad up to 16 bytes | |
292 | // Function Name | |
293 | const char *funcName; | |
294 | #endif // TARGET_WINNT | |
295 | void (*func)(MyoArena); | |
296 | } InitTableEntry; | |
297 | ||
298 | #else // HOST_LIBRARY | |
299 | ||
300 | // Target-side MYO function table entry layout | |
301 | typedef MyoiTargetSharedFptrEntry FptrTableEntry; | |
302 | ||
303 | // Target-side MYO init routine table entry layout | |
304 | struct InitTableEntry { | |
305 | void (*func)(void); | |
306 | }; | |
307 | ||
308 | #endif // HOST_LIBRARY | |
309 | ||
310 | #ifdef TARGET_WINNT | |
311 | ||
312 | #define OFFLOAD_MYO_SHARED_TABLE_SECTION_START ".MyoSharedTable$a" | |
313 | #define OFFLOAD_MYO_SHARED_TABLE_SECTION_END ".MyoSharedTable$z" | |
314 | ||
315 | #define OFFLOAD_MYO_SHARED_VTABLE_SECTION_START ".MyoSharedVTable$a" | |
316 | #define OFFLOAD_MYO_SHARED_VTABLE_SECTION_END ".MyoSharedVTable$z" | |
317 | ||
318 | #define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START ".MyoSharedInitTable$a" | |
319 | #define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_END ".MyoSharedInitTable$z" | |
320 | ||
321 | #define OFFLOAD_MYO_FPTR_TABLE_SECTION_START ".MyoFptrTable$a" | |
322 | #define OFFLOAD_MYO_FPTR_TABLE_SECTION_END ".MyoFptrTable$z" | |
323 | ||
324 | #else // TARGET_WINNT | |
325 | ||
326 | #define OFFLOAD_MYO_SHARED_TABLE_SECTION_START ".MyoSharedTable." | |
327 | #define OFFLOAD_MYO_SHARED_TABLE_SECTION_END ".MyoSharedTable." | |
328 | ||
329 | #define OFFLOAD_MYO_SHARED_VTABLE_SECTION_START ".MyoSharedVTable." | |
330 | #define OFFLOAD_MYO_SHARED_VTABLE_SECTION_END ".MyoSharedVTable." | |
331 | ||
332 | #define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START ".MyoSharedInitTable." | |
333 | #define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_END ".MyoSharedInitTable." | |
334 | ||
335 | #define OFFLOAD_MYO_FPTR_TABLE_SECTION_START ".MyoFptrTable." | |
336 | #define OFFLOAD_MYO_FPTR_TABLE_SECTION_END ".MyoFptrTable." | |
337 | ||
338 | #endif // TARGET_WINNT | |
339 | ||
340 | #pragma section(OFFLOAD_MYO_SHARED_TABLE_SECTION_START, read, write) | |
341 | #pragma section(OFFLOAD_MYO_SHARED_TABLE_SECTION_END, read, write) | |
342 | ||
343 | #pragma section(OFFLOAD_MYO_SHARED_VTABLE_SECTION_START, read, write) | |
344 | #pragma section(OFFLOAD_MYO_SHARED_VTABLE_SECTION_END, read, write) | |
345 | ||
346 | #pragma section(OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START, read, write) | |
347 | #pragma section(OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_END, read, write) | |
348 | ||
349 | #pragma section(OFFLOAD_MYO_FPTR_TABLE_SECTION_START, read, write) | |
350 | #pragma section(OFFLOAD_MYO_FPTR_TABLE_SECTION_END, read, write) | |
351 | ||
352 | // List of MYO shared variable tables | |
353 | struct MYOVarTable { | |
354 | typedef SharedTableEntry Entry; | |
355 | const Entry *entries; | |
356 | }; | |
357 | ||
358 | class MYOVarTableList : public TableList<MYOVarTable> { | |
359 | public: | |
360 | MYOVarTableList() : TableList<Table>() | |
361 | {} | |
362 | ||
363 | // add table to the list | |
364 | void add_table(Node *node) { | |
365 | // add table | |
366 | TableList<Table>::add_table(node); | |
367 | } | |
368 | ||
369 | // debug dump | |
370 | void dump(void); | |
371 | ||
372 | // check if any shared variables | |
373 | bool is_empty(); | |
374 | ||
375 | // process the table contents for ordinary variables | |
376 | void process(); | |
377 | ||
378 | // process the table contents for vtable objects | |
379 | void process_vtable(); | |
380 | }; | |
381 | ||
382 | // List of MYO shared function tables | |
383 | struct MYOFuncTable { | |
384 | typedef FptrTableEntry Entry; | |
385 | const Entry *entries; | |
386 | }; | |
387 | ||
388 | class MYOFuncTableList : public TableList<MYOFuncTable> { | |
389 | public: | |
390 | MYOFuncTableList() : TableList<Table>() | |
391 | {} | |
392 | ||
393 | // add table to the list | |
394 | void add_table(Node *node) { | |
395 | // add table | |
396 | TableList<Table>::add_table(node); | |
397 | } | |
398 | ||
399 | // debug dump | |
400 | void dump(void); | |
401 | ||
402 | // check if any shared functions | |
403 | bool is_empty(); | |
404 | ||
405 | // process the table contents | |
406 | void process(); | |
407 | }; | |
408 | ||
409 | // List of MYO shared variable initialization routine tables | |
410 | struct MYOInitTable { | |
411 | typedef InitTableEntry Entry; | |
412 | const Entry *entries; | |
413 | }; | |
414 | ||
415 | class MYOInitTableList : public TableList<MYOInitTable> { | |
416 | public: | |
417 | MYOInitTableList() : TableList<Table>() | |
418 | {} | |
419 | ||
420 | // add table to the list | |
421 | void add_table(Node *node) { | |
422 | // add table | |
423 | TableList<Table>::add_table(node); | |
424 | } | |
425 | ||
426 | // debug dump | |
427 | void dump(void); | |
428 | ||
429 | // check if any init routines | |
430 | bool is_empty(); | |
431 | ||
432 | // process the table contents | |
433 | void process(); | |
434 | }; | |
435 | ||
436 | extern MYOVarTableList __offload_myo_var_tables; | |
437 | extern MYOVarTableList __offload_myo_vtable_tables; | |
438 | extern MYOFuncTableList __offload_myo_func_tables; | |
439 | extern MYOInitTableList __offload_myo_init_tables; | |
440 | ||
441 | extern "C" void __offload_myoRegisterTables1( | |
442 | MYOInitTableList::Node *init_table, | |
443 | MYOVarTableList::Node *shared_table, | |
444 | MYOVarTableList::Node *shared_vtable, | |
445 | MYOFuncTableList::Node *fptr_table | |
446 | ); | |
447 | ||
448 | extern "C" void __offload_myoRemoveTables( | |
449 | MYOInitTableList::Node *init_table, | |
450 | MYOVarTableList::Node *shared_table, | |
451 | MYOVarTableList::Node *shared_vtable, | |
452 | MYOFuncTableList::Node *fptr_table | |
453 | ); | |
454 | ||
455 | #endif // MYO_SUPPORT | |
456 | ||
5f520819 | 457 | #endif // OFFLOAD_TABLE_H_INCLUDED |