1*da0073e9SAndroid Build Coastguard Worker #include <c10/util/Gauge.h> 2*da0073e9SAndroid Build Coastguard Worker 3*da0073e9SAndroid Build Coastguard Worker #include <c10/util/Synchronized.h> 4*da0073e9SAndroid Build Coastguard Worker 5*da0073e9SAndroid Build Coastguard Worker #include <memory> 6*da0073e9SAndroid Build Coastguard Worker #include <string> 7*da0073e9SAndroid Build Coastguard Worker #include <string_view> 8*da0073e9SAndroid Build Coastguard Worker #include <unordered_map> 9*da0073e9SAndroid Build Coastguard Worker #include <vector> 10*da0073e9SAndroid Build Coastguard Worker 11*da0073e9SAndroid Build Coastguard Worker namespace c10::monitor { 12*da0073e9SAndroid Build Coastguard Worker 13*da0073e9SAndroid Build Coastguard Worker namespace detail { 14*da0073e9SAndroid Build Coastguard Worker namespace { 15*da0073e9SAndroid Build Coastguard Worker using GaugeBackendFactories = 16*da0073e9SAndroid Build Coastguard Worker std::vector<std::shared_ptr<GaugeBackendFactoryIf>>; 17*da0073e9SAndroid Build Coastguard Worker gaugeBackendFactories()18*da0073e9SAndroid Build Coastguard WorkerSynchronized<GaugeBackendFactories>& gaugeBackendFactories() { 19*da0073e9SAndroid Build Coastguard Worker static auto instance = new Synchronized<GaugeBackendFactories>(); 20*da0073e9SAndroid Build Coastguard Worker return *instance; 21*da0073e9SAndroid Build Coastguard Worker } 22*da0073e9SAndroid Build Coastguard Worker } // namespace 23*da0073e9SAndroid Build Coastguard Worker 24*da0073e9SAndroid Build Coastguard Worker class GaugeImpl { 25*da0073e9SAndroid Build Coastguard Worker public: getInstance(std::string_view key)26*da0073e9SAndroid Build Coastguard Worker static GaugeImpl& getInstance(std::string_view key) { 27*da0073e9SAndroid Build Coastguard Worker static auto& implMapSynchronized = *new Synchronized< 28*da0073e9SAndroid Build Coastguard Worker std::unordered_map<std::string, std::unique_ptr<GaugeImpl>>>(); 29*da0073e9SAndroid Build Coastguard Worker 30*da0073e9SAndroid Build Coastguard Worker return *implMapSynchronized.withLock([&](auto& implMap) { 31*da0073e9SAndroid Build Coastguard Worker if (auto implIt = implMap.find(std::string(key)); 32*da0073e9SAndroid Build Coastguard Worker implIt != implMap.end()) { 33*da0073e9SAndroid Build Coastguard Worker return implIt->second.get(); 34*da0073e9SAndroid Build Coastguard Worker } 35*da0073e9SAndroid Build Coastguard Worker 36*da0073e9SAndroid Build Coastguard Worker auto [implIt, emplaceSuccess] = implMap.emplace( 37*da0073e9SAndroid Build Coastguard Worker std::string{key}, std::unique_ptr<GaugeImpl>(new GaugeImpl(key))); 38*da0073e9SAndroid Build Coastguard Worker 39*da0073e9SAndroid Build Coastguard Worker assert(emplaceSuccess); 40*da0073e9SAndroid Build Coastguard Worker 41*da0073e9SAndroid Build Coastguard Worker return implIt->second.get(); 42*da0073e9SAndroid Build Coastguard Worker }); 43*da0073e9SAndroid Build Coastguard Worker } 44*da0073e9SAndroid Build Coastguard Worker record(int64_t value)45*da0073e9SAndroid Build Coastguard Worker void record(int64_t value) { 46*da0073e9SAndroid Build Coastguard Worker for (auto& backend : backends_) { 47*da0073e9SAndroid Build Coastguard Worker backend->record(value); 48*da0073e9SAndroid Build Coastguard Worker } 49*da0073e9SAndroid Build Coastguard Worker } 50*da0073e9SAndroid Build Coastguard Worker 51*da0073e9SAndroid Build Coastguard Worker private: GaugeImpl(std::string_view key)52*da0073e9SAndroid Build Coastguard Worker explicit GaugeImpl(std::string_view key) { 53*da0073e9SAndroid Build Coastguard Worker auto factoriesCopy = gaugeBackendFactories().withLock( 54*da0073e9SAndroid Build Coastguard Worker [](auto& factories) { return factories; }); 55*da0073e9SAndroid Build Coastguard Worker for (const auto& factory : factoriesCopy) { 56*da0073e9SAndroid Build Coastguard Worker if (auto backend = factory->create(key)) { 57*da0073e9SAndroid Build Coastguard Worker backends_.push_back(std::move(backend)); 58*da0073e9SAndroid Build Coastguard Worker } 59*da0073e9SAndroid Build Coastguard Worker } 60*da0073e9SAndroid Build Coastguard Worker } 61*da0073e9SAndroid Build Coastguard Worker 62*da0073e9SAndroid Build Coastguard Worker SmallVector<std::unique_ptr<GaugeBackendIf>> backends_; 63*da0073e9SAndroid Build Coastguard Worker }; 64*da0073e9SAndroid Build Coastguard Worker registerGaugeBackend(std::unique_ptr<GaugeBackendFactoryIf> backend)65*da0073e9SAndroid Build Coastguard Workervoid registerGaugeBackend(std::unique_ptr<GaugeBackendFactoryIf> backend) { 66*da0073e9SAndroid Build Coastguard Worker gaugeBackendFactories().withLock( 67*da0073e9SAndroid Build Coastguard Worker [&](auto& backends) { backends.push_back(std::move(backend)); }); 68*da0073e9SAndroid Build Coastguard Worker } 69*da0073e9SAndroid Build Coastguard Worker 70*da0073e9SAndroid Build Coastguard Worker } // namespace detail 71*da0073e9SAndroid Build Coastguard Worker GaugeHandle(std::string_view key)72*da0073e9SAndroid Build Coastguard WorkerGaugeHandle::GaugeHandle(std::string_view key) 73*da0073e9SAndroid Build Coastguard Worker : impl_(detail::GaugeImpl::getInstance(key)) {} 74*da0073e9SAndroid Build Coastguard Worker record(int64_t value)75*da0073e9SAndroid Build Coastguard Workervoid GaugeHandle::record(int64_t value) { 76*da0073e9SAndroid Build Coastguard Worker impl_.record(value); 77*da0073e9SAndroid Build Coastguard Worker } 78*da0073e9SAndroid Build Coastguard Worker 79*da0073e9SAndroid Build Coastguard Worker } // namespace c10::monitor 80