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

Side by Side Diff: chrome/browser/experiments/memory_ablation_experiment.cc

Issue 2896523004: Touch memory ablation payload in chunks. (Closed)
Patch Set: Clarify Unretained(this) Created 3 years, 7 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 | « chrome/browser/experiments/memory_ablation_experiment.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 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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 "chrome/browser/experiments/memory_ablation_experiment.h" 5 #include "chrome/browser/experiments/memory_ablation_experiment.h"
6 6
7 #include <algorithm>
7 #include <limits> 8 #include <limits>
8 9
9 #include "base/bind.h" 10 #include "base/bind.h"
10 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
11 #include "base/debug/alias.h" 12 #include "base/debug/alias.h"
12 #include "base/metrics/field_trial_params.h" 13 #include "base/metrics/field_trial_params.h"
13 #include "base/process/process_metrics.h" 14 #include "base/process/process_metrics.h"
14 #include "base/sequenced_task_runner.h" 15 #include "base/sequenced_task_runner.h"
15 #include "base/sys_info.h" 16 #include "base/sys_info.h"
16 17
17 const base::Feature kMemoryAblationFeature{"MemoryAblation", 18 const base::Feature kMemoryAblationFeature{"MemoryAblation",
18 base::FEATURE_DISABLED_BY_DEFAULT}; 19 base::FEATURE_DISABLED_BY_DEFAULT};
19 20
20 const char kMemoryAblationFeatureSizeParam[] = "Size"; 21 const char kMemoryAblationFeatureSizeParam[] = "Size";
21 const char kMemoryAblationFeatureMinRAMParam[] = "MinRAM"; 22 const char kMemoryAblationFeatureMinRAMParam[] = "MinRAM";
22 const char kMemoryAblationFeatureMaxRAMParam[] = "MaxRAM"; 23 const char kMemoryAblationFeatureMaxRAMParam[] = "MaxRAM";
23 24
24 constexpr size_t kMemoryAblationDelaySeconds = 5; 25 // Since MaybeStart() is called during startup, we delay the allocation
26 // to avoid slowing things down.
27 constexpr size_t kAllocationDelaySeconds = 5;
28
29 // We need to touch allocated memory to "dirty" it. However, touching
30 // large chunks of memory (even a single byte per page) can be costly
31 // (~60ms per 10MiB on Nexus 5). So we touch in chunks to allow other
32 // things to happen in between. With the following values we'll touch
33 // 2MiB per second, spending ~10% of 250ms time slice per chunk.
34 constexpr size_t kTouchDelayMilliseconds = 250;
35 constexpr size_t kTouchChunkSize = 512 * 1024;
25 36
26 MemoryAblationExperiment::MemoryAblationExperiment() {} 37 MemoryAblationExperiment::MemoryAblationExperiment() {}
27 38
28 MemoryAblationExperiment::~MemoryAblationExperiment() {} 39 MemoryAblationExperiment::~MemoryAblationExperiment() {}
29 40
30 MemoryAblationExperiment* MemoryAblationExperiment::GetInstance() { 41 MemoryAblationExperiment* MemoryAblationExperiment::GetInstance() {
31 static auto* instance = new MemoryAblationExperiment(); 42 static auto* instance = new MemoryAblationExperiment();
32 return instance; 43 return instance;
33 } 44 }
34 45
(...skipping 14 matching lines...) Expand all
49 kMemoryAblationFeature, kMemoryAblationFeatureSizeParam, 60 kMemoryAblationFeature, kMemoryAblationFeatureSizeParam,
50 0 /* default value */); 61 0 /* default value */);
51 if (size > 0) { 62 if (size > 0) {
52 GetInstance()->Start(task_runner, size); 63 GetInstance()->Start(task_runner, size);
53 } 64 }
54 } 65 }
55 66
56 void MemoryAblationExperiment::Start( 67 void MemoryAblationExperiment::Start(
57 scoped_refptr<base::SequencedTaskRunner> task_runner, 68 scoped_refptr<base::SequencedTaskRunner> task_runner,
58 size_t memory_size) { 69 size_t memory_size) {
59 task_runner->PostDelayedTask( 70 DCHECK(task_runner_ == nullptr) << "Already started";
71 task_runner_ = task_runner;
72 // This class is a singleton, so "Unretained(this)" below is fine.
73 task_runner_->PostDelayedTask(
60 FROM_HERE, 74 FROM_HERE,
61 base::BindOnce(&MemoryAblationExperiment::AllocateMemory, 75 base::BindOnce(&MemoryAblationExperiment::AllocateMemory,
62 base::Unretained(this), memory_size), 76 base::Unretained(this), memory_size),
63 base::TimeDelta::FromSeconds(kMemoryAblationDelaySeconds)); 77 base::TimeDelta::FromSeconds(kAllocationDelaySeconds));
64 } 78 }
65 79
66 void MemoryAblationExperiment::AllocateMemory(size_t size) { 80 void MemoryAblationExperiment::AllocateMemory(size_t size) {
67 memory_size_ = size; 81 memory_size_ = size;
68 memory_.reset(new uint8_t[size]); 82 memory_.reset(new uint8_t[size]);
69 TouchMemory(); 83 ScheduleTouchMemory(0);
70 } 84 }
71 85
72 void MemoryAblationExperiment::TouchMemory() { 86 void MemoryAblationExperiment::TouchMemory(size_t offset) {
73 if (memory_) { 87 if (memory_) {
74 size_t page_size = base::GetPageSize(); 88 size_t page_size = base::GetPageSize();
75 auto* memory = static_cast<volatile uint8_t*>(memory_.get()); 89 auto* memory = static_cast<volatile uint8_t*>(memory_.get());
76 for (size_t i = 0; i < memory_size_; i += page_size) { 90 size_t max_offset = std::min(offset + kTouchChunkSize, memory_size_);
77 memory[i] = i; 91 for (; offset < max_offset; offset += page_size) {
92 memory[offset] = static_cast<uint8_t>(offset);
78 } 93 }
79 base::debug::Alias(memory_.get()); 94 base::debug::Alias(memory_.get());
95 if (offset < memory_size_) {
96 ScheduleTouchMemory(offset);
97 }
80 } 98 }
81 } 99 }
100
101 void MemoryAblationExperiment::ScheduleTouchMemory(size_t offset) {
102 // This class is a singleton, so "Unretained(this)" below is fine.
103 task_runner_->PostDelayedTask(
104 FROM_HERE,
105 base::BindOnce(&MemoryAblationExperiment::TouchMemory,
106 base::Unretained(this), offset),
107 base::TimeDelta::FromMilliseconds(kTouchDelayMilliseconds));
108 }
OLDNEW
« no previous file with comments | « chrome/browser/experiments/memory_ablation_experiment.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698