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

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

Issue 2832333002: Revert of Embed a single sample in histogram metadata. (Closed)
Patch Set: Created 3 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
« no previous file with comments | « base/metrics/histogram_unittest.cc ('k') | base/metrics/persistent_sample_map.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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> 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 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 static constexpr size_t kExpectedInstanceSize = 233 static constexpr size_t kExpectedInstanceSize =
234 40 + 2 * HistogramSamples::Metadata::kExpectedInstanceSize; 234 40 + 2 * HistogramSamples::Metadata::kExpectedInstanceSize;
235 235
236 int32_t histogram_type; 236 int32_t histogram_type;
237 int32_t flags; 237 int32_t flags;
238 int32_t minimum; 238 int32_t minimum;
239 int32_t maximum; 239 int32_t maximum;
240 uint32_t bucket_count; 240 uint32_t bucket_count;
241 PersistentMemoryAllocator::Reference ranges_ref; 241 PersistentMemoryAllocator::Reference ranges_ref;
242 uint32_t ranges_checksum; 242 uint32_t ranges_checksum;
243 subtle::Atomic32 counts_ref; // PersistentMemoryAllocator::Reference 243 PersistentMemoryAllocator::Reference counts_ref;
244 HistogramSamples::Metadata samples_metadata; 244 HistogramSamples::Metadata samples_metadata;
245 HistogramSamples::Metadata logged_metadata; 245 HistogramSamples::Metadata logged_metadata;
246 246
247 // Space for the histogram name will be added during the actual allocation 247 // Space for the histogram name will be added during the actual allocation
248 // request. This must be the last field of the structure. A zero-size array 248 // request. This must be the last field of the structure. A zero-size array
249 // or a "flexible" array would be preferred but is not (yet) valid C++. 249 // or a "flexible" array would be preferred but is not (yet) valid C++.
250 char name[sizeof(uint64_t)]; // Force 64-bit alignment on 32-bit builds. 250 char name[sizeof(uint64_t)]; // Force 64-bit alignment on 32-bit builds.
251 }; 251 };
252 252
253 PersistentHistogramAllocator::Iterator::Iterator( 253 PersistentHistogramAllocator::Iterator::Iterator(
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 } else { 368 } else {
369 // This should never happen but be tolerant if it does. 369 // This should never happen but be tolerant if it does.
370 NOTREACHED(); 370 NOTREACHED();
371 ranges_ref = PersistentMemoryAllocator::kReferenceNull; 371 ranges_ref = PersistentMemoryAllocator::kReferenceNull;
372 } 372 }
373 } 373 }
374 } else { 374 } else {
375 DCHECK_EQ(kTypeIdRangesArray, memory_allocator_->GetType(ranges_ref)); 375 DCHECK_EQ(kTypeIdRangesArray, memory_allocator_->GetType(ranges_ref));
376 } 376 }
377 377
378 PersistentMemoryAllocator::Reference counts_ref =
379 memory_allocator_->Allocate(counts_bytes, kTypeIdCountsArray);
378 380
379 // 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,
380 // 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
381 // 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
382 // any future attempts will also fail. 384 // any future attempts will also fail.
383 if (ranges_ref && histogram_data) { 385 if (counts_ref && ranges_ref && histogram_data) {
384 histogram_data->minimum = minimum; 386 histogram_data->minimum = minimum;
385 histogram_data->maximum = maximum; 387 histogram_data->maximum = maximum;
386 // |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
387 // array would have failed for being too large; the allocator supports 389 // array would have failed for being too large; the allocator supports
388 // less than 4GB total size. 390 // less than 4GB total size.
389 histogram_data->bucket_count = static_cast<uint32_t>(bucket_count); 391 histogram_data->bucket_count = static_cast<uint32_t>(bucket_count);
390 histogram_data->ranges_ref = ranges_ref; 392 histogram_data->ranges_ref = ranges_ref;
391 histogram_data->ranges_checksum = bucket_ranges->checksum(); 393 histogram_data->ranges_checksum = bucket_ranges->checksum();
394 histogram_data->counts_ref = counts_ref;
392 } else { 395 } else {
393 histogram_data = nullptr; // Clear this for proper handling below. 396 histogram_data = nullptr; // Clear this for proper handling below.
394 } 397 }
395 } 398 }
396 399
397 if (histogram_data) { 400 if (histogram_data) {
398 // Create the histogram using resources in persistent memory. This ends up 401 // Create the histogram using resources in persistent memory. This ends up
399 // resolving the "ref" values stored in histogram_data instad of just 402 // resolving the "ref" values stored in histogram_data instad of just
400 // using what is already known above but avoids duplicating the switch 403 // using what is already known above but avoids duplicating the switch
401 // statement here and serves as a double-check that everything is 404 // statement here and serves as a double-check that everything is
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 histogram_data.bucket_count + 1); 599 histogram_data.bucket_count + 1);
597 if (!created_ranges) { 600 if (!created_ranges) {
598 RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_RANGES_ARRAY); 601 RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_RANGES_ARRAY);
599 NOTREACHED(); 602 NOTREACHED();
600 return nullptr; 603 return nullptr;
601 } 604 }
602 const BucketRanges* ranges = 605 const BucketRanges* ranges =
603 StatisticsRecorder::RegisterOrDeleteDuplicateRanges( 606 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(
604 created_ranges.release()); 607 created_ranges.release());
605 608
609 HistogramBase::AtomicCount* counts_data =
610 memory_allocator_->GetAsArray<HistogramBase::AtomicCount>(
611 histogram_data.counts_ref, kTypeIdCountsArray,
612 PersistentMemoryAllocator::kSizeAny);
606 size_t counts_bytes = 613 size_t counts_bytes =
607 CalculateRequiredCountsBytes(histogram_data.bucket_count); 614 CalculateRequiredCountsBytes(histogram_data.bucket_count);
608 PersistentMemoryAllocator::Reference counts_ref = 615 if (!counts_data || counts_bytes == 0 ||
609 subtle::NoBarrier_Load(&histogram_data.counts_ref); 616 memory_allocator_->GetAllocSize(histogram_data.counts_ref) <
610 if (counts_bytes == 0 || 617 counts_bytes) {
611 (counts_ref != 0 &&
612 memory_allocator_->GetAllocSize(counts_ref) < counts_bytes)) {
613 RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_COUNTS_ARRAY); 618 RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_COUNTS_ARRAY);
614 NOTREACHED(); 619 NOTREACHED();
615 return nullptr; 620 return nullptr;
616 } 621 }
617 622
618 // The "counts" data (including both samples and logged samples) is a delayed 623 // After the main "counts" array is a second array using for storing what
619 // persistent allocation meaning that though its size and storage for a 624 // was previously logged. This is used to calculate the "delta" during
620 // reference is defined, no space is reserved until actually needed. When 625 // snapshot operations.
621 // it is needed, memory will be allocated from the persistent segment and 626 HistogramBase::AtomicCount* logged_data =
622 // a reference to it stored at the passed address. Other threads can then 627 counts_data + histogram_data.bucket_count;
623 // notice the valid reference and access the same data.
624 DelayedPersistentAllocation counts_data(memory_allocator_.get(),
625 &histogram_data_ptr->counts_ref,
626 kTypeIdCountsArray, counts_bytes, 0);
627 628
628 // A second delayed allocations is defined using the same reference storage
629 // location as the first so the allocation of one will automatically be found
630 // by the other. Within the block, the first half of the space is for "counts"
631 // and the second half is for "logged counts".
632 DelayedPersistentAllocation logged_data(
633 memory_allocator_.get(), &histogram_data_ptr->counts_ref,
634 kTypeIdCountsArray, counts_bytes, counts_bytes / 2,
635 /*make_iterable=*/false);
636
637 // Create the right type of histogram.
638 std::string name(histogram_data_ptr->name); 629 std::string name(histogram_data_ptr->name);
639 std::unique_ptr<HistogramBase> histogram; 630 std::unique_ptr<HistogramBase> histogram;
640 switch (histogram_data.histogram_type) { 631 switch (histogram_data.histogram_type) {
641 case HISTOGRAM: 632 case HISTOGRAM:
642 histogram = Histogram::PersistentCreate( 633 histogram = Histogram::PersistentCreate(
643 name, histogram_data.minimum, histogram_data.maximum, ranges, 634 name, histogram_data.minimum, histogram_data.maximum, ranges,
644 counts_data, logged_data, &histogram_data_ptr->samples_metadata, 635 counts_data, logged_data, histogram_data.bucket_count,
636 &histogram_data_ptr->samples_metadata,
645 &histogram_data_ptr->logged_metadata); 637 &histogram_data_ptr->logged_metadata);
646 DCHECK(histogram); 638 DCHECK(histogram);
647 break; 639 break;
648 case LINEAR_HISTOGRAM: 640 case LINEAR_HISTOGRAM:
649 histogram = LinearHistogram::PersistentCreate( 641 histogram = LinearHistogram::PersistentCreate(
650 name, histogram_data.minimum, histogram_data.maximum, ranges, 642 name, histogram_data.minimum, histogram_data.maximum, ranges,
651 counts_data, logged_data, &histogram_data_ptr->samples_metadata, 643 counts_data, logged_data, histogram_data.bucket_count,
644 &histogram_data_ptr->samples_metadata,
652 &histogram_data_ptr->logged_metadata); 645 &histogram_data_ptr->logged_metadata);
653 DCHECK(histogram); 646 DCHECK(histogram);
654 break; 647 break;
655 case BOOLEAN_HISTOGRAM: 648 case BOOLEAN_HISTOGRAM:
656 histogram = BooleanHistogram::PersistentCreate( 649 histogram = BooleanHistogram::PersistentCreate(
657 name, ranges, counts_data, logged_data, 650 name, ranges, counts_data, logged_data,
658 &histogram_data_ptr->samples_metadata, 651 &histogram_data_ptr->samples_metadata,
659 &histogram_data_ptr->logged_metadata); 652 &histogram_data_ptr->logged_metadata);
660 DCHECK(histogram); 653 DCHECK(histogram);
661 break; 654 break;
662 case CUSTOM_HISTOGRAM: 655 case CUSTOM_HISTOGRAM:
663 histogram = CustomHistogram::PersistentCreate( 656 histogram = CustomHistogram::PersistentCreate(
664 name, ranges, counts_data, logged_data, 657 name, ranges, counts_data, logged_data, histogram_data.bucket_count,
665 &histogram_data_ptr->samples_metadata, 658 &histogram_data_ptr->samples_metadata,
666 &histogram_data_ptr->logged_metadata); 659 &histogram_data_ptr->logged_metadata);
667 DCHECK(histogram); 660 DCHECK(histogram);
668 break; 661 break;
669 default: 662 default:
670 NOTREACHED(); 663 NOTREACHED();
671 } 664 }
672 665
673 if (histogram) { 666 if (histogram) {
674 DCHECK_EQ(histogram_data.histogram_type, histogram->GetHistogramType()); 667 DCHECK_EQ(histogram_data.histogram_type, histogram->GetHistogramType());
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 while (true) { 953 while (true) {
961 std::unique_ptr<HistogramBase> histogram = 954 std::unique_ptr<HistogramBase> histogram =
962 import_iterator_.GetNextWithIgnore(record_to_ignore); 955 import_iterator_.GetNextWithIgnore(record_to_ignore);
963 if (!histogram) 956 if (!histogram)
964 break; 957 break;
965 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram.release()); 958 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram.release());
966 } 959 }
967 } 960 }
968 961
969 } // namespace base 962 } // namespace base
OLDNEW
« no previous file with comments | « base/metrics/histogram_unittest.cc ('k') | base/metrics/persistent_sample_map.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698