diff options
author | Yabin Cui <yabinc@google.com> | 2016-10-31 17:33:58 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2016-10-31 17:33:58 +0000 |
commit | d2fcab88ef855a9a415159b669f7ea7e00f5a575 (patch) | |
tree | c0fe9fc7dd8a01c9629f51a9556d13072b95eb7b | |
parent | 2a1689219257ceb3d242e2c4838619ed65a421e9 (diff) | |
parent | 265f6a04691b7b820d717b4e40fe6b7f35585f1d (diff) | |
download | extras-d2fcab88ef855a9a415159b669f7ea7e00f5a575.tar.gz |
Merge "simpleperf: remove external sort."
-rw-r--r-- | simpleperf/cmd_record.cpp | 10 | ||||
-rw-r--r-- | simpleperf/event_selection_set.cpp | 8 | ||||
-rw-r--r-- | simpleperf/event_selection_set.h | 1 | ||||
-rw-r--r-- | simpleperf/record_file.h | 3 | ||||
-rw-r--r-- | simpleperf/record_file_writer.cpp | 126 |
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"; |