1 // Copyright 2020 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 //============================================================================== 15 // 16 17 #pragma once 18 19 #include <stdbool.h> 20 #include <stddef.h> 21 #include <stdint.h> 22 23 #include "pw_preprocessor/arguments.h" 24 #include "pw_preprocessor/util.h" 25 26 // Because __FUNCTION__ is not a string literal to the preprocessor it can't be 27 // tokenized. So this backend redefines the implementation to instead use the 28 // file name and line number. 29 // TODO(rgoliver): A build step could be added which checks the token dictionary 30 // for these and uses add2line to replace the database with the function names. 31 #define PW_TRACE_FUNCTION_LABEL_FILE_LINE(file, line) \ 32 "[" PW_STRINGIFY(file) ":" PW_STRINGIFY(line) "]" 33 #define PW_TRACE_FUNCTION_LABEL \ 34 PW_TRACE_FUNCTION_LABEL_FILE_LINE(__FILE__, __LINE__) 35 36 // Enable these trace types 37 #define PW_TRACE_TYPE_INSTANT PW_TRACE_EVENT_TYPE_INSTANT 38 #define PW_TRACE_TYPE_INSTANT_GROUP PW_TRACE_EVENT_TYPE_INSTANT_GROUP 39 40 #define PW_TRACE_TYPE_DURATION_START PW_TRACE_EVENT_TYPE_DURATION_START 41 #define PW_TRACE_TYPE_DURATION_END PW_TRACE_EVENT_TYPE_DURATION_END 42 43 #define PW_TRACE_TYPE_DURATION_GROUP_START \ 44 PW_TRACE_EVENT_TYPE_DURATION_GROUP_START 45 #define PW_TRACE_TYPE_DURATION_GROUP_END PW_TRACE_EVENT_TYPE_DURATION_GROUP_END 46 47 #define PW_TRACE_TYPE_ASYNC_START PW_TRACE_EVENT_TYPE_ASYNC_START 48 #define PW_TRACE_TYPE_ASYNC_INSTANT PW_TRACE_EVENT_TYPE_ASYNC_STEP 49 #define PW_TRACE_TYPE_ASYNC_END PW_TRACE_EVENT_TYPE_ASYNC_END 50 51 PW_EXTERN_C_START 52 53 typedef enum { 54 PW_TRACE_EVENT_TYPE_INVALID = 0, 55 PW_TRACE_EVENT_TYPE_INSTANT = 1, 56 PW_TRACE_EVENT_TYPE_INSTANT_GROUP = 2, 57 PW_TRACE_EVENT_TYPE_ASYNC_START = 3, 58 PW_TRACE_EVENT_TYPE_ASYNC_STEP = 4, 59 PW_TRACE_EVENT_TYPE_ASYNC_END = 5, 60 PW_TRACE_EVENT_TYPE_DURATION_START = 6, 61 PW_TRACE_EVENT_TYPE_DURATION_END = 7, 62 PW_TRACE_EVENT_TYPE_DURATION_GROUP_START = 8, 63 PW_TRACE_EVENT_TYPE_DURATION_GROUP_END = 9, 64 } pw_trace_EventType; 65 66 typedef struct { 67 uint32_t trace_token; 68 pw_trace_EventType event_type; 69 const char* module; 70 uint8_t flags; 71 uint32_t trace_id; 72 size_t data_size; 73 const void* data_buffer; 74 } pw_trace_tokenized_TraceEvent; 75 76 // This should not be called directly, instead use the PW_TRACE_* macros. 77 void pw_trace_TraceEvent(uint32_t trace_token, 78 pw_trace_EventType event_type, 79 const char* module, 80 uint32_t trace_id, 81 uint8_t flags, 82 const void* data_buffer, 83 size_t data_size); 84 85 // This should not be called directly, insted: PW_TRACE_SET_ENABLED 86 void pw_trace_Enable(bool enabled); 87 88 // Returns true if tracing is currently enabled. 89 bool pw_trace_IsEnabled(void); 90 91 PW_EXTERN_C_END 92 93 // These are what the facade actually calls. 94 #define PW_TRACE(event_type, flags, label, group, trace_id) \ 95 do { \ 96 static const uint32_t kLabelToken = \ 97 PW_TRACE_REF(event_type, PW_TRACE_MODULE_NAME, label, flags, group); \ 98 pw_trace_TraceEvent(kLabelToken, \ 99 event_type, \ 100 PW_TRACE_MODULE_NAME, \ 101 trace_id, \ 102 flags, \ 103 NULL, \ 104 0); \ 105 } while (0) 106 107 #define PW_TRACE_DATA( \ 108 event_type, flags, label, group, trace_id, type, data, size) \ 109 do { \ 110 static const uint32_t kLabelToken = PW_TRACE_REF_DATA( \ 111 event_type, PW_TRACE_MODULE_NAME, label, flags, group, type); \ 112 pw_trace_TraceEvent(kLabelToken, \ 113 event_type, \ 114 PW_TRACE_MODULE_NAME, \ 115 trace_id, \ 116 flags, \ 117 data, \ 118 size); \ 119 } while (0) 120