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 |