offload_table.cpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. /*
  2. Copyright (c) 2014 Intel Corporation. All Rights Reserved.
  3. Redistribution and use in source and binary forms, with or without
  4. modification, are permitted provided that the following conditions
  5. are met:
  6. * Redistributions of source code must retain the above copyright
  7. notice, this list of conditions and the following disclaimer.
  8. * Redistributions in binary form must reproduce the above copyright
  9. notice, this list of conditions and the following disclaimer in the
  10. documentation and/or other materials provided with the distribution.
  11. * Neither the name of Intel Corporation nor the names of its
  12. contributors may be used to endorse or promote products derived
  13. from this software without specific prior written permission.
  14. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  16. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  17. A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  18. HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  19. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  20. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  21. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  22. THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  24. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #include "offload_table.h"
  27. #include "offload_common.h"
  28. #if !HOST_LIBRARY
  29. // Predefined offload entries
  30. extern void omp_set_num_threads_lrb(void*);
  31. extern void omp_get_max_threads_lrb(void*);
  32. extern void omp_get_num_procs_lrb(void*);
  33. extern void omp_set_dynamic_lrb(void*);
  34. extern void omp_get_dynamic_lrb(void*);
  35. extern void omp_set_nested_lrb(void*);
  36. extern void omp_get_nested_lrb(void*);
  37. extern void omp_set_schedule_lrb(void*);
  38. extern void omp_get_schedule_lrb(void*);
  39. extern void omp_init_lock_lrb(void*);
  40. extern void omp_destroy_lock_lrb(void*);
  41. extern void omp_set_lock_lrb(void*);
  42. extern void omp_unset_lock_lrb(void*);
  43. extern void omp_test_lock_lrb(void*);
  44. extern void omp_init_nest_lock_lrb(void*);
  45. extern void omp_destroy_nest_lock_lrb(void*);
  46. extern void omp_set_nest_lock_lrb(void*);
  47. extern void omp_unset_nest_lock_lrb(void*);
  48. extern void omp_test_nest_lock_lrb(void*);
  49. // Predefined entries on the target side
  50. static FuncTable::Entry predefined_entries[] = {
  51. "omp_set_num_threads_target",
  52. (void*) &omp_set_num_threads_lrb,
  53. "omp_get_max_threads_target",
  54. (void*) &omp_get_max_threads_lrb,
  55. "omp_get_num_procs_target",
  56. (void*) &omp_get_num_procs_lrb,
  57. "omp_set_dynamic_target",
  58. (void*) &omp_set_dynamic_lrb,
  59. "omp_get_dynamic_target",
  60. (void*) &omp_get_dynamic_lrb,
  61. "omp_set_nested_target",
  62. (void*) &omp_set_nested_lrb,
  63. "omp_get_nested_target",
  64. (void*) &omp_get_nested_lrb,
  65. "omp_set_schedule_target",
  66. (void*) &omp_set_schedule_lrb,
  67. "omp_get_schedule_target",
  68. (void*) &omp_get_schedule_lrb,
  69. "omp_init_lock_target",
  70. (void*) &omp_init_lock_lrb,
  71. "omp_destroy_lock_target",
  72. (void*) &omp_destroy_lock_lrb,
  73. "omp_set_lock_target",
  74. (void*) &omp_set_lock_lrb,
  75. "omp_unset_lock_target",
  76. (void*) &omp_unset_lock_lrb,
  77. "omp_test_lock_target",
  78. (void*) &omp_test_lock_lrb,
  79. "omp_init_nest_lock_target",
  80. (void*) &omp_init_nest_lock_lrb,
  81. "omp_destroy_nest_lock_target",
  82. (void*) &omp_destroy_nest_lock_lrb,
  83. "omp_set_nest_lock_target",
  84. (void*) &omp_set_nest_lock_lrb,
  85. "omp_unset_nest_lock_target",
  86. (void*) &omp_unset_nest_lock_lrb,
  87. "omp_test_nest_lock_target",
  88. (void*) &omp_test_nest_lock_lrb,
  89. (const char*) -1,
  90. (void*) -1
  91. };
  92. static FuncList::Node predefined_table = {
  93. { predefined_entries, -1 },
  94. 0, 0
  95. };
  96. // Entry table
  97. FuncList __offload_entries(&predefined_table);
  98. #else
  99. FuncList __offload_entries;
  100. #endif // !HOST_LIBRARY
  101. // Function table. No predefined entries.
  102. FuncList __offload_funcs;
  103. // Var table
  104. VarList __offload_vars;
  105. // Given the function name returns the associtated function pointer
  106. const void* FuncList::find_addr(const char *name)
  107. {
  108. const void* func = 0;
  109. m_lock.lock();
  110. for (Node *n = m_head; n != 0; n = n->next) {
  111. for (const Table::Entry *e = n->table.entries;
  112. e->name != (const char*) -1; e++) {
  113. if (e->name != 0 && strcmp(e->name, name) == 0) {
  114. func = e->func;
  115. break;
  116. }
  117. }
  118. }
  119. m_lock.unlock();
  120. return func;
  121. }
  122. // Given the function pointer returns the associtated function name
  123. const char* FuncList::find_name(const void *func)
  124. {
  125. const char* name = 0;
  126. m_lock.lock();
  127. for (Node *n = m_head; n != 0; n = n->next) {
  128. for (const Table::Entry *e = n->table.entries;
  129. e->name != (const char*) -1; e++) {
  130. if (e->func == func) {
  131. name = e->name;
  132. break;
  133. }
  134. }
  135. }
  136. m_lock.unlock();
  137. return name;
  138. }
  139. // Returns max name length from all tables
  140. int64_t FuncList::max_name_length(void)
  141. {
  142. if (m_max_name_len < 0) {
  143. m_lock.lock();
  144. m_max_name_len = 0;
  145. for (Node *n = m_head; n != 0; n = n->next) {
  146. if (n->table.max_name_len < 0) {
  147. n->table.max_name_len = 0;
  148. // calculate max name length in a single table
  149. for (const Table::Entry *e = n->table.entries;
  150. e->name != (const char*) -1; e++) {
  151. if (e->name != 0) {
  152. size_t len = strlen(e->name) + 1;
  153. if (n->table.max_name_len < len) {
  154. n->table.max_name_len = len;
  155. }
  156. }
  157. }
  158. }
  159. // select max from all tables
  160. if (m_max_name_len < n->table.max_name_len) {
  161. m_max_name_len = n->table.max_name_len;
  162. }
  163. }
  164. m_lock.unlock();
  165. }
  166. return m_max_name_len;
  167. }
  168. // Debugging dump
  169. void FuncList::dump(void)
  170. {
  171. OFFLOAD_DEBUG_TRACE(2, "Function table:\n");
  172. m_lock.lock();
  173. for (Node *n = m_head; n != 0; n = n->next) {
  174. for (const Table::Entry *e = n->table.entries;
  175. e->name != (const char*) -1; e++) {
  176. if (e->name != 0) {
  177. OFFLOAD_DEBUG_TRACE(2, "%p %s\n", e->func, e->name);
  178. }
  179. }
  180. }
  181. m_lock.unlock();
  182. }
  183. // Debugging dump
  184. void VarList::dump(void)
  185. {
  186. OFFLOAD_DEBUG_TRACE(2, "Var table:\n");
  187. m_lock.lock();
  188. for (Node *n = m_head; n != 0; n = n->next) {
  189. for (const Table::Entry *e = n->table.entries;
  190. e->name != (const char*) -1; e++) {
  191. if (e->name != 0) {
  192. #if HOST_LIBRARY
  193. OFFLOAD_DEBUG_TRACE(2, "%s %p %ld\n", e->name, e->addr,
  194. e->size);
  195. #else // HOST_LIBRARY
  196. OFFLOAD_DEBUG_TRACE(2, "%s %p\n", e->name, e->addr);
  197. #endif // HOST_LIBRARY
  198. }
  199. }
  200. }
  201. m_lock.unlock();
  202. }
  203. //
  204. int64_t VarList::table_size(int64_t &nelems)
  205. {
  206. int64_t length = 0;
  207. nelems = 0;
  208. // calculate string table size and number of elements
  209. for (Node *n = m_head; n != 0; n = n->next) {
  210. for (const Table::Entry *e = n->table.entries;
  211. e->name != (const char*) -1; e++) {
  212. if (e->name != 0) {
  213. length += strlen(e->name) + 1;
  214. nelems++;
  215. }
  216. }
  217. }
  218. return nelems * sizeof(BufEntry) + length;
  219. }
  220. // copy table to the gven buffer
  221. void VarList::table_copy(void *buf, int64_t nelems)
  222. {
  223. BufEntry* elems = static_cast<BufEntry*>(buf);
  224. char* names = reinterpret_cast<char*>(elems + nelems);
  225. // copy entries to buffer
  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. // name field contains offset to the name from the beginning
  231. // of the buffer
  232. elems->name = names - static_cast<char*>(buf);
  233. elems->addr = reinterpret_cast<intptr_t>(e->addr);
  234. // copy name to string table
  235. const char *name = e->name;
  236. while ((*names++ = *name++) != '\0');
  237. elems++;
  238. }
  239. }
  240. }
  241. }
  242. // patch name offsets in a buffer
  243. void VarList::table_patch_names(void *buf, int64_t nelems)
  244. {
  245. BufEntry* elems = static_cast<BufEntry*>(buf);
  246. for (int i = 0; i < nelems; i++) {
  247. elems[i].name += reinterpret_cast<intptr_t>(buf);
  248. }
  249. }
  250. // Adds given list element to the global lookup table list
  251. extern "C" void __offload_register_tables(
  252. FuncList::Node *entry_table,
  253. FuncList::Node *func_table,
  254. VarList::Node *var_table
  255. )
  256. {
  257. OFFLOAD_DEBUG_TRACE(2, "Registering offload function entry table %p\n",
  258. entry_table);
  259. __offload_entries.add_table(entry_table);
  260. OFFLOAD_DEBUG_TRACE(2, "Registering function table %p\n", func_table);
  261. __offload_funcs.add_table(func_table);
  262. OFFLOAD_DEBUG_TRACE(2, "Registering var table %p\n", var_table);
  263. __offload_vars.add_table(var_table);
  264. }
  265. // Removes given list element from the global lookup table list
  266. extern "C" void __offload_unregister_tables(
  267. FuncList::Node *entry_table,
  268. FuncList::Node *func_table,
  269. VarList::Node *var_table
  270. )
  271. {
  272. __offload_entries.remove_table(entry_table);
  273. OFFLOAD_DEBUG_TRACE(2, "Unregistering function table %p\n", func_table);
  274. __offload_funcs.remove_table(func_table);
  275. OFFLOAD_DEBUG_TRACE(2, "Unregistering var table %p\n", var_table);
  276. __offload_vars.remove_table(var_table);
  277. }