================ @@ -174,6 +177,86 @@ struct StatisticsOptions { std::optional<bool> m_include_transcript; }; +/// A class that represents statistics about a TypeSummaryProviders invocations +class SummaryStatistics { +public: + explicit SummaryStatistics(std::string name, std::string impl_type) + : m_total_time(), m_impl_type(impl_type), m_name(name), + m_summary_count(0) {} + + std::string GetName() const { return m_name; }; + double GetTotalTime() const { return m_total_time.get().count(); } + + uint64_t GetSummaryCount() const { + return m_summary_count.load(std::memory_order_relaxed); + } + + StatsDuration &GetDurationReference() { return m_total_time; }; + + std::string GetSummaryKindName() const { return m_impl_type; } + + llvm::json::Value ToJSON() const; + + void IncrementSummaryCount() { + m_summary_count.fetch_add(1, std::memory_order_relaxed); + } + +private: + lldb_private::StatsDuration m_total_time; + std::string m_impl_type; + std::string m_name; + std::atomic<uint64_t> m_summary_count; +}; + +/// A class that wraps a std::map of SummaryStatistics objects behind a mutex. +class SummaryStatisticsCache { +public: + /// Basic RAII class to increment the summary count when the call is complete. + /// In the future this can be extended to collect information about the + /// elapsed time for a single request. + class SummaryInvocation { + public: + SummaryInvocation(SummaryStatistics &summary, SummaryStatisticsCache &cache) + : m_provider_key(summary.GetName()), m_cache(cache), + m_elapsed_time(summary.GetDurationReference()) {} + ~SummaryInvocation() { m_cache.OnInvoked(m_provider_key); } + + /// Delete the copy constructor and assignment operator to prevent + /// accidental double counting. + /// @{ + SummaryInvocation(const SummaryInvocation &) = delete; + SummaryInvocation &operator=(const SummaryInvocation &) = delete; + /// @} + + private: + std::string m_provider_key; + SummaryStatisticsCache &m_cache; + ElapsedTime m_elapsed_time; + }; + + /// Get the SummaryStatistics object for a given provider name, or insert + /// if statistics for that provider is not in the map. + SummaryStatisticsCache::SummaryInvocation + GetSummaryStatisticsForProviderName(lldb_private::TypeSummaryImpl &provider) { + std::lock_guard<std::mutex> guard(m_map_mutex); + auto pair = m_summary_stats_map.try_emplace( + provider.GetName(), provider.GetName(), provider.GetSummaryKindName()); + + return SummaryInvocation(pair.first->second, *this); + } + + llvm::json::Value ToJSON(); + +private: + /// Called when Summary Invocation is destructed. + void OnInvoked(std::string provider_name) noexcept { + // .at give us a const reference, and [provider_name] = will give us a copy + m_summary_stats_map.find(provider_name)->second.IncrementSummaryCount(); ---------------- Jlalond wrote:
@Michael137 Preferably I wouldn't like to call find at all, but `at` only returns to us a const reference, so we wouldn't be able to increment it. If find is our only option, then I'll add the assert and lock under the mutex https://github.com/llvm/llvm-project/pull/102708 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits