Index: chrome/browser/chromeos/arc/arc_lowmemorykiller_monitor.cc |
diff --git a/chrome/browser/chromeos/arc/arc_lowmemorykiller_monitor.cc b/chrome/browser/chromeos/arc/arc_lowmemorykiller_monitor.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..47ac33463e62a7a479229f82dc588e2a4371c72d |
--- /dev/null |
+++ b/chrome/browser/chromeos/arc/arc_lowmemorykiller_monitor.cc |
@@ -0,0 +1,93 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
Yusuke Sato
2016/03/12 00:24:29
high level question: what's the point for having t
cylee1
2016/03/14 13:03:35
It's a good question. Though it didn't ARC specifi
|
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/chromeos/arc/arc_lowmemorykiller_monitor.h" |
Yusuke Sato
2016/03/12 00:24:29
I believe the general mapping rule for class/file
cylee1
2016/03/14 13:03:35
Done.
|
+ |
+#include <vector> |
+ |
+#include "base/bind.h" |
+#include "base/location.h" |
+#include "base/logging.h" |
+#include "base/memory/ref_counted.h" |
+#include "base/metrics/histogram_macros.h" |
+#include "base/sequenced_task_runner.h" |
+#include "base/strings/string_number_conversions.h" |
+#include "base/strings/string_split.h" |
+#include "base/time/time.h" |
+#include "third_party/re2/src/re2/re2.h" |
+ |
+namespace arc { |
+ |
+using base::SequencedWorkerPool; |
+using base::TimeDelta; |
Yusuke Sato
2016/03/12 00:24:29
Can you sort them alphabetically?
cylee1
2016/03/14 13:03:35
Done.
|
+using base::StringPiece; |
+ |
+#define UMA_HISTOGRAM_LOWMEMORYKILL_TIMES(name, sample) \ |
+ UMA_HISTOGRAM_CUSTOM_TIMES( \ |
+ name, sample, base::TimeDelta::FromMilliseconds(1), \ |
+ base::TimeDelta::FromSeconds(30), 50) |
+ |
+ArcLowMemoryKillerMonitor::ArcLowMemoryKillerMonitor() |
+ : worker_pool_(new SequencedWorkerPool(1, "arc_lmk_monitor")) {} |
Yusuke Sato
2016/03/12 00:24:29
please spell that out. lmk -> low_memory_killer
h
cylee1
2016/03/14 13:03:35
Done.
|
+ |
+ArcLowMemoryKillerMonitor::~ArcLowMemoryKillerMonitor() { |
+ Stop(); |
+} |
+ |
+void ArcLowMemoryKillerMonitor::Start() { |
+ auto task_runner = worker_pool_->GetTaskRunnerWithShutdownBehavior( |
+ SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); |
+ task_runner->PostTask( |
+ FROM_HERE, |
+ base::Bind(&ArcLowMemoryKillerMonitor::Run, base::Unretained(this))); |
Yusuke Sato
2016/03/12 00:24:29
* Is it always safe to use Unretained(this)? What'
cylee1
2016/03/14 13:03:35
* The life cycle of |this| is meant to be the same
Yusuke Sato
2016/03/14 18:02:12
Copying a smart pointer seems just fine. What I'm
cylee1
2016/03/15 12:49:15
I see. Changed.
|
+} |
+ |
+void ArcLowMemoryKillerMonitor::Stop() { |
+ worker_pool_->Shutdown(); |
+} |
+ |
+void ArcLowMemoryKillerMonitor::Run() { |
+ // Keep a reference to worker_pool_ in case |this| is deleted in |
+ // shutdown process while this thread returns from a blocking read. |
+ scoped_refptr<SequencedWorkerPool> worker_pool(worker_pool_); |
Yusuke Sato
2016/03/12 00:24:29
Is SequencedWorkerPool derived from RefCountedThre
cylee1
2016/03/14 13:03:35
Acknowledged.
|
+ |
+ static const int kMaxBufSize = 512; |
+ |
+ FILE* kmsg_fd = fopen("/dev/kmsg", "r"); |
Yusuke Sato
2016/03/12 00:24:29
Using the raw stdio library seems error-prone. Can
cylee1
2016/03/14 13:03:35
I didn't see class like FileLineReader in chrome c
|
+ char buf[kMaxBufSize]; |
+ int freed_size; |
+ int64_t timestamp, last_timestamp = -1; |
+ TimeDelta time_delta; |
Yusuke Sato
2016/03/12 00:24:29
Add a variable comment please (to explain what thi
cylee1
2016/03/14 13:03:35
Done.
|
+ |
+ while (fgets(buf, kMaxBufSize, kmsg_fd)) { |
+ if (worker_pool->IsShutdownInProgress()) { |
Yusuke Sato
2016/03/12 00:24:29
Is it safe to use worker_pool_ from this thread?
cylee1
2016/03/14 13:03:35
From the comments of IsShutdownInProcess
// Chec
|
+ LOG(WARNING) << "Chrome is shutting down, exit now."; |
+ break; |
+ } |
+ if (RE2::PartialMatch(buf, |
+ "lowmemorykiller: .* to free (\\d+)kB", |
Yusuke Sato
2016/03/12 00:24:29
* Please give 1-2 example lines of /dev/kmsg (as a
cylee1
2016/03/14 13:03:35
Done.
Yes it's always in kB as reported from kerne
|
+ &freed_size)) { |
+ std::vector<StringPiece> fields = SplitStringPiece( |
+ buf, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
+ |
+ time_delta = TimeDelta::Max(); |
+ // Timestamp is the third field in a line of /dev/kmsg. |
+ if (fields.size() >= 3) { |
+ base::StringToInt64(fields[2], ×tamp); |
+ if (last_timestamp > 0) { |
+ time_delta = TimeDelta::FromMicroseconds(timestamp - last_timestamp); |
+ } |
+ last_timestamp = timestamp; |
+ } |
+ |
+ UMA_HISTOGRAM_MEMORY_KB( |
+ "ArcRuntime.LowMemoryKiller.FreedSize", freed_size); |
+ UMA_HISTOGRAM_LOWMEMORYKILL_TIMES( |
Yusuke Sato
2016/03/12 00:24:29
Shouldn't we move this call to the 'if (fields.siz
cylee1
2016/03/14 13:03:35
You're right that I should move it to the if claus
|
+ "ArcRuntime.LowMemoryKiller.TimeDelta", time_delta); |
+ } |
+ } |
+ fclose(kmsg_fd); |
+} |
+ |
+} // namespace arc |