| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 // | 4 // |
| 5 // A StatsTable is a table of statistics. It can be used across multiple | 5 // A StatsTable is a table of statistics. It can be used across multiple |
| 6 // processes and threads, maintaining cheap statistics counters without | 6 // processes and threads, maintaining cheap statistics counters without |
| 7 // locking. | 7 // locking. |
| 8 // | 8 // |
| 9 // The goal is to make it very cheap and easy for developers to add | 9 // The goal is to make it very cheap and easy for developers to add |
| 10 // counters to code, without having to build one-off utilities or mechanisms | 10 // counters to code, without having to build one-off utilities or mechanisms |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 // will use the same shared memory segment as the original. Otherwise, | 39 // will use the same shared memory segment as the original. Otherwise, |
| 40 // a new StatsTable is created and all counters are zeroed. | 40 // a new StatsTable is created and all counters are zeroed. |
| 41 // | 41 // |
| 42 // name is the name of the StatsTable to use. | 42 // name is the name of the StatsTable to use. |
| 43 // | 43 // |
| 44 // max_threads is the maximum number of threads the table will support. | 44 // max_threads is the maximum number of threads the table will support. |
| 45 // If the StatsTable already exists, this number is ignored. | 45 // If the StatsTable already exists, this number is ignored. |
| 46 // | 46 // |
| 47 // max_counters is the maximum number of counters the table will support. | 47 // max_counters is the maximum number of counters the table will support. |
| 48 // If the StatsTable already exists, this number is ignored. | 48 // If the StatsTable already exists, this number is ignored. |
| 49 StatsTable(const std::wstring& name, int max_threads, int max_counters); | 49 StatsTable(const std::string& name, int max_threads, int max_counters); |
| 50 | 50 |
| 51 // Destroys the StatsTable. When the last StatsTable is destroyed | 51 // Destroys the StatsTable. When the last StatsTable is destroyed |
| 52 // (across all processes), the StatsTable is removed from disk. | 52 // (across all processes), the StatsTable is removed from disk. |
| 53 ~StatsTable(); | 53 ~StatsTable(); |
| 54 | 54 |
| 55 // For convenience, we create a static table. This is generally | 55 // For convenience, we create a static table. This is generally |
| 56 // used automatically by the counters. | 56 // used automatically by the counters. |
| 57 static StatsTable* current() { return global_table_; } | 57 static StatsTable* current() { return global_table_; } |
| 58 | 58 |
| 59 // Set the global table for use in this process. | 59 // Set the global table for use in this process. |
| 60 static void set_current(StatsTable* value) { global_table_ = value; } | 60 static void set_current(StatsTable* value) { global_table_ = value; } |
| 61 | 61 |
| 62 // Get the slot id for the calling thread. Returns 0 if no | 62 // Get the slot id for the calling thread. Returns 0 if no |
| 63 // slot is assigned. | 63 // slot is assigned. |
| 64 int GetSlot() const; | 64 int GetSlot() const; |
| 65 | 65 |
| 66 // All threads that contribute data to the table must register with the | 66 // All threads that contribute data to the table must register with the |
| 67 // table first. This function will set thread local storage for the | 67 // table first. This function will set thread local storage for the |
| 68 // thread containing the location in the table where this thread will | 68 // thread containing the location in the table where this thread will |
| 69 // write its counter data. | 69 // write its counter data. |
| 70 // | 70 // |
| 71 // name is just a debugging tag to label the thread, and it does not | 71 // name is just a debugging tag to label the thread, and it does not |
| 72 // need to be unique. It will be truncated to kMaxThreadNameLength-1 | 72 // need to be unique. It will be truncated to kMaxThreadNameLength-1 |
| 73 // characters. | 73 // characters. |
| 74 // | 74 // |
| 75 // On success, returns the slot id for this thread. On failure, | 75 // On success, returns the slot id for this thread. On failure, |
| 76 // returns 0. | 76 // returns 0. |
| 77 int RegisterThread(const std::wstring& name); | 77 int RegisterThread(const std::string& name); |
| 78 | 78 |
| 79 // Returns the number of threads currently registered. This is really not | 79 // Returns the number of threads currently registered. This is really not |
| 80 // useful except for diagnostics and debugging. | 80 // useful except for diagnostics and debugging. |
| 81 int CountThreadsRegistered() const; | 81 int CountThreadsRegistered() const; |
| 82 | 82 |
| 83 // Find a counter in the StatsTable. | 83 // Find a counter in the StatsTable. |
| 84 // | 84 // |
| 85 // Returns an id for the counter which can be used to call GetLocation(). | 85 // Returns an id for the counter which can be used to call GetLocation(). |
| 86 // If the counter does not exist, attempts to create a row for the new | 86 // If the counter does not exist, attempts to create a row for the new |
| 87 // counter. If there is no space in the table for the new counter, | 87 // counter. If there is no space in the table for the new counter, |
| 88 // returns 0. | 88 // returns 0. |
| 89 int FindCounter(const std::wstring& name); | 89 int FindCounter(const std::string& name); |
| 90 | 90 |
| 91 // TODO(mbelshe): implement RemoveCounter. | 91 // TODO(mbelshe): implement RemoveCounter. |
| 92 | 92 |
| 93 // Gets the location of a particular value in the table based on | 93 // Gets the location of a particular value in the table based on |
| 94 // the counter id and slot id. | 94 // the counter id and slot id. |
| 95 int* GetLocation(int counter_id, int slot_id) const; | 95 int* GetLocation(int counter_id, int slot_id) const; |
| 96 | 96 |
| 97 // Gets the counter name at a particular row. If the row is empty, | 97 // Gets the counter name at a particular row. If the row is empty, |
| 98 // returns NULL. | 98 // returns NULL. |
| 99 const wchar_t* GetRowName(int index) const; | 99 const char* GetRowName(int index) const; |
| 100 | 100 |
| 101 // Gets the sum of the values for a particular row. | 101 // Gets the sum of the values for a particular row. |
| 102 int GetRowValue(int index) const; | 102 int GetRowValue(int index) const; |
| 103 | 103 |
| 104 // Gets the sum of the values for a particular row for a given pid. | 104 // Gets the sum of the values for a particular row for a given pid. |
| 105 int GetRowValue(int index, int pid) const; | 105 int GetRowValue(int index, int pid) const; |
| 106 | 106 |
| 107 // Gets the sum of the values for a particular counter. If the counter | 107 // Gets the sum of the values for a particular counter. If the counter |
| 108 // does not exist, creates the counter. | 108 // does not exist, creates the counter. |
| 109 int GetCounterValue(const std::wstring& name); | 109 int GetCounterValue(const std::string& name); |
| 110 | 110 |
| 111 // Gets the sum of the values for a particular counter for a given pid. | 111 // Gets the sum of the values for a particular counter for a given pid. |
| 112 // If the counter does not exist, creates the counter. | 112 // If the counter does not exist, creates the counter. |
| 113 int GetCounterValue(const std::wstring& name, int pid); | 113 int GetCounterValue(const std::string& name, int pid); |
| 114 | 114 |
| 115 // The maxinum number of counters/rows in the table. | 115 // The maxinum number of counters/rows in the table. |
| 116 int GetMaxCounters() const; | 116 int GetMaxCounters() const; |
| 117 | 117 |
| 118 // The maxinum number of threads/columns in the table. | 118 // The maxinum number of threads/columns in the table. |
| 119 int GetMaxThreads() const; | 119 int GetMaxThreads() const; |
| 120 | 120 |
| 121 // The maximum length (in characters) of a Thread's name including | 121 // The maximum length (in characters) of a Thread's name including |
| 122 // null terminator, as stored in the shared memory. | 122 // null terminator, as stored in the shared memory. |
| 123 static const int kMaxThreadNameLength = 32; | 123 static const int kMaxThreadNameLength = 32; |
| 124 | 124 |
| 125 // The maximum length (in characters) of a Counter's name including | 125 // The maximum length (in characters) of a Counter's name including |
| 126 // null terminator, as stored in the shared memory. | 126 // null terminator, as stored in the shared memory. |
| 127 static const int kMaxCounterNameLength = 32; | 127 static const int kMaxCounterNameLength = 32; |
| 128 | 128 |
| 129 // Convenience function to lookup a counter location for a | 129 // Convenience function to lookup a counter location for a |
| 130 // counter by name for the calling thread. Will register | 130 // counter by name for the calling thread. Will register |
| 131 // the thread if it is not already registered. | 131 // the thread if it is not already registered. |
| 132 static int* FindLocation(const wchar_t *name); | 132 static int* FindLocation(const char *name); |
| 133 | 133 |
| 134 private: | 134 private: |
| 135 // Returns the space occupied by a thread in the table. Generally used | 135 // Returns the space occupied by a thread in the table. Generally used |
| 136 // if a thread terminates but the process continues. This function | 136 // if a thread terminates but the process continues. This function |
| 137 // does not zero out the thread's counters. | 137 // does not zero out the thread's counters. |
| 138 // Cannot be used inside a posix tls destructor. | 138 // Cannot be used inside a posix tls destructor. |
| 139 void UnregisterThread(); | 139 void UnregisterThread(); |
| 140 | 140 |
| 141 // This variant expects the tls data to be passed in, so it is safe to | 141 // This variant expects the tls data to be passed in, so it is safe to |
| 142 // call from inside a posix tls destructor (see doc for pthread_key_create). | 142 // call from inside a posix tls destructor (see doc for pthread_key_create). |
| 143 void UnregisterThread(StatsTableTLSData* tls_data); | 143 void UnregisterThread(StatsTableTLSData* tls_data); |
| 144 | 144 |
| 145 // The SlotReturnFunction is called at thread exit for each thread | 145 // The SlotReturnFunction is called at thread exit for each thread |
| 146 // which used the StatsTable. | 146 // which used the StatsTable. |
| 147 static void SlotReturnFunction(void* data); | 147 static void SlotReturnFunction(void* data); |
| 148 | 148 |
| 149 // Locates a free slot in the table. Returns a number > 0 on success, | 149 // Locates a free slot in the table. Returns a number > 0 on success, |
| 150 // or 0 on failure. The caller must hold the shared_memory lock when | 150 // or 0 on failure. The caller must hold the shared_memory lock when |
| 151 // calling this function. | 151 // calling this function. |
| 152 int FindEmptyThread() const; | 152 int FindEmptyThread() const; |
| 153 | 153 |
| 154 // Locates a counter in the table or finds an empty row. Returns a | 154 // Locates a counter in the table or finds an empty row. Returns a |
| 155 // number > 0 on success, or 0 on failure. The caller must hold the | 155 // number > 0 on success, or 0 on failure. The caller must hold the |
| 156 // shared_memory_lock when calling this function. | 156 // shared_memory_lock when calling this function. |
| 157 int FindCounterOrEmptyRow(const std::wstring& name) const; | 157 int FindCounterOrEmptyRow(const std::string& name) const; |
| 158 | 158 |
| 159 // Internal function to add a counter to the StatsTable. Assumes that | 159 // Internal function to add a counter to the StatsTable. Assumes that |
| 160 // the counter does not already exist in the table. | 160 // the counter does not already exist in the table. |
| 161 // | 161 // |
| 162 // name is a unique identifier for this counter, and will be truncated | 162 // name is a unique identifier for this counter, and will be truncated |
| 163 // to kMaxCounterNameLength-1 characters. | 163 // to kMaxCounterNameLength-1 characters. |
| 164 // | 164 // |
| 165 // On success, returns the counter_id for the newly added counter. | 165 // On success, returns the counter_id for the newly added counter. |
| 166 // On failure, returns 0. | 166 // On failure, returns 0. |
| 167 int AddCounter(const std::wstring& name); | 167 int AddCounter(const std::string& name); |
| 168 | 168 |
| 169 // Get the TLS data for the calling thread. Returns NULL if none is | 169 // Get the TLS data for the calling thread. Returns NULL if none is |
| 170 // initialized. | 170 // initialized. |
| 171 StatsTableTLSData* GetTLSData() const; | 171 StatsTableTLSData* GetTLSData() const; |
| 172 | 172 |
| 173 typedef base::hash_map<std::wstring, int> CountersMap; | 173 typedef base::hash_map<std::string, int> CountersMap; |
| 174 | 174 |
| 175 bool opened_; | 175 bool opened_; |
| 176 StatsTablePrivate* impl_; | 176 StatsTablePrivate* impl_; |
| 177 // The counters_lock_ protects the counters_ hash table. | 177 // The counters_lock_ protects the counters_ hash table. |
| 178 Lock counters_lock_; | 178 Lock counters_lock_; |
| 179 // The counters_ hash map is an in-memory hash of the counters. | 179 // The counters_ hash map is an in-memory hash of the counters. |
| 180 // It is used for quick lookup of counters, but is cannot be used | 180 // It is used for quick lookup of counters, but is cannot be used |
| 181 // as a substitute for what is in the shared memory. Even though | 181 // as a substitute for what is in the shared memory. Even though |
| 182 // we don't have a counter in our hash table, another process may | 182 // we don't have a counter in our hash table, another process may |
| 183 // have created it. | 183 // have created it. |
| 184 CountersMap counters_; | 184 CountersMap counters_; |
| 185 TLSSlot tls_index_; | 185 TLSSlot tls_index_; |
| 186 | 186 |
| 187 static StatsTable* global_table_; | 187 static StatsTable* global_table_; |
| 188 DISALLOW_EVIL_CONSTRUCTORS(StatsTable); | 188 DISALLOW_EVIL_CONSTRUCTORS(StatsTable); |
| 189 }; | 189 }; |
| 190 | 190 |
| 191 #endif // BASE_STATS_TABLE_H__ | 191 #endif // BASE_STATS_TABLE_H__ |
| OLD | NEW |