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

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

Issue 2449143002: Actually update FieldTrialEntry's activated field (Closed)
Patch Set: address comments Created 4 years, 1 month 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
« base/metrics/field_trial.h ('K') | « base/metrics/field_trial.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 FieldTrialList::AddToAllocator(this);
343 } 348 }
344 349
345 bool FieldTrial::GetActiveGroup(ActiveGroup* active_group) const { 350 bool FieldTrial::GetActiveGroup(ActiveGroup* active_group) const {
346 if (!group_reported_ || !enable_field_trial_) 351 if (!group_reported_ || !enable_field_trial_)
347 return false; 352 return false;
348 DCHECK_NE(group_, kNotFinalized); 353 DCHECK_NE(group_, kNotFinalized);
349 active_group->trial_name = trial_name_; 354 active_group->trial_name = trial_name_;
350 active_group->group_name = group_name_; 355 active_group->group_name = group_name_;
351 return true; 356 return true;
352 } 357 }
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
777 return; 782 return;
778 783
779 { 784 {
780 AutoLock auto_lock(global_->lock_); 785 AutoLock auto_lock(global_->lock_);
781 if (field_trial->group_reported_) 786 if (field_trial->group_reported_)
782 return; 787 return;
783 field_trial->group_reported_ = true; 788 field_trial->group_reported_ = true;
784 789
785 if (!field_trial->enable_field_trial_) 790 if (!field_trial->enable_field_trial_)
786 return; 791 return;
792 }
787 793
788 if (kUseSharedMemoryForFieldTrials) { 794 if (kUseSharedMemoryForFieldTrials)
789 field_trial->AddToAllocatorWhileLocked( 795 ActivateFieldTrialEntry(field_trial);
790 global_->field_trial_allocator_.get());
791 }
792 }
793 796
794 global_->observer_list_->Notify( 797 global_->observer_list_->Notify(
795 FROM_HERE, &FieldTrialList::Observer::OnFieldTrialGroupFinalized, 798 FROM_HERE, &FieldTrialList::Observer::OnFieldTrialGroupFinalized,
796 field_trial->trial_name(), field_trial->group_name_internal()); 799 field_trial->trial_name(), field_trial->group_name_internal());
797 } 800 }
798 801
802 // static
803 void FieldTrialList::ActivateFieldTrialEntry(FieldTrial* field_trial) {
804 SharedPersistentMemoryAllocator* allocator =
805 global_->field_trial_allocator_.get();
806 SharedPersistentMemoryAllocator::Reference ref = field_trial->ref_;
807 if (ref == SharedPersistentMemoryAllocator::kReferenceNull) {
808 // It's fine to do this even if the allocator hasn't been instantiated
809 // yet -- it'll just return early.
810 AddToAllocator(field_trial);
811 } else {
812 // It's also okay to do this even though the callee doesn't have a lock --
813 // the only thing that happens on a stale read here is a slight performance
814 // hit from the child re-synchronizing activation state.
815 FieldTrialEntry* entry =
816 allocator->GetAsObject<FieldTrialEntry>(ref, kFieldTrialType);
817 entry->activated = true;
818 }
819 }
820
799 #if !defined(OS_NACL) 821 #if !defined(OS_NACL)
800 // static 822 // static
801 void FieldTrialList::InstantiateFieldTrialAllocatorIfNeeded() { 823 void FieldTrialList::InstantiateFieldTrialAllocatorIfNeeded() {
802 AutoLock auto_lock(global_->lock_); 824 if (!global_)
803 // Create the allocator if not already created and add all existing trials.
804 if (global_->field_trial_allocator_ != nullptr)
805 return; 825 return;
826 {
827 AutoLock auto_lock(global_->lock_);
828 // Create the allocator if not already created and add all existing trials.
829 if (global_->field_trial_allocator_ != nullptr)
830 return;
806 831
807 std::unique_ptr<SharedMemory> shm(new SharedMemory()); 832 std::unique_ptr<SharedMemory> shm(new SharedMemory());
808 if (!shm->CreateAndMapAnonymous(kFieldTrialAllocationSize)) 833 if (!shm->CreateAndMapAnonymous(kFieldTrialAllocationSize))
809 TerminateBecauseOutOfMemory(kFieldTrialAllocationSize); 834 TerminateBecauseOutOfMemory(kFieldTrialAllocationSize);
810 835
811 // TODO(lawrencewu): call UpdateTrackingHistograms() when all field trials 836 // TODO(lawrencewu): call UpdateTrackingHistograms() when all field trials
812 // have been registered (perhaps in the destructor?) 837 // have been registered (perhaps in the destructor?)
813 global_->field_trial_allocator_.reset(new SharedPersistentMemoryAllocator( 838 global_->field_trial_allocator_.reset(new SharedPersistentMemoryAllocator(
814 std::move(shm), 0, kAllocatorName, false)); 839 std::move(shm), 0, kAllocatorName, false));
815 global_->field_trial_allocator_->CreateTrackingHistograms(kAllocatorName); 840 global_->field_trial_allocator_->CreateTrackingHistograms(kAllocatorName);
816 841
817 // Add all existing field trials. 842 #if defined(OS_WIN)
818 for (const auto& registered : global_->registered_) { 843 // Set |readonly_allocator_handle_| so we can pass it to be inherited and
819 registered.second->AddToAllocatorWhileLocked( 844 // via the command line.
820 global_->field_trial_allocator_.get()); 845 global_->readonly_allocator_handle_ =
846 CreateReadOnlyHandle(global_->field_trial_allocator_.get());
847 #endif
821 } 848 }
822 849
823 #if defined(OS_WIN) 850 // Add all existing field trials. Needs to be outside the lock since
824 // Set |readonly_allocator_handle_| so we can pass it to be inherited and via 851 // AddToAllocator locks as well.
825 // the command line. 852 for (const auto& registered : global_->registered_) {
826 global_->readonly_allocator_handle_ = 853 AddToAllocator(registered.second);
827 CreateReadOnlyHandle(global_->field_trial_allocator_.get()); 854 }
828 #endif
829 } 855 }
830 #endif 856 #endif
831 857
832 void FieldTrial::AddToAllocatorWhileLocked( 858 // static
833 SharedPersistentMemoryAllocator* allocator) { 859 size_t FieldTrialList::GetFieldTrialCount() {
860 if (!global_)
861 return 0;
862 AutoLock auto_lock(global_->lock_);
863 return global_->registered_.size();
864 }
865
866 // static
867 void FieldTrialList::AddToAllocator(FieldTrial* field_trial) {
868 if (!global_)
869 return;
870 AutoLock auto_lock(global_->lock_);
871
872 SharedPersistentMemoryAllocator* allocator =
873 global_->field_trial_allocator_.get();
874
834 // Don't do anything if the allocator hasn't been instantiated yet. 875 // Don't do anything if the allocator hasn't been instantiated yet.
835 if (allocator == nullptr) 876 if (allocator == nullptr)
836 return; 877 return;
837 878
838 State trial_state; 879 // Or if we've already added it.
839 if (!GetState(&trial_state)) 880 if (field_trial->ref_ != SharedPersistentMemoryAllocator::kReferenceNull)
881 return;
882
883 FieldTrial::State trial_state;
884 if (!field_trial->GetState(&trial_state))
840 return; 885 return;
841 886
842 size_t trial_name_size = trial_state.trial_name.size() + 1; 887 size_t trial_name_size = trial_state.trial_name.size() + 1;
843 size_t group_name_size = trial_state.group_name.size() + 1; 888 size_t group_name_size = trial_state.group_name.size() + 1;
844 size_t size = sizeof(FieldTrialEntry) + trial_name_size + group_name_size; 889 size_t size = sizeof(FieldTrialEntry) + trial_name_size + group_name_size;
845 890
846 // Allocate just enough memory to fit the FieldTrialEntry struct, trial name, 891 // Allocate just enough memory to fit the FieldTrialEntry struct, trial name,
847 // and group name. 892 // and group name.
848 SharedPersistentMemoryAllocator::Reference ref = 893 SharedPersistentMemoryAllocator::Reference ref =
849 allocator->Allocate(size, kFieldTrialType); 894 allocator->Allocate(size, kFieldTrialType);
(...skipping 12 matching lines...) Expand all
862 char* trial_name = reinterpret_cast<char*>(entry) + trial_name_offset; 907 char* trial_name = reinterpret_cast<char*>(entry) + trial_name_offset;
863 char* group_name = reinterpret_cast<char*>(entry) + group_name_offset; 908 char* group_name = reinterpret_cast<char*>(entry) + group_name_offset;
864 memcpy(trial_name, trial_state.trial_name.data(), trial_name_size); 909 memcpy(trial_name, trial_state.trial_name.data(), trial_name_size);
865 memcpy(group_name, trial_state.group_name.data(), group_name_size); 910 memcpy(group_name, trial_state.group_name.data(), group_name_size);
866 911
867 // Null terminate the strings. 912 // Null terminate the strings.
868 trial_name[trial_state.trial_name.size()] = '\0'; 913 trial_name[trial_state.trial_name.size()] = '\0';
869 group_name[trial_state.group_name.size()] = '\0'; 914 group_name[trial_state.group_name.size()] = '\0';
870 915
871 allocator->MakeIterable(ref); 916 allocator->MakeIterable(ref);
917 field_trial->ref_ = ref;
872 } 918 }
873 919
874 // static 920 // static
875 size_t FieldTrialList::GetFieldTrialCount() {
876 if (!global_)
877 return 0;
878 AutoLock auto_lock(global_->lock_);
879 return global_->registered_.size();
880 }
881
882 // static
883 const FieldTrial::EntropyProvider* 921 const FieldTrial::EntropyProvider*
884 FieldTrialList::GetEntropyProviderForOneTimeRandomization() { 922 FieldTrialList::GetEntropyProviderForOneTimeRandomization() {
885 if (!global_) { 923 if (!global_) {
886 used_without_global_ = true; 924 used_without_global_ = true;
887 return NULL; 925 return NULL;
888 } 926 }
889 927
890 return global_->entropy_provider_.get(); 928 return global_->entropy_provider_.get();
891 } 929 }
892 930
(...skipping 11 matching lines...) Expand all
904 return; 942 return;
905 } 943 }
906 AutoLock auto_lock(global_->lock_); 944 AutoLock auto_lock(global_->lock_);
907 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name(); 945 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name();
908 trial->AddRef(); 946 trial->AddRef();
909 trial->SetTrialRegistered(); 947 trial->SetTrialRegistered();
910 global_->registered_[trial->trial_name()] = trial; 948 global_->registered_[trial->trial_name()] = trial;
911 } 949 }
912 950
913 } // namespace base 951 } // namespace base
OLDNEW
« base/metrics/field_trial.h ('K') | « base/metrics/field_trial.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698