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

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

Issue 2570473003: NoBarrier_Load()/NoBarrier_Store() for manipulating activated field. (Closed)
Patch Set: Created 4 years 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/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 708 matching lines...) Expand 10 before | Expand all | Expand 10 after
719 FieldTrialAllocator::Iterator mem_iter(allocator); 719 FieldTrialAllocator::Iterator mem_iter(allocator);
720 FieldTrial::FieldTrialRef ref; 720 FieldTrial::FieldTrialRef ref;
721 while ((ref = mem_iter.GetNextOfType(kFieldTrialType)) != 721 while ((ref = mem_iter.GetNextOfType(kFieldTrialType)) !=
722 SharedPersistentMemoryAllocator::kReferenceNull) { 722 SharedPersistentMemoryAllocator::kReferenceNull) {
723 const FieldTrial::FieldTrialEntry* entry = 723 const FieldTrial::FieldTrialEntry* entry =
724 allocator->GetAsObject<const FieldTrial::FieldTrialEntry>( 724 allocator->GetAsObject<const FieldTrial::FieldTrialEntry>(
725 ref, kFieldTrialType); 725 ref, kFieldTrialType);
726 726
727 StringPiece trial_name; 727 StringPiece trial_name;
728 StringPiece group_name; 728 StringPiece group_name;
729 if (entry->activated && 729 if (subtle::NoBarrier_Load(&entry->activated) &&
730 entry->GetTrialAndGroupName(&trial_name, &group_name)) { 730 entry->GetTrialAndGroupName(&trial_name, &group_name)) {
731 FieldTrial::ActiveGroup group; 731 FieldTrial::ActiveGroup group;
732 group.trial_name = trial_name.as_string(); 732 group.trial_name = trial_name.as_string();
733 group.group_name = group_name.as_string(); 733 group.group_name = group_name.as_string();
734 active_groups->push_back(group); 734 active_groups->push_back(group);
735 } 735 }
736 } 736 }
737 } 737 }
738 738
739 // static 739 // static
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
1076 // Write a new entry, minus the params. 1076 // Write a new entry, minus the params.
1077 Pickle pickle; 1077 Pickle pickle;
1078 pickle.WriteString(trial_name); 1078 pickle.WriteString(trial_name);
1079 pickle.WriteString(group_name); 1079 pickle.WriteString(group_name);
1080 size_t total_size = sizeof(FieldTrial::FieldTrialEntry) + pickle.size(); 1080 size_t total_size = sizeof(FieldTrial::FieldTrialEntry) + pickle.size();
1081 FieldTrial::FieldTrialRef new_ref = 1081 FieldTrial::FieldTrialRef new_ref =
1082 allocator->Allocate(total_size, kFieldTrialType); 1082 allocator->Allocate(total_size, kFieldTrialType);
1083 FieldTrial::FieldTrialEntry* new_entry = 1083 FieldTrial::FieldTrialEntry* new_entry =
1084 allocator->GetAsObject<FieldTrial::FieldTrialEntry>(new_ref, 1084 allocator->GetAsObject<FieldTrial::FieldTrialEntry>(new_ref,
1085 kFieldTrialType); 1085 kFieldTrialType);
1086 // Note: No need to use NoBarrier ops below because this is the browser
1087 // process so the value we're reading won't change underneath us and the new
1088 // entry we're assigning to is not iterable yet.
1086 new_entry->activated = prev_entry->activated; 1089 new_entry->activated = prev_entry->activated;
bcwhite 2016/12/13 13:38:50 These need to be accessed using atomic ops or you'
Alexei Svitkine (slow) 2016/12/13 15:26:04 Done.
1087 new_entry->pickle_size = pickle.size(); 1090 new_entry->pickle_size = pickle.size();
1088 1091
1089 // TODO(lawrencewu): Modify base::Pickle to be able to write over a section 1092 // TODO(lawrencewu): Modify base::Pickle to be able to write over a section
1090 // in memory, so we can avoid this memcpy. 1093 // in memory, so we can avoid this memcpy.
1091 char* dst = reinterpret_cast<char*>(new_entry) + 1094 char* dst = reinterpret_cast<char*>(new_entry) +
1092 sizeof(FieldTrial::FieldTrialEntry); 1095 sizeof(FieldTrial::FieldTrialEntry);
1093 memcpy(dst, pickle.data(), pickle.size()); 1096 memcpy(dst, pickle.data(), pickle.size());
1094 1097
1095 // Update the ref on the field trial and add it to the list to be made 1098 // Update the ref on the field trial and add it to the list to be made
1096 // iterable. 1099 // iterable.
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1179 StringPiece group_name; 1182 StringPiece group_name;
1180 if (!entry->GetTrialAndGroupName(&trial_name, &group_name)) 1183 if (!entry->GetTrialAndGroupName(&trial_name, &group_name))
1181 return false; 1184 return false;
1182 1185
1183 // TODO(lawrencewu): Convert the API for CreateFieldTrial to take 1186 // TODO(lawrencewu): Convert the API for CreateFieldTrial to take
1184 // StringPieces. 1187 // StringPieces.
1185 FieldTrial* trial = 1188 FieldTrial* trial =
1186 CreateFieldTrial(trial_name.as_string(), group_name.as_string()); 1189 CreateFieldTrial(trial_name.as_string(), group_name.as_string());
1187 1190
1188 trial->ref_ = ref; 1191 trial->ref_ = ref;
1189 if (entry->activated) { 1192 if (subtle::NoBarrier_Load(&entry->activated)) {
1190 // Call |group()| to mark the trial as "used" and notify observers, if 1193 // Call |group()| to mark the trial as "used" and notify observers, if
1191 // any. This is useful to ensure that field trials created in child 1194 // any. This is useful to ensure that field trials created in child
1192 // processes are properly reported in crash reports. 1195 // processes are properly reported in crash reports.
1193 trial->group(); 1196 trial->group();
1194 } 1197 }
1195 } 1198 }
1196 return true; 1199 return true;
1197 } 1200 }
1198 1201
1199 #if !defined(OS_NACL) 1202 #if !defined(OS_NACL)
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1271 size_t total_size = sizeof(FieldTrial::FieldTrialEntry) + pickle.size(); 1274 size_t total_size = sizeof(FieldTrial::FieldTrialEntry) + pickle.size();
1272 FieldTrial::FieldTrialRef ref = 1275 FieldTrial::FieldTrialRef ref =
1273 allocator->Allocate(total_size, kFieldTrialType); 1276 allocator->Allocate(total_size, kFieldTrialType);
1274 if (ref == FieldTrialAllocator::kReferenceNull) { 1277 if (ref == FieldTrialAllocator::kReferenceNull) {
1275 NOTREACHED(); 1278 NOTREACHED();
1276 return; 1279 return;
1277 } 1280 }
1278 1281
1279 FieldTrial::FieldTrialEntry* entry = 1282 FieldTrial::FieldTrialEntry* entry =
1280 allocator->GetAsObject<FieldTrial::FieldTrialEntry>(ref, kFieldTrialType); 1283 allocator->GetAsObject<FieldTrial::FieldTrialEntry>(ref, kFieldTrialType);
1284 // Note: The entry isn't iterable yet, so no need to use NoBarrier_Store().
1281 entry->activated = trial_state.activated; 1285 entry->activated = trial_state.activated;
bcwhite 2016/12/13 13:38:50 Still need to so "linters" and "sanitizers" won't
Alexei Svitkine (slow) 2016/12/13 15:26:04 Done.
1282 entry->pickle_size = pickle.size(); 1286 entry->pickle_size = pickle.size();
1283 1287
1284 // TODO(lawrencewu): Modify base::Pickle to be able to write over a section in 1288 // TODO(lawrencewu): Modify base::Pickle to be able to write over a section in
1285 // memory, so we can avoid this memcpy. 1289 // memory, so we can avoid this memcpy.
1286 char* dst = 1290 char* dst =
1287 reinterpret_cast<char*>(entry) + sizeof(FieldTrial::FieldTrialEntry); 1291 reinterpret_cast<char*>(entry) + sizeof(FieldTrial::FieldTrialEntry);
1288 memcpy(dst, pickle.data(), pickle.size()); 1292 memcpy(dst, pickle.data(), pickle.size());
1289 1293
1290 allocator->MakeIterable(ref); 1294 allocator->MakeIterable(ref);
1291 field_trial->ref_ = ref; 1295 field_trial->ref_ = ref;
(...skipping 14 matching lines...) Expand all
1306 // yet -- it'll just return early. 1310 // yet -- it'll just return early.
1307 AddToAllocatorWhileLocked(global_->field_trial_allocator_.get(), 1311 AddToAllocatorWhileLocked(global_->field_trial_allocator_.get(),
1308 field_trial); 1312 field_trial);
1309 } else { 1313 } else {
1310 // It's also okay to do this even though the callee doesn't have a lock -- 1314 // It's also okay to do this even though the callee doesn't have a lock --
1311 // the only thing that happens on a stale read here is a slight performance 1315 // the only thing that happens on a stale read here is a slight performance
1312 // hit from the child re-synchronizing activation state. 1316 // hit from the child re-synchronizing activation state.
1313 FieldTrial::FieldTrialEntry* entry = 1317 FieldTrial::FieldTrialEntry* entry =
1314 allocator->GetAsObject<FieldTrial::FieldTrialEntry>(ref, 1318 allocator->GetAsObject<FieldTrial::FieldTrialEntry>(ref,
1315 kFieldTrialType); 1319 kFieldTrialType);
1316 entry->activated = true; 1320 subtle::NoBarrier_Store(&entry->activated, 1);
1317 } 1321 }
1318 } 1322 }
1319 1323
1320 // static 1324 // static
1321 const FieldTrial::EntropyProvider* 1325 const FieldTrial::EntropyProvider*
1322 FieldTrialList::GetEntropyProviderForOneTimeRandomization() { 1326 FieldTrialList::GetEntropyProviderForOneTimeRandomization() {
1323 if (!global_) { 1327 if (!global_) {
1324 used_without_global_ = true; 1328 used_without_global_ = true;
1325 return NULL; 1329 return NULL;
1326 } 1330 }
(...skipping 15 matching lines...) Expand all
1342 return; 1346 return;
1343 } 1347 }
1344 AutoLock auto_lock(global_->lock_); 1348 AutoLock auto_lock(global_->lock_);
1345 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name(); 1349 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name();
1346 trial->AddRef(); 1350 trial->AddRef();
1347 trial->SetTrialRegistered(); 1351 trial->SetTrialRegistered();
1348 global_->registered_[trial->trial_name()] = trial; 1352 global_->registered_[trial->trial_name()] = trial;
1349 } 1353 }
1350 1354
1351 } // namespace base 1355 } // namespace base
OLDNEW
« no previous file with comments | « base/metrics/field_trial.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698