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 #pragma once 16 17 #include <cstddef> 18 #include <cstring> 19 20 // Enable traces 21 #define PW_TRACE_TYPE_INSTANT trace_fake_backend::Instantaneous 22 #define PW_TRACE_TYPE_INSTANT_GROUP trace_fake_backend::InstantaneousGroup 23 #define PW_TRACE_TYPE_DURATION_START trace_fake_backend::DurationStart 24 #define PW_TRACE_TYPE_DURATION_END trace_fake_backend::DurationEnd 25 26 #define PW_TRACE_TYPE_DURATION_GROUP_START \ 27 trace_fake_backend::DurationGroupStart 28 #define PW_TRACE_TYPE_DURATION_GROUP_END trace_fake_backend::DurationGroupEnd 29 30 #define PW_TRACE_TYPE_ASYNC_START trace_fake_backend::AsyncStart 31 #define PW_TRACE_TYPE_ASYNC_INSTANT trace_fake_backend::AsyncStep 32 #define PW_TRACE_TYPE_ASYNC_END trace_fake_backend::AsyncEnd 33 34 namespace trace_fake_backend { 35 36 typedef enum { 37 Invalid, 38 Instantaneous, 39 InstantaneousGroup, 40 AsyncStart, 41 AsyncStep, 42 AsyncEnd, 43 DurationStart, 44 DurationEnd, 45 DurationGroupStart, 46 DurationGroupEnd, 47 } pw_trace_EventType; 48 49 // Define a helper class for holding events and checking equality. 50 class Event { 51 public: Event()52 Event() 53 : event_type_(Invalid), 54 flags_(0), 55 label_(nullptr), 56 group_(nullptr), 57 trace_id_(0), 58 has_data_(false), 59 data_format_string_(nullptr), 60 data_(nullptr), 61 data_size_(0) {} Event(pw_trace_EventType event_type,uint8_t flags,const char * label,const char * group,uint32_t trace_id)62 Event(pw_trace_EventType event_type, 63 uint8_t flags, 64 const char* label, 65 const char* group, 66 uint32_t trace_id) 67 : event_type_(event_type), 68 flags_(flags), 69 label_(label), 70 group_(group), 71 trace_id_(trace_id), 72 has_data_(false), 73 data_format_string_(nullptr), 74 data_(nullptr), 75 data_size_(0) {} Event(pw_trace_EventType event_type,uint8_t flags,const char * label,const char * group,uint32_t trace_id,const char * data_type,const char * data,size_t size)76 Event(pw_trace_EventType event_type, 77 uint8_t flags, 78 const char* label, 79 const char* group, 80 uint32_t trace_id, 81 const char* data_type, 82 const char* data, 83 size_t size) 84 : event_type_(event_type), 85 flags_(flags), 86 label_(label), 87 group_(group), 88 trace_id_(trace_id), 89 has_data_(true), 90 data_format_string_(data_type), 91 data_(data), 92 data_size_(size) {} 93 bool operator==(const Event& rhs) const { 94 return event_type_ == rhs.event_type_ && // 95 flags_ == rhs.flags_ && // 96 label_ == rhs.label_ && // 97 group_ == rhs.group_ && trace_id_ == rhs.trace_id_ && // 98 has_data_ == rhs.has_data_ && // 99 data_format_string_ == rhs.data_format_string_ && // 100 data_size_ == rhs.data_size_ && // 101 (data_size_ == 0 || // 102 (std::memcmp(data_, rhs.data_, data_size_) == 0)); 103 } 104 IsEqualIgnoreLabel(const Event & rhs)105 bool IsEqualIgnoreLabel(const Event& rhs) const { 106 return event_type_ == rhs.event_type_ && // 107 flags_ == rhs.flags_ && // 108 group_ == rhs.group_ && trace_id_ == rhs.trace_id_ && // 109 has_data_ == rhs.has_data_ && // 110 data_format_string_ == rhs.data_format_string_ && // 111 data_size_ == rhs.data_size_ && // 112 (data_size_ == 0 || // 113 (std::memcmp(data_, rhs.data_, data_size_) == 0)); 114 } 115 116 private: 117 pw_trace_EventType event_type_; 118 uint8_t flags_; 119 const char* label_; 120 const char* group_; 121 uint32_t trace_id_; 122 123 bool has_data_; 124 const char* data_format_string_; 125 const char* data_; 126 size_t data_size_; 127 }; 128 129 class LastEvent { 130 public: Instance()131 static LastEvent& Instance() { return instance_; } Get()132 Event& Get() { return last_event_; } Set(const Event & event)133 void Set(const Event& event) { last_event_ = event; } 134 135 private: 136 Event last_event_{}; 137 static LastEvent instance_; 138 }; 139 140 #define PW_TRACE(event_type, flags, label, group, trace_id) \ 141 LastEvent::Instance().Set(Event(event_type, flags, label, group, trace_id)); 142 143 #define PW_TRACE_DATA( \ 144 event_type, flags, label, group, trace_id, type, data, size) \ 145 LastEvent::Instance().Set( \ 146 Event(event_type, flags, label, group, trace_id, type, data, size)); 147 148 } // namespace trace_fake_backend 149