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 <stdint.h> 21 22 #include "pw_preprocessor/arguments.h" 23 24 // Because __FUNCTION__ is not a string literal to the preprocessor it can't be 25 // tokenized. So this backend redefines the implementation to instead use the 26 // file name and line number. 27 // TODO(rgoliver): A build step could be added which checks the token dictionary 28 // for these and uses add2line to replace the database with the function names. 29 #define PW_TRACE_FUNCTION_LABEL_FILE_LINE(file, line) \ 30 "[" PW_STRINGIFY(file) ":" PW_STRINGIFY(line) "]" 31 #define PW_TRACE_FUNCTION_LABEL \ 32 PW_TRACE_FUNCTION_LABEL_FILE_LINE(__FILE__, __LINE__) 33 34 // Enable these trace types 35 #define PW_TRACE_TYPE_INSTANT PW_TRACE_EVENT_TYPE_INSTANT 36 #define PW_TRACE_TYPE_INSTANT_GROUP PW_TRACE_EVENT_TYPE_INSTANT_GROUP 37 38 #define PW_TRACE_TYPE_DURATION_START PW_TRACE_EVENT_TYPE_DURATION_START 39 #define PW_TRACE_TYPE_DURATION_END PW_TRACE_EVENT_TYPE_DURATION_END 40 41 #define PW_TRACE_TYPE_DURATION_GROUP_START \ 42 PW_TRACE_EVENT_TYPE_DURATION_GROUP_START 43 #define PW_TRACE_TYPE_DURATION_GROUP_END PW_TRACE_EVENT_TYPE_DURATION_GROUP_END 44 45 #define PW_TRACE_TYPE_ASYNC_START PW_TRACE_EVENT_TYPE_ASYNC_START 46 #define PW_TRACE_TYPE_ASYNC_INSTANT PW_TRACE_EVENT_TYPE_ASYNC_STEP 47 #define PW_TRACE_TYPE_ASYNC_END PW_TRACE_EVENT_TYPE_ASYNC_END 48 49 PW_EXTERN_C_START 50 typedef enum { 51 PW_TRACE_EVENT_TYPE_INVALID = 0, 52 PW_TRACE_EVENT_TYPE_INSTANT = 1, 53 PW_TRACE_EVENT_TYPE_INSTANT_GROUP = 2, 54 PW_TRACE_EVENT_TYPE_ASYNC_START = 3, 55 PW_TRACE_EVENT_TYPE_ASYNC_STEP = 4, 56 PW_TRACE_EVENT_TYPE_ASYNC_END = 5, 57 PW_TRACE_EVENT_TYPE_DURATION_START = 6, 58 PW_TRACE_EVENT_TYPE_DURATION_END = 7, 59 PW_TRACE_EVENT_TYPE_DURATION_GROUP_START = 8, 60 PW_TRACE_EVENT_TYPE_DURATION_GROUP_END = 9, 61 } pw_trace_EventType; 62 63 // This should not be called directly, instead use the PW_TRACE_* macros. 64 void pw_trace_TraceEvent(uint32_t trace_token, 65 pw_trace_EventType event_type, 66 const char* module, 67 uint32_t trace_id, 68 uint8_t flags, 69 const void* data_buffer, 70 size_t data_size); 71 72 // This should not be called directly, insted: PW_TRACE_SET_ENABLED 73 void pw_trace_Enable(bool enabled); 74 75 // Returns true if tracing is currently enabled. 76 bool pw_trace_IsEnabled(void); 77 78 PW_EXTERN_C_END 79 80 // These are what the facade actually calls. 81 #define PW_TRACE(event_type, flags, label, group, trace_id) \ 82 do { \ 83 static const uint32_t kLabelToken = \ 84 PW_TRACE_REF(event_type, PW_TRACE_MODULE_NAME, label, flags, group); \ 85 pw_trace_TraceEvent(kLabelToken, \ 86 event_type, \ 87 PW_TRACE_MODULE_NAME, \ 88 trace_id, \ 89 flags, \ 90 NULL, \ 91 0); \ 92 } while (0) 93 94 #define PW_TRACE_DATA( \ 95 event_type, flags, label, group, trace_id, type, data, size) \ 96 do { \ 97 static const uint32_t kLabelToken = PW_TRACE_REF_DATA( \ 98 event_type, PW_TRACE_MODULE_NAME, label, flags, group, type); \ 99 pw_trace_TraceEvent(kLabelToken, \ 100 event_type, \ 101 PW_TRACE_MODULE_NAME, \ 102 trace_id, \ 103 flags, \ 104 data, \ 105 size); \ 106 } while (0) 107