OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #include "base/metrics/stats_table.h" | 5 #include "base/metrics/stats_table.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/memory/shared_memory.h" | 9 #include "base/memory/shared_memory.h" |
10 #include "base/process/process_handle.h" | 10 #include "base/process/process_handle.h" |
11 #include "base/strings/string_piece.h" | 11 #include "base/strings/string_piece.h" |
12 #include "base/strings/string_util.h" | 12 #include "base/strings/string_util.h" |
13 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
14 #include "base/threading/platform_thread.h" | 14 #include "base/threading/platform_thread.h" |
15 #include "base/threading/thread_local_storage.h" | 15 #include "base/threading/thread_local_storage.h" |
16 | 16 |
17 #if defined(OS_POSIX) | 17 #if defined(OS_POSIX) |
18 #include "base/posix/global_descriptors.h" | |
18 #include "errno.h" | 19 #include "errno.h" |
20 #include "ipc/ipc_descriptors.h" | |
19 #endif | 21 #endif |
20 | 22 |
21 namespace base { | 23 namespace base { |
22 | 24 |
23 // The StatsTable uses a shared memory segment that is laid out as follows | 25 // The StatsTable uses a shared memory segment that is laid out as follows |
24 // | 26 // |
25 // +-------------------------------------------+ | 27 // +-------------------------------------------+ |
26 // | Version | Size | MaxCounters | MaxThreads | | 28 // | Version | Size | MaxCounters | MaxThreads | |
27 // +-------------------------------------------+ | 29 // +-------------------------------------------+ |
28 // | Thread names table | | 30 // | Thread names table | |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
99 int size; | 101 int size; |
100 int max_counters; | 102 int max_counters; |
101 int max_threads; | 103 int max_threads; |
102 }; | 104 }; |
103 | 105 |
104 // Construct a new Private based on expected size parameters, or | 106 // Construct a new Private based on expected size parameters, or |
105 // return NULL on failure. | 107 // return NULL on failure. |
106 static Private* New(const std::string& name, int size, | 108 static Private* New(const std::string& name, int size, |
107 int max_threads, int max_counters); | 109 int max_threads, int max_counters); |
108 | 110 |
109 SharedMemory* shared_memory() { return &shared_memory_; } | 111 SharedMemory* shared_memory() { return shared_memory_.get(); } |
110 | 112 |
111 // Accessors for our header pointers | 113 // Accessors for our header pointers |
112 TableHeader* table_header() const { return table_header_; } | 114 TableHeader* table_header() const { return table_header_; } |
113 int version() const { return table_header_->version; } | 115 int version() const { return table_header_->version; } |
114 int size() const { return table_header_->size; } | 116 int size() const { return table_header_->size; } |
115 int max_counters() const { return table_header_->max_counters; } | 117 int max_counters() const { return table_header_->max_counters; } |
116 int max_threads() const { return table_header_->max_threads; } | 118 int max_threads() const { return table_header_->max_threads; } |
117 | 119 |
118 // Accessors for our tables | 120 // Accessors for our tables |
119 char* thread_name(int slot_id) const { | 121 char* thread_name(int slot_id) const { |
120 return &thread_names_table_[ | 122 return &thread_names_table_[ |
121 (slot_id-1) * (StatsTable::kMaxThreadNameLength)]; | 123 (slot_id-1) * (StatsTable::kMaxThreadNameLength)]; |
122 } | 124 } |
123 PlatformThreadId* thread_tid(int slot_id) const { | 125 PlatformThreadId* thread_tid(int slot_id) const { |
124 return &(thread_tid_table_[slot_id-1]); | 126 return &(thread_tid_table_[slot_id-1]); |
125 } | 127 } |
126 int* thread_pid(int slot_id) const { | 128 int* thread_pid(int slot_id) const { |
127 return &(thread_pid_table_[slot_id-1]); | 129 return &(thread_pid_table_[slot_id-1]); |
128 } | 130 } |
129 char* counter_name(int counter_id) const { | 131 char* counter_name(int counter_id) const { |
130 return &counter_names_table_[ | 132 return &counter_names_table_[ |
131 (counter_id-1) * (StatsTable::kMaxCounterNameLength)]; | 133 (counter_id-1) * (StatsTable::kMaxCounterNameLength)]; |
132 } | 134 } |
133 int* row(int counter_id) const { | 135 int* row(int counter_id) const { |
134 return &data_table_[(counter_id-1) * max_threads()]; | 136 return &data_table_[(counter_id-1) * max_threads()]; |
135 } | 137 } |
136 | 138 |
137 private: | 139 private: |
138 // Constructor is private because you should use New() instead. | 140 // Constructor is private because you should use New() instead. |
139 Private() | 141 Private(SharedMemory* shared_memory) |
jar (doing other things)
2013/08/21 01:09:46
nit: explicit
rmcilroy
2013/08/21 10:37:16
Done.
| |
140 : table_header_(NULL), | 142 : shared_memory_(shared_memory), |
143 table_header_(NULL), | |
141 thread_names_table_(NULL), | 144 thread_names_table_(NULL), |
142 thread_tid_table_(NULL), | 145 thread_tid_table_(NULL), |
143 thread_pid_table_(NULL), | 146 thread_pid_table_(NULL), |
144 counter_names_table_(NULL), | 147 counter_names_table_(NULL), |
145 data_table_(NULL) { | 148 data_table_(NULL) { |
146 } | 149 } |
147 | 150 |
151 // Create or open the SharedMemory used by the stats table. | |
152 static SharedMemory* CreateSharedMemory(int size); | |
153 | |
148 // Initializes the table on first access. Sets header values | 154 // Initializes the table on first access. Sets header values |
149 // appropriately and zeroes all counters. | 155 // appropriately and zeroes all counters. |
150 void InitializeTable(void* memory, int size, int max_counters, | 156 void InitializeTable(void* memory, int size, int max_counters, |
151 int max_threads); | 157 int max_threads); |
152 | 158 |
153 // Initializes our in-memory pointers into a pre-created StatsTable. | 159 // Initializes our in-memory pointers into a pre-created StatsTable. |
154 void ComputeMappedPointers(void* memory); | 160 void ComputeMappedPointers(void* memory); |
155 | 161 |
156 SharedMemory shared_memory_; | 162 scoped_ptr<SharedMemory> shared_memory_; |
157 TableHeader* table_header_; | 163 TableHeader* table_header_; |
158 char* thread_names_table_; | 164 char* thread_names_table_; |
159 PlatformThreadId* thread_tid_table_; | 165 PlatformThreadId* thread_tid_table_; |
160 int* thread_pid_table_; | 166 int* thread_pid_table_; |
161 char* counter_names_table_; | 167 char* counter_names_table_; |
162 int* data_table_; | 168 int* data_table_; |
163 }; | 169 }; |
164 | 170 |
165 // static | 171 // static |
166 StatsTable::Private* StatsTable::Private::New(const std::string& name, | 172 StatsTable::Private* StatsTable::Private::New(const std::string& name, |
167 int size, | 173 int size, |
168 int max_threads, | 174 int max_threads, |
169 int max_counters) { | 175 int max_counters) { |
170 scoped_ptr<Private> priv(new Private()); | 176 scoped_ptr<Private> priv(new Private(CreateSharedMemory(size))); |
171 if (!priv->shared_memory_.CreateNamed(name, true, size)) | 177 |
178 if (!priv->shared_memory_->Map(size)) | |
jar (doing other things)
2013/08/21 01:09:46
Your code can return a null in several cases (line
rmcilroy
2013/08/21 10:37:16
Good point, done.
| |
172 return NULL; | 179 return NULL; |
173 if (!priv->shared_memory_.Map(size)) | 180 void* memory = priv->shared_memory_->memory(); |
174 return NULL; | |
175 void* memory = priv->shared_memory_.memory(); | |
176 | 181 |
177 TableHeader* header = static_cast<TableHeader*>(memory); | 182 TableHeader* header = static_cast<TableHeader*>(memory); |
178 | 183 |
179 // If the version does not match, then assume the table needs | 184 // If the version does not match, then assume the table needs |
180 // to be initialized. | 185 // to be initialized. |
181 if (header->version != kTableVersion) | 186 if (header->version != kTableVersion) |
182 priv->InitializeTable(memory, size, max_counters, max_threads); | 187 priv->InitializeTable(memory, size, max_counters, max_threads); |
183 | 188 |
184 // We have a valid table, so compute our pointers. | 189 // We have a valid table, so compute our pointers. |
185 priv->ComputeMappedPointers(memory); | 190 priv->ComputeMappedPointers(memory); |
186 | 191 |
187 return priv.release(); | 192 return priv.release(); |
188 } | 193 } |
189 | 194 |
195 // static | |
196 SharedMemory* StatsTable::Private::CreateSharedMemory(int size) { | |
197 #if defined(OS_POSIX) | |
198 GlobalDescriptors* global_descriptors = GlobalDescriptors::GetInstance(); | |
199 if (global_descriptors->MaybeGet(kStatsTableSharedMemFd) == -1) { | |
200 // If no global table exists, create it. | |
201 scoped_ptr<SharedMemory> shared_memory(new SharedMemory()); | |
202 if (!shared_memory->CreateAnonymous(size)) | |
203 return NULL; | |
204 return shared_memory.release(); | |
205 } else { | |
jar (doing other things)
2013/08/21 01:09:46
nit: no need for "else" and indent, since you retu
rmcilroy
2013/08/21 10:37:16
Done.
| |
206 // Otherwise open the file descriptor passed by the browser process. | |
207 FileDescriptor file_descriptor( | |
208 global_descriptors->Get(kStatsTableSharedMemFd), false); | |
209 return new SharedMemory(file_descriptor, false); | |
210 } | |
211 #elif defined(OS_WIN) | |
212 scoped_ptr<SharedMemory> shared_memory(new SharedMemory()); | |
213 if (!shared_memory.CreateNamed(name, true, size)) | |
214 return NULL; | |
215 return shared_memory.release(); | |
216 #endif | |
217 } | |
218 | |
190 void StatsTable::Private::InitializeTable(void* memory, int size, | 219 void StatsTable::Private::InitializeTable(void* memory, int size, |
191 int max_counters, | 220 int max_counters, |
192 int max_threads) { | 221 int max_threads) { |
193 // Zero everything. | 222 // Zero everything. |
194 memset(memory, 0, size); | 223 memset(memory, 0, size); |
195 | 224 |
196 // Initialize the header. | 225 // Initialize the header. |
197 TableHeader* header = static_cast<TableHeader*>(memory); | 226 TableHeader* header = static_cast<TableHeader*>(memory); |
198 header->version = kTableVersion; | 227 header->version = kTableVersion; |
199 header->size = size; | 228 header->size = size; |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
558 TLSData* data = | 587 TLSData* data = |
559 static_cast<TLSData*>(tls_index_.Get()); | 588 static_cast<TLSData*>(tls_index_.Get()); |
560 if (!data) | 589 if (!data) |
561 return NULL; | 590 return NULL; |
562 | 591 |
563 DCHECK(data->slot); | 592 DCHECK(data->slot); |
564 DCHECK_EQ(data->table, this); | 593 DCHECK_EQ(data->table, this); |
565 return data; | 594 return data; |
566 } | 595 } |
567 | 596 |
597 #if defined(OS_POSIX) | |
598 base::SharedMemoryHandle StatsTable::GetSharedMemoryHandle() const { | |
599 return impl_->shared_memory()->handle(); | |
jar (doing other things)
2013/08/21 01:09:46
Shouldn't you handle impl_ == NULL?
rmcilroy
2013/08/21 10:37:16
Done.
| |
600 } | |
601 #endif | |
602 | |
568 } // namespace base | 603 } // namespace base |
OLD | NEW |