1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/base/stats_table.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,191 @@ 1.4 +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 +// 1.8 +// A StatsTable is a table of statistics. It can be used across multiple 1.9 +// processes and threads, maintaining cheap statistics counters without 1.10 +// locking. 1.11 +// 1.12 +// The goal is to make it very cheap and easy for developers to add 1.13 +// counters to code, without having to build one-off utilities or mechanisms 1.14 +// to track the counters, and also to allow a single "view" to display 1.15 +// the contents of all counters. 1.16 +// 1.17 +// To achieve this, StatsTable creates a shared memory segment to store 1.18 +// the data for the counters. Upon creation, it has a specific size 1.19 +// which governs the maximum number of counters and concurrent 1.20 +// threads/processes which can use it. 1.21 +// 1.22 + 1.23 +#ifndef BASE_STATS_TABLE_H__ 1.24 +#define BASE_STATS_TABLE_H__ 1.25 + 1.26 +#include <string> 1.27 +#include "base/basictypes.h" 1.28 +#include "base/hash_tables.h" 1.29 +#include "base/lock.h" 1.30 +#include "base/thread_local_storage.h" 1.31 + 1.32 +class StatsTablePrivate; 1.33 + 1.34 +namespace { 1.35 +struct StatsTableTLSData; 1.36 +} 1.37 + 1.38 +class StatsTable { 1.39 + public: 1.40 + // Create a new StatsTable. 1.41 + // If a StatsTable already exists with the specified name, this StatsTable 1.42 + // will use the same shared memory segment as the original. Otherwise, 1.43 + // a new StatsTable is created and all counters are zeroed. 1.44 + // 1.45 + // name is the name of the StatsTable to use. 1.46 + // 1.47 + // max_threads is the maximum number of threads the table will support. 1.48 + // If the StatsTable already exists, this number is ignored. 1.49 + // 1.50 + // max_counters is the maximum number of counters the table will support. 1.51 + // If the StatsTable already exists, this number is ignored. 1.52 + StatsTable(const std::string& name, int max_threads, int max_counters); 1.53 + 1.54 + // Destroys the StatsTable. When the last StatsTable is destroyed 1.55 + // (across all processes), the StatsTable is removed from disk. 1.56 + ~StatsTable(); 1.57 + 1.58 + // For convenience, we create a static table. This is generally 1.59 + // used automatically by the counters. 1.60 + static StatsTable* current() { return global_table_; } 1.61 + 1.62 + // Set the global table for use in this process. 1.63 + static void set_current(StatsTable* value) { global_table_ = value; } 1.64 + 1.65 + // Get the slot id for the calling thread. Returns 0 if no 1.66 + // slot is assigned. 1.67 + int GetSlot() const; 1.68 + 1.69 + // All threads that contribute data to the table must register with the 1.70 + // table first. This function will set thread local storage for the 1.71 + // thread containing the location in the table where this thread will 1.72 + // write its counter data. 1.73 + // 1.74 + // name is just a debugging tag to label the thread, and it does not 1.75 + // need to be unique. It will be truncated to kMaxThreadNameLength-1 1.76 + // characters. 1.77 + // 1.78 + // On success, returns the slot id for this thread. On failure, 1.79 + // returns 0. 1.80 + int RegisterThread(const std::string& name); 1.81 + 1.82 + // Returns the number of threads currently registered. This is really not 1.83 + // useful except for diagnostics and debugging. 1.84 + int CountThreadsRegistered() const; 1.85 + 1.86 + // Find a counter in the StatsTable. 1.87 + // 1.88 + // Returns an id for the counter which can be used to call GetLocation(). 1.89 + // If the counter does not exist, attempts to create a row for the new 1.90 + // counter. If there is no space in the table for the new counter, 1.91 + // returns 0. 1.92 + int FindCounter(const std::string& name); 1.93 + 1.94 + // TODO(mbelshe): implement RemoveCounter. 1.95 + 1.96 + // Gets the location of a particular value in the table based on 1.97 + // the counter id and slot id. 1.98 + int* GetLocation(int counter_id, int slot_id) const; 1.99 + 1.100 + // Gets the counter name at a particular row. If the row is empty, 1.101 + // returns NULL. 1.102 + const char* GetRowName(int index) const; 1.103 + 1.104 + // Gets the sum of the values for a particular row. 1.105 + int GetRowValue(int index) const; 1.106 + 1.107 + // Gets the sum of the values for a particular row for a given pid. 1.108 + int GetRowValue(int index, int pid) const; 1.109 + 1.110 + // Gets the sum of the values for a particular counter. If the counter 1.111 + // does not exist, creates the counter. 1.112 + int GetCounterValue(const std::string& name); 1.113 + 1.114 + // Gets the sum of the values for a particular counter for a given pid. 1.115 + // If the counter does not exist, creates the counter. 1.116 + int GetCounterValue(const std::string& name, int pid); 1.117 + 1.118 + // The maxinum number of counters/rows in the table. 1.119 + int GetMaxCounters() const; 1.120 + 1.121 + // The maxinum number of threads/columns in the table. 1.122 + int GetMaxThreads() const; 1.123 + 1.124 + // The maximum length (in characters) of a Thread's name including 1.125 + // null terminator, as stored in the shared memory. 1.126 + static const int kMaxThreadNameLength = 32; 1.127 + 1.128 + // The maximum length (in characters) of a Counter's name including 1.129 + // null terminator, as stored in the shared memory. 1.130 + static const int kMaxCounterNameLength = 32; 1.131 + 1.132 + // Convenience function to lookup a counter location for a 1.133 + // counter by name for the calling thread. Will register 1.134 + // the thread if it is not already registered. 1.135 + static int* FindLocation(const char *name); 1.136 + 1.137 + private: 1.138 + // Returns the space occupied by a thread in the table. Generally used 1.139 + // if a thread terminates but the process continues. This function 1.140 + // does not zero out the thread's counters. 1.141 + // Cannot be used inside a posix tls destructor. 1.142 + void UnregisterThread(); 1.143 + 1.144 + // This variant expects the tls data to be passed in, so it is safe to 1.145 + // call from inside a posix tls destructor (see doc for pthread_key_create). 1.146 + void UnregisterThread(StatsTableTLSData* tls_data); 1.147 + 1.148 + // The SlotReturnFunction is called at thread exit for each thread 1.149 + // which used the StatsTable. 1.150 + static void SlotReturnFunction(void* data); 1.151 + 1.152 + // Locates a free slot in the table. Returns a number > 0 on success, 1.153 + // or 0 on failure. The caller must hold the shared_memory lock when 1.154 + // calling this function. 1.155 + int FindEmptyThread() const; 1.156 + 1.157 + // Locates a counter in the table or finds an empty row. Returns a 1.158 + // number > 0 on success, or 0 on failure. The caller must hold the 1.159 + // shared_memory_lock when calling this function. 1.160 + int FindCounterOrEmptyRow(const std::string& name) const; 1.161 + 1.162 + // Internal function to add a counter to the StatsTable. Assumes that 1.163 + // the counter does not already exist in the table. 1.164 + // 1.165 + // name is a unique identifier for this counter, and will be truncated 1.166 + // to kMaxCounterNameLength-1 characters. 1.167 + // 1.168 + // On success, returns the counter_id for the newly added counter. 1.169 + // On failure, returns 0. 1.170 + int AddCounter(const std::string& name); 1.171 + 1.172 + // Get the TLS data for the calling thread. Returns NULL if none is 1.173 + // initialized. 1.174 + StatsTableTLSData* GetTLSData() const; 1.175 + 1.176 + typedef base::hash_map<std::string, int> CountersMap; 1.177 + 1.178 + StatsTablePrivate* impl_; 1.179 + // The counters_lock_ protects the counters_ hash table. 1.180 + Lock counters_lock_; 1.181 + // The counters_ hash map is an in-memory hash of the counters. 1.182 + // It is used for quick lookup of counters, but is cannot be used 1.183 + // as a substitute for what is in the shared memory. Even though 1.184 + // we don't have a counter in our hash table, another process may 1.185 + // have created it. 1.186 + CountersMap counters_; 1.187 + TLSSlot tls_index_; 1.188 + 1.189 + static StatsTable* global_table_; 1.190 + 1.191 + DISALLOW_EVIL_CONSTRUCTORS(StatsTable); 1.192 +}; 1.193 + 1.194 +#endif // BASE_STATS_TABLE_H__