OLD | NEW |
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> | 7 #include <memory> |
8 | 8 |
9 #include "base/atomicops.h" | 9 #include "base/atomicops.h" |
10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 // Create the remaining metadata necessary for regular histograms. | 333 // Create the remaining metadata necessary for regular histograms. |
334 if (histogram_type != SPARSE_HISTOGRAM) { | 334 if (histogram_type != SPARSE_HISTOGRAM) { |
335 size_t bucket_count = bucket_ranges->bucket_count(); | 335 size_t bucket_count = bucket_ranges->bucket_count(); |
336 size_t counts_bytes = CalculateRequiredCountsBytes(bucket_count); | 336 size_t counts_bytes = CalculateRequiredCountsBytes(bucket_count); |
337 if (counts_bytes == 0) { | 337 if (counts_bytes == 0) { |
338 // |bucket_count| was out-of-range. | 338 // |bucket_count| was out-of-range. |
339 NOTREACHED(); | 339 NOTREACHED(); |
340 return nullptr; | 340 return nullptr; |
341 } | 341 } |
342 | 342 |
343 size_t ranges_count = bucket_count + 1; | 343 // Since the StasticsRecorder keeps a global collection of BucketRanges |
344 size_t ranges_bytes = ranges_count * sizeof(HistogramBase::Sample); | 344 // objects for re-use, it would be dangerous for one to hold a reference |
| 345 // from a persistent allocator that is not the global one (which is |
| 346 // permanent once set). If this stops being the case, this check can |
| 347 // become an "if" condition beside "!ranges_ref" below and before |
| 348 // set_persistent_reference() farther down. |
| 349 DCHECK_EQ(this, GlobalHistogramAllocator::Get()); |
| 350 |
| 351 // Re-use an existing BucketRanges persistent allocation if one is known; |
| 352 // otherwise, create one. |
| 353 PersistentMemoryAllocator::Reference ranges_ref = |
| 354 bucket_ranges->persistent_reference(); |
| 355 if (!ranges_ref) { |
| 356 size_t ranges_count = bucket_count + 1; |
| 357 size_t ranges_bytes = ranges_count * sizeof(HistogramBase::Sample); |
| 358 ranges_ref = |
| 359 memory_allocator_->Allocate(ranges_bytes, kTypeIdRangesArray); |
| 360 if (ranges_ref) { |
| 361 HistogramBase::Sample* ranges_data = |
| 362 memory_allocator_->GetAsArray<HistogramBase::Sample>( |
| 363 ranges_ref, kTypeIdRangesArray, ranges_count); |
| 364 if (ranges_data) { |
| 365 for (size_t i = 0; i < bucket_ranges->size(); ++i) |
| 366 ranges_data[i] = bucket_ranges->range(i); |
| 367 bucket_ranges->set_persistent_reference(ranges_ref); |
| 368 } else { |
| 369 // This should never happen but be tolerant if it does. |
| 370 NOTREACHED(); |
| 371 ranges_ref = PersistentMemoryAllocator::kReferenceNull; |
| 372 } |
| 373 } |
| 374 } else { |
| 375 DCHECK_EQ(kTypeIdRangesArray, memory_allocator_->GetType(ranges_ref)); |
| 376 } |
| 377 |
345 PersistentMemoryAllocator::Reference counts_ref = | 378 PersistentMemoryAllocator::Reference counts_ref = |
346 memory_allocator_->Allocate(counts_bytes, kTypeIdCountsArray); | 379 memory_allocator_->Allocate(counts_bytes, kTypeIdCountsArray); |
347 PersistentMemoryAllocator::Reference ranges_ref = | |
348 memory_allocator_->Allocate(ranges_bytes, kTypeIdRangesArray); | |
349 HistogramBase::Sample* ranges_data = | |
350 memory_allocator_->GetAsArray<HistogramBase::Sample>( | |
351 ranges_ref, kTypeIdRangesArray, ranges_count); | |
352 | 380 |
353 // Only continue here if all allocations were successful. If they weren't, | 381 // Only continue here if all allocations were successful. If they weren't, |
354 // there is no way to free the space but that's not really a problem since | 382 // there is no way to free the space but that's not really a problem since |
355 // the allocations only fail because the space is full or corrupt and so | 383 // the allocations only fail because the space is full or corrupt and so |
356 // any future attempts will also fail. | 384 // any future attempts will also fail. |
357 if (counts_ref && ranges_data && histogram_data) { | 385 if (counts_ref && ranges_ref && histogram_data) { |
358 for (size_t i = 0; i < bucket_ranges->size(); ++i) | |
359 ranges_data[i] = bucket_ranges->range(i); | |
360 | |
361 histogram_data->minimum = minimum; | 386 histogram_data->minimum = minimum; |
362 histogram_data->maximum = maximum; | 387 histogram_data->maximum = maximum; |
363 // |bucket_count| must fit within 32-bits or the allocation of the counts | 388 // |bucket_count| must fit within 32-bits or the allocation of the counts |
364 // array would have failed for being too large; the allocator supports | 389 // array would have failed for being too large; the allocator supports |
365 // less than 4GB total size. | 390 // less than 4GB total size. |
366 histogram_data->bucket_count = static_cast<uint32_t>(bucket_count); | 391 histogram_data->bucket_count = static_cast<uint32_t>(bucket_count); |
367 histogram_data->ranges_ref = ranges_ref; | 392 histogram_data->ranges_ref = ranges_ref; |
368 histogram_data->ranges_checksum = bucket_ranges->checksum(); | 393 histogram_data->ranges_checksum = bucket_ranges->checksum(); |
369 histogram_data->counts_ref = counts_ref; | 394 histogram_data->counts_ref = counts_ref; |
370 } else { | 395 } else { |
(...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
928 while (true) { | 953 while (true) { |
929 std::unique_ptr<HistogramBase> histogram = | 954 std::unique_ptr<HistogramBase> histogram = |
930 import_iterator_.GetNextWithIgnore(record_to_ignore); | 955 import_iterator_.GetNextWithIgnore(record_to_ignore); |
931 if (!histogram) | 956 if (!histogram) |
932 break; | 957 break; |
933 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram.release()); | 958 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram.release()); |
934 } | 959 } |
935 } | 960 } |
936 | 961 |
937 } // namespace base | 962 } // namespace base |
OLD | NEW |