2015-05-12 Pierre-Marie de Rodat <derodat@adacore.com>
[official-gcc.git] / liboffloadmic / runtime / offload_table.cpp
blobd73def16e70218948a747b25056721425f83ba4f
1 /*
2 Copyright (c) 2014 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
6 are met:
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"
34 #if !HOST_LIBRARY
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,
101 (const char*) -1,
102 (void*) -1
105 static FuncList::Node predefined_table = {
106 { predefined_entries, -1 },
107 0, 0
110 // Entry table
111 FuncList __offload_entries(&predefined_table);
112 #else
113 FuncList __offload_entries;
114 #endif // !HOST_LIBRARY
116 // Function table. No predefined entries.
117 FuncList __offload_funcs;
119 // Var table
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;
127 m_lock.lock();
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) {
133 func = e->func;
134 break;
139 m_lock.unlock();
141 return func;
144 // Given the function pointer returns the associtated function name
145 const char* FuncList::find_name(const void *func)
147 const char* name = 0;
149 m_lock.lock();
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) {
155 name = e->name;
156 break;
161 m_lock.unlock();
163 return name;
166 // Returns max name length from all tables
167 int64_t FuncList::max_name_length(void)
169 if (m_max_name_len < 0) {
170 m_lock.lock();
172 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++) {
180 if (e->name != 0) {
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;
195 m_lock.unlock();
197 return m_max_name_len;
200 // Debugging dump
201 void FuncList::dump(void)
203 OFFLOAD_DEBUG_TRACE(2, "Function table:\n");
205 m_lock.lock();
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++) {
210 if (e->name != 0) {
211 OFFLOAD_DEBUG_TRACE(2, "%p %s\n", e->func, e->name);
216 m_lock.unlock();
219 // Debugging dump
220 void VarList::dump(void)
222 OFFLOAD_DEBUG_TRACE(2, "Var table:\n");
224 m_lock.lock();
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++) {
229 if (e->name != 0) {
230 #if HOST_LIBRARY
231 OFFLOAD_DEBUG_TRACE(2, "%s %p %ld\n", e->name, e->addr,
232 e->size);
233 #else // HOST_LIBRARY
234 OFFLOAD_DEBUG_TRACE(2, "%s %p\n", e->name, e->addr);
235 #endif // HOST_LIBRARY
240 m_lock.unlock();
244 int64_t VarList::table_size(int64_t &nelems)
246 int64_t length = 0;
248 nelems = 0;
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++) {
254 if (e->name != 0) {
255 length += strlen(e->name) + 1;
256 nelems++;
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++) {
274 if (e->name != 0) {
275 // name field contains offset to the name from the beginning
276 // of the buffer
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');
284 elems++;
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",
307 entry_table);
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_entries.remove_table(entry_table);
326 OFFLOAD_DEBUG_TRACE(2, "Unregistering function table %p\n", func_table);
327 __offload_funcs.remove_table(func_table);
329 OFFLOAD_DEBUG_TRACE(2, "Unregistering var table %p\n", var_table);
330 __offload_vars.remove_table(var_table);