Home | History | Annotate | Download | only in metrics
      1 // Copyright (c) 2010 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.
      4 
      5 #include "base/metrics/stats_counters.h"
      6 
      7 namespace base {
      8 
      9 StatsCounter::StatsCounter(const std::string& name)
     10     : counter_id_(-1) {
     11   // We prepend the name with 'c:' to indicate that it is a counter.
     12   if (StatsTable::current()) {
     13     // TODO(mbelshe): name_ construction is racy and it may corrupt memory for
     14     // static.
     15     name_ = "c:";
     16     name_.append(name);
     17   }
     18 }
     19 
     20 StatsCounter::~StatsCounter() {
     21 }
     22 
     23 void StatsCounter::Set(int value) {
     24   int* loc = GetPtr();
     25   if (loc)
     26     *loc = value;
     27 }
     28 
     29 void StatsCounter::Add(int value) {
     30   int* loc = GetPtr();
     31   if (loc)
     32     (*loc) += value;
     33 }
     34 
     35 StatsCounter::StatsCounter()
     36     : counter_id_(-1) {
     37 }
     38 
     39 int* StatsCounter::GetPtr() {
     40   StatsTable* table = StatsTable::current();
     41   if (!table)
     42     return NULL;
     43 
     44   // If counter_id_ is -1, then we haven't looked it up yet.
     45   if (counter_id_ == -1) {
     46     counter_id_ = table->FindCounter(name_);
     47     if (table->GetSlot() == 0) {
     48       if (!table->RegisterThread(std::string())) {
     49         // There is no room for this thread.  This thread
     50         // cannot use counters.
     51         counter_id_ = 0;
     52         return NULL;
     53       }
     54     }
     55   }
     56 
     57   // If counter_id_ is > 0, then we have a valid counter.
     58   if (counter_id_ > 0)
     59     return table->GetLocation(counter_id_, table->GetSlot());
     60 
     61   // counter_id_ was zero, which means the table is full.
     62   return NULL;
     63 }
     64 
     65 
     66 StatsCounterTimer::StatsCounterTimer(const std::string& name) {
     67   // we prepend the name with 't:' to indicate that it is a timer.
     68   if (StatsTable::current()) {
     69     // TODO(mbelshe): name_ construction is racy and it may corrupt memory for
     70     // static.
     71     name_ = "t:";
     72     name_.append(name);
     73   }
     74 }
     75 
     76 StatsCounterTimer::~StatsCounterTimer() {
     77 }
     78 
     79 void StatsCounterTimer::Start() {
     80   if (!Enabled())
     81     return;
     82   start_time_ = TimeTicks::Now();
     83   stop_time_ = TimeTicks();
     84 }
     85 
     86 // Stop the timer and record the results.
     87 void StatsCounterTimer::Stop() {
     88   if (!Enabled() || !Running())
     89     return;
     90   stop_time_ = TimeTicks::Now();
     91   Record();
     92 }
     93 
     94 // Returns true if the timer is running.
     95 bool StatsCounterTimer::Running() {
     96   return Enabled() && !start_time_.is_null() && stop_time_.is_null();
     97 }
     98 
     99 // Accept a TimeDelta to increment.
    100 void StatsCounterTimer::AddTime(TimeDelta time) {
    101   Add(static_cast<int>(time.InMilliseconds()));
    102 }
    103 
    104 void StatsCounterTimer::Record() {
    105   AddTime(stop_time_ - start_time_);
    106 }
    107 
    108 
    109 StatsRate::StatsRate(const std::string& name)
    110     : StatsCounterTimer(name),
    111       counter_(name),
    112       largest_add_(std::string(" ").append(name).append("MAX")) {
    113 }
    114 
    115 StatsRate::~StatsRate() {
    116 }
    117 
    118 void StatsRate::Add(int value) {
    119   counter_.Increment();
    120   StatsCounterTimer::Add(value);
    121   if (value > largest_add_.value())
    122     largest_add_.Set(value);
    123 }
    124 
    125 }  // namespace base
    126