summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2016-08-19 17:24:37 -0700
committerYabin Cui <yabinc@google.com>2016-08-19 17:32:10 -0700
commit994cb626a9b0ad6cb723a9dfa7c5e05849647c87 (patch)
tree29d9f84cc135da3194ec3d244b64d1803c51ca83
parentcb0112fe640d7b8a9668f91d2cad7234bd63f880 (diff)
downloadextras-994cb626a9b0ad6cb723a9dfa7c5e05849647c87.tar.gz
simpleperf: monitor cpu hotplug in stat cmd.
Move code used to monitor cpu hotplug events from cmd_record.cpp to event_selection_set.cpp, so it can also be used by stat cmd. Bug: http://b/29245608 Change-Id: I1f5f3268192aa5c98c0be9fc1de763352c08eab6 Test: run simpleperf stat, and online/offline a cpu.
-rw-r--r--simpleperf/cmd_record.cpp31
-rw-r--r--simpleperf/cmd_stat.cpp13
-rw-r--r--simpleperf/event_selection_set.cpp36
-rw-r--r--simpleperf/event_selection_set.h14
4 files changed, 61 insertions, 33 deletions
diff --git a/simpleperf/cmd_record.cpp b/simpleperf/cmd_record.cpp
index 7d653411..5527e68b 100644
--- a/simpleperf/cmd_record.cpp
+++ b/simpleperf/cmd_record.cpp
@@ -67,8 +67,6 @@ constexpr uint32_t MAX_DUMP_STACK_SIZE = 65528;
// successfully, the buffer size = 1024 * 4K (page size) = 4M.
constexpr size_t DESIRED_PAGES_IN_MAPPED_BUFFER = 1024;
-constexpr double PERIOD_TO_DETECT_CPU_HOTPLUG_EVENTS_IN_SEC = 0.5;
-
class RecordCommand : public Command {
public:
RecordCommand()
@@ -192,7 +190,6 @@ class RecordCommand : public Command {
bool DumpAdditionalFeatures(const std::vector<std::string>& args);
bool DumpBuildIdFeature();
void CollectHitFileInfo(Record* record);
- bool DetectCpuHotplugEvents();
bool use_sample_freq_;
uint64_t sample_freq_; // Sample 'sample_freq_' times per second.
@@ -225,8 +222,6 @@ class RecordCommand : public Command {
uint64_t sample_record_count_;
uint64_t lost_record_count_;
-
- std::vector<int> online_cpus_;
};
bool RecordCommand::Run(const std::vector<std::string>& args) {
@@ -295,6 +290,9 @@ bool RecordCommand::Run(const std::vector<std::string>& args) {
if (!event_selection_set_.PrepareToReadMmapEventData(loop, callback)) {
return false;
}
+ if (!event_selection_set_.HandleCpuHotplugEvents(loop, cpus_)) {
+ return false;
+ }
if (!loop.AddSignalEvents({SIGCHLD, SIGINT, SIGTERM},
[&]() { return loop.ExitLoop(); })) {
return false;
@@ -305,12 +303,6 @@ bool RecordCommand::Run(const std::vector<std::string>& args) {
return false;
}
}
- online_cpus_ = GetOnlineCpus();
- if (!loop.AddPeriodicEvent(
- SecondToTimeval(PERIOD_TO_DETECT_CPU_HOTPLUG_EVENTS_IN_SEC),
- [&]() { return DetectCpuHotplugEvents(); })) {
- return false;
- }
// 6. Write records in mapped buffers of perf_event_files to output file while
// workload is running.
@@ -1098,23 +1090,6 @@ void RecordCommand::CollectHitFileInfo(Record* record) {
}
}
-bool RecordCommand::DetectCpuHotplugEvents() {
- std::vector<int> new_cpus = GetOnlineCpus();
- for (auto& cpu : online_cpus_) {
- if (std::find(new_cpus.begin(), new_cpus.end(), cpu) == new_cpus.end()) {
- LOG(INFO) << "Cpu " << cpu << " is offlined";
- }
- }
- for (auto& cpu : new_cpus) {
- if (std::find(online_cpus_.begin(), online_cpus_.end(), cpu) ==
- online_cpus_.end()) {
- LOG(INFO) << "Cpu " << cpu << " is onlined";
- }
- }
- online_cpus_ = new_cpus;
- return true;
-}
-
void RegisterRecordCommand() {
RegisterCommand("record",
[] { return std::unique_ptr<Command>(new RecordCommand()); });
diff --git a/simpleperf/cmd_stat.cpp b/simpleperf/cmd_stat.cpp
index 5a0694e7..41992939 100644
--- a/simpleperf/cmd_stat.cpp
+++ b/simpleperf/cmd_stat.cpp
@@ -360,17 +360,20 @@ bool StatCommand::Run(const std::vector<std::string>& args) {
return false;
}
} else {
- if (cpus_.empty()) {
- cpus_ = {-1};
- }
- if (!event_selection_set_.OpenEventFilesForThreadsOnCpus(monitored_threads_,
- cpus_)) {
+ std::vector<int> all_cpus = {-1};
+ if (!event_selection_set_.OpenEventFilesForThreadsOnCpus(
+ monitored_threads_, cpus_.empty() ? all_cpus : cpus_)) {
return false;
}
}
// 4. Create IOEventLoop and add signal/periodic Events.
IOEventLoop loop;
+ if (system_wide_collection_ || !cpus_.empty()) {
+ if (!event_selection_set_.HandleCpuHotplugEvents(loop, cpus_)) {
+ return false;
+ }
+ }
if (!loop.AddSignalEvents({SIGCHLD, SIGINT, SIGTERM},
[&]() { return loop.ExitLoop(); })) {
return false;
diff --git a/simpleperf/event_selection_set.cpp b/simpleperf/event_selection_set.cpp
index 6235e32b..edff1749 100644
--- a/simpleperf/event_selection_set.cpp
+++ b/simpleperf/event_selection_set.cpp
@@ -24,6 +24,7 @@
#include "event_type.h"
#include "IOEventLoop.h"
#include "perf_regs.h"
+#include "utils.h"
bool IsBranchSamplingSupported() {
const EventType* type = FindEventTypeByName("cpu-cycles");
@@ -439,3 +440,38 @@ bool EventSelectionSet::FinishReadMmapEventData() {
}
return true;
}
+
+bool EventSelectionSet::HandleCpuHotplugEvents(
+ IOEventLoop& loop, const std::vector<int>& monitored_cpus,
+ double check_interval_in_sec) {
+ monitored_cpus_.insert(monitored_cpus.begin(), monitored_cpus.end());
+ online_cpus_ = GetOnlineCpus();
+ if (!loop.AddPeriodicEvent(SecondToTimeval(check_interval_in_sec),
+ [&]() { return DetectCpuHotplugEvents(); })) {
+ return false;
+ }
+ return true;
+}
+
+bool EventSelectionSet::DetectCpuHotplugEvents() {
+ std::vector<int> new_cpus = GetOnlineCpus();
+ for (const auto& cpu : online_cpus_) {
+ if (std::find(new_cpus.begin(), new_cpus.end(), cpu) == new_cpus.end()) {
+ if (monitored_cpus_.empty() ||
+ monitored_cpus_.find(cpu) != monitored_cpus_.end()) {
+ LOG(INFO) << "Cpu " << cpu << " is offlined";
+ }
+ }
+ }
+ for (const auto& cpu : new_cpus) {
+ if (std::find(online_cpus_.begin(), online_cpus_.end(), cpu) ==
+ online_cpus_.end()) {
+ if (monitored_cpus_.empty() ||
+ monitored_cpus_.find(cpu) != monitored_cpus_.end()) {
+ LOG(INFO) << "Cpu " << cpu << " is onlined";
+ }
+ }
+ }
+ online_cpus_ = new_cpus;
+ return true;
+}
diff --git a/simpleperf/event_selection_set.h b/simpleperf/event_selection_set.h
index a947320f..c24dad4c 100644
--- a/simpleperf/event_selection_set.h
+++ b/simpleperf/event_selection_set.h
@@ -19,6 +19,7 @@
#include <functional>
#include <map>
+#include <set>
#include <unordered_map>
#include <vector>
@@ -29,6 +30,8 @@
#include "perf_event.h"
#include "record.h"
+constexpr double DEFAULT_PERIOD_TO_DETECT_CPU_HOTPLUG_EVENTS_IN_SEC = 0.5;
+
struct EventSelection {
uint32_t group_id;
uint32_t selection_id;
@@ -96,6 +99,12 @@ class EventSelectionSet {
const std::function<bool(Record*)>& callback);
bool FinishReadMmapEventData();
+ // If monitored_cpus is empty, monitor all cpus.
+ bool HandleCpuHotplugEvents(
+ IOEventLoop& loop, const std::vector<int>& monitored_cpus,
+ double check_interval_in_sec =
+ DEFAULT_PERIOD_TO_DETECT_CPU_HOTPLUG_EVENTS_IN_SEC);
+
private:
bool BuildAndCheckEventSelection(const std::string& event_name,
EventSelection* selection);
@@ -105,10 +114,15 @@ class EventSelectionSet {
bool MmapEventFiles(size_t mmap_pages, bool report_error);
bool ReadMmapEventDataForFd(std::unique_ptr<EventFd>& event_fd);
+ bool DetectCpuHotplugEvents();
+
std::vector<EventSelectionGroup> groups_;
std::function<bool(Record*)> record_callback_;
+ std::set<int> monitored_cpus_;
+ std::vector<int> online_cpus_;
+
DISALLOW_COPY_AND_ASSIGN(EventSelectionSet);
};