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 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |