trace.hpp 9.0 KB

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