| // Copyright 2017 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // TODO(dje): The "category" mechanism is limiting but it's what we have |
| // at the moment. |
| |
| #ifndef GARNET_BIN_CPUPERF_PROVIDER_CATEGORIES_H_ |
| #define GARNET_BIN_CPUPERF_PROVIDER_CATEGORIES_H_ |
| |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| #include <functional> |
| #include <string> |
| #include <unordered_set> |
| |
| #include <lib/zircon-internal/device/cpu-trace/perf-mon.h> |
| |
| #include "garnet/lib/perfmon/config.h" |
| #include "garnet/lib/perfmon/events.h" |
| |
| namespace cpuperf_provider { |
| |
| enum class TraceOption { |
| // Collect data from the o/s. |
| kOs, |
| // Collect data from userspace. |
| kUser, |
| // Collect the PC value for each event that is its own timebase. |
| kPc, |
| // Collect the set of last branch entries for each event that is its |
| // own timebase. |
| kLastBranch, |
| }; |
| |
| enum class CategoryGroup { |
| // Options like os vs user. |
| kOption, |
| // The sampling mode and frequency. |
| kSample, |
| // Collection of architecturally defined fixed-purpose events. |
| kFixedArch, |
| // Collection of architecturally defined programmable events. |
| kProgrammableArch, |
| // Collection of model-specific fixed-purpose events. |
| kFixedModel, |
| // Collection of model-specific programmable events. |
| kProgrammableModel, |
| }; |
| |
| using CategoryValue = uint32_t; |
| |
| struct CategorySpec { |
| const char* name; |
| CategoryGroup group; |
| // This is only used by kOption and kSample. |
| CategoryValue value; |
| size_t count; |
| const perfmon::EventId* events; |
| }; |
| |
| struct TimebaseSpec { |
| const char* name; |
| const perfmon::EventId event; |
| }; |
| |
| extern const CategorySpec kCommonCategories[]; |
| extern const size_t kNumCommonCategories; |
| |
| extern const CategorySpec kTargetCategories[]; |
| extern const size_t kNumTargetCategories; |
| |
| extern const TimebaseSpec kTimebaseCategories[]; |
| extern const size_t kNumTimebaseCategories; |
| |
| // A data collection run is called a "trace". |
| // This records the user-specified configuration of the trace. |
| class TraceConfig final { |
| public: |
| using IsCategoryEnabledFunc = std::function<bool(const char* name)>; |
| |
| static std::unique_ptr<TraceConfig> Create( |
| perfmon::ModelEventManager* model_event_manager, |
| IsCategoryEnabledFunc category_is_enabled); |
| |
| perfmon::ModelEventManager* model_event_manager() const { |
| return model_event_manager_; |
| } |
| |
| bool is_enabled() const { return is_enabled_; } |
| |
| bool trace_os() const { return trace_os_; } |
| bool trace_user() const { return trace_user_; } |
| bool trace_pc() const { return trace_pc_; } |
| bool trace_last_branch() const { return trace_last_branch_; } |
| |
| uint32_t sample_rate() const { return sample_rate_; } |
| |
| perfmon::EventId timebase_event() const { return timebase_event_; } |
| |
| // Return true if the configuration has changed. |
| bool Changed(const TraceConfig& old) const; |
| |
| // Translate our representation of the configuration to the device's. |
| bool TranslateToDeviceConfig(perfmon::Config* out_config) const; |
| |
| // Return a string representation of the config for error reporting. |
| std::string ToString() const; |
| |
| private: |
| // Keeps track of category data for ProcessCategories. |
| struct CategoryData { |
| bool have_data_to_collect = false; |
| bool have_sample_rate = false; |
| bool have_programmable_category = false; |
| }; |
| |
| TraceConfig(perfmon::ModelEventManager* model_event_manager, |
| IsCategoryEnabledFunc category_is_enabled); |
| |
| bool ProcessAllCategories(); |
| bool ProcessCategories(const CategorySpec categories[], |
| size_t num_categories, |
| CategoryData* data); |
| |
| bool ProcessTimebase(); |
| |
| // Non-owning. |
| perfmon::ModelEventManager* const model_event_manager_; |
| |
| const IsCategoryEnabledFunc is_category_enabled_; |
| |
| bool is_enabled_ = false; |
| |
| bool trace_os_ = false; |
| bool trace_user_ = false; |
| bool trace_pc_ = false; |
| bool trace_last_branch_ = false; |
| uint32_t sample_rate_ = 0; |
| perfmon::EventId timebase_event_ = perfmon::kEventIdNone; |
| |
| // Set of selected fixed + programmable categories. |
| std::unordered_set<const CategorySpec*> selected_categories_; |
| }; |
| |
| } // namespace cpuperf_provider |
| |
| #endif // GARNET_BIN_CPUPERF_PROVIDER_CATEGORIES_H_ |