• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
StatsCounter(const std::string & name)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 
~StatsCounter()20 StatsCounter::~StatsCounter() {
21 }
22 
Set(int value)23 void StatsCounter::Set(int value) {
24   int* loc = GetPtr();
25   if (loc)
26     *loc = value;
27 }
28 
Add(int value)29 void StatsCounter::Add(int value) {
30   int* loc = GetPtr();
31   if (loc)
32     (*loc) += value;
33 }
34 
StatsCounter()35 StatsCounter::StatsCounter()
36     : counter_id_(-1) {
37 }
38 
GetPtr()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 
StatsCounterTimer(const std::string & name)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 
~StatsCounterTimer()76 StatsCounterTimer::~StatsCounterTimer() {
77 }
78 
Start()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.
Stop()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.
Running()95 bool StatsCounterTimer::Running() {
96   return Enabled() && !start_time_.is_null() && stop_time_.is_null();
97 }
98 
99 // Accept a TimeDelta to increment.
AddTime(TimeDelta time)100 void StatsCounterTimer::AddTime(TimeDelta time) {
101   Add(static_cast<int>(time.InMilliseconds()));
102 }
103 
Record()104 void StatsCounterTimer::Record() {
105   AddTime(stop_time_ - start_time_);
106 }
107 
108 
StatsRate(const std::string & name)109 StatsRate::StatsRate(const std::string& name)
110     : StatsCounterTimer(name),
111       counter_(name),
112       largest_add_(std::string(" ").append(name).append("MAX")) {
113 }
114 
~StatsRate()115 StatsRate::~StatsRate() {
116 }
117 
Add(int value)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