Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Side by Side Diff: base/metrics/persistent_histogram_allocator.cc

Issue 1852433005: Convert //base to use std::unique_ptr (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase after r384946 Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/persistent_histogram_allocator.h" 5 #include "base/metrics/persistent_histogram_allocator.h"
6 6
7 #include <memory>
8
7 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
8 #include "base/logging.h" 10 #include "base/logging.h"
9 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/ptr_util.h"
10 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
11 #include "base/metrics/histogram_base.h" 13 #include "base/metrics/histogram_base.h"
12 #include "base/metrics/histogram_samples.h" 14 #include "base/metrics/histogram_samples.h"
13 #include "base/metrics/sparse_histogram.h" 15 #include "base/metrics/sparse_histogram.h"
14 #include "base/metrics/statistics_recorder.h" 16 #include "base/metrics/statistics_recorder.h"
15 #include "base/synchronization/lock.h" 17 #include "base/synchronization/lock.h"
16 18
17 // TODO(bcwhite): Order these methods to match the header file. The current 19 // TODO(bcwhite): Order these methods to match the header file. The current
18 // order is only temporary in order to aid review of the transition from 20 // order is only temporary in order to aid review of the transition from
19 // a non-class implementation. 21 // a non-class implementation.
(...skipping 20 matching lines...) Expand all
40 // The object held here will obviously not be destructed at process exit 42 // The object held here will obviously not be destructed at process exit
41 // but that's best since PersistentMemoryAllocator objects (that underlie 43 // but that's best since PersistentMemoryAllocator objects (that underlie
42 // PersistentHistogramAllocator objects) are explicitly forbidden from doing 44 // PersistentHistogramAllocator objects) are explicitly forbidden from doing
43 // anything essential at exit anyway due to the fact that they depend on data 45 // anything essential at exit anyway due to the fact that they depend on data
44 // managed elsewhere and which could be destructed first. 46 // managed elsewhere and which could be destructed first.
45 PersistentHistogramAllocator* g_allocator; 47 PersistentHistogramAllocator* g_allocator;
46 48
47 // Take an array of range boundaries and create a proper BucketRanges object 49 // Take an array of range boundaries and create a proper BucketRanges object
48 // which is returned to the caller. A return of nullptr indicates that the 50 // which is returned to the caller. A return of nullptr indicates that the
49 // passed boundaries are invalid. 51 // passed boundaries are invalid.
50 scoped_ptr<BucketRanges> CreateRangesFromData( 52 std::unique_ptr<BucketRanges> CreateRangesFromData(
51 HistogramBase::Sample* ranges_data, 53 HistogramBase::Sample* ranges_data,
52 uint32_t ranges_checksum, 54 uint32_t ranges_checksum,
53 size_t count) { 55 size_t count) {
54 // To avoid racy destruction at shutdown, the following may be leaked. 56 // To avoid racy destruction at shutdown, the following may be leaked.
55 scoped_ptr<BucketRanges> ranges(new BucketRanges(count)); 57 std::unique_ptr<BucketRanges> ranges(new BucketRanges(count));
56 DCHECK_EQ(count, ranges->size()); 58 DCHECK_EQ(count, ranges->size());
57 for (size_t i = 0; i < count; ++i) { 59 for (size_t i = 0; i < count; ++i) {
58 if (i > 0 && ranges_data[i] <= ranges_data[i - 1]) 60 if (i > 0 && ranges_data[i] <= ranges_data[i - 1])
59 return nullptr; 61 return nullptr;
60 ranges->set_range(i, ranges_data[i]); 62 ranges->set_range(i, ranges_data[i]);
61 } 63 }
62 64
63 ranges->ResetChecksum(); 65 ranges->ResetChecksum();
64 if (ranges->checksum() != ranges_checksum) 66 if (ranges->checksum() != ranges_checksum)
65 return nullptr; 67 return nullptr;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 HistogramSamples::Metadata samples_metadata; 105 HistogramSamples::Metadata samples_metadata;
104 HistogramSamples::Metadata logged_metadata; 106 HistogramSamples::Metadata logged_metadata;
105 107
106 // Space for the histogram name will be added during the actual allocation 108 // Space for the histogram name will be added during the actual allocation
107 // request. This must be the last field of the structure. A zero-size array 109 // request. This must be the last field of the structure. A zero-size array
108 // or a "flexible" array would be preferred but is not (yet) valid C++. 110 // or a "flexible" array would be preferred but is not (yet) valid C++.
109 char name[1]; 111 char name[1];
110 }; 112 };
111 113
112 PersistentHistogramAllocator::PersistentHistogramAllocator( 114 PersistentHistogramAllocator::PersistentHistogramAllocator(
113 scoped_ptr<PersistentMemoryAllocator> memory) 115 std::unique_ptr<PersistentMemoryAllocator> memory)
114 : memory_allocator_(std::move(memory)) {} 116 : memory_allocator_(std::move(memory)) {}
115 117
116 PersistentHistogramAllocator::~PersistentHistogramAllocator() {} 118 PersistentHistogramAllocator::~PersistentHistogramAllocator() {}
117 119
118 void PersistentHistogramAllocator::CreateIterator(Iterator* iter) { 120 void PersistentHistogramAllocator::CreateIterator(Iterator* iter) {
119 memory_allocator_->CreateIterator(&iter->memory_iter); 121 memory_allocator_->CreateIterator(&iter->memory_iter);
120 } 122 }
121 123
122 void PersistentHistogramAllocator::CreateTrackingHistograms(StringPiece name) { 124 void PersistentHistogramAllocator::CreateTrackingHistograms(StringPiece name) {
123 memory_allocator_->CreateTrackingHistograms(name); 125 memory_allocator_->CreateTrackingHistograms(name);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 // static 169 // static
168 void PersistentHistogramAllocator::RecordCreateHistogramResult( 170 void PersistentHistogramAllocator::RecordCreateHistogramResult(
169 CreateHistogramResultType result) { 171 CreateHistogramResultType result) {
170 HistogramBase* result_histogram = GetCreateHistogramResultHistogram(); 172 HistogramBase* result_histogram = GetCreateHistogramResultHistogram();
171 if (result_histogram) 173 if (result_histogram)
172 result_histogram->Add(result); 174 result_histogram->Add(result);
173 } 175 }
174 176
175 // static 177 // static
176 void PersistentHistogramAllocator::SetGlobalAllocator( 178 void PersistentHistogramAllocator::SetGlobalAllocator(
177 scoped_ptr<PersistentHistogramAllocator> allocator) { 179 std::unique_ptr<PersistentHistogramAllocator> allocator) {
178 // Releasing or changing an allocator is extremely dangerous because it 180 // Releasing or changing an allocator is extremely dangerous because it
179 // likely has histograms stored within it. If the backing memory is also 181 // likely has histograms stored within it. If the backing memory is also
180 // also released, future accesses to those histograms will seg-fault. 182 // also released, future accesses to those histograms will seg-fault.
181 CHECK(!g_allocator); 183 CHECK(!g_allocator);
182 g_allocator = allocator.release(); 184 g_allocator = allocator.release();
183 185
184 size_t existing = StatisticsRecorder::GetHistogramCount(); 186 size_t existing = StatisticsRecorder::GetHistogramCount();
185 DLOG_IF(WARNING, existing) 187 DLOG_IF(WARNING, existing)
186 << existing 188 << existing
187 << " histograms were created before persistence was enabled."; 189 << " histograms were created before persistence was enabled.";
188 } 190 }
189 191
190 // static 192 // static
191 PersistentHistogramAllocator* 193 PersistentHistogramAllocator*
192 PersistentHistogramAllocator::GetGlobalAllocator() { 194 PersistentHistogramAllocator::GetGlobalAllocator() {
193 return g_allocator; 195 return g_allocator;
194 } 196 }
195 197
196 // static 198 // static
197 scoped_ptr<PersistentHistogramAllocator> 199 std::unique_ptr<PersistentHistogramAllocator>
198 PersistentHistogramAllocator::ReleaseGlobalAllocatorForTesting() { 200 PersistentHistogramAllocator::ReleaseGlobalAllocatorForTesting() {
199 PersistentHistogramAllocator* histogram_allocator = g_allocator; 201 PersistentHistogramAllocator* histogram_allocator = g_allocator;
200 if (!histogram_allocator) 202 if (!histogram_allocator)
201 return nullptr; 203 return nullptr;
202 PersistentMemoryAllocator* memory_allocator = 204 PersistentMemoryAllocator* memory_allocator =
203 histogram_allocator->memory_allocator(); 205 histogram_allocator->memory_allocator();
204 206
205 // Before releasing the memory, it's necessary to have the Statistics- 207 // Before releasing the memory, it's necessary to have the Statistics-
206 // Recorder forget about the histograms contained therein; otherwise, 208 // Recorder forget about the histograms contained therein; otherwise,
207 // some operations will try to access them and the released memory. 209 // some operations will try to access them and the released memory.
(...skipping 14 matching lines...) Expand all
222 // If that memory segment were to be deleted, future calls to create 224 // If that memory segment were to be deleted, future calls to create
223 // persistent histograms would crash. To avoid this, have the test call 225 // persistent histograms would crash. To avoid this, have the test call
224 // the method GetCreateHistogramResultHistogram() *before* setting 226 // the method GetCreateHistogramResultHistogram() *before* setting
225 // the (temporary) memory allocator via SetGlobalAllocator() so that 227 // the (temporary) memory allocator via SetGlobalAllocator() so that
226 // histogram is instead allocated from the process heap. 228 // histogram is instead allocated from the process heap.
227 DCHECK_NE(kResultHistogram, histogram_data->name); 229 DCHECK_NE(kResultHistogram, histogram_data->name);
228 } 230 }
229 } 231 }
230 232
231 g_allocator = nullptr; 233 g_allocator = nullptr;
232 return make_scoped_ptr(histogram_allocator); 234 return WrapUnique(histogram_allocator);
233 }; 235 };
234 236
235 // static 237 // static
236 void PersistentHistogramAllocator::CreateGlobalAllocatorOnPersistentMemory( 238 void PersistentHistogramAllocator::CreateGlobalAllocatorOnPersistentMemory(
237 void* base, 239 void* base,
238 size_t size, 240 size_t size,
239 size_t page_size, 241 size_t page_size,
240 uint64_t id, 242 uint64_t id,
241 StringPiece name) { 243 StringPiece name) {
242 SetGlobalAllocator(make_scoped_ptr(new PersistentHistogramAllocator( 244 SetGlobalAllocator(WrapUnique(new PersistentHistogramAllocator(
243 make_scoped_ptr(new PersistentMemoryAllocator( 245 WrapUnique(new PersistentMemoryAllocator(base, size, page_size, id,
244 base, size, page_size, id, name, false))))); 246 name, false)))));
245 } 247 }
246 248
247 // static 249 // static
248 void PersistentHistogramAllocator::CreateGlobalAllocatorOnLocalMemory( 250 void PersistentHistogramAllocator::CreateGlobalAllocatorOnLocalMemory(
249 size_t size, 251 size_t size,
250 uint64_t id, 252 uint64_t id,
251 StringPiece name) { 253 StringPiece name) {
252 SetGlobalAllocator(make_scoped_ptr(new PersistentHistogramAllocator( 254 SetGlobalAllocator(WrapUnique(new PersistentHistogramAllocator(
253 make_scoped_ptr(new LocalPersistentMemoryAllocator(size, id, name))))); 255 WrapUnique(new LocalPersistentMemoryAllocator(size, id, name)))));
254 } 256 }
255 257
256 // static 258 // static
257 void PersistentHistogramAllocator::CreateGlobalAllocatorOnSharedMemory( 259 void PersistentHistogramAllocator::CreateGlobalAllocatorOnSharedMemory(
258 size_t size, 260 size_t size,
259 const SharedMemoryHandle& handle) { 261 const SharedMemoryHandle& handle) {
260 scoped_ptr<SharedMemory> shm(new SharedMemory(handle, /*readonly=*/false)); 262 std::unique_ptr<SharedMemory> shm(
263 new SharedMemory(handle, /*readonly=*/false));
261 if (!shm->Map(size)) { 264 if (!shm->Map(size)) {
262 NOTREACHED(); 265 NOTREACHED();
263 return; 266 return;
264 } 267 }
265 268
266 SetGlobalAllocator(make_scoped_ptr(new PersistentHistogramAllocator( 269 SetGlobalAllocator(WrapUnique(new PersistentHistogramAllocator(
267 make_scoped_ptr(new SharedPersistentMemoryAllocator( 270 WrapUnique(new SharedPersistentMemoryAllocator(
268 std::move(shm), 0, StringPiece(), /*readonly=*/false))))); 271 std::move(shm), 0, StringPiece(), /*readonly=*/false)))));
269 } 272 }
270 273
271 // static 274 // static
272 scoped_ptr<HistogramBase> PersistentHistogramAllocator::CreateHistogram( 275 std::unique_ptr<HistogramBase> PersistentHistogramAllocator::CreateHistogram(
273 PersistentHistogramData* histogram_data_ptr) { 276 PersistentHistogramData* histogram_data_ptr) {
274 if (!histogram_data_ptr) { 277 if (!histogram_data_ptr) {
275 RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_METADATA_POINTER); 278 RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_METADATA_POINTER);
276 NOTREACHED(); 279 NOTREACHED();
277 return nullptr; 280 return nullptr;
278 } 281 }
279 282
280 // Sparse histograms are quite different so handle them as a special case. 283 // Sparse histograms are quite different so handle them as a special case.
281 if (histogram_data_ptr->histogram_type == SPARSE_HISTOGRAM) { 284 if (histogram_data_ptr->histogram_type == SPARSE_HISTOGRAM) {
282 scoped_ptr<HistogramBase> histogram = SparseHistogram::PersistentCreate( 285 std::unique_ptr<HistogramBase> histogram =
283 memory_allocator(), histogram_data_ptr->name, 286 SparseHistogram::PersistentCreate(memory_allocator(),
284 &histogram_data_ptr->samples_metadata, 287 histogram_data_ptr->name,
285 &histogram_data_ptr->logged_metadata); 288 &histogram_data_ptr->samples_metadata,
289 &histogram_data_ptr->logged_metadata);
286 DCHECK(histogram); 290 DCHECK(histogram);
287 histogram->SetFlags(histogram_data_ptr->flags); 291 histogram->SetFlags(histogram_data_ptr->flags);
288 RecordCreateHistogramResult(CREATE_HISTOGRAM_SUCCESS); 292 RecordCreateHistogramResult(CREATE_HISTOGRAM_SUCCESS);
289 return histogram; 293 return histogram;
290 } 294 }
291 295
292 // Copy the histogram_data to local storage because anything in persistent 296 // Copy the histogram_data to local storage because anything in persistent
293 // memory cannot be trusted as it could be changed at any moment by a 297 // memory cannot be trusted as it could be changed at any moment by a
294 // malicious actor that shares access. The contents of histogram_data are 298 // malicious actor that shares access. The contents of histogram_data are
295 // validated below; the local copy is to ensure that the contents cannot 299 // validated below; the local copy is to ensure that the contents cannot
(...skipping 11 matching lines...) Expand all
307 size_t allocated_bytes = 311 size_t allocated_bytes =
308 memory_allocator_->GetAllocSize(histogram_data.ranges_ref); 312 memory_allocator_->GetAllocSize(histogram_data.ranges_ref);
309 if (!ranges_data || histogram_data.bucket_count < 2 || 313 if (!ranges_data || histogram_data.bucket_count < 2 ||
310 histogram_data.bucket_count >= max_buckets || 314 histogram_data.bucket_count >= max_buckets ||
311 allocated_bytes < required_bytes) { 315 allocated_bytes < required_bytes) {
312 RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_RANGES_ARRAY); 316 RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_RANGES_ARRAY);
313 NOTREACHED(); 317 NOTREACHED();
314 return nullptr; 318 return nullptr;
315 } 319 }
316 320
317 scoped_ptr<const BucketRanges> created_ranges = 321 std::unique_ptr<const BucketRanges> created_ranges =
318 CreateRangesFromData(ranges_data, histogram_data.ranges_checksum, 322 CreateRangesFromData(ranges_data, histogram_data.ranges_checksum,
319 histogram_data.bucket_count + 1); 323 histogram_data.bucket_count + 1);
320 if (!created_ranges) { 324 if (!created_ranges) {
321 RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_RANGES_ARRAY); 325 RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_RANGES_ARRAY);
322 NOTREACHED(); 326 NOTREACHED();
323 return nullptr; 327 return nullptr;
324 } 328 }
325 const BucketRanges* ranges = 329 const BucketRanges* ranges =
326 StatisticsRecorder::RegisterOrDeleteDuplicateRanges( 330 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(
327 created_ranges.release()); 331 created_ranges.release());
(...skipping 11 matching lines...) Expand all
339 return nullptr; 343 return nullptr;
340 } 344 }
341 345
342 // After the main "counts" array is a second array using for storing what 346 // After the main "counts" array is a second array using for storing what
343 // was previously logged. This is used to calculate the "delta" during 347 // was previously logged. This is used to calculate the "delta" during
344 // snapshot operations. 348 // snapshot operations.
345 HistogramBase::AtomicCount* logged_data = 349 HistogramBase::AtomicCount* logged_data =
346 counts_data + histogram_data.bucket_count; 350 counts_data + histogram_data.bucket_count;
347 351
348 std::string name(histogram_data_ptr->name); 352 std::string name(histogram_data_ptr->name);
349 scoped_ptr<HistogramBase> histogram; 353 std::unique_ptr<HistogramBase> histogram;
350 switch (histogram_data.histogram_type) { 354 switch (histogram_data.histogram_type) {
351 case HISTOGRAM: 355 case HISTOGRAM:
352 histogram = Histogram::PersistentCreate( 356 histogram = Histogram::PersistentCreate(
353 name, histogram_data.minimum, histogram_data.maximum, ranges, 357 name, histogram_data.minimum, histogram_data.maximum, ranges,
354 counts_data, logged_data, histogram_data.bucket_count, 358 counts_data, logged_data, histogram_data.bucket_count,
355 &histogram_data_ptr->samples_metadata, 359 &histogram_data_ptr->samples_metadata,
356 &histogram_data_ptr->logged_metadata); 360 &histogram_data_ptr->logged_metadata);
357 DCHECK(histogram); 361 DCHECK(histogram);
358 break; 362 break;
359 case LINEAR_HISTOGRAM: 363 case LINEAR_HISTOGRAM:
(...skipping 26 matching lines...) Expand all
386 DCHECK_EQ(histogram_data.histogram_type, histogram->GetHistogramType()); 390 DCHECK_EQ(histogram_data.histogram_type, histogram->GetHistogramType());
387 histogram->SetFlags(histogram_data.flags); 391 histogram->SetFlags(histogram_data.flags);
388 RecordCreateHistogramResult(CREATE_HISTOGRAM_SUCCESS); 392 RecordCreateHistogramResult(CREATE_HISTOGRAM_SUCCESS);
389 } else { 393 } else {
390 RecordCreateHistogramResult(CREATE_HISTOGRAM_UNKNOWN_TYPE); 394 RecordCreateHistogramResult(CREATE_HISTOGRAM_UNKNOWN_TYPE);
391 } 395 }
392 396
393 return histogram; 397 return histogram;
394 } 398 }
395 399
396 scoped_ptr<HistogramBase> PersistentHistogramAllocator::GetHistogram( 400 std::unique_ptr<HistogramBase> PersistentHistogramAllocator::GetHistogram(
397 Reference ref) { 401 Reference ref) {
398 // Unfortunately, the histogram "pickle" methods cannot be used as part of 402 // Unfortunately, the histogram "pickle" methods cannot be used as part of
399 // the persistance because the deserialization methods always create local 403 // the persistance because the deserialization methods always create local
400 // count data (while these must reference the persistent counts) and always 404 // count data (while these must reference the persistent counts) and always
401 // add it to the local list of known histograms (while these may be simple 405 // add it to the local list of known histograms (while these may be simple
402 // references to histograms in other processes). 406 // references to histograms in other processes).
403 PersistentHistogramData* histogram_data = 407 PersistentHistogramData* histogram_data =
404 memory_allocator_->GetAsObject<PersistentHistogramData>( 408 memory_allocator_->GetAsObject<PersistentHistogramData>(
405 ref, kTypeIdHistogram); 409 ref, kTypeIdHistogram);
406 size_t length = memory_allocator_->GetAllocSize(ref); 410 size_t length = memory_allocator_->GetAllocSize(ref);
407 if (!histogram_data || 411 if (!histogram_data ||
408 reinterpret_cast<char*>(histogram_data)[length - 1] != '\0') { 412 reinterpret_cast<char*>(histogram_data)[length - 1] != '\0') {
409 RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_METADATA); 413 RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_METADATA);
410 NOTREACHED(); 414 NOTREACHED();
411 return nullptr; 415 return nullptr;
412 } 416 }
413 return CreateHistogram(histogram_data); 417 return CreateHistogram(histogram_data);
414 } 418 }
415 419
416 scoped_ptr<HistogramBase> 420 std::unique_ptr<HistogramBase>
417 PersistentHistogramAllocator::GetNextHistogramWithIgnore(Iterator* iter, 421 PersistentHistogramAllocator::GetNextHistogramWithIgnore(Iterator* iter,
418 Reference ignore) { 422 Reference ignore) {
419 PersistentMemoryAllocator::Reference ref; 423 PersistentMemoryAllocator::Reference ref;
420 uint32_t type_id; 424 uint32_t type_id;
421 while ((ref = memory_allocator_->GetNextIterable(&iter->memory_iter, 425 while ((ref = memory_allocator_->GetNextIterable(&iter->memory_iter,
422 &type_id)) != 0) { 426 &type_id)) != 0) {
423 if (ref == ignore) 427 if (ref == ignore)
424 continue; 428 continue;
425 if (type_id == kTypeIdHistogram) 429 if (type_id == kTypeIdHistogram)
426 return GetHistogram(ref); 430 return GetHistogram(ref);
427 } 431 }
428 return nullptr; 432 return nullptr;
429 } 433 }
430 434
431 void PersistentHistogramAllocator::FinalizeHistogram(Reference ref, 435 void PersistentHistogramAllocator::FinalizeHistogram(Reference ref,
432 bool registered) { 436 bool registered) {
433 // If the created persistent histogram was registered then it needs to 437 // If the created persistent histogram was registered then it needs to
434 // be marked as "iterable" in order to be found by other processes. 438 // be marked as "iterable" in order to be found by other processes.
435 if (registered) 439 if (registered)
436 memory_allocator_->MakeIterable(ref); 440 memory_allocator_->MakeIterable(ref);
437 // If it wasn't registered then a race condition must have caused 441 // If it wasn't registered then a race condition must have caused
438 // two to be created. The allocator does not support releasing the 442 // two to be created. The allocator does not support releasing the
439 // acquired memory so just change the type to be empty. 443 // acquired memory so just change the type to be empty.
440 else 444 else
441 memory_allocator_->SetType(ref, 0); 445 memory_allocator_->SetType(ref, 0);
442 } 446 }
443 447
444 scoped_ptr<HistogramBase> PersistentHistogramAllocator::AllocateHistogram( 448 std::unique_ptr<HistogramBase> PersistentHistogramAllocator::AllocateHistogram(
445 HistogramType histogram_type, 449 HistogramType histogram_type,
446 const std::string& name, 450 const std::string& name,
447 int minimum, 451 int minimum,
448 int maximum, 452 int maximum,
449 const BucketRanges* bucket_ranges, 453 const BucketRanges* bucket_ranges,
450 int32_t flags, 454 int32_t flags,
451 Reference* ref_ptr) { 455 Reference* ref_ptr) {
452 // If the allocator is corrupt, don't waste time trying anything else. 456 // If the allocator is corrupt, don't waste time trying anything else.
453 // This also allows differentiating on the dashboard between allocations 457 // This also allows differentiating on the dashboard between allocations
454 // failed due to a corrupt allocator and the number of process instances 458 // failed due to a corrupt allocator and the number of process instances
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
514 histogram_data = nullptr; // Clear this for proper handling below. 518 histogram_data = nullptr; // Clear this for proper handling below.
515 } 519 }
516 } 520 }
517 521
518 if (histogram_data) { 522 if (histogram_data) {
519 // Create the histogram using resources in persistent memory. This ends up 523 // Create the histogram using resources in persistent memory. This ends up
520 // resolving the "ref" values stored in histogram_data instad of just 524 // resolving the "ref" values stored in histogram_data instad of just
521 // using what is already known above but avoids duplicating the switch 525 // using what is already known above but avoids duplicating the switch
522 // statement here and serves as a double-check that everything is 526 // statement here and serves as a double-check that everything is
523 // correct before commiting the new histogram to persistent space. 527 // correct before commiting the new histogram to persistent space.
524 scoped_ptr<HistogramBase> histogram = CreateHistogram(histogram_data); 528 std::unique_ptr<HistogramBase> histogram = CreateHistogram(histogram_data);
525 DCHECK(histogram); 529 DCHECK(histogram);
526 if (ref_ptr != nullptr) 530 if (ref_ptr != nullptr)
527 *ref_ptr = histogram_ref; 531 *ref_ptr = histogram_ref;
528 532
529 // By storing the reference within the allocator to this histogram, the 533 // By storing the reference within the allocator to this histogram, the
530 // next import (which will happen before the next histogram creation) 534 // next import (which will happen before the next histogram creation)
531 // will know to skip it. See also the comment in ImportGlobalHistograms(). 535 // will know to skip it. See also the comment in ImportGlobalHistograms().
532 subtle::NoBarrier_Store(&last_created_, histogram_ref); 536 subtle::NoBarrier_Store(&last_created_, histogram_ref);
533 return histogram; 537 return histogram;
534 } 538 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 // Skip the import if it's the histogram that was last created. Should a 572 // Skip the import if it's the histogram that was last created. Should a
569 // race condition cause the "last created" to be overwritten before it 573 // race condition cause the "last created" to be overwritten before it
570 // is recognized here then the histogram will be created and be ignored 574 // is recognized here then the histogram will be created and be ignored
571 // when it is detected as a duplicate by the statistics-recorder. This 575 // when it is detected as a duplicate by the statistics-recorder. This
572 // simple check reduces the time of creating persistent histograms by 576 // simple check reduces the time of creating persistent histograms by
573 // about 40%. 577 // about 40%.
574 Reference last_created = 578 Reference last_created =
575 subtle::NoBarrier_Load(&g_allocator->last_created_); 579 subtle::NoBarrier_Load(&g_allocator->last_created_);
576 580
577 while (true) { 581 while (true) {
578 scoped_ptr<HistogramBase> histogram = 582 std::unique_ptr<HistogramBase> histogram =
579 g_allocator->GetNextHistogramWithIgnore(&iter, last_created); 583 g_allocator->GetNextHistogramWithIgnore(&iter, last_created);
580 if (!histogram) 584 if (!histogram)
581 break; 585 break;
582 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram.release()); 586 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram.release());
583 } 587 }
584 } 588 }
585 } 589 }
586 590
587 } // namespace base 591 } // namespace base
OLDNEW
« no previous file with comments | « base/metrics/persistent_histogram_allocator.h ('k') | base/metrics/persistent_histogram_allocator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698