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