Bug 1061889 - remove Chromium statistics code. rs=bent

This commit is contained in:
Josh Aas 2014-09-02 18:04:59 -05:00
parent 42f650ec56
commit e89d979263
6 changed files with 0 additions and 1010 deletions

View File

@ -56,7 +56,6 @@ UNIFIED_SOURCES += [
'src/base/revocable_store.cc',
'src/base/scoped_temp_dir.cc',
'src/base/simple_thread.cc',
'src/base/stats_table.cc',
'src/base/string_piece.cc',
'src/base/string_util.cc',
'src/base/system_monitor.cc',

View File

@ -1,257 +0,0 @@
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_STATS_COUNTERS_H__
#define BASE_STATS_COUNTERS_H__
#include <string>
#include "base/stats_table.h"
#include "base/time.h"
// StatsCounters are dynamically created values which can be tracked in
// the StatsTable. They are designed to be lightweight to create and
// easy to use.
//
// Since StatsCounters can be created dynamically by name, there is
// a hash table lookup to find the counter in the table. A StatsCounter
// object can be created once and used across multiple threads safely.
//
// Example usage:
// {
// StatsCounter request_count("RequestCount");
// request_count.Increment();
// }
//
// Note that creating counters on the stack does work, however creating
// the counter object requires a hash table lookup. For inner loops, it
// may be better to create the counter either as a member of another object
// (or otherwise outside of the loop) for maximum performance.
//
// Internally, a counter represents a value in a row of a StatsTable.
// The row has a 32bit value for each process/thread in the table and also
// a name (stored in the table metadata).
//
// NOTE: In order to make stats_counters usable in lots of different code,
// avoid any dependencies inside this header file.
//
//------------------------------------------------------------------------------
// Define macros for ease of use. They also allow us to change definitions
// as the implementation varies, or depending on compile options.
//------------------------------------------------------------------------------
// First provide generic macros, which exist in production as well as debug.
#define STATS_COUNTER(name, delta) do { \
static StatsCounter counter(name); \
counter.Add(delta); \
} while (0)
#define SIMPLE_STATS_COUNTER(name) STATS_COUNTER(name, 1)
#define RATE_COUNTER(name, duration) do { \
static StatsRate hit_count(name); \
hit_count.AddTime(duration); \
} while (0)
// Define Debug vs non-debug flavors of macros.
#ifndef NDEBUG
#define DSTATS_COUNTER(name, delta) STATS_COUNTER(name, delta)
#define DSIMPLE_STATS_COUNTER(name) SIMPLE_STATS_COUNTER(name)
#define DRATE_COUNTER(name, duration) RATE_COUNTER(name, duration)
#else // NDEBUG
#define DSTATS_COUNTER(name, delta) do {} while (0)
#define DSIMPLE_STATS_COUNTER(name) do {} while (0)
#define DRATE_COUNTER(name, duration) do {} while (0)
#endif // NDEBUG
//------------------------------------------------------------------------------
// StatsCounter represents a counter in the StatsTable class.
class StatsCounter {
public:
// Create a StatsCounter object.
explicit StatsCounter(const std::string& name)
: counter_id_(-1) {
// We prepend the name with 'c:' to indicate that it is a counter.
name_ = "c:";
name_.append(name);
};
virtual ~StatsCounter() {}
// Sets the counter to a specific value.
void Set(int value) {
int* loc = GetPtr();
if (loc) *loc = value;
}
// Increments the counter.
void Increment() {
Add(1);
}
virtual void Add(int value) {
int* loc = GetPtr();
if (loc)
(*loc) += value;
}
// Decrements the counter.
void Decrement() {
Add(-1);
}
void Subtract(int value) {
Add(-value);
}
// Is this counter enabled?
// Returns false if table is full.
bool Enabled() {
return GetPtr() != NULL;
}
int value() {
int* loc = GetPtr();
if (loc) return *loc;
return 0;
}
protected:
StatsCounter()
: counter_id_(-1) {
}
// Returns the cached address of this counter location.
int* GetPtr() {
StatsTable* table = StatsTable::current();
if (!table)
return NULL;
// If counter_id_ is -1, then we haven't looked it up yet.
if (counter_id_ == -1) {
counter_id_ = table->FindCounter(name_);
if (table->GetSlot() == 0) {
if (!table->RegisterThread("")) {
// There is no room for this thread. This thread
// cannot use counters.
counter_id_ = 0;
return NULL;
}
}
}
// If counter_id_ is > 0, then we have a valid counter.
if (counter_id_ > 0)
return table->GetLocation(counter_id_, table->GetSlot());
// counter_id_ was zero, which means the table is full.
return NULL;
}
std::string name_;
// The counter id in the table. We initialize to -1 (an invalid value)
// and then cache it once it has been looked up. The counter_id is
// valid across all threads and processes.
int32_t counter_id_;
};
// A StatsCounterTimer is a StatsCounter which keeps a timer during
// the scope of the StatsCounterTimer. On destruction, it will record
// its time measurement.
class StatsCounterTimer : protected StatsCounter {
public:
// Constructs and starts the timer.
explicit StatsCounterTimer(const std::string& name) {
// we prepend the name with 't:' to indicate that it is a timer.
name_ = "t:";
name_.append(name);
}
// Start the timer.
void Start() {
if (!Enabled())
return;
start_time_ = base::TimeTicks::Now();
stop_time_ = base::TimeTicks();
}
// Stop the timer and record the results.
void Stop() {
if (!Enabled() || !Running())
return;
stop_time_ = base::TimeTicks::Now();
Record();
}
// Returns true if the timer is running.
bool Running() {
return Enabled() && !start_time_.is_null() && stop_time_.is_null();
}
// Accept a TimeDelta to increment.
virtual void AddTime(base::TimeDelta time) {
Add(static_cast<int>(time.InMilliseconds()));
}
protected:
// Compute the delta between start and stop, in milliseconds.
void Record() {
AddTime(stop_time_ - start_time_);
}
base::TimeTicks start_time_;
base::TimeTicks stop_time_;
};
// A StatsRate is a timer that keeps a count of the number of intervals added so
// that several statistics can be produced:
// min, max, avg, count, total
class StatsRate : public StatsCounterTimer {
public:
// Constructs and starts the timer.
explicit StatsRate(const char* name)
: StatsCounterTimer(name),
counter_(name),
largest_add_(std::string(" ").append(name).append("MAX").c_str()) {
}
virtual void Add(int value) {
counter_.Increment();
StatsCounterTimer::Add(value);
if (value > largest_add_.value())
largest_add_.Set(value);
}
private:
StatsCounter counter_;
StatsCounter largest_add_;
};
// Helper class for scoping a timer or rate.
template<class T> class StatsScope {
public:
explicit StatsScope<T>(T& timer)
: timer_(timer) {
timer_.Start();
}
~StatsScope() {
timer_.Stop();
}
void Stop() {
timer_.Stop();
}
private:
T& timer_;
};
#endif // BASE_STATS_COUNTERS_H__

View File

@ -1,559 +0,0 @@
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/stats_table.h"
#include "base/logging.h"
#include "base/platform_thread.h"
#include "base/process_util.h"
#include "base/scoped_ptr.h"
#include "base/shared_memory.h"
#include "base/string_piece.h"
#include "base/string_util.h"
#include "base/sys_string_conversions.h"
#include "base/thread_local_storage.h"
#if defined(OS_POSIX)
#include "errno.h"
#endif
// The StatsTable uses a shared memory segment that is laid out as follows
//
// +-------------------------------------------+
// | Version | Size | MaxCounters | MaxThreads |
// +-------------------------------------------+
// | Thread names table |
// +-------------------------------------------+
// | Thread TID table |
// +-------------------------------------------+
// | Thread PID table |
// +-------------------------------------------+
// | Counter names table |
// +-------------------------------------------+
// | Data |
// +-------------------------------------------+
//
// The data layout is a grid, where the columns are the thread_ids and the
// rows are the counter_ids.
//
// If the first character of the thread_name is '\0', then that column is
// empty.
// If the first character of the counter_name is '\0', then that row is
// empty.
//
// About Locking:
// This class is designed to be both multi-thread and multi-process safe.
// Aside from initialization, this is done by partitioning the data which
// each thread uses so that no locking is required. However, to allocate
// the rows and columns of the table to particular threads, locking is
// required.
//
// At the shared-memory level, we have a lock. This lock protects the
// shared-memory table only, and is used when we create new counters (e.g.
// use rows) or when we register new threads (e.g. use columns). Reading
// data from the table does not require any locking at the shared memory
// level.
//
// Each process which accesses the table will create a StatsTable object.
// The StatsTable maintains a hash table of the existing counters in the
// table for faster lookup. Since the hash table is process specific,
// each process maintains its own cache. We avoid complexity here by never
// de-allocating from the hash table. (Counters are dynamically added,
// but not dynamically removed).
// In order for external viewers to be able to read our shared memory,
// we all need to use the same size ints.
COMPILE_ASSERT(sizeof(int)==4, expect_4_byte_ints);
namespace {
// An internal version in case we ever change the format of this
// file, and so that we can identify our table.
const int kTableVersion = 0x13131313;
// The name for un-named counters and threads in the table.
const char kUnknownName[] = "<unknown>";
// Calculates delta to align an offset to the size of an int
inline int AlignOffset(int offset) {
return (sizeof(int) - (offset % sizeof(int))) % sizeof(int);
}
inline int AlignedSize(int size) {
return size + AlignOffset(size);
}
// StatsTableTLSData carries the data stored in the TLS slots for the
// StatsTable. This is used so that we can properly cleanup when the
// thread exits and return the table slot.
//
// Each thread that calls RegisterThread in the StatsTable will have
// a StatsTableTLSData stored in its TLS.
struct StatsTableTLSData {
StatsTable* table;
int slot;
};
} // namespace
// The StatsTablePrivate maintains convenience pointers into the
// shared memory segment. Use this class to keep the data structure
// clean and accessible.
class StatsTablePrivate {
public:
// Various header information contained in the memory mapped segment.
struct TableHeader {
int version;
int size;
int max_counters;
int max_threads;
};
// Construct a new StatsTablePrivate based on expected size parameters, or
// return NULL on failure.
static StatsTablePrivate* New(const std::string& name, int size,
int max_threads, int max_counters);
base::SharedMemory* shared_memory() { return &shared_memory_; }
// Accessors for our header pointers
TableHeader* table_header() const { return table_header_; }
int version() const { return table_header_->version; }
int size() const { return table_header_->size; }
int max_counters() const { return table_header_->max_counters; }
int max_threads() const { return table_header_->max_threads; }
// Accessors for our tables
char* thread_name(int slot_id) const {
return &thread_names_table_[
(slot_id-1) * (StatsTable::kMaxThreadNameLength)];
}
PlatformThreadId* thread_tid(int slot_id) const {
return &(thread_tid_table_[slot_id-1]);
}
int* thread_pid(int slot_id) const {
return &(thread_pid_table_[slot_id-1]);
}
char* counter_name(int counter_id) const {
return &counter_names_table_[
(counter_id-1) * (StatsTable::kMaxCounterNameLength)];
}
int* row(int counter_id) const {
return &data_table_[(counter_id-1) * max_threads()];
}
private:
// Constructor is private because you should use New() instead.
StatsTablePrivate() {}
// Initializes the table on first access. Sets header values
// appropriately and zeroes all counters.
void InitializeTable(void* memory, int size, int max_counters,
int max_threads);
// Initializes our in-memory pointers into a pre-created StatsTable.
void ComputeMappedPointers(void* memory);
base::SharedMemory shared_memory_;
TableHeader* table_header_;
char* thread_names_table_;
PlatformThreadId* thread_tid_table_;
int* thread_pid_table_;
char* counter_names_table_;
int* data_table_;
};
// static
StatsTablePrivate* StatsTablePrivate::New(const std::string& name,
int size,
int max_threads,
int max_counters) {
scoped_ptr<StatsTablePrivate> priv(new StatsTablePrivate());
if (!priv->shared_memory_.Create(name, false, true, size))
return NULL;
if (!priv->shared_memory_.Map(size))
return NULL;
void* memory = priv->shared_memory_.memory();
TableHeader* header = static_cast<TableHeader*>(memory);
// If the version does not match, then assume the table needs
// to be initialized.
if (header->version != kTableVersion)
priv->InitializeTable(memory, size, max_counters, max_threads);
// We have a valid table, so compute our pointers.
priv->ComputeMappedPointers(memory);
return priv.release();
}
void StatsTablePrivate::InitializeTable(void* memory, int size,
int max_counters,
int max_threads) {
// Zero everything.
memset(memory, 0, size);
// Initialize the header.
TableHeader* header = static_cast<TableHeader*>(memory);
header->version = kTableVersion;
header->size = size;
header->max_counters = max_counters;
header->max_threads = max_threads;
}
void StatsTablePrivate::ComputeMappedPointers(void* memory) {
char* data = static_cast<char*>(memory);
int offset = 0;
table_header_ = reinterpret_cast<TableHeader*>(data);
offset += sizeof(*table_header_);
offset += AlignOffset(offset);
// Verify we're looking at a valid StatsTable.
DCHECK_EQ(table_header_->version, kTableVersion);
thread_names_table_ = reinterpret_cast<char*>(data + offset);
offset += sizeof(char) *
max_threads() * StatsTable::kMaxThreadNameLength;
offset += AlignOffset(offset);
thread_tid_table_ = reinterpret_cast<PlatformThreadId*>(data + offset);
offset += sizeof(int) * max_threads();
offset += AlignOffset(offset);
thread_pid_table_ = reinterpret_cast<int*>(data + offset);
offset += sizeof(int) * max_threads();
offset += AlignOffset(offset);
counter_names_table_ = reinterpret_cast<char*>(data + offset);
offset += sizeof(char) *
max_counters() * StatsTable::kMaxCounterNameLength;
offset += AlignOffset(offset);
data_table_ = reinterpret_cast<int*>(data + offset);
offset += sizeof(int) * max_threads() * max_counters();
DCHECK_EQ(offset, size());
}
// We keep a singleton table which can be easily accessed.
StatsTable* StatsTable::global_table_ = NULL;
StatsTable::StatsTable(const std::string& name, int max_threads,
int max_counters)
: impl_(NULL),
tls_index_(SlotReturnFunction) {
int table_size =
AlignedSize(sizeof(StatsTablePrivate::TableHeader)) +
AlignedSize((max_counters * sizeof(char) * kMaxCounterNameLength)) +
AlignedSize((max_threads * sizeof(char) * kMaxThreadNameLength)) +
AlignedSize(max_threads * sizeof(int)) +
AlignedSize(max_threads * sizeof(int)) +
AlignedSize((sizeof(int) * (max_counters * max_threads)));
impl_ = StatsTablePrivate::New(name, table_size, max_threads, max_counters);
// TODO(port): clean up this error reporting.
#if defined(OS_WIN)
if (!impl_)
CHROMIUM_LOG(ERROR) << "StatsTable did not initialize:" << GetLastError();
#elif defined(OS_POSIX)
if (!impl_)
CHROMIUM_LOG(ERROR) << "StatsTable did not initialize:" << strerror(errno);
#endif
}
StatsTable::~StatsTable() {
// Before we tear down our copy of the table, be sure to
// unregister our thread.
UnregisterThread();
// Return ThreadLocalStorage. At this point, if any registered threads
// still exist, they cannot Unregister.
tls_index_.Free();
// Cleanup our shared memory.
delete impl_;
// If we are the global table, unregister ourselves.
if (global_table_ == this)
global_table_ = NULL;
}
int StatsTable::RegisterThread(const std::string& name) {
int slot = 0;
// Registering a thread requires that we lock the shared memory
// so that two threads don't grab the same slot. Fortunately,
// thread creation shouldn't happen in inner loops.
{
base::SharedMemoryAutoLock lock(impl_->shared_memory());
slot = FindEmptyThread();
if (!slot) {
return 0;
}
DCHECK(impl_);
// We have space, so consume a column in the table.
std::string thread_name = name;
if (name.empty())
thread_name = kUnknownName;
base::strlcpy(impl_->thread_name(slot), thread_name.c_str(),
kMaxThreadNameLength);
*(impl_->thread_tid(slot)) = PlatformThread::CurrentId();
*(impl_->thread_pid(slot)) = base::GetCurrentProcId();
}
// Set our thread local storage.
StatsTableTLSData* data = new StatsTableTLSData;
data->table = this;
data->slot = slot;
tls_index_.Set(data);
return slot;
}
StatsTableTLSData* StatsTable::GetTLSData() const {
StatsTableTLSData* data =
static_cast<StatsTableTLSData*>(tls_index_.Get());
if (!data)
return NULL;
DCHECK(data->slot);
DCHECK_EQ(data->table, this);
return data;
}
void StatsTable::UnregisterThread() {
UnregisterThread(GetTLSData());
}
void StatsTable::UnregisterThread(StatsTableTLSData* data) {
if (!data)
return;
DCHECK(impl_);
// Mark the slot free by zeroing out the thread name.
char* name = impl_->thread_name(data->slot);
*name = '\0';
// Remove the calling thread's TLS so that it cannot use the slot.
tls_index_.Set(NULL);
delete data;
}
void StatsTable::SlotReturnFunction(void* data) {
// This is called by the TLS destructor, which on some platforms has
// already cleared the TLS info, so use the tls_data argument
// rather than trying to fetch it ourselves.
StatsTableTLSData* tls_data = static_cast<StatsTableTLSData*>(data);
if (tls_data) {
DCHECK(tls_data->table);
tls_data->table->UnregisterThread(tls_data);
}
}
int StatsTable::CountThreadsRegistered() const {
if (!impl_)
return 0;
// Loop through the shared memory and count the threads that are active.
// We intentionally do not lock the table during the operation.
int count = 0;
for (int index = 1; index <= impl_->max_threads(); index++) {
char* name = impl_->thread_name(index);
if (*name != '\0')
count++;
}
return count;
}
int StatsTable::GetSlot() const {
StatsTableTLSData* data = GetTLSData();
if (!data)
return 0;
return data->slot;
}
int StatsTable::FindEmptyThread() const {
// Note: the API returns slots numbered from 1..N, although
// internally, the array is 0..N-1. This is so that we can return
// zero as "not found".
//
// The reason for doing this is because the thread 'slot' is stored
// in TLS, which is always initialized to zero, not -1. If 0 were
// returned as a valid slot number, it would be confused with the
// uninitialized state.
if (!impl_)
return 0;
int index = 1;
for (; index <= impl_->max_threads(); index++) {
char* name = impl_->thread_name(index);
if (!*name)
break;
}
if (index > impl_->max_threads())
return 0; // The table is full.
return index;
}
int StatsTable::FindCounterOrEmptyRow(const std::string& name) const {
// Note: the API returns slots numbered from 1..N, although
// internally, the array is 0..N-1. This is so that we can return
// zero as "not found".
//
// There isn't much reason for this other than to be consistent
// with the way we track columns for thread slots. (See comments
// in FindEmptyThread for why it is done this way).
if (!impl_)
return 0;
int free_slot = 0;
for (int index = 1; index <= impl_->max_counters(); index++) {
char* row_name = impl_->counter_name(index);
if (!*row_name && !free_slot)
free_slot = index; // save that we found a free slot
else if (!strncmp(row_name, name.c_str(), kMaxCounterNameLength))
return index;
}
return free_slot;
}
int StatsTable::FindCounter(const std::string& name) {
// Note: the API returns counters numbered from 1..N, although
// internally, the array is 0..N-1. This is so that we can return
// zero as "not found".
if (!impl_)
return 0;
// Create a scope for our auto-lock.
{
AutoLock scoped_lock(counters_lock_);
// Attempt to find the counter.
CountersMap::const_iterator iter;
iter = counters_.find(name);
if (iter != counters_.end())
return iter->second;
}
// Counter does not exist, so add it.
return AddCounter(name);
}
int StatsTable::AddCounter(const std::string& name) {
DCHECK(impl_);
if (!impl_)
return 0;
int counter_id = 0;
{
// To add a counter to the shared memory, we need the
// shared memory lock.
base::SharedMemoryAutoLock lock(impl_->shared_memory());
// We have space, so create a new counter.
counter_id = FindCounterOrEmptyRow(name);
if (!counter_id)
return 0;
std::string counter_name = name;
if (name.empty())
counter_name = kUnknownName;
base::strlcpy(impl_->counter_name(counter_id), counter_name.c_str(),
kMaxCounterNameLength);
}
// now add to our in-memory cache
{
AutoLock lock(counters_lock_);
counters_[name] = counter_id;
}
return counter_id;
}
int* StatsTable::GetLocation(int counter_id, int slot_id) const {
if (!impl_)
return NULL;
if (slot_id > impl_->max_threads())
return NULL;
int* row = impl_->row(counter_id);
return &(row[slot_id-1]);
}
const char* StatsTable::GetRowName(int index) const {
if (!impl_)
return NULL;
return impl_->counter_name(index);
}
int StatsTable::GetRowValue(int index, int pid) const {
if (!impl_)
return 0;
int rv = 0;
int* row = impl_->row(index);
for (int slot_id = 0; slot_id < impl_->max_threads(); slot_id++) {
if (pid == 0 || *impl_->thread_pid(slot_id) == pid)
rv += row[slot_id];
}
return rv;
}
int StatsTable::GetRowValue(int index) const {
return GetRowValue(index, 0);
}
int StatsTable::GetCounterValue(const std::string& name, int pid) {
if (!impl_)
return 0;
int row = FindCounter(name);
if (!row)
return 0;
return GetRowValue(row, pid);
}
int StatsTable::GetCounterValue(const std::string& name) {
return GetCounterValue(name, 0);
}
int StatsTable::GetMaxCounters() const {
if (!impl_)
return 0;
return impl_->max_counters();
}
int StatsTable::GetMaxThreads() const {
if (!impl_)
return 0;
return impl_->max_threads();
}
int* StatsTable::FindLocation(const char* name) {
// Get the static StatsTable
StatsTable *table = StatsTable::current();
if (!table)
return NULL;
// Get the slot for this thread. Try to register
// it if none exists.
int slot = table->GetSlot();
if (!slot && !(slot = table->RegisterThread("")))
return NULL;
// Find the counter id for the counter.
std::string str_name(name);
int counter = table->FindCounter(str_name);
// Now we can find the location in the table.
return table->GetLocation(counter, slot);
}

View File

@ -1,191 +0,0 @@
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// A StatsTable is a table of statistics. It can be used across multiple
// processes and threads, maintaining cheap statistics counters without
// locking.
//
// The goal is to make it very cheap and easy for developers to add
// counters to code, without having to build one-off utilities or mechanisms
// to track the counters, and also to allow a single "view" to display
// the contents of all counters.
//
// To achieve this, StatsTable creates a shared memory segment to store
// the data for the counters. Upon creation, it has a specific size
// which governs the maximum number of counters and concurrent
// threads/processes which can use it.
//
#ifndef BASE_STATS_TABLE_H__
#define BASE_STATS_TABLE_H__
#include <string>
#include "base/basictypes.h"
#include "base/hash_tables.h"
#include "base/lock.h"
#include "base/thread_local_storage.h"
class StatsTablePrivate;
namespace {
struct StatsTableTLSData;
}
class StatsTable {
public:
// Create a new StatsTable.
// If a StatsTable already exists with the specified name, this StatsTable
// will use the same shared memory segment as the original. Otherwise,
// a new StatsTable is created and all counters are zeroed.
//
// name is the name of the StatsTable to use.
//
// max_threads is the maximum number of threads the table will support.
// If the StatsTable already exists, this number is ignored.
//
// max_counters is the maximum number of counters the table will support.
// If the StatsTable already exists, this number is ignored.
StatsTable(const std::string& name, int max_threads, int max_counters);
// Destroys the StatsTable. When the last StatsTable is destroyed
// (across all processes), the StatsTable is removed from disk.
~StatsTable();
// For convenience, we create a static table. This is generally
// used automatically by the counters.
static StatsTable* current() { return global_table_; }
// Set the global table for use in this process.
static void set_current(StatsTable* value) { global_table_ = value; }
// Get the slot id for the calling thread. Returns 0 if no
// slot is assigned.
int GetSlot() const;
// All threads that contribute data to the table must register with the
// table first. This function will set thread local storage for the
// thread containing the location in the table where this thread will
// write its counter data.
//
// name is just a debugging tag to label the thread, and it does not
// need to be unique. It will be truncated to kMaxThreadNameLength-1
// characters.
//
// On success, returns the slot id for this thread. On failure,
// returns 0.
int RegisterThread(const std::string& name);
// Returns the number of threads currently registered. This is really not
// useful except for diagnostics and debugging.
int CountThreadsRegistered() const;
// Find a counter in the StatsTable.
//
// Returns an id for the counter which can be used to call GetLocation().
// If the counter does not exist, attempts to create a row for the new
// counter. If there is no space in the table for the new counter,
// returns 0.
int FindCounter(const std::string& name);
// TODO(mbelshe): implement RemoveCounter.
// Gets the location of a particular value in the table based on
// the counter id and slot id.
int* GetLocation(int counter_id, int slot_id) const;
// Gets the counter name at a particular row. If the row is empty,
// returns NULL.
const char* GetRowName(int index) const;
// Gets the sum of the values for a particular row.
int GetRowValue(int index) const;
// Gets the sum of the values for a particular row for a given pid.
int GetRowValue(int index, int pid) const;
// Gets the sum of the values for a particular counter. If the counter
// does not exist, creates the counter.
int GetCounterValue(const std::string& name);
// Gets the sum of the values for a particular counter for a given pid.
// If the counter does not exist, creates the counter.
int GetCounterValue(const std::string& name, int pid);
// The maxinum number of counters/rows in the table.
int GetMaxCounters() const;
// The maxinum number of threads/columns in the table.
int GetMaxThreads() const;
// The maximum length (in characters) of a Thread's name including
// null terminator, as stored in the shared memory.
static const int kMaxThreadNameLength = 32;
// The maximum length (in characters) of a Counter's name including
// null terminator, as stored in the shared memory.
static const int kMaxCounterNameLength = 32;
// Convenience function to lookup a counter location for a
// counter by name for the calling thread. Will register
// the thread if it is not already registered.
static int* FindLocation(const char *name);
private:
// Returns the space occupied by a thread in the table. Generally used
// if a thread terminates but the process continues. This function
// does not zero out the thread's counters.
// Cannot be used inside a posix tls destructor.
void UnregisterThread();
// This variant expects the tls data to be passed in, so it is safe to
// call from inside a posix tls destructor (see doc for pthread_key_create).
void UnregisterThread(StatsTableTLSData* tls_data);
// The SlotReturnFunction is called at thread exit for each thread
// which used the StatsTable.
static void SlotReturnFunction(void* data);
// Locates a free slot in the table. Returns a number > 0 on success,
// or 0 on failure. The caller must hold the shared_memory lock when
// calling this function.
int FindEmptyThread() const;
// Locates a counter in the table or finds an empty row. Returns a
// number > 0 on success, or 0 on failure. The caller must hold the
// shared_memory_lock when calling this function.
int FindCounterOrEmptyRow(const std::string& name) const;
// Internal function to add a counter to the StatsTable. Assumes that
// the counter does not already exist in the table.
//
// name is a unique identifier for this counter, and will be truncated
// to kMaxCounterNameLength-1 characters.
//
// On success, returns the counter_id for the newly added counter.
// On failure, returns 0.
int AddCounter(const std::string& name);
// Get the TLS data for the calling thread. Returns NULL if none is
// initialized.
StatsTableTLSData* GetTLSData() const;
typedef base::hash_map<std::string, int> CountersMap;
StatsTablePrivate* impl_;
// The counters_lock_ protects the counters_ hash table.
Lock counters_lock_;
// The counters_ hash map is an in-memory hash of the counters.
// It is used for quick lookup of counters, but is cannot be used
// as a substitute for what is in the shared memory. Even though
// we don't have a counter in our hash table, another process may
// have created it.
CountersMap counters_;
TLSSlot tls_index_;
static StatsTable* global_table_;
DISALLOW_EVIL_CONSTRUCTORS(StatsTable);
};
#endif // BASE_STATS_TABLE_H__

View File

@ -25,7 +25,6 @@
#include "base/scoped_ptr.h"
#include "base/string_util.h"
#include "base/singleton.h"
#include "base/stats_counters.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/file_descriptor_set_posix.h"
#include "chrome/common/ipc_logging.h"

View File

@ -10,7 +10,6 @@
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/non_thread_safe.h"
#include "base/stats_counters.h"
#include "base/win_util.h"
#include "chrome/common/ipc_logging.h"
#include "chrome/common/ipc_message_utils.h"