13345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Copyright (c) 2010 The Chromium Authors. All rights reserved. 23345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Use of this source code is governed by a BSD-style license that can be 33345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// found in the LICENSE file. 43345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/metrics/stats_counters.h" 6731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 7731df977c0511bca2206b5f333555b1205ff1f43Iain Merricknamespace base { 83345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 93345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickStatsCounter::StatsCounter(const std::string& name) 103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : counter_id_(-1) { 113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We prepend the name with 'c:' to indicate that it is a counter. 12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (StatsTable::current()) { 13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // TODO(mbelshe): name_ construction is racy and it may corrupt memory for 14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // static. 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen name_ = "c:"; 16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen name_.append(name); 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 203345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickStatsCounter::~StatsCounter() { 213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid StatsCounter::Set(int value) { 243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int* loc = GetPtr(); 253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (loc) 263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick *loc = value; 273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid StatsCounter::Add(int value) { 303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int* loc = GetPtr(); 313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (loc) 323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick (*loc) += value; 333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 353345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickStatsCounter::StatsCounter() 363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : counter_id_(-1) { 373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickint* StatsCounter::GetPtr() { 403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick StatsTable* table = StatsTable::current(); 413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!table) 423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return NULL; 433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // If counter_id_ is -1, then we haven't looked it up yet. 453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (counter_id_ == -1) { 463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick counter_id_ = table->FindCounter(name_); 473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (table->GetSlot() == 0) { 483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!table->RegisterThread("")) { 493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // There is no room for this thread. This thread 503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // cannot use counters. 513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick counter_id_ = 0; 523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return NULL; 533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // If counter_id_ is > 0, then we have a valid counter. 583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (counter_id_ > 0) 593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return table->GetLocation(counter_id_, table->GetSlot()); 603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // counter_id_ was zero, which means the table is full. 623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return NULL; 633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 663345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickStatsCounterTimer::StatsCounterTimer(const std::string& name) { 673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // we prepend the name with 't:' to indicate that it is a timer. 68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (StatsTable::current()) { 69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // TODO(mbelshe): name_ construction is racy and it may corrupt memory for 70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // static. 71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen name_ = "t:"; 72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen name_.append(name); 73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 763345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickStatsCounterTimer::~StatsCounterTimer() { 773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid StatsCounterTimer::Start() { 803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!Enabled()) 813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return; 82731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick start_time_ = TimeTicks::Now(); 83731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick stop_time_ = TimeTicks(); 843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Stop the timer and record the results. 873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid StatsCounterTimer::Stop() { 883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!Enabled() || !Running()) 893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return; 90731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick stop_time_ = TimeTicks::Now(); 913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Record(); 923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Returns true if the timer is running. 953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool StatsCounterTimer::Running() { 963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return Enabled() && !start_time_.is_null() && stop_time_.is_null(); 973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Accept a TimeDelta to increment. 100731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid StatsCounterTimer::AddTime(TimeDelta time) { 1013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Add(static_cast<int>(time.InMilliseconds())); 1023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid StatsCounterTimer::Record() { 1053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick AddTime(stop_time_ - start_time_); 1063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 109731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickStatsRate::StatsRate(const std::string& name) 1103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : StatsCounterTimer(name), 1113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick counter_(name), 112731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick largest_add_(std::string(" ").append(name).append("MAX")) { 1133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1153345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickStatsRate::~StatsRate() { 1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid StatsRate::Add(int value) { 1193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick counter_.Increment(); 1203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick StatsCounterTimer::Add(value); 1213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (value > largest_add_.value()) 1223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick largest_add_.Set(value); 1233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 124731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 125731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} // namespace base 126