You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

278 lines
12 KiB

  1. /*
  2. Copyright 2005-2014 Intel Corporation. All Rights Reserved.
  3. This file is part of Threading Building Blocks.
  4. Threading Building Blocks is free software; you can redistribute it
  5. and/or modify it under the terms of the GNU General Public License
  6. version 2 as published by the Free Software Foundation.
  7. Threading Building Blocks is distributed in the hope that it will be
  8. useful, but WITHOUT ANY WARRANTY; without even the implied warranty
  9. of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with Threading Building Blocks; if not, write to the Free Software
  13. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  14. As a special exception, you may use this file as part of a free software
  15. library without restriction. Specifically, if other files instantiate
  16. templates or use macros or inline functions from this file, or you compile
  17. this file and link it with other files to produce an executable, this
  18. file does not by itself cause the resulting executable to be covered by
  19. the GNU General Public License. This exception does not however
  20. invalidate any other reasons why the executable file might be covered by
  21. the GNU General Public License.
  22. */
  23. #ifndef __TBB_profiling_H
  24. #define __TBB_profiling_H
  25. namespace tbb {
  26. namespace internal {
  27. //
  28. // This is not under __TBB_ITT_STRUCTURE_API because these values are used directly in flow_graph.h.
  29. //
  30. // include list of index names
  31. #define TBB_STRING_RESOURCE(index_name,str) index_name,
  32. enum string_index {
  33. #include "internal/_tbb_strings.h"
  34. NUM_STRINGS
  35. };
  36. #undef TBB_STRING_RESOURCE
  37. enum itt_relation
  38. {
  39. __itt_relation_is_unknown = 0,
  40. __itt_relation_is_dependent_on, /**< "A is dependent on B" means that A cannot start until B completes */
  41. __itt_relation_is_sibling_of, /**< "A is sibling of B" means that A and B were created as a group */
  42. __itt_relation_is_parent_of, /**< "A is parent of B" means that A created B */
  43. __itt_relation_is_continuation_of, /**< "A is continuation of B" means that A assumes the dependencies of B */
  44. __itt_relation_is_child_of, /**< "A is child of B" means that A was created by B (inverse of is_parent_of) */
  45. __itt_relation_is_continued_by, /**< "A is continued by B" means that B assumes the dependencies of A (inverse of is_continuation_of) */
  46. __itt_relation_is_predecessor_to /**< "A is predecessor to B" means that B cannot start until A completes (inverse of is_dependent_on) */
  47. };
  48. }
  49. }
  50. // Check if the tools support is enabled
  51. #if (_WIN32||_WIN64||__linux__) && !__MINGW32__ && TBB_USE_THREADING_TOOLS
  52. #if _WIN32||_WIN64
  53. #include <stdlib.h> /* mbstowcs_s */
  54. #endif
  55. #include "tbb_stddef.h"
  56. namespace tbb {
  57. namespace internal {
  58. #if _WIN32||_WIN64
  59. void __TBB_EXPORTED_FUNC itt_set_sync_name_v3( void *obj, const wchar_t* name );
  60. inline size_t multibyte_to_widechar( wchar_t* wcs, const char* mbs, size_t bufsize) {
  61. #if _MSC_VER>=1400
  62. size_t len;
  63. mbstowcs_s( &len, wcs, bufsize, mbs, _TRUNCATE );
  64. return len; // mbstowcs_s counts null terminator
  65. #else
  66. size_t len = mbstowcs( wcs, mbs, bufsize );
  67. if(wcs && len!=size_t(-1) )
  68. wcs[len<bufsize-1? len: bufsize-1] = wchar_t('\0');
  69. return len+1; // mbstowcs does not count null terminator
  70. #endif
  71. }
  72. #else
  73. void __TBB_EXPORTED_FUNC itt_set_sync_name_v3( void *obj, const char* name );
  74. #endif
  75. } // namespace internal
  76. } // namespace tbb
  77. //! Macro __TBB_DEFINE_PROFILING_SET_NAME(T) defines "set_name" methods for sync objects of type T
  78. /** Should be used in the "tbb" namespace only.
  79. Don't place semicolon after it to avoid compiler warnings. **/
  80. #if _WIN32||_WIN64
  81. #define __TBB_DEFINE_PROFILING_SET_NAME(sync_object_type) \
  82. namespace profiling { \
  83. inline void set_name( sync_object_type& obj, const wchar_t* name ) { \
  84. tbb::internal::itt_set_sync_name_v3( &obj, name ); \
  85. } \
  86. inline void set_name( sync_object_type& obj, const char* name ) { \
  87. size_t len = tbb::internal::multibyte_to_widechar(NULL, name, 0); \
  88. wchar_t *wname = new wchar_t[len]; \
  89. tbb::internal::multibyte_to_widechar(wname, name, len); \
  90. set_name( obj, wname ); \
  91. delete[] wname; \
  92. } \
  93. }
  94. #else /* !WIN */
  95. #define __TBB_DEFINE_PROFILING_SET_NAME(sync_object_type) \
  96. namespace profiling { \
  97. inline void set_name( sync_object_type& obj, const char* name ) { \
  98. tbb::internal::itt_set_sync_name_v3( &obj, name ); \
  99. } \
  100. }
  101. #endif /* !WIN */
  102. #else /* no tools support */
  103. #if _WIN32||_WIN64
  104. #define __TBB_DEFINE_PROFILING_SET_NAME(sync_object_type) \
  105. namespace profiling { \
  106. inline void set_name( sync_object_type&, const wchar_t* ) {} \
  107. inline void set_name( sync_object_type&, const char* ) {} \
  108. }
  109. #else /* !WIN */
  110. #define __TBB_DEFINE_PROFILING_SET_NAME(sync_object_type) \
  111. namespace profiling { \
  112. inline void set_name( sync_object_type&, const char* ) {} \
  113. }
  114. #endif /* !WIN */
  115. #endif /* no tools support */
  116. #include "atomic.h"
  117. // Need these to work regardless of tools support
  118. namespace tbb {
  119. namespace internal {
  120. enum notify_type {prepare=0, cancel, acquired, releasing};
  121. const uintptr_t NUM_NOTIFY_TYPES = 4; // set to # elements in enum above
  122. void __TBB_EXPORTED_FUNC call_itt_notify_v5(int t, void *ptr);
  123. void __TBB_EXPORTED_FUNC itt_store_pointer_with_release_v3(void *dst, void *src);
  124. void* __TBB_EXPORTED_FUNC itt_load_pointer_with_acquire_v3(const void *src);
  125. void* __TBB_EXPORTED_FUNC itt_load_pointer_v3( const void* src );
  126. #if __TBB_ITT_STRUCTURE_API
  127. enum itt_domain_enum { ITT_DOMAIN_FLOW=0 };
  128. void __TBB_EXPORTED_FUNC itt_make_task_group_v7( itt_domain_enum domain, void *group, unsigned long long group_extra,
  129. void *parent, unsigned long long parent_extra, string_index name_index );
  130. void __TBB_EXPORTED_FUNC itt_metadata_str_add_v7( itt_domain_enum domain, void *addr, unsigned long long addr_extra,
  131. string_index key, const char *value );
  132. void __TBB_EXPORTED_FUNC itt_relation_add_v7( itt_domain_enum domain, void *addr0, unsigned long long addr0_extra,
  133. itt_relation relation, void *addr1, unsigned long long addr1_extra );
  134. void __TBB_EXPORTED_FUNC itt_task_begin_v7( itt_domain_enum domain, void *task, unsigned long long task_extra,
  135. void *parent, unsigned long long parent_extra, string_index name_index );
  136. void __TBB_EXPORTED_FUNC itt_task_end_v7( itt_domain_enum domain );
  137. #endif // __TBB_ITT_STRUCTURE_API
  138. // two template arguments are to workaround /Wp64 warning with tbb::atomic specialized for unsigned type
  139. template <typename T, typename U>
  140. inline void itt_store_word_with_release(tbb::atomic<T>& dst, U src) {
  141. #if TBB_USE_THREADING_TOOLS
  142. // This assertion should be replaced with static_assert
  143. __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized.");
  144. itt_store_pointer_with_release_v3(&dst, (void *)uintptr_t(src));
  145. #else
  146. dst = src;
  147. #endif // TBB_USE_THREADING_TOOLS
  148. }
  149. template <typename T>
  150. inline T itt_load_word_with_acquire(const tbb::atomic<T>& src) {
  151. #if TBB_USE_THREADING_TOOLS
  152. // This assertion should be replaced with static_assert
  153. __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized.");
  154. #if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
  155. // Workaround for overzealous compiler warnings
  156. #pragma warning (push)
  157. #pragma warning (disable: 4311)
  158. #endif
  159. T result = (T)itt_load_pointer_with_acquire_v3(&src);
  160. #if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
  161. #pragma warning (pop)
  162. #endif
  163. return result;
  164. #else
  165. return src;
  166. #endif // TBB_USE_THREADING_TOOLS
  167. }
  168. template <typename T>
  169. inline void itt_store_word_with_release(T& dst, T src) {
  170. #if TBB_USE_THREADING_TOOLS
  171. // This assertion should be replaced with static_assert
  172. __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized.");
  173. itt_store_pointer_with_release_v3(&dst, (void *)src);
  174. #else
  175. __TBB_store_with_release(dst, src);
  176. #endif // TBB_USE_THREADING_TOOLS
  177. }
  178. template <typename T>
  179. inline T itt_load_word_with_acquire(const T& src) {
  180. #if TBB_USE_THREADING_TOOLS
  181. // This assertion should be replaced with static_assert
  182. __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized");
  183. return (T)itt_load_pointer_with_acquire_v3(&src);
  184. #else
  185. return __TBB_load_with_acquire(src);
  186. #endif // TBB_USE_THREADING_TOOLS
  187. }
  188. template <typename T>
  189. inline void itt_hide_store_word(T& dst, T src) {
  190. #if TBB_USE_THREADING_TOOLS
  191. // This assertion should be replaced with static_assert
  192. __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized");
  193. itt_store_pointer_with_release_v3(&dst, (void *)src);
  194. #else
  195. dst = src;
  196. #endif
  197. }
  198. template <typename T>
  199. inline T itt_hide_load_word(const T& src) {
  200. #if TBB_USE_THREADING_TOOLS
  201. // This assertion should be replaced with static_assert
  202. __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized.");
  203. return (T)itt_load_pointer_v3(&src);
  204. #else
  205. return src;
  206. #endif
  207. }
  208. #if TBB_USE_THREADING_TOOLS
  209. inline void call_itt_notify(notify_type t, void *ptr) {
  210. call_itt_notify_v5((int)t, ptr);
  211. }
  212. #else
  213. inline void call_itt_notify(notify_type /*t*/, void * /*ptr*/) {}
  214. #endif // TBB_USE_THREADING_TOOLS
  215. #if __TBB_ITT_STRUCTURE_API
  216. inline void itt_make_task_group( itt_domain_enum domain, void *group, unsigned long long group_extra,
  217. void *parent, unsigned long long parent_extra, string_index name_index ) {
  218. itt_make_task_group_v7( domain, group, group_extra, parent, parent_extra, name_index );
  219. }
  220. inline void itt_metadata_str_add( itt_domain_enum domain, void *addr, unsigned long long addr_extra,
  221. string_index key, const char *value ) {
  222. itt_metadata_str_add_v7( domain, addr, addr_extra, key, value );
  223. }
  224. inline void itt_relation_add( itt_domain_enum domain, void *addr0, unsigned long long addr0_extra,
  225. itt_relation relation, void *addr1, unsigned long long addr1_extra ) {
  226. itt_relation_add_v7( domain, addr0, addr0_extra, relation, addr1, addr1_extra );
  227. }
  228. inline void itt_task_begin( itt_domain_enum domain, void *task, unsigned long long task_extra,
  229. void *parent, unsigned long long parent_extra, string_index name_index ) {
  230. itt_task_begin_v7( domain, task, task_extra, parent, parent_extra, name_index );
  231. }
  232. inline void itt_task_end( itt_domain_enum domain ) {
  233. itt_task_end_v7( domain );
  234. }
  235. #endif // __TBB_ITT_STRUCTURE_API
  236. } // namespace internal
  237. } // namespace tbb
  238. #endif /* __TBB_profiling_H */