summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2016-10-31 17:33:58 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2016-10-31 17:33:58 +0000
commitd2fcab88ef855a9a415159b669f7ea7e00f5a575 (patch)
treec0fe9fc7dd8a01c9629f51a9556d13072b95eb7b
parent2a1689219257ceb3d242e2c4838619ed65a421e9 (diff)
parent265f6a04691b7b820d717b4e40fe6b7f35585f1d (diff)
downloadextras-d2fcab88ef855a9a415159b669f7ea7e00f5a575.tar.gz
Merge "simpleperf: remove external sort."
-rw-r--r--simpleperf/cmd_record.cpp10
-rw-r--r--simpleperf/event_selection_set.cpp8
-rw-r--r--simpleperf/event_selection_set.h1
-rw-r--r--simpleperf/record_file.h3
-rw-r--r--simpleperf/record_file_writer.cpp126
5 files changed, 0 insertions, 148 deletions
diff --git a/simpleperf/cmd_record.cpp b/simpleperf/cmd_record.cpp
index 58f9805c..e3390b05 100644
--- a/simpleperf/cmd_record.cpp
+++ b/simpleperf/cmd_record.cpp
@@ -313,10 +313,6 @@ bool RecordCommand::Run(const std::vector<std::string>& args) {
if (!event_selection_set_.FinishReadMmapEventData()) {
return false;
}
- // TODO: remove SortDataSection as we have merged records in memory.
- if (!record_file_writer_->SortDataSection()) {
- return false;
- }
// 7. Dump additional features, and close record file.
if (!DumpAdditionalFeatures(args)) {
@@ -593,12 +589,6 @@ bool RecordCommand::SetEventSelectionFlags() {
}
}
event_selection_set_.SetInherit(child_inherit_);
- // TODO: remove SetLowWatermark() as we have merged records in memory.
- // If Unwinding while recording, records are used before being sorted.
- // By using low watermark, records are almost sorted when read from kernel.
- if (dwarf_callchain_sampling_ && unwind_dwarf_callchain_ && !post_unwind_) {
- event_selection_set_.SetLowWatermark();
- }
return true;
}
diff --git a/simpleperf/event_selection_set.cpp b/simpleperf/event_selection_set.cpp
index 5bdf5397..58c51296 100644
--- a/simpleperf/event_selection_set.cpp
+++ b/simpleperf/event_selection_set.cpp
@@ -295,14 +295,6 @@ void EventSelectionSet::SetInherit(bool enable) {
}
}
-void EventSelectionSet::SetLowWatermark() {
- for (auto& group : groups_) {
- for (auto& selection : group) {
- selection.event_attr.wakeup_events = 1;
- }
- }
-}
-
bool EventSelectionSet::NeedKernelSymbol() const {
for (const auto& group : groups_) {
for (const auto& selection : group) {
diff --git a/simpleperf/event_selection_set.h b/simpleperf/event_selection_set.h
index 2ec58402..b82b9177 100644
--- a/simpleperf/event_selection_set.h
+++ b/simpleperf/event_selection_set.h
@@ -85,7 +85,6 @@ class EventSelectionSet {
void EnableFpCallChainSampling();
bool EnableDwarfCallChainSampling(uint32_t dump_stack_size);
void SetInherit(bool enable);
- void SetLowWatermark();
bool NeedKernelSymbol() const;
void AddMonitoredProcesses(const std::set<pid_t>& processes) {
diff --git a/simpleperf/record_file.h b/simpleperf/record_file.h
index 2d62343e..9594d166 100644
--- a/simpleperf/record_file.h
+++ b/simpleperf/record_file.h
@@ -42,7 +42,6 @@ class RecordFileWriter {
bool WriteAttrSection(const std::vector<EventAttrWithId>& attr_ids);
bool WriteRecord(const Record& record);
- bool SortDataSection();
bool WriteFeatureHeader(size_t feature_count);
bool WriteBuildIdFeature(const std::vector<BuildIdRecord>& build_id_records);
@@ -63,8 +62,6 @@ class RecordFileWriter {
bool WriteFileHeader();
bool WriteData(const void* buf, size_t len);
bool Write(const void* buf, size_t len);
- std::unique_ptr<Record> ReadRecordFromFile(FILE* fp, std::vector<char>& buf);
- bool WriteRecordToFile(FILE* fp, std::unique_ptr<Record> r);
bool SeekFileEnd(uint64_t* file_end);
bool WriteFeatureBegin(uint64_t* start_offset);
bool WriteFeatureEnd(int feature, uint64_t start_offset);
diff --git a/simpleperf/record_file_writer.cpp b/simpleperf/record_file_writer.cpp
index 8b57e836..f90f5727 100644
--- a/simpleperf/record_file_writer.cpp
+++ b/simpleperf/record_file_writer.cpp
@@ -173,132 +173,6 @@ bool RecordFileWriter::Write(const void* buf, size_t len) {
return true;
}
-std::unique_ptr<Record> RecordFileWriter::ReadRecordFromFile(FILE* fp, std::vector<char>& buf) {
- if (buf.size() < sizeof(perf_event_header)) {
- buf.resize(sizeof(perf_event_header));
- }
- auto pheader = reinterpret_cast<perf_event_header*>(buf.data());
- if (fread(pheader, sizeof(*pheader), 1, fp) != 1) {
- PLOG(ERROR) << "read failed";
- return nullptr;
- }
- if (pheader->size > sizeof(*pheader)) {
- if (pheader->size > buf.size()) {
- buf.resize(pheader->size);
- }
- pheader = reinterpret_cast<perf_event_header*>(buf.data());
- if (fread(pheader + 1, pheader->size - sizeof(*pheader), 1, fp) != 1) {
- PLOG(ERROR) << "read failed";
- return nullptr;
- }
- }
- return ReadRecordFromBuffer(event_attr_, pheader->type, buf.data());
-}
-
-bool RecordFileWriter::WriteRecordToFile(FILE* fp, std::unique_ptr<Record> r) {
- if (fwrite(r->Binary(), r->size(), 1, fp) != 1) {
- PLOG(ERROR) << "write failed";
- return false;
- }
- return true;
-}
-
-// SortDataSection() sorts records in data section in time order.
-// This method is suitable for the situation that there is only one buffer
-// between kernel and simpleperf for each cpu. The order of records in each
-// cpu buffer is already sorted, so we only need to merge records from different
-// cpu buffers.
-// 1. Create one temporary file for each cpu, and write records to different
-// temporary files according to their cpu value.
-// 2. Use RecordCache to merge records from different temporary files.
-bool RecordFileWriter::SortDataSection() {
- if (!IsTimestampSupported(event_attr_) || !IsCpuSupported(event_attr_)) {
- // Omit the sort if either timestamp or cpu is not recorded.
- return true;
- }
- struct CpuData {
- std::string path;
- FILE* fp;
- std::vector<char> buf;
- uint64_t data_size;
-
- explicit CpuData(const std::string& path) : path(path), fp(nullptr), data_size(0) {
- fp = fopen(path.c_str(), "web+");
- }
- ~CpuData() {
- fclose(fp);
- unlink(path.c_str());
- }
- };
- std::unordered_map<uint32_t, std::unique_ptr<CpuData>> cpu_map;
- if (fseek(record_fp_, data_section_offset_, SEEK_SET) == -1) {
- PLOG(ERROR) << "fseek() failed";
- return false;
- }
- uint64_t cur_size = 0;
- std::vector<char> global_buf;
- while (cur_size < data_section_size_) {
- std::unique_ptr<Record> r = ReadRecordFromFile(record_fp_, global_buf);
- if (r == nullptr) {
- return false;
- }
- cur_size += r->size();
- std::unique_ptr<CpuData>& cpu_data = cpu_map[r->Cpu()];
- if (cpu_data == nullptr) {
- // Create temporary file in the same directory as filename_, because we
- // may not have permission to create temporary file in other directories.
- cpu_data.reset(new CpuData(filename_ + "." + std::to_string(r->Cpu())));
- if (cpu_data->fp == nullptr) {
- PLOG(ERROR) << "failed to open tmpfile " << cpu_data->path;
- return false;
- }
- }
- cpu_data->data_size += r->size();
- if (!WriteRecordToFile(cpu_data->fp, std::move(r))) {
- return false;
- }
- }
- if (fseek(record_fp_, data_section_offset_, SEEK_SET) == -1) {
- PLOG(ERROR) << "fseek() failed";
- return false;
- }
- RecordCache global_cache(true);
- for (auto it = cpu_map.begin(); it != cpu_map.end(); ++it) {
- if (fseek(it->second->fp, 0, SEEK_SET) == -1) {
- PLOG(ERROR) << "fseek() failed";
- return false;
- }
- std::unique_ptr<Record> r = ReadRecordFromFile(it->second->fp, it->second->buf);
- if (r == nullptr) {
- return false;
- }
- it->second->data_size -= r->size();
- global_cache.Push(std::move(r));
- }
- while (true) {
- std::unique_ptr<Record> r = global_cache.ForcedPop();
- if (r == nullptr) {
- break;
- }
- uint32_t cpu = r->Cpu();
- if (!WriteRecordToFile(record_fp_, std::move(r))) {
- return false;
- }
- // Each time writing one record of a cpu, push the next record from the
- // temporary file belong to that cpu into the record cache.
- std::unique_ptr<CpuData>& cpu_data = cpu_map[cpu];
- if (cpu_data->data_size > 0) {
- r = ReadRecordFromFile(cpu_data->fp, cpu_data->buf);
- if (r == nullptr) {
- return false;
- }
- cpu_data->data_size -= r->size();
- global_cache.Push(std::move(r));
- }
- }
- return true;
-}
-
bool RecordFileWriter::SeekFileEnd(uint64_t* file_end) {
if (fseek(record_fp_, 0, SEEK_END) == -1) {
PLOG(ERROR) << "fseek() failed";