Chromium Code Reviews| 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" |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 302 : trial_name_(trial_name), | 302 : trial_name_(trial_name), |
| 303 divisor_(total_probability), | 303 divisor_(total_probability), |
| 304 default_group_name_(default_group_name), | 304 default_group_name_(default_group_name), |
| 305 random_(GetGroupBoundaryValue(total_probability, entropy_value)), | 305 random_(GetGroupBoundaryValue(total_probability, entropy_value)), |
| 306 accumulated_group_probability_(0), | 306 accumulated_group_probability_(0), |
| 307 next_group_number_(kDefaultGroupNumber + 1), | 307 next_group_number_(kDefaultGroupNumber + 1), |
| 308 group_(kNotFinalized), | 308 group_(kNotFinalized), |
| 309 enable_field_trial_(true), | 309 enable_field_trial_(true), |
| 310 forced_(false), | 310 forced_(false), |
| 311 group_reported_(false), | 311 group_reported_(false), |
| 312 trial_registered_(false) { | 312 trial_registered_(false), |
| 313 ref_(SharedPersistentMemoryAllocator::kReferenceNull) { | |
| 313 DCHECK_GT(total_probability, 0); | 314 DCHECK_GT(total_probability, 0); |
| 314 DCHECK(!trial_name_.empty()); | 315 DCHECK(!trial_name_.empty()); |
| 315 DCHECK(!default_group_name_.empty()); | 316 DCHECK(!default_group_name_.empty()); |
| 316 } | 317 } |
| 317 | 318 |
| 318 FieldTrial::~FieldTrial() {} | 319 FieldTrial::~FieldTrial() {} |
| 319 | 320 |
| 320 void FieldTrial::SetTrialRegistered() { | 321 void FieldTrial::SetTrialRegistered() { |
| 321 DCHECK_EQ(kNotFinalized, group_); | 322 DCHECK_EQ(kNotFinalized, group_); |
| 322 DCHECK(!trial_registered_); | 323 DCHECK(!trial_registered_); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 333 } | 334 } |
| 334 | 335 |
| 335 void FieldTrial::FinalizeGroupChoice() { | 336 void FieldTrial::FinalizeGroupChoice() { |
| 336 if (group_ != kNotFinalized) | 337 if (group_ != kNotFinalized) |
| 337 return; | 338 return; |
| 338 accumulated_group_probability_ = divisor_; | 339 accumulated_group_probability_ = divisor_; |
| 339 // Here it's OK to use |kDefaultGroupNumber| since we can't be forced and not | 340 // Here it's OK to use |kDefaultGroupNumber| since we can't be forced and not |
| 340 // finalized. | 341 // finalized. |
| 341 DCHECK(!forced_); | 342 DCHECK(!forced_); |
| 342 SetGroupChoice(default_group_name_, kDefaultGroupNumber); | 343 SetGroupChoice(default_group_name_, kDefaultGroupNumber); |
| 344 | |
| 345 // Add the field trial to shared memory. | |
| 346 if (kUseSharedMemoryForFieldTrials) { | |
| 347 SharedPersistentMemoryAllocator* allocator = | |
| 348 FieldTrialList::GetFieldTrialAllocator(); | |
|
Alexei Svitkine (slow)
2016/10/25 19:18:53
I'm not a fan of having a public getter for the al
lawrencewu
2016/10/25 20:27:33
I moved the AddToAllocatorWhileLocked function to
| |
| 349 this->AddToAllocatorWhileLocked(allocator); | |
| 350 } | |
| 343 } | 351 } |
| 344 | 352 |
| 345 bool FieldTrial::GetActiveGroup(ActiveGroup* active_group) const { | 353 bool FieldTrial::GetActiveGroup(ActiveGroup* active_group) const { |
| 346 if (!group_reported_ || !enable_field_trial_) | 354 if (!group_reported_ || !enable_field_trial_) |
| 347 return false; | 355 return false; |
| 348 DCHECK_NE(group_, kNotFinalized); | 356 DCHECK_NE(group_, kNotFinalized); |
| 349 active_group->trial_name = trial_name_; | 357 active_group->trial_name = trial_name_; |
| 350 active_group->group_name = group_name_; | 358 active_group->group_name = group_name_; |
| 351 return true; | 359 return true; |
| 352 } | 360 } |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 779 { | 787 { |
| 780 AutoLock auto_lock(global_->lock_); | 788 AutoLock auto_lock(global_->lock_); |
| 781 if (field_trial->group_reported_) | 789 if (field_trial->group_reported_) |
| 782 return; | 790 return; |
| 783 field_trial->group_reported_ = true; | 791 field_trial->group_reported_ = true; |
| 784 | 792 |
| 785 if (!field_trial->enable_field_trial_) | 793 if (!field_trial->enable_field_trial_) |
| 786 return; | 794 return; |
| 787 | 795 |
| 788 if (kUseSharedMemoryForFieldTrials) { | 796 if (kUseSharedMemoryForFieldTrials) { |
| 789 field_trial->AddToAllocatorWhileLocked( | 797 SharedPersistentMemoryAllocator* allocator = |
|
Alexei Svitkine (slow)
2016/10/25 19:18:53
Nit: Please make a helper function for this block
lawrencewu
2016/10/25 20:27:33
Done.
| |
| 790 global_->field_trial_allocator_.get()); | 798 global_->field_trial_allocator_.get(); |
| 799 SharedPersistentMemoryAllocator::Reference ref = field_trial->ref_; | |
| 800 if (ref == SharedPersistentMemoryAllocator::kReferenceNull) { | |
| 801 // It's fine to do this even if the allocator hasn't been instantiated | |
| 802 // yet -- it'll just return early. | |
| 803 field_trial->AddToAllocatorWhileLocked(allocator); | |
| 804 } else { | |
| 805 FieldTrialEntry* entry = | |
| 806 allocator->GetAsObject<FieldTrialEntry>(ref, kFieldTrialType); | |
| 807 entry->activated = true; | |
| 808 } | |
| 791 } | 809 } |
| 792 } | 810 } |
| 793 | 811 |
| 794 global_->observer_list_->Notify( | 812 global_->observer_list_->Notify( |
| 795 FROM_HERE, &FieldTrialList::Observer::OnFieldTrialGroupFinalized, | 813 FROM_HERE, &FieldTrialList::Observer::OnFieldTrialGroupFinalized, |
| 796 field_trial->trial_name(), field_trial->group_name_internal()); | 814 field_trial->trial_name(), field_trial->group_name_internal()); |
| 797 } | 815 } |
| 798 | 816 |
| 799 #if !defined(OS_NACL) | 817 #if !defined(OS_NACL) |
| 800 // static | 818 // static |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 828 #endif | 846 #endif |
| 829 } | 847 } |
| 830 #endif | 848 #endif |
| 831 | 849 |
| 832 void FieldTrial::AddToAllocatorWhileLocked( | 850 void FieldTrial::AddToAllocatorWhileLocked( |
| 833 SharedPersistentMemoryAllocator* allocator) { | 851 SharedPersistentMemoryAllocator* allocator) { |
| 834 // Don't do anything if the allocator hasn't been instantiated yet. | 852 // Don't do anything if the allocator hasn't been instantiated yet. |
| 835 if (allocator == nullptr) | 853 if (allocator == nullptr) |
| 836 return; | 854 return; |
| 837 | 855 |
| 856 // Or if we've already added it. | |
| 857 if (ref_ != SharedPersistentMemoryAllocator::kReferenceNull) | |
| 858 return; | |
| 859 | |
| 838 State trial_state; | 860 State trial_state; |
| 839 if (!GetState(&trial_state)) | 861 if (!GetState(&trial_state)) |
| 840 return; | 862 return; |
| 841 | 863 |
| 842 size_t trial_name_size = trial_state.trial_name.size() + 1; | 864 size_t trial_name_size = trial_state.trial_name.size() + 1; |
| 843 size_t group_name_size = trial_state.group_name.size() + 1; | 865 size_t group_name_size = trial_state.group_name.size() + 1; |
| 844 size_t size = sizeof(FieldTrialEntry) + trial_name_size + group_name_size; | 866 size_t size = sizeof(FieldTrialEntry) + trial_name_size + group_name_size; |
| 845 | 867 |
| 846 // Allocate just enough memory to fit the FieldTrialEntry struct, trial name, | 868 // Allocate just enough memory to fit the FieldTrialEntry struct, trial name, |
| 847 // and group name. | 869 // and group name. |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 862 char* trial_name = reinterpret_cast<char*>(entry) + trial_name_offset; | 884 char* trial_name = reinterpret_cast<char*>(entry) + trial_name_offset; |
| 863 char* group_name = reinterpret_cast<char*>(entry) + group_name_offset; | 885 char* group_name = reinterpret_cast<char*>(entry) + group_name_offset; |
| 864 memcpy(trial_name, trial_state.trial_name.data(), trial_name_size); | 886 memcpy(trial_name, trial_state.trial_name.data(), trial_name_size); |
| 865 memcpy(group_name, trial_state.group_name.data(), group_name_size); | 887 memcpy(group_name, trial_state.group_name.data(), group_name_size); |
| 866 | 888 |
| 867 // Null terminate the strings. | 889 // Null terminate the strings. |
| 868 trial_name[trial_state.trial_name.size()] = '\0'; | 890 trial_name[trial_state.trial_name.size()] = '\0'; |
| 869 group_name[trial_state.group_name.size()] = '\0'; | 891 group_name[trial_state.group_name.size()] = '\0'; |
| 870 | 892 |
| 871 allocator->MakeIterable(ref); | 893 allocator->MakeIterable(ref); |
| 894 ref_ = ref; | |
| 872 } | 895 } |
| 873 | 896 |
| 874 // static | 897 // static |
| 875 size_t FieldTrialList::GetFieldTrialCount() { | 898 size_t FieldTrialList::GetFieldTrialCount() { |
| 876 if (!global_) | 899 if (!global_) |
| 877 return 0; | 900 return 0; |
| 878 AutoLock auto_lock(global_->lock_); | 901 AutoLock auto_lock(global_->lock_); |
| 879 return global_->registered_.size(); | 902 return global_->registered_.size(); |
| 880 } | 903 } |
| 881 | 904 |
| 882 // static | 905 // static |
| 906 SharedPersistentMemoryAllocator* FieldTrialList::GetFieldTrialAllocator() { | |
| 907 return global_->field_trial_allocator_.get(); | |
| 908 } | |
| 909 | |
| 910 // static | |
| 883 const FieldTrial::EntropyProvider* | 911 const FieldTrial::EntropyProvider* |
| 884 FieldTrialList::GetEntropyProviderForOneTimeRandomization() { | 912 FieldTrialList::GetEntropyProviderForOneTimeRandomization() { |
| 885 if (!global_) { | 913 if (!global_) { |
| 886 used_without_global_ = true; | 914 used_without_global_ = true; |
| 887 return NULL; | 915 return NULL; |
| 888 } | 916 } |
| 889 | 917 |
| 890 return global_->entropy_provider_.get(); | 918 return global_->entropy_provider_.get(); |
| 891 } | 919 } |
| 892 | 920 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 904 return; | 932 return; |
| 905 } | 933 } |
| 906 AutoLock auto_lock(global_->lock_); | 934 AutoLock auto_lock(global_->lock_); |
| 907 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name(); | 935 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name(); |
| 908 trial->AddRef(); | 936 trial->AddRef(); |
| 909 trial->SetTrialRegistered(); | 937 trial->SetTrialRegistered(); |
| 910 global_->registered_[trial->trial_name()] = trial; | 938 global_->registered_[trial->trial_name()] = trial; |
| 911 } | 939 } |
| 912 | 940 |
| 913 } // namespace base | 941 } // namespace base |
| OLD | NEW |