1b1994897Sopenharmony_ci/* 2b1994897Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3b1994897Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4b1994897Sopenharmony_ci * you may not use this file except in compliance with the License. 5b1994897Sopenharmony_ci * You may obtain a copy of the License at 6b1994897Sopenharmony_ci * 7b1994897Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8b1994897Sopenharmony_ci * 9b1994897Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10b1994897Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11b1994897Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12b1994897Sopenharmony_ci * See the License for the specific language governing permissions and 13b1994897Sopenharmony_ci * limitations under the License. 14b1994897Sopenharmony_ci */ 15b1994897Sopenharmony_ci 16b1994897Sopenharmony_ci// Autogenerated file -- DO NOT EDIT! 17b1994897Sopenharmony_ci 18b1994897Sopenharmony_ci#ifndef PANDA_EVENTS_GEN_H 19b1994897Sopenharmony_ci#define PANDA_EVENTS_GEN_H 20b1994897Sopenharmony_ci 21b1994897Sopenharmony_ci#include "macros.h" 22b1994897Sopenharmony_ci#include "os/mutex.h" 23b1994897Sopenharmony_ci#include "utils/list.h" 24b1994897Sopenharmony_ci#include "runtime/include/mem/panda_string.h" 25b1994897Sopenharmony_ci#include <fstream> 26b1994897Sopenharmony_ci#include <variant> 27b1994897Sopenharmony_ci#include <vector> 28b1994897Sopenharmony_ci 29b1994897Sopenharmony_cinamespace panda { 30b1994897Sopenharmony_ci 31b1994897Sopenharmony_cinamespace events { 32b1994897Sopenharmony_ci 33b1994897Sopenharmony_ci% EventsData.events.each do |event| 34b1994897Sopenharmony_ci% event.fields.select(&:is_enum?).each do |field| 35b1994897Sopenharmony_cienum class <%= field.type %> { 36b1994897Sopenharmony_ci <%= field.enums.map(&:upcase).join(', ') %> 37b1994897Sopenharmony_ci}; 38b1994897Sopenharmony_ci% end 39b1994897Sopenharmony_ci% end 40b1994897Sopenharmony_ci 41b1994897Sopenharmony_ciclass EventsBase { 42b1994897Sopenharmony_cipublic: 43b1994897Sopenharmony_ci EventsBase() = default; 44b1994897Sopenharmony_ci virtual ~EventsBase() = default; 45b1994897Sopenharmony_ci NO_COPY_SEMANTIC(EventsBase); 46b1994897Sopenharmony_ci NO_MOVE_SEMANTIC(EventsBase); 47b1994897Sopenharmony_ci 48b1994897Sopenharmony_ci% EventsData.events.each do |event| 49b1994897Sopenharmony_ci virtual void <%= event.name.camelize %>(<%= event.fields.map {|f| f.arg_type}.join(', ') %>) {} // NOLINT 50b1994897Sopenharmony_ci% end 51b1994897Sopenharmony_ci 52b1994897Sopenharmony_ci auto& GetLock() { 53b1994897Sopenharmony_ci return lock_; 54b1994897Sopenharmony_ci } 55b1994897Sopenharmony_ciprivate: 56b1994897Sopenharmony_ci os::memory::Mutex lock_; 57b1994897Sopenharmony_ci}; 58b1994897Sopenharmony_ci 59b1994897Sopenharmony_ci% EventsData.events.each do |event| 60b1994897Sopenharmony_ci% event.fields.select(&:is_enum?).each do |field| 61b1994897Sopenharmony_ciinline std::ostream& operator<<(std::ostream& os, <%= field.type %> field) { 62b1994897Sopenharmony_ci switch (field) { 63b1994897Sopenharmony_ci% field.enums.each do |enum| 64b1994897Sopenharmony_ci case <%= field.type %>::<%= enum.upcase %>: os << "<%= enum.upcase %>"; break; 65b1994897Sopenharmony_ci% end 66b1994897Sopenharmony_ci } 67b1994897Sopenharmony_ci return os; 68b1994897Sopenharmony_ci} 69b1994897Sopenharmony_ci% end 70b1994897Sopenharmony_ci% end 71b1994897Sopenharmony_ci 72b1994897Sopenharmony_ciclass EventsMemory : public events::EventsBase { 73b1994897Sopenharmony_ci 74b1994897Sopenharmony_cipublic: 75b1994897Sopenharmony_ci% EventsData.events.each do |event| 76b1994897Sopenharmony_ci struct <%= event.name.camelize %>Event{ 77b1994897Sopenharmony_ci% event.fields.each do |field| 78b1994897Sopenharmony_ci <%= field.type %> <%= field.name %>; 79b1994897Sopenharmony_ci% end 80b1994897Sopenharmony_ci }; 81b1994897Sopenharmony_ci% end 82b1994897Sopenharmony_ci 83b1994897Sopenharmony_ci // NOLINTNEXTLINE(fuchsia-multiple-inheritance) 84b1994897Sopenharmony_ci struct EventRecord : public ListNode, public std::variant<<%= EventsData.events.map{|e| e.name.camelize + 'Event'}.join(', ') %>> { 85b1994897Sopenharmony_ci using VariantBase = std::variant<<%= EventsData.events.map{|e| e.name.camelize + 'Event'}.join(', ') %>>; 86b1994897Sopenharmony_ci% EventsData.events.each do |event| 87b1994897Sopenharmony_ci explicit EventRecord(<%= event.name.camelize %>Event v) : VariantBase(v) {} 88b1994897Sopenharmony_ci% end 89b1994897Sopenharmony_ci }; 90b1994897Sopenharmony_ci 91b1994897Sopenharmony_cipublic: 92b1994897Sopenharmony_ci EventsMemory() = default; 93b1994897Sopenharmony_ci ~EventsMemory() override { 94b1994897Sopenharmony_ci os::memory::LockHolder lock(GetLock()); 95b1994897Sopenharmony_ci for (auto it = event_list_.begin(); it != event_list_.end(); ) { 96b1994897Sopenharmony_ci delete &*(it++); 97b1994897Sopenharmony_ci } 98b1994897Sopenharmony_ci } 99b1994897Sopenharmony_ci NO_COPY_SEMANTIC(EventsMemory); 100b1994897Sopenharmony_ci NO_MOVE_SEMANTIC(EventsMemory); 101b1994897Sopenharmony_ci 102b1994897Sopenharmony_ci% EventsData.events.each do |event| 103b1994897Sopenharmony_ci void <%= event.name.camelize %>(<%= event.fields.map {|f| f.arg_type + ' ' + f.name }.join(', ') %>) override { 104b1994897Sopenharmony_ci os::memory::LockHolder lock(GetLock()); 105b1994897Sopenharmony_ci auto event = new EventRecord(<%= event.name.camelize %>Event{<%= event.fields.map(&:name).join(', ') %>}); 106b1994897Sopenharmony_ci last_ = event_list_.InsertAfter(last_, *event); 107b1994897Sopenharmony_ci } 108b1994897Sopenharmony_ci% end 109b1994897Sopenharmony_ci 110b1994897Sopenharmony_ci template<typename EventT, typename Func> 111b1994897Sopenharmony_ci void EnumerateEvents(Func func) { 112b1994897Sopenharmony_ci os::memory::LockHolder lock(GetLock()); 113b1994897Sopenharmony_ci for (const auto& event : event_list_) { 114b1994897Sopenharmony_ci if(auto p = std::get_if<EventT>(&event)) { 115b1994897Sopenharmony_ci func(static_cast<const EventT&>(*p)); 116b1994897Sopenharmony_ci } 117b1994897Sopenharmony_ci } 118b1994897Sopenharmony_ci } 119b1994897Sopenharmony_ci 120b1994897Sopenharmony_ci template<typename EventT, typename Comp> 121b1994897Sopenharmony_ci bool Find(Comp cmp) { 122b1994897Sopenharmony_ci bool found = false; 123b1994897Sopenharmony_ci EnumerateEvents<EventT>([&found, &cmp](const auto& event) { 124b1994897Sopenharmony_ci if (cmp(event)) { 125b1994897Sopenharmony_ci found = true; 126b1994897Sopenharmony_ci return false; 127b1994897Sopenharmony_ci } 128b1994897Sopenharmony_ci return true; 129b1994897Sopenharmony_ci }); 130b1994897Sopenharmony_ci return found; 131b1994897Sopenharmony_ci } 132b1994897Sopenharmony_ci 133b1994897Sopenharmony_ci template<typename EventT, typename F = bool> 134b1994897Sopenharmony_ci std::vector<const EventT*> Select([[maybe_unused]] F pred = false) { 135b1994897Sopenharmony_ci std::vector<const EventT*> res; 136b1994897Sopenharmony_ci if constexpr (std::is_same_v<F, bool>) { 137b1994897Sopenharmony_ci EnumerateEvents<EventT>([&res](const auto& event) { res.push_back(&event); }); 138b1994897Sopenharmony_ci } else { 139b1994897Sopenharmony_ci EnumerateEvents<EventT>([&pred, &res](const auto& event) { 140b1994897Sopenharmony_ci if (pred(&event)) { 141b1994897Sopenharmony_ci res.push_back(&event); 142b1994897Sopenharmony_ci } 143b1994897Sopenharmony_ci }); 144b1994897Sopenharmony_ci } 145b1994897Sopenharmony_ci return res; 146b1994897Sopenharmony_ci } 147b1994897Sopenharmony_ci 148b1994897Sopenharmony_ciprivate: 149b1994897Sopenharmony_ci List<EventRecord> event_list_ GUARDED_BY(GetLock()); 150b1994897Sopenharmony_ci List<EventRecord>::Iterator last_{event_list_.before_begin()}; 151b1994897Sopenharmony_ci}; 152b1994897Sopenharmony_ci 153b1994897Sopenharmony_ciclass EventsCsv : public events::EventsBase { 154b1994897Sopenharmony_cipublic: 155b1994897Sopenharmony_ci EventsCsv() { 156b1994897Sopenharmony_ci file_.open("events.csv"); 157b1994897Sopenharmony_ci } 158b1994897Sopenharmony_ci explicit EventsCsv(std::string_view path) { 159b1994897Sopenharmony_ci file_.open(path.data()); 160b1994897Sopenharmony_ci } 161b1994897Sopenharmony_ci ~EventsCsv() override { 162b1994897Sopenharmony_ci os::memory::LockHolder lock(GetLock()); 163b1994897Sopenharmony_ci file_.close(); 164b1994897Sopenharmony_ci } 165b1994897Sopenharmony_ci NO_COPY_SEMANTIC(EventsCsv); 166b1994897Sopenharmony_ci NO_MOVE_SEMANTIC(EventsCsv); 167b1994897Sopenharmony_ci 168b1994897Sopenharmony_ci% EventsData.events.each do |event| 169b1994897Sopenharmony_ci void <%= event.name.camelize %>(<%= event.fields.map {|f| f.arg_type + ' ' + f.name }.join(', ') %>) override { 170b1994897Sopenharmony_ci os::memory::LockHolder lock(GetLock()); 171b1994897Sopenharmony_ci file_ << "<%= event.name.camelize %>," << <%= event.fields.map(&:name).join(" << ',' << ") %> << std::endl; 172b1994897Sopenharmony_ci } 173b1994897Sopenharmony_ci% end 174b1994897Sopenharmony_ci 175b1994897Sopenharmony_ciprivate: 176b1994897Sopenharmony_ci std::ofstream file_ GUARDED_BY(GetLock()); 177b1994897Sopenharmony_ci}; 178b1994897Sopenharmony_ci 179b1994897Sopenharmony_ciclass EventsLog : public events::EventsBase { 180b1994897Sopenharmony_cipublic: 181b1994897Sopenharmony_ci EventsLog() { 182b1994897Sopenharmony_ci Logger::EnableComponent(Logger::EVENTS); 183b1994897Sopenharmony_ci } 184b1994897Sopenharmony_ci ~EventsLog() override { 185b1994897Sopenharmony_ci Logger::DisableComponent(Logger::EVENTS); 186b1994897Sopenharmony_ci } 187b1994897Sopenharmony_ci NO_COPY_SEMANTIC(EventsLog); 188b1994897Sopenharmony_ci NO_MOVE_SEMANTIC(EventsLog); 189b1994897Sopenharmony_ci 190b1994897Sopenharmony_ci% EventsData.events.each do |event| 191b1994897Sopenharmony_ci void <%= event.name.camelize %>(<%= event.fields.map {|f| f.arg_type + ' ' + f.name }.join(', ') %>) override { 192b1994897Sopenharmony_ci LOG(INFO, EVENTS) << "<%= event.name.camelize %>," << <%= event.fields.map(&:name).join(" << ',' << ") %>; 193b1994897Sopenharmony_ci } 194b1994897Sopenharmony_ci% end 195b1994897Sopenharmony_ci}; 196b1994897Sopenharmony_ci 197b1994897Sopenharmony_ci} // namespace events 198b1994897Sopenharmony_ci 199b1994897Sopenharmony_ciclass Events { 200b1994897Sopenharmony_cipublic: 201b1994897Sopenharmony_ci enum StreamKind { CSV, MEMORY, LOG }; 202b1994897Sopenharmony_ci 203b1994897Sopenharmony_ci template<StreamKind kind, typename... Args> 204b1994897Sopenharmony_ci static void Create(Args&&... args) { 205b1994897Sopenharmony_ci if constexpr (kind == StreamKind::CSV) { // NOLINT 206b1994897Sopenharmony_ci pevents = new events::EventsCsv(std::forward<Args>(args)...); 207b1994897Sopenharmony_ci } else if constexpr (kind == StreamKind::MEMORY) { // NOLINT 208b1994897Sopenharmony_ci pevents = new events::EventsMemory; 209b1994897Sopenharmony_ci } else if constexpr (kind == StreamKind::LOG) { // NOLINT 210b1994897Sopenharmony_ci pevents = new events::EventsLog; 211b1994897Sopenharmony_ci } else { // NOLINT 212b1994897Sopenharmony_ci UNREACHABLE(); 213b1994897Sopenharmony_ci } 214b1994897Sopenharmony_ci } 215b1994897Sopenharmony_ci 216b1994897Sopenharmony_ci template<typename... Args> 217b1994897Sopenharmony_ci static void Create(std::string_view output, Args&&... args) { 218b1994897Sopenharmony_ci if (output == "csv") { 219b1994897Sopenharmony_ci pevents = new events::EventsCsv(std::forward<Args>(args)...); 220b1994897Sopenharmony_ci } else if (output == "memory") { 221b1994897Sopenharmony_ci pevents = new events::EventsMemory; 222b1994897Sopenharmony_ci } else if (output == "log") { 223b1994897Sopenharmony_ci pevents = new events::EventsLog; 224b1994897Sopenharmony_ci } else { // NOLINT 225b1994897Sopenharmony_ci UNREACHABLE(); 226b1994897Sopenharmony_ci } 227b1994897Sopenharmony_ci } 228b1994897Sopenharmony_ci 229b1994897Sopenharmony_ci static void Destroy() { 230b1994897Sopenharmony_ci delete pevents; 231b1994897Sopenharmony_ci pevents = nullptr; 232b1994897Sopenharmony_ci } 233b1994897Sopenharmony_ci 234b1994897Sopenharmony_ci template<StreamKind kind> 235b1994897Sopenharmony_ci static auto CastTo() { 236b1994897Sopenharmony_ci if constexpr (kind == StreamKind::CSV) { // NOLINT 237b1994897Sopenharmony_ci return static_cast<events::EventsCsv*>(pevents); 238b1994897Sopenharmony_ci } else if constexpr (kind == StreamKind::MEMORY) { // NOLINT 239b1994897Sopenharmony_ci return static_cast<events::EventsMemory*>(pevents); 240b1994897Sopenharmony_ci } else { // NOLINT 241b1994897Sopenharmony_ci UNREACHABLE(); 242b1994897Sopenharmony_ci } 243b1994897Sopenharmony_ci } 244b1994897Sopenharmony_ci 245b1994897Sopenharmony_ci static bool IsEnabled() { 246b1994897Sopenharmony_ci return pevents != nullptr; 247b1994897Sopenharmony_ci } 248b1994897Sopenharmony_ci 249b1994897Sopenharmony_ci static events::EventsBase* GetEvents() { 250b1994897Sopenharmony_ci return pevents; 251b1994897Sopenharmony_ci } 252b1994897Sopenharmony_ci 253b1994897Sopenharmony_ciprivate: 254b1994897Sopenharmony_ci static inline events::EventsBase* pevents{nullptr}; 255b1994897Sopenharmony_ci}; 256b1994897Sopenharmony_ci 257b1994897Sopenharmony_ci#ifndef NDEBUG 258b1994897Sopenharmony_ci 259b1994897Sopenharmony_ci#define PANDA_EVENTS_ENABLED 260b1994897Sopenharmony_ci 261b1994897Sopenharmony_ci% EventsData.events.each do |event| 262b1994897Sopenharmony_ci% if !event.enable? 263b1994897Sopenharmony_ci// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 264b1994897Sopenharmony_ci#define EVENT_<%= event.name.upcase %>_ENABLED 0 265b1994897Sopenharmony_ci// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 266b1994897Sopenharmony_ci#define EVENT_<%= event.name.upcase %>(<%= event.fields.map(&:name).join(', ') %>) 267b1994897Sopenharmony_ci% else 268b1994897Sopenharmony_ci// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 269b1994897Sopenharmony_ci#define EVENT_<%= event.name.upcase %>_ENABLED 1 270b1994897Sopenharmony_ci// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 271b1994897Sopenharmony_ci#define EVENT_<%= event.name.upcase %>(<%= event.fields.map(&:name).join(', ') %>) \ 272b1994897Sopenharmony_ci if (Events::IsEnabled()) { \ 273b1994897Sopenharmony_ci Events::GetEvents()-><%= event.name.camelize %>(<%= event.fields.map(&:name).join(', ') %>); \ 274b1994897Sopenharmony_ci } 275b1994897Sopenharmony_ci% end 276b1994897Sopenharmony_ci% end 277b1994897Sopenharmony_ci#else 278b1994897Sopenharmony_ci% EventsData.events.each do |event| 279b1994897Sopenharmony_ci// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 280b1994897Sopenharmony_ci#define EVENT_<%= event.name.upcase %>(<%= event.fields.map(&:name).join(', ') %>) 281b1994897Sopenharmony_ci% end 282b1994897Sopenharmony_ci#endif 283b1994897Sopenharmony_ci 284b1994897Sopenharmony_ci} // namespace panda 285b1994897Sopenharmony_ci 286b1994897Sopenharmony_ci#endif // PANDA_EVENTS_GEN_H 287