LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/system_wrappers/source - metrics_default.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 139 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 33 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
       2             : //
       3             : // Use of this source code is governed by a BSD-style license
       4             : // that can be found in the LICENSE file in the root of the source
       5             : // tree. An additional intellectual property rights grant can be found
       6             : // in the file PATENTS.  All contributing project authors may
       7             : // be found in the AUTHORS file in the root of the source tree.
       8             : //
       9             : 
      10             : #include "webrtc/system_wrappers/include/metrics_default.h"
      11             : 
      12             : #include <algorithm>
      13             : 
      14             : #include "webrtc/base/criticalsection.h"
      15             : #include "webrtc/base/thread_annotations.h"
      16             : #include "webrtc/system_wrappers/include/metrics.h"
      17             : 
      18             : // Default implementation of histogram methods for WebRTC clients that do not
      19             : // want to provide their own implementation.
      20             : 
      21             : namespace webrtc {
      22             : namespace metrics {
      23             : class Histogram;
      24             : 
      25             : namespace {
      26             : // Limit for the maximum number of sample values that can be stored.
      27             : // TODO(asapersson): Consider using bucket count (and set up
      28             : // linearly/exponentially spaced buckets) if samples are logged more frequently.
      29             : const int kMaxSampleMapSize = 300;
      30             : 
      31           0 : class RtcHistogram {
      32             :  public:
      33           0 :   RtcHistogram(const std::string& name, int min, int max, int bucket_count)
      34           0 :       : min_(min), max_(max), info_(name, min, max, bucket_count) {
      35           0 :     RTC_DCHECK_GT(bucket_count, 0);
      36           0 :   }
      37             : 
      38           0 :   void Add(int sample) {
      39           0 :     sample = std::min(sample, max_);
      40           0 :     sample = std::max(sample, min_ - 1);  // Underflow bucket.
      41             : 
      42           0 :     rtc::CritScope cs(&crit_);
      43           0 :     if (info_.samples.size() == kMaxSampleMapSize &&
      44           0 :         info_.samples.find(sample) == info_.samples.end()) {
      45           0 :       return;
      46             :     }
      47           0 :     ++info_.samples[sample];
      48             :   }
      49             : 
      50             :   // Returns a copy (or nullptr if there are no samples) and clears samples.
      51           0 :   std::unique_ptr<SampleInfo> GetAndReset() {
      52           0 :     rtc::CritScope cs(&crit_);
      53           0 :     if (info_.samples.empty())
      54           0 :       return nullptr;
      55             : 
      56             :     SampleInfo* copy =
      57           0 :         new SampleInfo(info_.name, info_.min, info_.max, info_.bucket_count);
      58             : 
      59           0 :     std::swap(info_.samples, copy->samples);
      60             : 
      61           0 :     return std::unique_ptr<SampleInfo>(copy);
      62             :   }
      63             : 
      64           0 :   const std::string& name() const { return info_.name; }
      65             : 
      66             :   // Functions only for testing.
      67           0 :   void Reset() {
      68           0 :     rtc::CritScope cs(&crit_);
      69           0 :     info_.samples.clear();
      70           0 :   }
      71             : 
      72           0 :   int NumEvents(int sample) const {
      73           0 :     rtc::CritScope cs(&crit_);
      74           0 :     const auto it = info_.samples.find(sample);
      75           0 :     return (it == info_.samples.end()) ? 0 : it->second;
      76             :   }
      77             : 
      78           0 :   int NumSamples() const {
      79           0 :     int num_samples = 0;
      80           0 :     rtc::CritScope cs(&crit_);
      81           0 :     for (const auto& sample : info_.samples) {
      82           0 :       num_samples += sample.second;
      83             :     }
      84           0 :     return num_samples;
      85             :   }
      86             : 
      87           0 :   int MinSample() const {
      88           0 :     rtc::CritScope cs(&crit_);
      89           0 :     return (info_.samples.empty()) ? -1 : info_.samples.begin()->first;
      90             :   }
      91             : 
      92             :  private:
      93             :   rtc::CriticalSection crit_;
      94             :   const int min_;
      95             :   const int max_;
      96             :   SampleInfo info_ GUARDED_BY(crit_);
      97             : 
      98             :   RTC_DISALLOW_COPY_AND_ASSIGN(RtcHistogram);
      99             : };
     100             : 
     101             : class RtcHistogramMap {
     102             :  public:
     103           0 :   RtcHistogramMap() {}
     104           0 :   ~RtcHistogramMap() {}
     105             : 
     106           0 :   Histogram* GetCountsHistogram(const std::string& name,
     107             :                                 int min,
     108             :                                 int max,
     109             :                                 int bucket_count) {
     110           0 :     rtc::CritScope cs(&crit_);
     111           0 :     const auto& it = map_.find(name);
     112           0 :     if (it != map_.end())
     113           0 :       return reinterpret_cast<Histogram*>(it->second.get());
     114             : 
     115           0 :     RtcHistogram* hist = new RtcHistogram(name, min, max, bucket_count);
     116           0 :     map_[name].reset(hist);
     117           0 :     return reinterpret_cast<Histogram*>(hist);
     118             :   }
     119             : 
     120           0 :   Histogram* GetEnumerationHistogram(const std::string& name, int boundary) {
     121           0 :     rtc::CritScope cs(&crit_);
     122           0 :     const auto& it = map_.find(name);
     123           0 :     if (it != map_.end())
     124           0 :       return reinterpret_cast<Histogram*>(it->second.get());
     125             : 
     126           0 :     RtcHistogram* hist = new RtcHistogram(name, 1, boundary, boundary + 1);
     127           0 :     map_[name].reset(hist);
     128           0 :     return reinterpret_cast<Histogram*>(hist);
     129             :   }
     130             : 
     131           0 :   void GetAndReset(
     132             :       std::map<std::string, std::unique_ptr<SampleInfo>>* histograms) {
     133           0 :     rtc::CritScope cs(&crit_);
     134           0 :     for (const auto& kv : map_) {
     135           0 :       std::unique_ptr<SampleInfo> info = kv.second->GetAndReset();
     136           0 :       if (info)
     137           0 :         histograms->insert(std::make_pair(kv.first, std::move(info)));
     138             :     }
     139           0 :   }
     140             : 
     141             :   // Functions only for testing.
     142           0 :   void Reset() {
     143           0 :     rtc::CritScope cs(&crit_);
     144           0 :     for (const auto& kv : map_)
     145           0 :       kv.second->Reset();
     146           0 :   }
     147             : 
     148           0 :   int NumEvents(const std::string& name, int sample) const {
     149           0 :     rtc::CritScope cs(&crit_);
     150           0 :     const auto& it = map_.find(name);
     151           0 :     return (it == map_.end()) ? 0 : it->second->NumEvents(sample);
     152             :   }
     153             : 
     154           0 :   int NumSamples(const std::string& name) const {
     155           0 :     rtc::CritScope cs(&crit_);
     156           0 :     const auto& it = map_.find(name);
     157           0 :     return (it == map_.end()) ? 0 : it->second->NumSamples();
     158             :   }
     159             : 
     160           0 :   int MinSample(const std::string& name) const {
     161           0 :     rtc::CritScope cs(&crit_);
     162           0 :     const auto& it = map_.find(name);
     163           0 :     return (it == map_.end()) ? -1 : it->second->MinSample();
     164             :   }
     165             : 
     166             :  private:
     167             :   rtc::CriticalSection crit_;
     168             :   std::map<std::string, std::unique_ptr<RtcHistogram>> map_ GUARDED_BY(crit_);
     169             : 
     170             :   RTC_DISALLOW_COPY_AND_ASSIGN(RtcHistogramMap);
     171             : };
     172             : 
     173             : // RtcHistogramMap is allocated upon call to Enable().
     174             : // The histogram getter functions, which return pointer values to the histograms
     175             : // in the map, are cached in WebRTC. Therefore, this memory is not freed by the
     176             : // application (the memory will be reclaimed by the OS).
     177             : static RtcHistogramMap* volatile g_rtc_histogram_map = nullptr;
     178             : 
     179           0 : void CreateMap() {
     180           0 :   RtcHistogramMap* map = rtc::AtomicOps::AcquireLoadPtr(&g_rtc_histogram_map);
     181           0 :   if (map == nullptr) {
     182           0 :     RtcHistogramMap* new_map = new RtcHistogramMap();
     183             :     RtcHistogramMap* old_map = rtc::AtomicOps::CompareAndSwapPtr(
     184           0 :         &g_rtc_histogram_map, static_cast<RtcHistogramMap*>(nullptr), new_map);
     185           0 :     if (old_map != nullptr)
     186           0 :       delete new_map;
     187             :   }
     188           0 : }
     189             : 
     190             : // Set the first time we start using histograms. Used to make sure Enable() is
     191             : // not called thereafter.
     192             : #if RTC_DCHECK_IS_ON
     193             : static volatile int g_rtc_histogram_called = 0;
     194             : #endif
     195             : 
     196             : // Gets the map (or nullptr).
     197           0 : RtcHistogramMap* GetMap() {
     198             : #if RTC_DCHECK_IS_ON
     199           0 :   rtc::AtomicOps::ReleaseStore(&g_rtc_histogram_called, 1);
     200             : #endif
     201           0 :   return g_rtc_histogram_map;
     202             : }
     203             : }  // namespace
     204             : 
     205             : // Implementation of histogram methods in
     206             : // webrtc/system_wrappers/interface/metrics.h.
     207             : 
     208             : // Histogram with exponentially spaced buckets.
     209             : // Creates (or finds) histogram.
     210             : // The returned histogram pointer is cached (and used for adding samples in
     211             : // subsequent calls).
     212           0 : Histogram* HistogramFactoryGetCounts(const std::string& name,
     213             :                                      int min,
     214             :                                      int max,
     215             :                                      int bucket_count) {
     216             :   // TODO(asapersson): Alternative implementation will be needed if this
     217             :   // histogram type should be truly exponential.
     218           0 :   return HistogramFactoryGetCountsLinear(name, min, max, bucket_count);
     219             : }
     220             : 
     221             : // Histogram with linearly spaced buckets.
     222             : // Creates (or finds) histogram.
     223             : // The returned histogram pointer is cached (and used for adding samples in
     224             : // subsequent calls).
     225           0 : Histogram* HistogramFactoryGetCountsLinear(const std::string& name,
     226             :                                            int min,
     227             :                                            int max,
     228             :                                            int bucket_count) {
     229           0 :   RtcHistogramMap* map = GetMap();
     230           0 :   if (!map)
     231           0 :     return nullptr;
     232             : 
     233           0 :   return map->GetCountsHistogram(name, min, max, bucket_count);
     234             : }
     235             : 
     236             : // Histogram with linearly spaced buckets.
     237             : // Creates (or finds) histogram.
     238             : // The returned histogram pointer is cached (and used for adding samples in
     239             : // subsequent calls).
     240           0 : Histogram* HistogramFactoryGetEnumeration(const std::string& name,
     241             :                                           int boundary) {
     242           0 :   RtcHistogramMap* map = GetMap();
     243           0 :   if (!map)
     244           0 :     return nullptr;
     245             : 
     246           0 :   return map->GetEnumerationHistogram(name, boundary);
     247             : }
     248             : 
     249           0 : const std::string& GetHistogramName(Histogram* histogram_pointer) {
     250           0 :   RtcHistogram* ptr = reinterpret_cast<RtcHistogram*>(histogram_pointer);
     251           0 :   return ptr->name();
     252             : }
     253             : 
     254             : // Fast path. Adds |sample| to cached |histogram_pointer|.
     255           0 : void HistogramAdd(Histogram* histogram_pointer, int sample) {
     256           0 :   RtcHistogram* ptr = reinterpret_cast<RtcHistogram*>(histogram_pointer);
     257           0 :   ptr->Add(sample);
     258           0 : }
     259             : 
     260           0 : SampleInfo::SampleInfo(const std::string& name,
     261             :                        int min,
     262             :                        int max,
     263           0 :                        size_t bucket_count)
     264           0 :     : name(name), min(min), max(max), bucket_count(bucket_count) {}
     265             : 
     266           0 : SampleInfo::~SampleInfo() {}
     267             : 
     268             : // Implementation of global functions in metrics_default.h.
     269           0 : void Enable() {
     270           0 :   RTC_DCHECK(g_rtc_histogram_map == nullptr);
     271             : #if RTC_DCHECK_IS_ON
     272           0 :   RTC_DCHECK_EQ(0, rtc::AtomicOps::AcquireLoad(&g_rtc_histogram_called));
     273             : #endif
     274           0 :   CreateMap();
     275           0 : }
     276             : 
     277           0 : void GetAndReset(
     278             :     std::map<std::string, std::unique_ptr<SampleInfo>>* histograms) {
     279           0 :   histograms->clear();
     280           0 :   RtcHistogramMap* map = GetMap();
     281           0 :   if (map)
     282           0 :     map->GetAndReset(histograms);
     283           0 : }
     284             : 
     285           0 : void Reset() {
     286           0 :   RtcHistogramMap* map = GetMap();
     287           0 :   if (map)
     288           0 :     map->Reset();
     289           0 : }
     290             : 
     291           0 : int NumEvents(const std::string& name, int sample) {
     292           0 :   RtcHistogramMap* map = GetMap();
     293           0 :   return map ? map->NumEvents(name, sample) : 0;
     294             : }
     295             : 
     296           0 : int NumSamples(const std::string& name) {
     297           0 :   RtcHistogramMap* map = GetMap();
     298           0 :   return map ? map->NumSamples(name) : 0;
     299             : }
     300             : 
     301           0 : int MinSample(const std::string& name) {
     302           0 :   RtcHistogramMap* map = GetMap();
     303           0 :   return map ? map->MinSample(name) : -1;
     304             : }
     305             : 
     306             : }  // namespace metrics
     307             : }  // namespace webrtc

Generated by: LCOV version 1.13