OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/field_trial.h" | 5 #include "base/metrics/field_trial.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/base_switches.h" | 10 #include "base/base_switches.h" |
11 #include "base/build_time.h" | 11 #include "base/build_time.h" |
12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
13 #include "base/feature_list.h" | 13 #include "base/feature_list.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/metrics/histogram_macros.h" |
15 #include "base/process/memory.h" | 16 #include "base/process/memory.h" |
16 #include "base/rand_util.h" | 17 #include "base/rand_util.h" |
17 #include "base/strings/string_number_conversions.h" | 18 #include "base/strings/string_number_conversions.h" |
18 #include "base/strings/string_util.h" | 19 #include "base/strings/string_util.h" |
19 #include "base/strings/stringprintf.h" | 20 #include "base/strings/stringprintf.h" |
20 #include "base/strings/utf_string_conversions.h" | 21 #include "base/strings/utf_string_conversions.h" |
21 | 22 |
22 namespace base { | 23 namespace base { |
23 | 24 |
24 namespace { | 25 namespace { |
(...skipping 22 matching lines...) Expand all Loading... |
47 | 48 |
48 // We create one FieldTrialEntry struct per field trial in shared memory (via | 49 // We create one FieldTrialEntry struct per field trial in shared memory (via |
49 // field_trial_allocator_). It contains whether or not it's activated, and the | 50 // field_trial_allocator_). It contains whether or not it's activated, and the |
50 // offset from the start of the allocated memory to the group name. We don't | 51 // offset from the start of the allocated memory to the group name. We don't |
51 // need the offset into the trial name because that's always a fixed position | 52 // need the offset into the trial name because that's always a fixed position |
52 // from the start of the struct. Two strings will be appended to the end of this | 53 // from the start of the struct. Two strings will be appended to the end of this |
53 // structure in allocated memory, so the result will look like this: | 54 // structure in allocated memory, so the result will look like this: |
54 // --------------------------------- | 55 // --------------------------------- |
55 // | fte | trial_name | group_name | | 56 // | fte | trial_name | group_name | |
56 // --------------------------------- | 57 // --------------------------------- |
57 // TODO(lawrencewu): Actually update the activated flag. | |
58 struct FieldTrialEntry { | 58 struct FieldTrialEntry { |
59 bool activated; | 59 bool activated; |
60 uint32_t group_name_offset; | 60 uint32_t group_name_offset; |
61 | 61 |
62 const char* GetTrialName() const { | 62 const char* GetTrialName() const { |
63 const char* src = | 63 const char* src = |
64 reinterpret_cast<char*>(const_cast<FieldTrialEntry*>(this)); | 64 reinterpret_cast<char*>(const_cast<FieldTrialEntry*>(this)); |
65 return src + sizeof(FieldTrialEntry); | 65 return src + sizeof(FieldTrialEntry); |
66 } | 66 } |
67 | 67 |
(...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
698 // command-line flag. The child process will do the reverse conversions to | 698 // command-line flag. The child process will do the reverse conversions to |
699 // retrieve the handle. See http://stackoverflow.com/a/153077 | 699 // retrieve the handle. See http://stackoverflow.com/a/153077 |
700 auto uintptr_handle = | 700 auto uintptr_handle = |
701 reinterpret_cast<uintptr_t>(global_->readonly_allocator_handle_); | 701 reinterpret_cast<uintptr_t>(global_->readonly_allocator_handle_); |
702 size_t field_trial_length = | 702 size_t field_trial_length = |
703 global_->field_trial_allocator_->shared_memory()->mapped_size(); | 703 global_->field_trial_allocator_->shared_memory()->mapped_size(); |
704 std::string field_trial_handle = std::to_string(uintptr_handle) + "," + | 704 std::string field_trial_handle = std::to_string(uintptr_handle) + "," + |
705 std::to_string(field_trial_length); | 705 std::to_string(field_trial_length); |
706 | 706 |
707 cmd_line->AppendSwitchASCII(field_trial_handle_switch, field_trial_handle); | 707 cmd_line->AppendSwitchASCII(field_trial_handle_switch, field_trial_handle); |
| 708 UMA_HISTOGRAM_COUNTS_10000("UMA.FieldTrialAllocator.Size", |
| 709 field_trial_length); |
708 return; | 710 return; |
709 } | 711 } |
710 #endif | 712 #endif |
711 | 713 |
712 AddForceFieldTrialsFlag(cmd_line); | 714 AddForceFieldTrialsFlag(cmd_line); |
713 } | 715 } |
714 | 716 |
715 // static | 717 // static |
716 FieldTrial* FieldTrialList::CreateFieldTrial( | 718 FieldTrial* FieldTrialList::CreateFieldTrial( |
717 const std::string& name, | 719 const std::string& name, |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
822 return; | 824 return; |
823 AutoLock auto_lock(global_->lock_); | 825 AutoLock auto_lock(global_->lock_); |
824 // Create the allocator if not already created and add all existing trials. | 826 // Create the allocator if not already created and add all existing trials. |
825 if (global_->field_trial_allocator_ != nullptr) | 827 if (global_->field_trial_allocator_ != nullptr) |
826 return; | 828 return; |
827 | 829 |
828 std::unique_ptr<SharedMemory> shm(new SharedMemory()); | 830 std::unique_ptr<SharedMemory> shm(new SharedMemory()); |
829 if (!shm->CreateAndMapAnonymous(kFieldTrialAllocationSize)) | 831 if (!shm->CreateAndMapAnonymous(kFieldTrialAllocationSize)) |
830 TerminateBecauseOutOfMemory(kFieldTrialAllocationSize); | 832 TerminateBecauseOutOfMemory(kFieldTrialAllocationSize); |
831 | 833 |
832 // TODO(lawrencewu): call UpdateTrackingHistograms() when all field trials | |
833 // have been registered (perhaps in the destructor?) | |
834 global_->field_trial_allocator_.reset(new SharedPersistentMemoryAllocator( | 834 global_->field_trial_allocator_.reset(new SharedPersistentMemoryAllocator( |
835 std::move(shm), 0, kAllocatorName, false)); | 835 std::move(shm), 0, kAllocatorName, false)); |
836 global_->field_trial_allocator_->CreateTrackingHistograms(kAllocatorName); | 836 global_->field_trial_allocator_->CreateTrackingHistograms(kAllocatorName); |
837 | 837 |
838 // Add all existing field trials. | 838 // Add all existing field trials. |
839 for (const auto& registered : global_->registered_) { | 839 for (const auto& registered : global_->registered_) { |
840 AddToAllocatorWhileLocked(registered.second); | 840 AddToAllocatorWhileLocked(registered.second); |
841 } | 841 } |
842 | 842 |
843 #if defined(OS_WIN) | 843 #if defined(OS_WIN) |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
944 return; | 944 return; |
945 } | 945 } |
946 AutoLock auto_lock(global_->lock_); | 946 AutoLock auto_lock(global_->lock_); |
947 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name(); | 947 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name(); |
948 trial->AddRef(); | 948 trial->AddRef(); |
949 trial->SetTrialRegistered(); | 949 trial->SetTrialRegistered(); |
950 global_->registered_[trial->trial_name()] = trial; | 950 global_->registered_[trial->trial_name()] = trial; |
951 } | 951 } |
952 | 952 |
953 } // namespace base | 953 } // namespace base |
OLD | NEW |