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

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

Issue 2365273004: Initial implementation for sharing field trial state (win) (Closed)
Patch Set: rebase + gclient sync Created 4 years, 2 months 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') | base/metrics/field_trial_unittest.cc » ('j') | 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/build_time.h" 11 #include "base/build_time.h"
12 #include "base/command_line.h"
13 #include "base/feature_list.h"
11 #include "base/logging.h" 14 #include "base/logging.h"
12 #include "base/rand_util.h" 15 #include "base/rand_util.h"
13 #include "base/strings/string_number_conversions.h" 16 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_util.h" 17 #include "base/strings/string_util.h"
15 #include "base/strings/stringprintf.h" 18 #include "base/strings/stringprintf.h"
16 #include "base/strings/utf_string_conversions.h" 19 #include "base/strings/utf_string_conversions.h"
17 20
18 namespace base { 21 namespace base {
19 22
20 namespace { 23 namespace {
21 24
22 // Define a separator character to use when creating a persistent form of an 25 // Define a separator character to use when creating a persistent form of an
23 // instance. This is intended for use as a command line argument, passed to a 26 // instance. This is intended for use as a command line argument, passed to a
24 // second process to mimic our state (i.e., provide the same group name). 27 // second process to mimic our state (i.e., provide the same group name).
25 const char kPersistentStringSeparator = '/'; // Currently a slash. 28 const char kPersistentStringSeparator = '/'; // Currently a slash.
26 29
27 // Define a marker character to be used as a prefix to a trial name on the 30 // Define a marker character to be used as a prefix to a trial name on the
28 // command line which forces its activation. 31 // command line which forces its activation.
29 const char kActivationMarker = '*'; 32 const char kActivationMarker = '*';
30 33
34 // Use shared memory to communicate field trial (experiment) state. Set to false
35 // for now while the implementation is fleshed out (e.g. data format, single
36 // shared memory segment). See https://codereview.chromium.org/2365273004/ and
37 // crbug.com/653874
38 #if defined(OS_WIN)
39 const bool kUseSharedMemoryForFieldTrials = false;
40 #endif
41
31 // Created a time value based on |year|, |month| and |day_of_month| parameters. 42 // Created a time value based on |year|, |month| and |day_of_month| parameters.
32 Time CreateTimeFromParams(int year, int month, int day_of_month) { 43 Time CreateTimeFromParams(int year, int month, int day_of_month) {
33 DCHECK_GT(year, 1970); 44 DCHECK_GT(year, 1970);
34 DCHECK_GT(month, 0); 45 DCHECK_GT(month, 0);
35 DCHECK_LT(month, 13); 46 DCHECK_LT(month, 13);
36 DCHECK_GT(day_of_month, 0); 47 DCHECK_GT(day_of_month, 0);
37 DCHECK_LT(day_of_month, 32); 48 DCHECK_LT(day_of_month, 32);
38 49
39 Time::Exploded exploded; 50 Time::Exploded exploded;
40 exploded.year = year; 51 exploded.year = year;
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 // Call |group()| to mark the trial as "used" and notify observers, if 562 // Call |group()| to mark the trial as "used" and notify observers, if
552 // any. This is useful to ensure that field trials created in child 563 // any. This is useful to ensure that field trials created in child
553 // processes are properly reported in crash reports. 564 // processes are properly reported in crash reports.
554 trial->group(); 565 trial->group();
555 } 566 }
556 } 567 }
557 return true; 568 return true;
558 } 569 }
559 570
560 // static 571 // static
572 void FieldTrialList::CreateTrialsFromCommandLine(
573 const base::CommandLine& cmd_line,
574 const char* field_trial_handle_switch) {
575 DCHECK(global_);
576
577 #if defined(OS_WIN)
578 if (cmd_line.HasSwitch(field_trial_handle_switch)) {
579 std::string arg = cmd_line.GetSwitchValueASCII(field_trial_handle_switch);
580 size_t token = arg.find(",");
581 int field_trial_handle = std::stoi(arg.substr(0, token));
582 int field_trial_length = std::stoi(arg.substr(token + 1, arg.length()));
583
584 HANDLE handle = reinterpret_cast<HANDLE>(field_trial_handle);
585 base::SharedMemoryHandle shm_handle =
586 base::SharedMemoryHandle(handle, base::GetCurrentProcId());
587
588 // Gets deleted when it gets out of scope, but that's OK because we need it
589 // only for the duration of this call currently anyway.
590 base::SharedMemory shared_memory(shm_handle, false);
591 shared_memory.Map(field_trial_length);
592
593 char* field_trial_state = static_cast<char*>(shared_memory.memory());
594 bool result = FieldTrialList::CreateTrialsFromString(
595 std::string(field_trial_state), std::set<std::string>());
596 DCHECK(result);
597 return;
598 }
599 #endif
600
601 if (cmd_line.HasSwitch(switches::kForceFieldTrials)) {
602 bool result = FieldTrialList::CreateTrialsFromString(
603 cmd_line.GetSwitchValueASCII(switches::kForceFieldTrials),
604 std::set<std::string>());
605 DCHECK(result);
606 }
607 }
608
609 // static
610 std::unique_ptr<base::SharedMemory> FieldTrialList::CopyFieldTrialStateToFlags(
611 const char* field_trial_handle_switch,
612 base::CommandLine* cmd_line) {
613 std::string field_trial_states;
614 base::FieldTrialList::AllStatesToString(&field_trial_states);
615 if (!field_trial_states.empty()) {
616 // Use shared memory to pass the state if the feature is enabled, otherwise
617 // fallback to passing it via the command line as a string.
618 #if defined(OS_WIN)
619 if (kUseSharedMemoryForFieldTrials) {
620 std::unique_ptr<base::SharedMemory> shm(new base::SharedMemory());
621 size_t length = field_trial_states.size() + 1;
622 shm->CreateAndMapAnonymous(length);
623 memcpy(shm->memory(), field_trial_states.c_str(), length);
624
625 // HANDLE is just typedef'd to void *
626 auto uintptr_handle =
627 reinterpret_cast<std::uintptr_t>(shm->handle().GetHandle());
628 std::string field_trial_handle =
629 std::to_string(uintptr_handle) + "," + std::to_string(length);
630
631 cmd_line->AppendSwitchASCII(field_trial_handle_switch,
632 field_trial_handle);
633 return shm;
634 }
635 #endif
636 cmd_line->AppendSwitchASCII(switches::kForceFieldTrials,
637 field_trial_states);
638 }
639 return std::unique_ptr<base::SharedMemory>(nullptr);
640 }
641
642 // static
561 FieldTrial* FieldTrialList::CreateFieldTrial( 643 FieldTrial* FieldTrialList::CreateFieldTrial(
562 const std::string& name, 644 const std::string& name,
563 const std::string& group_name) { 645 const std::string& group_name) {
564 DCHECK(global_); 646 DCHECK(global_);
565 DCHECK_GE(name.size(), 0u); 647 DCHECK_GE(name.size(), 0u);
566 DCHECK_GE(group_name.size(), 0u); 648 DCHECK_GE(group_name.size(), 0u);
567 if (name.empty() || group_name.empty() || !global_) 649 if (name.empty() || group_name.empty() || !global_)
568 return NULL; 650 return NULL;
569 651
570 FieldTrial* field_trial = FieldTrialList::Find(name); 652 FieldTrial* field_trial = FieldTrialList::Find(name);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 return; 732 return;
651 } 733 }
652 AutoLock auto_lock(global_->lock_); 734 AutoLock auto_lock(global_->lock_);
653 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name(); 735 CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name();
654 trial->AddRef(); 736 trial->AddRef();
655 trial->SetTrialRegistered(); 737 trial->SetTrialRegistered();
656 global_->registered_[trial->trial_name()] = trial; 738 global_->registered_[trial->trial_name()] = trial;
657 } 739 }
658 740
659 } // namespace base 741 } // namespace base
OLDNEW
« no previous file with comments | « base/metrics/field_trial.h ('k') | base/metrics/field_trial_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698