1*22144e20SJacob Lalonde #include "lldb/DataFormatters/TypeSummary.h" 2*22144e20SJacob Lalonde #include "lldb/Target/Statistics.h" 3*22144e20SJacob Lalonde #include "lldb/Utility/Stream.h" 4*22144e20SJacob Lalonde #include "lldb/lldb-forward.h" 5*22144e20SJacob Lalonde #include "lldb/lldb-private-enumerations.h" 6*22144e20SJacob Lalonde #include "lldb/lldb-private.h" 7*22144e20SJacob Lalonde #include "llvm/Testing/Support/Error.h" 8*22144e20SJacob Lalonde #include "gtest/gtest.h" 9*22144e20SJacob Lalonde #include <thread> 10*22144e20SJacob Lalonde 11*22144e20SJacob Lalonde using namespace lldb_private; 12*22144e20SJacob Lalonde using Duration = std::chrono::duration<double>; 13*22144e20SJacob Lalonde 14*22144e20SJacob Lalonde class DummySummaryImpl : public lldb_private::TypeSummaryImpl { 15*22144e20SJacob Lalonde public: 16*22144e20SJacob Lalonde DummySummaryImpl() 17*22144e20SJacob Lalonde : TypeSummaryImpl(TypeSummaryImpl::Kind::eSummaryString, 18*22144e20SJacob Lalonde TypeSummaryImpl::Flags()) {} 19*22144e20SJacob Lalonde 20*22144e20SJacob Lalonde std::string GetName() override { return "DummySummary"; } 21*22144e20SJacob Lalonde 22*22144e20SJacob Lalonde std::string GetSummaryKindName() override { return "dummy"; } 23*22144e20SJacob Lalonde 24*22144e20SJacob Lalonde std::string GetDescription() override { return ""; } 25*22144e20SJacob Lalonde 26*22144e20SJacob Lalonde bool FormatObject(ValueObject *valobj, std::string &dest, 27*22144e20SJacob Lalonde const TypeSummaryOptions &options) override { 28*22144e20SJacob Lalonde return false; 29*22144e20SJacob Lalonde } 30*22144e20SJacob Lalonde }; 31*22144e20SJacob Lalonde 32*22144e20SJacob Lalonde TEST(MultithreadFormatting, Multithread) { 33*22144e20SJacob Lalonde SummaryStatisticsCache statistics_cache; 34*22144e20SJacob Lalonde DummySummaryImpl summary; 35*22144e20SJacob Lalonde std::vector<std::thread> threads; 36*22144e20SJacob Lalonde for (int i = 0; i < 10; ++i) { 37*22144e20SJacob Lalonde threads.emplace_back(std::thread([&statistics_cache, &summary]() { 38*22144e20SJacob Lalonde auto sp = statistics_cache.GetSummaryStatisticsForProvider(summary); 39*22144e20SJacob Lalonde { 40*22144e20SJacob Lalonde SummaryStatistics::SummaryInvocation invocation(sp); 41*22144e20SJacob Lalonde std::this_thread::sleep_for(Duration(1)); 42*22144e20SJacob Lalonde } 43*22144e20SJacob Lalonde })); 44*22144e20SJacob Lalonde } 45*22144e20SJacob Lalonde 46*22144e20SJacob Lalonde for (auto &thread : threads) 47*22144e20SJacob Lalonde thread.join(); 48*22144e20SJacob Lalonde 49*22144e20SJacob Lalonde auto sp = statistics_cache.GetSummaryStatisticsForProvider(summary); 50*22144e20SJacob Lalonde ASSERT_TRUE(sp->GetDurationReference().get().count() > 10); 51*22144e20SJacob Lalonde ASSERT_TRUE(sp->GetSummaryCount() == 10); 52*22144e20SJacob Lalonde 53*22144e20SJacob Lalonde std::string stats_as_json; 54*22144e20SJacob Lalonde llvm::raw_string_ostream ss(stats_as_json); 55*22144e20SJacob Lalonde ss << sp->ToJSON(); 56*22144e20SJacob Lalonde ASSERT_THAT(stats_as_json, ::testing::HasSubstr("\"name\":\"DummySummary\"")); 57*22144e20SJacob Lalonde ASSERT_THAT(stats_as_json, ::testing::HasSubstr("\"type\":\"dummy\"")); 58*22144e20SJacob Lalonde } 59