2 Copyright (c) 2014-2015 Intel Corporation. All Rights Reserved.
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
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.
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.
31 #include "offload_table.h"
32 #include "offload_common.h"
35 // Predefined offload entries
36 extern void omp_set_num_threads_lrb(void*);
37 extern void omp_get_max_threads_lrb(void*);
38 extern void omp_get_num_procs_lrb(void*);
39 extern void omp_set_dynamic_lrb(void*);
40 extern void omp_get_dynamic_lrb(void*);
41 extern void omp_set_nested_lrb(void*);
42 extern void omp_get_nested_lrb(void*);
43 extern void omp_set_schedule_lrb(void*);
44 extern void omp_get_schedule_lrb(void*);
46 extern void omp_init_lock_lrb(void*);
47 extern void omp_destroy_lock_lrb(void*);
48 extern void omp_set_lock_lrb(void*);
49 extern void omp_unset_lock_lrb(void*);
50 extern void omp_test_lock_lrb(void*);
52 extern void omp_init_nest_lock_lrb(void*);
53 extern void omp_destroy_nest_lock_lrb(void*);
54 extern void omp_set_nest_lock_lrb(void*);
55 extern void omp_unset_nest_lock_lrb(void*);
56 extern void omp_test_nest_lock_lrb(void*);
58 // Predefined entries on the target side
59 static FuncTable::Entry predefined_entries
[] = {
60 "omp_set_num_threads_target",
61 (void*) &omp_set_num_threads_lrb
,
62 "omp_get_max_threads_target",
63 (void*) &omp_get_max_threads_lrb
,
64 "omp_get_num_procs_target",
65 (void*) &omp_get_num_procs_lrb
,
66 "omp_set_dynamic_target",
67 (void*) &omp_set_dynamic_lrb
,
68 "omp_get_dynamic_target",
69 (void*) &omp_get_dynamic_lrb
,
70 "omp_set_nested_target",
71 (void*) &omp_set_nested_lrb
,
72 "omp_get_nested_target",
73 (void*) &omp_get_nested_lrb
,
74 "omp_set_schedule_target",
75 (void*) &omp_set_schedule_lrb
,
76 "omp_get_schedule_target",
77 (void*) &omp_get_schedule_lrb
,
79 "omp_init_lock_target",
80 (void*) &omp_init_lock_lrb
,
81 "omp_destroy_lock_target",
82 (void*) &omp_destroy_lock_lrb
,
83 "omp_set_lock_target",
84 (void*) &omp_set_lock_lrb
,
85 "omp_unset_lock_target",
86 (void*) &omp_unset_lock_lrb
,
87 "omp_test_lock_target",
88 (void*) &omp_test_lock_lrb
,
90 "omp_init_nest_lock_target",
91 (void*) &omp_init_nest_lock_lrb
,
92 "omp_destroy_nest_lock_target",
93 (void*) &omp_destroy_nest_lock_lrb
,
94 "omp_set_nest_lock_target",
95 (void*) &omp_set_nest_lock_lrb
,
96 "omp_unset_nest_lock_target",
97 (void*) &omp_unset_nest_lock_lrb
,
98 "omp_test_nest_lock_target",
99 (void*) &omp_test_nest_lock_lrb
,
105 static FuncList::Node predefined_table
= {
106 { predefined_entries
, -1 },
111 FuncList
__offload_entries(&predefined_table
);
113 FuncList __offload_entries
;
114 #endif // !HOST_LIBRARY
116 // Function table. No predefined entries.
117 FuncList __offload_funcs
;
120 VarList __offload_vars
;
122 // Given the function name returns the associtated function pointer
123 const void* FuncList::find_addr(const char *name
)
125 const void* func
= 0;
129 for (Node
*n
= m_head
; n
!= 0; n
= n
->next
) {
130 for (const Table::Entry
*e
= n
->table
.entries
;
131 e
->name
!= (const char*) -1; e
++) {
132 if (e
->name
!= 0 && strcmp(e
->name
, name
) == 0) {
144 // Given the function pointer returns the associtated function name
145 const char* FuncList::find_name(const void *func
)
147 const char* name
= 0;
151 for (Node
*n
= m_head
; n
!= 0; n
= n
->next
) {
152 for (const Table::Entry
*e
= n
->table
.entries
;
153 e
->name
!= (const char*) -1; e
++) {
154 if (e
->func
== func
) {
166 // Returns max name length from all tables
167 int64_t FuncList::max_name_length(void)
169 if (m_max_name_len
< 0) {
173 for (Node
*n
= m_head
; n
!= 0; n
= n
->next
) {
174 if (n
->table
.max_name_len
< 0) {
175 n
->table
.max_name_len
= 0;
177 // calculate max name length in a single table
178 for (const Table::Entry
*e
= n
->table
.entries
;
179 e
->name
!= (const char*) -1; e
++) {
181 size_t len
= strlen(e
->name
) + 1;
182 if (n
->table
.max_name_len
< len
) {
183 n
->table
.max_name_len
= len
;
189 // select max from all tables
190 if (m_max_name_len
< n
->table
.max_name_len
) {
191 m_max_name_len
= n
->table
.max_name_len
;
197 return m_max_name_len
;
201 void FuncList::dump(void)
203 OFFLOAD_DEBUG_TRACE(2, "Function table:\n");
207 for (Node
*n
= m_head
; n
!= 0; n
= n
->next
) {
208 for (const Table::Entry
*e
= n
->table
.entries
;
209 e
->name
!= (const char*) -1; e
++) {
211 OFFLOAD_DEBUG_TRACE(2, "%p %s\n", e
->func
, e
->name
);
220 void VarList::dump(void)
222 OFFLOAD_DEBUG_TRACE(2, "Var table:\n");
226 for (Node
*n
= m_head
; n
!= 0; n
= n
->next
) {
227 for (const Table::Entry
*e
= n
->table
.entries
;
228 e
->name
!= (const char*) -1; e
++) {
231 OFFLOAD_DEBUG_TRACE(2, "%s %p %ld\n", e
->name
, e
->addr
,
233 #else // HOST_LIBRARY
234 OFFLOAD_DEBUG_TRACE(2, "%s %p\n", e
->name
, e
->addr
);
235 #endif // HOST_LIBRARY
244 int64_t VarList::table_size(int64_t &nelems
)
250 // calculate string table size and number of elements
251 for (Node
*n
= m_head
; n
!= 0; n
= n
->next
) {
252 for (const Table::Entry
*e
= n
->table
.entries
;
253 e
->name
!= (const char*) -1; e
++) {
255 length
+= strlen(e
->name
) + 1;
261 return nelems
* sizeof(BufEntry
) + length
;
264 // copy table to the gven buffer
265 void VarList::table_copy(void *buf
, int64_t nelems
)
267 BufEntry
* elems
= static_cast<BufEntry
*>(buf
);
268 char* names
= reinterpret_cast<char*>(elems
+ nelems
);
270 // copy entries to buffer
271 for (Node
*n
= m_head
; n
!= 0; n
= n
->next
) {
272 for (const Table::Entry
*e
= n
->table
.entries
;
273 e
->name
!= (const char*) -1; e
++) {
275 // name field contains offset to the name from the beginning
277 elems
->name
= names
- static_cast<char*>(buf
);
278 elems
->addr
= reinterpret_cast<intptr_t>(e
->addr
);
280 // copy name to string table
281 const char *name
= e
->name
;
282 while ((*names
++ = *name
++) != '\0');
290 // patch name offsets in a buffer
291 void VarList::table_patch_names(void *buf
, int64_t nelems
)
293 BufEntry
* elems
= static_cast<BufEntry
*>(buf
);
294 for (int i
= 0; i
< nelems
; i
++) {
295 elems
[i
].name
+= reinterpret_cast<intptr_t>(buf
);
299 // Adds given list element to the global lookup table list
300 extern "C" void __offload_register_tables(
301 FuncList::Node
*entry_table
,
302 FuncList::Node
*func_table
,
303 VarList::Node
*var_table
306 OFFLOAD_DEBUG_TRACE(2, "Registering offload function entry table %p\n",
308 __offload_entries
.add_table(entry_table
);
310 OFFLOAD_DEBUG_TRACE(2, "Registering function table %p\n", func_table
);
311 __offload_funcs
.add_table(func_table
);
313 OFFLOAD_DEBUG_TRACE(2, "Registering var table %p\n", var_table
);
314 __offload_vars
.add_table(var_table
);
317 // Removes given list element from the global lookup table list
318 extern "C" void __offload_unregister_tables(
319 FuncList::Node
*entry_table
,
320 FuncList::Node
*func_table
,
321 VarList::Node
*var_table
324 OFFLOAD_DEBUG_TRACE(2, "Unregistering offload function entry table %p\n",
326 __offload_entries
.remove_table(entry_table
);
328 OFFLOAD_DEBUG_TRACE(2, "Unregistering function table %p\n", func_table
);
329 __offload_funcs
.remove_table(func_table
);
331 OFFLOAD_DEBUG_TRACE(2, "Unregistering var table %p\n", var_table
);
332 __offload_vars
.remove_table(var_table
);
337 MYOVarTableList __offload_myo_var_tables
;
338 MYOVarTableList __offload_myo_vtable_tables
;
339 MYOFuncTableList __offload_myo_func_tables
;
340 MYOInitTableList __offload_myo_init_tables
;
343 void MYOVarTableList::dump(void)
345 OFFLOAD_DEBUG_TRACE(2, "MYO Var tables:\n");
349 for (Node
*n
= m_head
; n
!= 0; n
= n
->next
) {
350 OFFLOAD_DEBUG_TRACE(2, " MYO Var table:\n");
351 for (const Table::Entry
*e
= n
->table
.entries
;
352 e
->varName
!= MYO_TABLE_END_MARKER(); e
++) {
354 if (e
->varName
== 0) {
357 #endif // TARGET_WINNT
358 OFFLOAD_DEBUG_TRACE(2, " %s %p\n",
359 e
->varName
, e
->sharedAddr
);
366 // check if any shared variables
367 bool MYOVarTableList::is_empty()
369 OFFLOAD_DEBUG_TRACE(3, "Are MYO Var tables empty?\n");
373 for (Node
*n
= m_head
; n
!= 0; n
= n
->next
) {
374 for (const Table::Entry
*e
= n
->table
.entries
;
375 e
->varName
!= MYO_TABLE_END_MARKER(); e
++) {
377 if (e
->varName
== 0) {
380 #endif // TARGET_WINNT
382 OFFLOAD_DEBUG_TRACE(3, "No\n");
388 OFFLOAD_DEBUG_TRACE(3, "Yes\n");
392 void MYOFuncTableList::dump(void)
394 OFFLOAD_DEBUG_TRACE(2, "MYO Func tables:\n");
398 for (Node
*n
= m_head
; n
!= 0; n
= n
->next
) {
399 OFFLOAD_DEBUG_TRACE(2, " MYO Func table:\n");
400 for (const Table::Entry
*e
= n
->table
.entries
;
401 e
->funcName
!= MYO_TABLE_END_MARKER(); e
++) {
403 if (e
->funcName
== 0) {
406 #endif // TARGET_WINNT
408 OFFLOAD_DEBUG_TRACE(2, " %s %p %p\n",
409 e
->funcName
, e
->funcAddr
, e
->localThunkAddr
);
410 #else // HOST_LIBRARY
411 OFFLOAD_DEBUG_TRACE(2, " %s %p %p %p\n",
412 e
->funcName
, e
->funcAddr
, e
->wrapFuncAddr
, e
->localThunkAddr
);
413 #endif // HOST_LIBRARY
420 // check if any shared functions
421 bool MYOFuncTableList::is_empty()
423 OFFLOAD_DEBUG_TRACE(3, "Are MYO Func tables empty?\n");
427 for (Node
*n
= m_head
; n
!= 0; n
= n
->next
) {
429 for (const Table::Entry
*e
= n
->table
.entries
;
430 e
->funcName
!= MYO_TABLE_END_MARKER(); e
++) {
432 if (e
->funcName
== 0) {
435 #endif // TARGET_WINNT
439 OFFLOAD_DEBUG_TRACE(3, "No\n");
446 OFFLOAD_DEBUG_TRACE(3, "Yes\n");
450 void MYOInitTableList::dump(void)
452 OFFLOAD_DEBUG_TRACE(2, "MYO Init tables:\n");
456 for (Node
*n
= m_head
; n
!= 0; n
= n
->next
) {
457 OFFLOAD_DEBUG_TRACE(2, " MYO Init table:\n");
458 for (const Table::Entry
*e
= n
->table
.entries
;
460 e
->funcName
!= MYO_TABLE_END_MARKER(); e
++) {
461 if (e
->funcName
== 0) {
464 OFFLOAD_DEBUG_TRACE(2, " %s %p\n", e
->funcName
, e
->func
);
465 #else // TARGET_WINNT
467 OFFLOAD_DEBUG_TRACE(2, " %p\n", e
->func
);
468 #endif // TARGET_WINNT
475 // check if any shared functions
476 bool MYOInitTableList::is_empty()
478 OFFLOAD_DEBUG_TRACE(3, "Are MYO Init tables empty?\n");
482 for (Node
*n
= m_head
; n
!= 0; n
= n
->next
) {
483 for (const Table::Entry
*e
= n
->table
.entries
;
485 e
->funcName
!= MYO_TABLE_END_MARKER(); e
++) {
486 if (e
->funcName
== 0) {
490 OFFLOAD_DEBUG_TRACE(3, "No\n");
492 #else // TARGET_WINNT
494 #endif // TARGET_WINNT
499 OFFLOAD_DEBUG_TRACE(3, "Yes\n");
503 extern "C" void __offload_myoRegisterTables1(
504 MYOInitTableList::Node
*init_table
,
505 MYOVarTableList::Node
*shared_table
,
506 MYOVarTableList::Node
*shared_vtable
,
507 MYOFuncTableList::Node
*fptr_table
510 OFFLOAD_DEBUG_TRACE(2, "Registering MYO shared var table %p\n",
512 __offload_myo_var_tables
.add_table(shared_table
);
514 OFFLOAD_DEBUG_TRACE(2, "Registering MYO shared vtable table %p\n",
516 __offload_myo_vtable_tables
.add_table(shared_vtable
);
518 OFFLOAD_DEBUG_TRACE(2, "Registering MYO function table %p\n", fptr_table
);
519 __offload_myo_func_tables
.add_table(fptr_table
);
521 OFFLOAD_DEBUG_TRACE(2, "Registering MYO init table %p\n", init_table
);
522 __offload_myo_init_tables
.add_table(init_table
);
525 extern "C" void __offload_myoRemoveTables(
526 MYOInitTableList::Node
*init_table
,
527 MYOVarTableList::Node
*shared_table
,
528 MYOVarTableList::Node
*shared_vtable
,
529 MYOFuncTableList::Node
*fptr_table
532 OFFLOAD_DEBUG_TRACE(3, "%s\n", __func__
);
534 OFFLOAD_DEBUG_TRACE(2, "Removing MYO shared var table %p\n",
536 __offload_myo_var_tables
.remove_table(shared_table
);
538 OFFLOAD_DEBUG_TRACE(2, "Removing MYO shared vtable table %p\n",
540 __offload_myo_vtable_tables
.remove_table(shared_vtable
);
542 OFFLOAD_DEBUG_TRACE(2, "Removing MYO function table %p\n", fptr_table
);
543 __offload_myo_func_tables
.remove_table(fptr_table
);
545 OFFLOAD_DEBUG_TRACE(2, "Removing MYO init table %p\n", init_table
);
546 __offload_myo_init_tables
.remove_table(init_table
);
549 #endif // MYO_SUPPORT