trace.hpp 9.4 KB

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