| 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 |