trace.hpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. // This file is part of OpenCV project.
  2. // It is subject to the license terms in the LICENSE file found in the top-level directory
  3. // of this distribution and at http://opencv.org/license.html.
  4. #ifndef OPENCV_TRACE_HPP
  5. #define OPENCV_TRACE_HPP
  6. #include <opencv2/core/cvdef.h>
  7. namespace cv {
  8. namespace utils {
  9. namespace trace {
  10. //! @addtogroup core_logging
  11. //! @{
  12. //! Macro to trace function
  13. #define CV_TRACE_FUNCTION()
  14. #define CV_TRACE_FUNCTION_SKIP_NESTED()
  15. //! Trace code scope.
  16. //! @note Dynamic names are not supported in this macro (on stack or heap). Use string literals here only, like "initialize".
  17. #define CV_TRACE_REGION(name_as_static_string_literal)
  18. //! mark completed of the current opened region and create new one
  19. //! @note Dynamic names are not supported in this macro (on stack or heap). Use string literals here only, like "step1".
  20. #define CV_TRACE_REGION_NEXT(name_as_static_string_literal)
  21. //! Macro to trace argument value
  22. #define CV_TRACE_ARG(arg_id)
  23. //! Macro to trace argument value (expanded version)
  24. #define CV_TRACE_ARG_VALUE(arg_id, arg_name, value)
  25. //! @cond IGNORED
  26. #define CV_TRACE_NS cv::utils::trace
  27. #if !defined(OPENCV_DISABLE_TRACE) && defined(__EMSCRIPTEN__)
  28. #define OPENCV_DISABLE_TRACE 1
  29. #endif
  30. namespace details {
  31. #ifndef __OPENCV_TRACE
  32. # if defined __OPENCV_BUILD && !defined __OPENCV_TESTS && !defined __OPENCV_APPS
  33. # define __OPENCV_TRACE 1
  34. # else
  35. # define __OPENCV_TRACE 0
  36. # endif
  37. #endif
  38. #ifndef CV_TRACE_FILENAME
  39. # define CV_TRACE_FILENAME __FILE__
  40. #endif
  41. #ifndef CV__TRACE_FUNCTION
  42. # if defined _MSC_VER
  43. # define CV__TRACE_FUNCTION __FUNCSIG__
  44. # elif defined __GNUC__
  45. # define CV__TRACE_FUNCTION __PRETTY_FUNCTION__
  46. # else
  47. # define CV__TRACE_FUNCTION "<unknown>"
  48. # endif
  49. #endif
  50. //! Thread-local instance (usually allocated on stack)
  51. class CV_EXPORTS Region
  52. {
  53. public:
  54. struct LocationExtraData;
  55. struct LocationStaticStorage
  56. {
  57. LocationExtraData** ppExtra; ///< implementation specific data
  58. const char* name; ///< region name (function name or other custom name)
  59. const char* filename; ///< source code filename
  60. int line; ///< source code line
  61. int flags; ///< flags (implementation code path: Plain, IPP, OpenCL)
  62. };
  63. Region(const LocationStaticStorage& location);
  64. inline ~Region()
  65. {
  66. if (implFlags != 0)
  67. destroy();
  68. CV_DbgAssert(implFlags == 0);
  69. CV_DbgAssert(pImpl == NULL);
  70. }
  71. class Impl;
  72. Impl* pImpl; // NULL if current region is not active
  73. int implFlags; // see RegionFlag, 0 if region is ignored
  74. bool isActive() const { return pImpl != NULL; }
  75. void destroy();
  76. private:
  77. Region(const Region&); // disabled
  78. Region& operator= (const Region&); // disabled
  79. };
  80. //! Specify region flags
  81. enum RegionLocationFlag {
  82. REGION_FLAG_FUNCTION = (1 << 0), ///< region is function (=1) / nested named region (=0)
  83. REGION_FLAG_APP_CODE = (1 << 1), ///< region is Application code (=1) / OpenCV library code (=0)
  84. REGION_FLAG_SKIP_NESTED = (1 << 2), ///< avoid processing of nested regions
  85. REGION_FLAG_IMPL_IPP = (1 << 16), ///< region is part of IPP code path
  86. REGION_FLAG_IMPL_OPENCL = (2 << 16), ///< region is part of OpenCL code path
  87. REGION_FLAG_IMPL_OPENVX = (3 << 16), ///< region is part of OpenVX code path
  88. REGION_FLAG_IMPL_MASK = (15 << 16),
  89. REGION_FLAG_REGION_FORCE = (1 << 30),
  90. REGION_FLAG_REGION_NEXT = (1 << 31), ///< close previous region (see #CV_TRACE_REGION_NEXT macro)
  91. ENUM_REGION_FLAG_FORCE_INT = INT_MAX
  92. };
  93. struct CV_EXPORTS TraceArg {
  94. public:
  95. struct ExtraData;
  96. ExtraData** ppExtra;
  97. const char* name;
  98. int flags;
  99. };
  100. /** @brief Add meta information to current region (function)
  101. * See CV_TRACE_ARG macro
  102. * @param arg argument information structure (global static cache)
  103. * @param value argument value (can by dynamic string literal in case of string, static allocation is not required)
  104. */
  105. CV_EXPORTS void traceArg(const TraceArg& arg, const char* value);
  106. //! @overload
  107. CV_EXPORTS void traceArg(const TraceArg& arg, int value);
  108. //! @overload
  109. CV_EXPORTS void traceArg(const TraceArg& arg, int64 value);
  110. //! @overload
  111. CV_EXPORTS void traceArg(const TraceArg& arg, double value);
  112. #define CV__TRACE_LOCATION_VARNAME(loc_id) CVAUX_CONCAT(CVAUX_CONCAT(__cv_trace_location_, loc_id), __LINE__)
  113. #define CV__TRACE_LOCATION_EXTRA_VARNAME(loc_id) CVAUX_CONCAT(CVAUX_CONCAT(__cv_trace_location_extra_, loc_id) , __LINE__)
  114. #define CV__TRACE_DEFINE_LOCATION_(loc_id, name, flags) \
  115. static CV_TRACE_NS::details::Region::LocationExtraData* CV__TRACE_LOCATION_EXTRA_VARNAME(loc_id) = 0; \
  116. static const CV_TRACE_NS::details::Region::LocationStaticStorage \
  117. CV__TRACE_LOCATION_VARNAME(loc_id) = { &(CV__TRACE_LOCATION_EXTRA_VARNAME(loc_id)), name, CV_TRACE_FILENAME, __LINE__, flags};
  118. #define CV__TRACE_DEFINE_LOCATION_FN(name, flags) CV__TRACE_DEFINE_LOCATION_(fn, name, ((flags) | CV_TRACE_NS::details::REGION_FLAG_FUNCTION))
  119. #define CV__TRACE_OPENCV_FUNCTION() \
  120. CV__TRACE_DEFINE_LOCATION_FN(CV__TRACE_FUNCTION, 0); \
  121. const CV_TRACE_NS::details::Region __region_fn(CV__TRACE_LOCATION_VARNAME(fn));
  122. #define CV__TRACE_OPENCV_FUNCTION_NAME(name) \
  123. CV__TRACE_DEFINE_LOCATION_FN(name, 0); \
  124. const CV_TRACE_NS::details::Region __region_fn(CV__TRACE_LOCATION_VARNAME(fn));
  125. #define CV__TRACE_APP_FUNCTION() \
  126. CV__TRACE_DEFINE_LOCATION_FN(CV__TRACE_FUNCTION, CV_TRACE_NS::details::REGION_FLAG_APP_CODE); \
  127. const CV_TRACE_NS::details::Region __region_fn(CV__TRACE_LOCATION_VARNAME(fn));
  128. #define CV__TRACE_APP_FUNCTION_NAME(name) \
  129. CV__TRACE_DEFINE_LOCATION_FN(name, CV_TRACE_NS::details::REGION_FLAG_APP_CODE); \
  130. const CV_TRACE_NS::details::Region __region_fn(CV__TRACE_LOCATION_VARNAME(fn));
  131. #define CV__TRACE_OPENCV_FUNCTION_SKIP_NESTED() \
  132. CV__TRACE_DEFINE_LOCATION_FN(CV__TRACE_FUNCTION, CV_TRACE_NS::details::REGION_FLAG_SKIP_NESTED); \
  133. const CV_TRACE_NS::details::Region __region_fn(CV__TRACE_LOCATION_VARNAME(fn));
  134. #define CV__TRACE_OPENCV_FUNCTION_NAME_SKIP_NESTED(name) \
  135. CV__TRACE_DEFINE_LOCATION_FN(name, CV_TRACE_NS::details::REGION_FLAG_SKIP_NESTED); \
  136. const CV_TRACE_NS::details::Region __region_fn(CV__TRACE_LOCATION_VARNAME(fn));
  137. #define CV__TRACE_APP_FUNCTION_SKIP_NESTED() \
  138. CV__TRACE_DEFINE_LOCATION_FN(CV__TRACE_FUNCTION, CV_TRACE_NS::details::REGION_FLAG_SKIP_NESTED | CV_TRACE_NS::details::REGION_FLAG_APP_CODE); \
  139. const CV_TRACE_NS::details::Region __region_fn(CV__TRACE_LOCATION_VARNAME(fn));
  140. #define CV__TRACE_REGION_(name_as_static_string_literal, flags) \
  141. CV__TRACE_DEFINE_LOCATION_(region, name_as_static_string_literal, flags); \
  142. CV_TRACE_NS::details::Region CVAUX_CONCAT(__region_, __LINE__)(CV__TRACE_LOCATION_VARNAME(region));
  143. #define CV__TRACE_REGION(name_as_static_string_literal) CV__TRACE_REGION_(name_as_static_string_literal, 0)
  144. #define CV__TRACE_REGION_NEXT(name_as_static_string_literal) CV__TRACE_REGION_(name_as_static_string_literal, CV_TRACE_NS::details::REGION_FLAG_REGION_NEXT)
  145. #define CV__TRACE_ARG_VARNAME(arg_id) CVAUX_CONCAT(__cv_trace_arg_ ## arg_id, __LINE__)
  146. #define CV__TRACE_ARG_EXTRA_VARNAME(arg_id) CVAUX_CONCAT(__cv_trace_arg_extra_ ## arg_id, __LINE__)
  147. #define CV__TRACE_DEFINE_ARG_(arg_id, name, flags) \
  148. static CV_TRACE_NS::details::TraceArg::ExtraData* CV__TRACE_ARG_EXTRA_VARNAME(arg_id) = 0; \
  149. static const CV_TRACE_NS::details::TraceArg \
  150. CV__TRACE_ARG_VARNAME(arg_id) = { &(CV__TRACE_ARG_EXTRA_VARNAME(arg_id)), name, flags };
  151. #define CV__TRACE_ARG_VALUE(arg_id, arg_name, value) \
  152. CV__TRACE_DEFINE_ARG_(arg_id, arg_name, 0); \
  153. CV_TRACE_NS::details::traceArg((CV__TRACE_ARG_VARNAME(arg_id)), value);
  154. #define CV__TRACE_ARG(arg_id) CV_TRACE_ARG_VALUE(arg_id, #arg_id, (arg_id))
  155. } // namespace
  156. #ifndef OPENCV_DISABLE_TRACE
  157. #undef CV_TRACE_FUNCTION
  158. #undef CV_TRACE_FUNCTION_SKIP_NESTED
  159. #if __OPENCV_TRACE
  160. #define CV_TRACE_FUNCTION CV__TRACE_OPENCV_FUNCTION
  161. #define CV_TRACE_FUNCTION_SKIP_NESTED CV__TRACE_OPENCV_FUNCTION_SKIP_NESTED
  162. #else
  163. #define CV_TRACE_FUNCTION CV__TRACE_APP_FUNCTION
  164. #define CV_TRACE_FUNCTION_SKIP_NESTED CV__TRACE_APP_FUNCTION_SKIP_NESTED
  165. #endif
  166. #undef CV_TRACE_REGION
  167. #define CV_TRACE_REGION CV__TRACE_REGION
  168. #undef CV_TRACE_REGION_NEXT
  169. #define CV_TRACE_REGION_NEXT CV__TRACE_REGION_NEXT
  170. #undef CV_TRACE_ARG_VALUE
  171. #define CV_TRACE_ARG_VALUE(arg_id, arg_name, value) \
  172. if (__region_fn.isActive()) \
  173. { \
  174. CV__TRACE_ARG_VALUE(arg_id, arg_name, value); \
  175. }
  176. #undef CV_TRACE_ARG
  177. #define CV_TRACE_ARG CV__TRACE_ARG
  178. #endif // OPENCV_DISABLE_TRACE
  179. #ifdef OPENCV_TRACE_VERBOSE
  180. #define CV_TRACE_FUNCTION_VERBOSE CV_TRACE_FUNCTION
  181. #define CV_TRACE_REGION_VERBOSE CV_TRACE_REGION
  182. #define CV_TRACE_REGION_NEXT_VERBOSE CV_TRACE_REGION_NEXT
  183. #define CV_TRACE_ARG_VALUE_VERBOSE CV_TRACE_ARG_VALUE
  184. #define CV_TRACE_ARG_VERBOSE CV_TRACE_ARG
  185. #else
  186. #define CV_TRACE_FUNCTION_VERBOSE(...)
  187. #define CV_TRACE_REGION_VERBOSE(...)
  188. #define CV_TRACE_REGION_NEXT_VERBOSE(...)
  189. #define CV_TRACE_ARG_VALUE_VERBOSE(...)
  190. #define CV_TRACE_ARG_VERBOSE(...)
  191. #endif
  192. //! @endcond
  193. //! @}
  194. }}} // namespace
  195. #endif // OPENCV_TRACE_HPP