1 /* 2 * Copyright (c) 2018 Intel Corporation 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 #ifndef ZEPHYR_INCLUDE_TRACING_TRACING_MACROS_H_ 7 #define ZEPHYR_INCLUDE_TRACING_TRACING_MACROS_H_ 8 9 #include <zephyr/sys/util_macro.h> 10 11 #if !defined(CONFIG_TRACING) && !defined(__DOXYGEN__) 12 13 #define SYS_PORT_TRACING_FUNC(type, func, ...) do { } while (false) 14 #define SYS_PORT_TRACING_FUNC_ENTER(type, func, ...) do { } while (false) 15 #define SYS_PORT_TRACING_FUNC_BLOCKING(type, func, ...) do { } while (false) 16 #define SYS_PORT_TRACING_FUNC_EXIT(type, func, ...) do { } while (false) 17 #define SYS_PORT_TRACING_OBJ_INIT(obj_type, obj, ...) do { } while (false) 18 #define SYS_PORT_TRACING_OBJ_FUNC(obj_type, func, obj, ...) do { } while (false) 19 #define SYS_PORT_TRACING_OBJ_FUNC_ENTER(obj_type, func, obj, ...) do { } while (false) 20 #define SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(obj_type, func, obj, ...) do { } while (false) 21 #define SYS_PORT_TRACING_OBJ_FUNC_EXIT(obj_type, func, obj, ...) do { } while (false) 22 23 #define SYS_PORT_TRACING_TRACKING_FIELD(type) 24 25 #else 26 27 /** 28 * @brief Tracing utility macros 29 * @defgroup subsys_tracing_macros Tracing utility macros 30 * @ingroup subsys_tracing 31 * @{ 32 */ 33 34 /** @cond INTERNAL_HIDDEN */ 35 36 /* 37 * Helper macros used by the extended tracing system 38 */ 39 40 #define _SYS_PORT_TRACING_TYPE_MASK(type) \ 41 sys_port_trace_type_mask_ ## type 42 #define _SYS_PORT_TRACING_FUNC(name, func) \ 43 sys_port_trace_ ## name ## _ ## func 44 #define _SYS_PORT_TRACING_FUNC_ENTER(name, func) \ 45 sys_port_trace_ ## name ## _ ## func ## _enter 46 #define _SYS_PORT_TRACING_FUNC_BLOCKING(name, func) \ 47 sys_port_trace_ ## name ## _ ## func ## _blocking 48 #define _SYS_PORT_TRACING_FUNC_EXIT(name, func) \ 49 sys_port_trace_ ## name ## _ ## func ## _exit 50 #define _SYS_PORT_TRACING_OBJ_INIT(name) \ 51 sys_port_trace_ ## name ## _init 52 #define _SYS_PORT_TRACING_OBJ_FUNC(name, func) \ 53 sys_port_trace_ ## name ## _ ## func 54 #define _SYS_PORT_TRACING_OBJ_FUNC_ENTER(name, func) \ 55 sys_port_trace_ ## name ## _ ## func ## _enter 56 #define _SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(name, func) \ 57 sys_port_trace_ ## name ## _ ## func ## _blocking 58 #define _SYS_PORT_TRACING_OBJ_FUNC_EXIT(name, func) \ 59 sys_port_trace_ ## name ## _ ## func ## _exit 60 61 /* 62 * Helper macros for the object tracking system 63 */ 64 65 #define _SYS_PORT_TRACKING_OBJ_INIT(name) \ 66 sys_port_track_ ## name ## _init 67 #define _SYS_PORT_TRACKING_OBJ_FUNC(name, func) \ 68 sys_port_track_ ## name ## _ ## func 69 70 /* 71 * Object trace macros part of the system for checking if certain 72 * objects should be traced or not depending on the tracing configuration. 73 */ 74 #if defined(CONFIG_TRACING_THREAD) 75 #define sys_port_trace_type_mask_k_thread(trace_call) trace_call 76 #else 77 #define sys_port_trace_type_mask_k_thread(trace_call) 78 #define sys_port_trace_k_thread_is_disabled 1 79 #endif 80 81 #if defined(CONFIG_TRACING_WORK) 82 #define sys_port_trace_type_mask_k_work(trace_call) trace_call 83 #define sys_port_trace_type_mask_k_work_queue(trace_call) trace_call 84 #define sys_port_trace_type_mask_k_work_delayable(trace_call) trace_call 85 #define sys_port_trace_type_mask_k_work_poll(trace_call) trace_call 86 #else 87 #define sys_port_trace_type_mask_k_work(trace_call) 88 #define sys_port_trace_type_mask_k_work_queue(trace_call) 89 #define sys_port_trace_type_mask_k_work_delayable(trace_call) 90 #define sys_port_trace_type_mask_k_work_poll(trace_call) 91 #endif 92 93 #if defined(CONFIG_TRACING_SEMAPHORE) 94 #define sys_port_trace_type_mask_k_sem(trace_call) trace_call 95 #else 96 #define sys_port_trace_type_mask_k_sem(trace_call) 97 #endif 98 99 #if defined(CONFIG_TRACING_MUTEX) 100 #define sys_port_trace_type_mask_k_mutex(trace_call) trace_call 101 #else 102 #define sys_port_trace_type_mask_k_mutex(trace_call) 103 #endif 104 105 #if defined(CONFIG_TRACING_CONDVAR) 106 #define sys_port_trace_type_mask_k_condvar(trace_call) trace_call 107 #else 108 #define sys_port_trace_type_mask_k_condvar(trace_call) 109 #endif 110 111 #if defined(CONFIG_TRACING_QUEUE) 112 #define sys_port_trace_type_mask_k_queue(trace_call) trace_call 113 #else 114 #define sys_port_trace_type_mask_k_queue(trace_call) 115 #endif 116 117 #if defined(CONFIG_TRACING_FIFO) 118 #define sys_port_trace_type_mask_k_fifo(trace_call) trace_call 119 #else 120 #define sys_port_trace_type_mask_k_fifo(trace_call) 121 #endif 122 123 #if defined(CONFIG_TRACING_LIFO) 124 #define sys_port_trace_type_mask_k_lifo(trace_call) trace_call 125 #else 126 #define sys_port_trace_type_mask_k_lifo(trace_call) 127 #endif 128 129 #if defined(CONFIG_TRACING_STACK) 130 #define sys_port_trace_type_mask_k_stack(trace_call) trace_call 131 #else 132 #define sys_port_trace_type_mask_k_stack(trace_call) 133 #endif 134 135 #if defined(CONFIG_TRACING_MESSAGE_QUEUE) 136 #define sys_port_trace_type_mask_k_msgq(trace_call) trace_call 137 #else 138 #define sys_port_trace_type_mask_k_msgq(trace_call) 139 #endif 140 141 #if defined(CONFIG_TRACING_MAILBOX) 142 #define sys_port_trace_type_mask_k_mbox(trace_call) trace_call 143 #else 144 #define sys_port_trace_type_mask_k_mbox(trace_call) 145 #endif 146 147 #if defined(CONFIG_TRACING_PIPE) 148 #define sys_port_trace_type_mask_k_pipe(trace_call) trace_call 149 #else 150 #define sys_port_trace_type_mask_k_pipe(trace_call) 151 #endif 152 153 #if defined(CONFIG_TRACING_HEAP) 154 #define sys_port_trace_type_mask_k_heap(trace_call) trace_call 155 #define sys_port_trace_type_mask_k_heap_sys(trace_call) trace_call 156 #else 157 #define sys_port_trace_type_mask_k_heap(trace_call) 158 #define sys_port_trace_type_mask_k_heap_sys(trace_call) 159 #endif 160 161 #if defined(CONFIG_TRACING_MEMORY_SLAB) 162 #define sys_port_trace_type_mask_k_mem_slab(trace_call) trace_call 163 #else 164 #define sys_port_trace_type_mask_k_mem_slab(trace_call) 165 #endif 166 167 #if defined(CONFIG_TRACING_TIMER) 168 #define sys_port_trace_type_mask_k_timer(trace_call) trace_call 169 #else 170 #define sys_port_trace_type_mask_k_timer(trace_call) 171 #endif 172 173 #if defined(CONFIG_TRACING_EVENT) 174 #define sys_port_trace_type_mask_k_event(trace_call) trace_call 175 #else 176 #define sys_port_trace_type_mask_k_event(trace_call) 177 #endif 178 179 #ifndef CONFIG_TRACING_POLLING 180 #define sys_port_trace_k_poll_api_is_disabled 1 181 #define sys_port_trace_k_work_poll_is_disabled 1 182 #endif 183 184 #ifndef CONFIG_TRACING_PM 185 #define sys_port_trace_pm_is_disabled 1 186 #endif 187 188 #if defined(CONFIG_TRACING_NET_SOCKETS) 189 #define sys_port_trace_type_mask_socket(trace_call) trace_call 190 #else 191 #define sys_port_trace_type_mask_socket(trace_call) 192 #endif 193 194 #if defined(CONFIG_TRACING_NET_CORE) 195 #define sys_port_trace_type_mask_net(trace_call) trace_call 196 #else 197 #define sys_port_trace_type_mask_net(trace_call) 198 #endif 199 200 /* 201 * We cannot positively enumerate all traced APIs, as applications may trace 202 * arbitrary custom APIs we know nothing about. Therefore we demand that tracing 203 * of an API must be actively disabled. 204 * 205 * This contrasts with object tracing/tracking as all traceable objects are well 206 * known, see the SYS_PORT_TRACING_TYPE_MASK approach below. 207 */ 208 #define _SYS_PORT_TRACE_IS_DISABLED(type) sys_port_trace_##type##_is_disabled 209 #define _SYS_PORT_TRACE_WRAP(func, ...) do { func(__VA_ARGS__); } while (false) 210 #define _SYS_PORT_TRACE_IF_NOT_DISABLED(type, func, ...) \ 211 COND_CODE_1(_SYS_PORT_TRACE_IS_DISABLED(type), (), \ 212 (_SYS_PORT_TRACE_WRAP(func, __VA_ARGS__))) 213 214 /** @endcond */ 215 216 /** 217 * @brief Checks if an object type should be traced or not. 218 * 219 * @param type Tracing event type/object 220 * @param trace_call Tracing call 221 */ 222 #define SYS_PORT_TRACING_TYPE_MASK(type, trace_call) \ 223 _SYS_PORT_TRACING_TYPE_MASK(type)(trace_call) 224 225 /** 226 * @brief Tracing macro for function calls which are not directly 227 * associated with a specific type of object. 228 * 229 * @param type Type of tracing event or object type 230 * @param func Name of the function responsible for the call. This does not need to exactly 231 * match the name of the function but should rather match what the user called in case of 232 * system calls etc. That is, we can often omit the z_vrfy/z_impl part of the name. 233 * @param ... Additional parameters relevant to the tracing call 234 */ 235 #define SYS_PORT_TRACING_FUNC(type, func, ...) \ 236 _SYS_PORT_TRACE_IF_NOT_DISABLED(type, _SYS_PORT_TRACING_FUNC(type, func), __VA_ARGS__) 237 238 /** 239 * @brief Tracing macro for the entry into a function that might or might not return 240 * a value. 241 * 242 * @param type Type of tracing event or object type 243 * @param func Name of the function responsible for the call. This does not need to exactly 244 * match the name of the function but should rather match what the user called in case of 245 * system calls etc. That is, we can often omit the z_vrfy/z_impl part of the name. 246 * @param ... Additional parameters relevant to the tracing call 247 */ 248 #define SYS_PORT_TRACING_FUNC_ENTER(type, func, ...) \ 249 _SYS_PORT_TRACE_IF_NOT_DISABLED(type, _SYS_PORT_TRACING_FUNC_ENTER(type, func), __VA_ARGS__) 250 251 /** 252 * @brief Tracing macro for when a function blocks during its execution. 253 * 254 * @param type Type of tracing event or object type 255 * @param func Name of the function responsible for the call. This does not need to exactly 256 * match the name of the function but should rather match what the user called in case of 257 * system calls etc. That is, we can often omit the z_vrfy/z_impl part of the name. 258 * @param ... Additional parameters relevant to the tracing call 259 */ 260 #define SYS_PORT_TRACING_FUNC_BLOCKING(type, func, ...) \ 261 _SYS_PORT_TRACE_IF_NOT_DISABLED(type, _SYS_PORT_TRACING_FUNC_BLOCKING(type, func), \ 262 __VA_ARGS__) 263 264 /** 265 * @brief Tracing macro for when a function ends its execution. Potential return values 266 * can be given as additional arguments. 267 * 268 * @param type Type of tracing event or object type 269 * @param func Name of the function responsible for the call. This does not need to exactly 270 * match the name of the function but should rather match what the user called in case of 271 * system calls etc. That is, we can often omit the z_vrfy/z_impl part of the name. 272 * @param ... Additional parameters relevant to the tracing call 273 */ 274 #define SYS_PORT_TRACING_FUNC_EXIT(type, func, ...) \ 275 _SYS_PORT_TRACE_IF_NOT_DISABLED(type, _SYS_PORT_TRACING_FUNC_EXIT(type, func), __VA_ARGS__) 276 277 /** 278 * @brief Tracing macro for the initialization of an object. 279 * 280 * @param obj_type The type of object associated with the call (k_thread, k_sem, k_mutex etc.) 281 * @param obj Object 282 */ 283 #define SYS_PORT_TRACING_OBJ_INIT(obj_type, obj, ...) \ 284 do { \ 285 SYS_PORT_TRACING_TYPE_MASK(obj_type, \ 286 _SYS_PORT_TRACING_OBJ_INIT(obj_type)(obj, ##__VA_ARGS__)); \ 287 SYS_PORT_TRACING_TYPE_MASK(obj_type, \ 288 _SYS_PORT_TRACKING_OBJ_INIT(obj_type)(obj, ##__VA_ARGS__)); \ 289 } while (false) 290 291 /** 292 * @brief Tracing macro for simple object function calls often without returns or branching. 293 * 294 * @param obj_type The type of object associated with the call (k_thread, k_sem, k_mutex etc.) 295 * @param func Name of the function responsible for the call. This does not need to exactly 296 * match the name of the function but should rather match what the user called in case of 297 * system calls etc. That is, we can often omit the z_vrfy/z_impl part of the name. 298 * @param obj Object 299 * @param ... Additional parameters relevant to the tracing call 300 */ 301 #define SYS_PORT_TRACING_OBJ_FUNC(obj_type, func, obj, ...) \ 302 do { \ 303 SYS_PORT_TRACING_TYPE_MASK(obj_type, \ 304 _SYS_PORT_TRACING_OBJ_FUNC(obj_type, func)(obj, ##__VA_ARGS__)); \ 305 SYS_PORT_TRACING_TYPE_MASK(obj_type, \ 306 _SYS_PORT_TRACKING_OBJ_FUNC(obj_type, func)(obj, ##__VA_ARGS__)); \ 307 } while (false) 308 309 /** 310 * @brief Tracing macro for the entry into a function that might or might not return 311 * a value. 312 * 313 * @param obj_type The type of object associated with the call (k_thread, k_sem, k_mutex etc.) 314 * @param func Name of the function responsible for the call. This does not need to exactly 315 * match the name of the function but should rather match what the user called in case of 316 * system calls etc. That is, we can often omit the z_vrfy/z_impl part of the name. 317 * @param obj Object 318 * @param ... Additional parameters relevant to the tracing call 319 */ 320 #define SYS_PORT_TRACING_OBJ_FUNC_ENTER(obj_type, func, obj, ...) \ 321 do { \ 322 SYS_PORT_TRACING_TYPE_MASK(obj_type, \ 323 _SYS_PORT_TRACING_OBJ_FUNC_ENTER(obj_type, func)(obj, ##__VA_ARGS__)); \ 324 } while (false) 325 326 /** 327 * @brief Tracing macro for when a function blocks during its execution. 328 * 329 * @param obj_type The type of object associated with the call (k_thread, k_sem, k_mutex etc.) 330 * @param func Name of the function responsible for the call. This does not need to exactly 331 * match the name of the function but should rather match what the user called in case of 332 * system calls etc. That is, we can often omit the z_vrfy/z_impl part of the name. 333 * @param obj Object 334 * @param timeout Timeout 335 * @param ... Additional parameters relevant to the tracing call 336 */ 337 #define SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(obj_type, func, obj, timeout, ...) \ 338 do { \ 339 SYS_PORT_TRACING_TYPE_MASK(obj_type, \ 340 _SYS_PORT_TRACING_OBJ_FUNC_BLOCKING(obj_type, func) \ 341 (obj, timeout, ##__VA_ARGS__)); \ 342 } while (false) 343 344 /** 345 * @brief Tracing macro for when a function ends its execution. Potential return values 346 * can be given as additional arguments. 347 * 348 * @param obj_type The type of object associated with the call (k_thread, k_sem, k_mutex etc.) 349 * @param func Name of the function responsible for the call. This does not need to exactly 350 * match the name of the function but should rather match what the user called in case of 351 * system calls etc. That is, we can often omit the z_vrfy/z_impl part of the name. 352 * @param obj Object 353 * @param ... Additional parameters relevant to the tracing call 354 */ 355 #define SYS_PORT_TRACING_OBJ_FUNC_EXIT(obj_type, func, obj, ...) \ 356 do { \ 357 SYS_PORT_TRACING_TYPE_MASK(obj_type, \ 358 _SYS_PORT_TRACING_OBJ_FUNC_EXIT(obj_type, func)(obj, ##__VA_ARGS__)); \ 359 } while (false) 360 361 /** 362 * @brief Field added to kernel objects so they are tracked. 363 * 364 * @param type Type of object being tracked (k_thread, k_sem, etc.) 365 */ 366 #define SYS_PORT_TRACING_TRACKING_FIELD(type) \ 367 SYS_PORT_TRACING_TYPE_MASK(type, struct type *_obj_track_next;) 368 369 /** @} */ /* end of subsys_tracing_macros */ 370 371 #endif /* CONFIG_TRACING */ 372 373 #endif /* ZEPHYR_INCLUDE_TRACING_TRACING_MACROS_H_ */ 374