diff options
Diffstat (limited to 'simpleperf/record_file_writer.cpp')
-rw-r--r-- | simpleperf/record_file_writer.cpp | 126 |
1 files changed, 0 insertions, 126 deletions
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"; |