ipc/chromium/src/base/stats_counters.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
     2 // Use of this source code is governed by a BSD-style license that can be
     3 // found in the LICENSE file.
     6 #ifndef BASE_STATS_COUNTERS_H__
     7 #define BASE_STATS_COUNTERS_H__
     9 #include <string>
    10 #include "base/stats_table.h"
    11 #include "base/time.h"
    13 // StatsCounters are dynamically created values which can be tracked in
    14 // the StatsTable.  They are designed to be lightweight to create and
    15 // easy to use.
    16 //
    17 // Since StatsCounters can be created dynamically by name, there is
    18 // a hash table lookup to find the counter in the table.  A StatsCounter
    19 // object can be created once and used across multiple threads safely.
    20 //
    21 // Example usage:
    22 //    {
    23 //      StatsCounter request_count("RequestCount");
    24 //      request_count.Increment();
    25 //    }
    26 //
    27 // Note that creating counters on the stack does work, however creating
    28 // the counter object requires a hash table lookup.  For inner loops, it
    29 // may be better to create the counter either as a member of another object
    30 // (or otherwise outside of the loop) for maximum performance.
    31 //
    32 // Internally, a counter represents a value in a row of a StatsTable.
    33 // The row has a 32bit value for each process/thread in the table and also
    34 // a name (stored in the table metadata).
    35 //
    36 // NOTE: In order to make stats_counters usable in lots of different code,
    37 // avoid any dependencies inside this header file.
    38 //
    40 //------------------------------------------------------------------------------
    41 // Define macros for ease of use. They also allow us to change definitions
    42 // as the implementation varies, or depending on compile options.
    43 //------------------------------------------------------------------------------
    44 // First provide generic macros, which exist in production as well as debug.
    45 #define STATS_COUNTER(name, delta) do { \
    46   static StatsCounter counter(name); \
    47   counter.Add(delta); \
    48 } while (0)
    50 #define SIMPLE_STATS_COUNTER(name) STATS_COUNTER(name, 1)
    52 #define RATE_COUNTER(name, duration) do { \
    53   static StatsRate hit_count(name); \
    54   hit_count.AddTime(duration); \
    55 } while (0)
    57 // Define Debug vs non-debug flavors of macros.
    58 #ifndef NDEBUG
    60 #define DSTATS_COUNTER(name, delta) STATS_COUNTER(name, delta)
    61 #define DSIMPLE_STATS_COUNTER(name) SIMPLE_STATS_COUNTER(name)
    62 #define DRATE_COUNTER(name, duration) RATE_COUNTER(name, duration)
    64 #else  // NDEBUG
    66 #define DSTATS_COUNTER(name, delta) do {} while (0)
    67 #define DSIMPLE_STATS_COUNTER(name) do {} while (0)
    68 #define DRATE_COUNTER(name, duration) do {} while (0)
    70 #endif  // NDEBUG
    72 //------------------------------------------------------------------------------
    73 // StatsCounter represents a counter in the StatsTable class.
    74 class StatsCounter {
    75  public:
    76   // Create a StatsCounter object.
    77   explicit StatsCounter(const std::string& name)
    78        : counter_id_(-1) {
    79     // We prepend the name with 'c:' to indicate that it is a counter.
    80     name_ = "c:";
    81     name_.append(name);
    82   };
    84   virtual ~StatsCounter() {}
    86   // Sets the counter to a specific value.
    87   void Set(int value) {
    88     int* loc = GetPtr();
    89     if (loc) *loc = value;
    90   }
    92   // Increments the counter.
    93   void Increment() {
    94     Add(1);
    95   }
    97   virtual void Add(int value) {
    98     int* loc = GetPtr();
    99     if (loc)
   100       (*loc) += value;
   101   }
   103   // Decrements the counter.
   104   void Decrement() {
   105     Add(-1);
   106   }
   108   void Subtract(int value) {
   109     Add(-value);
   110   }
   112   // Is this counter enabled?
   113   // Returns false if table is full.
   114   bool Enabled() {
   115     return GetPtr() != NULL;
   116   }
   118   int value() {
   119     int* loc = GetPtr();
   120     if (loc) return *loc;
   121     return 0;
   122   }
   124  protected:
   125   StatsCounter()
   126     : counter_id_(-1) {
   127   }
   129   // Returns the cached address of this counter location.
   130   int* GetPtr() {
   131     StatsTable* table = StatsTable::current();
   132     if (!table)
   133       return NULL;
   135     // If counter_id_ is -1, then we haven't looked it up yet.
   136     if (counter_id_ == -1) {
   137       counter_id_ = table->FindCounter(name_);
   138       if (table->GetSlot() == 0) {
   139         if (!table->RegisterThread("")) {
   140           // There is no room for this thread.  This thread
   141           // cannot use counters.
   142           counter_id_ = 0;
   143           return NULL;
   144         }
   145       }
   146     }
   148     // If counter_id_ is > 0, then we have a valid counter.
   149     if (counter_id_ > 0)
   150       return table->GetLocation(counter_id_, table->GetSlot());
   152     // counter_id_ was zero, which means the table is full.
   153     return NULL;
   154   }
   156   std::string name_;
   157   // The counter id in the table.  We initialize to -1 (an invalid value)
   158   // and then cache it once it has been looked up.  The counter_id is
   159   // valid across all threads and processes.
   160   int32_t counter_id_;
   161 };
   164 // A StatsCounterTimer is a StatsCounter which keeps a timer during
   165 // the scope of the StatsCounterTimer.  On destruction, it will record
   166 // its time measurement.
   167 class StatsCounterTimer : protected StatsCounter {
   168  public:
   169   // Constructs and starts the timer.
   170   explicit StatsCounterTimer(const std::string& name) {
   171     // we prepend the name with 't:' to indicate that it is a timer.
   172     name_ = "t:";
   173     name_.append(name);
   174   }
   176   // Start the timer.
   177   void Start() {
   178     if (!Enabled())
   179       return;
   180     start_time_ = base::TimeTicks::Now();
   181     stop_time_ = base::TimeTicks();
   182   }
   184   // Stop the timer and record the results.
   185   void Stop() {
   186     if (!Enabled() || !Running())
   187       return;
   188     stop_time_ = base::TimeTicks::Now();
   189     Record();
   190   }
   192   // Returns true if the timer is running.
   193   bool Running() {
   194     return Enabled() && !start_time_.is_null() && stop_time_.is_null();
   195   }
   197   // Accept a TimeDelta to increment.
   198   virtual void AddTime(base::TimeDelta time) {
   199     Add(static_cast<int>(time.InMilliseconds()));
   200   }
   202  protected:
   203   // Compute the delta between start and stop, in milliseconds.
   204   void Record() {
   205     AddTime(stop_time_ - start_time_);
   206   }
   208   base::TimeTicks start_time_;
   209   base::TimeTicks stop_time_;
   210 };
   212 // A StatsRate is a timer that keeps a count of the number of intervals added so
   213 // that several statistics can be produced:
   214 //    min, max, avg, count, total
   215 class StatsRate : public StatsCounterTimer {
   216  public:
   217   // Constructs and starts the timer.
   218   explicit StatsRate(const char* name)
   219       : StatsCounterTimer(name),
   220       counter_(name),
   221       largest_add_(std::string(" ").append(name).append("MAX").c_str()) {
   222   }
   224   virtual void Add(int value) {
   225     counter_.Increment();
   226     StatsCounterTimer::Add(value);
   227     if (value > largest_add_.value())
   228       largest_add_.Set(value);
   229   }
   231  private:
   232   StatsCounter counter_;
   233   StatsCounter largest_add_;
   234 };
   237 // Helper class for scoping a timer or rate.
   238 template<class T> class StatsScope {
   239  public:
   240   explicit StatsScope<T>(T& timer)
   241       : timer_(timer) {
   242     timer_.Start();
   243   }
   245   ~StatsScope() {
   246     timer_.Stop();
   247   }
   249   void Stop() {
   250     timer_.Stop();
   251   }
   253  private:
   254   T& timer_;
   255 };
   257 #endif  // BASE_STATS_COUNTERS_H__

mercurial