| 1040 | } |
| 1041 | |
| 1042 | void cmInstrumentation::WriteTraceFile(Json::Value const& index, |
| 1043 | std::string const& trace_name) |
| 1044 | { |
| 1045 | std::vector<std::string> snippets = std::vector<std::string>(); |
| 1046 | for (auto const& f : index["snippets"]) { |
| 1047 | snippets.push_back(f.asString()); |
| 1048 | } |
| 1049 | // Reverse-sort snippets by timeEnd (timeStart + duration) as a |
| 1050 | // prerequisite for AssignTargetToTraceThread(). |
| 1051 | auto extractSnippetTimestamp = [](std::string file) -> std::string { |
| 1052 | cmsys::RegularExpression snippetTimeRegex( |
| 1053 | "[A-Za-z]+-[A-Za-z0-9]+-([0-9T\\-]+)\\.json"); |
| 1054 | cmsys::RegularExpressionMatch matchA; |
| 1055 | if (snippetTimeRegex.find(file.c_str(), matchA)) { |
| 1056 | return matchA.match(1); |
| 1057 | } |
| 1058 | return ""; |
| 1059 | }; |
| 1060 | std::sort( |
| 1061 | snippets.begin(), snippets.end(), |
| 1062 | [extractSnippetTimestamp](std::string snippetA, std::string snippetB) { |
| 1063 | return extractSnippetTimestamp(snippetA) > |
| 1064 | extractSnippetTimestamp(snippetB); |
| 1065 | }); |
| 1066 | |
| 1067 | std::string traceDir = cmStrCat(this->timingDirv1, "/data/trace/"); |
| 1068 | std::string traceFile = cmStrCat(traceDir, trace_name); |
| 1069 | cmSystemTools::MakeDirectory(traceDir); |
| 1070 | cmsys::ofstream traceStream; |
| 1071 | Json::StreamWriterBuilder wbuilder; |
| 1072 | wbuilder["indentation"] = "\t"; |
| 1073 | std::unique_ptr<Json::StreamWriter> jsonWriter = |
| 1074 | std::unique_ptr<Json::StreamWriter>(wbuilder.newStreamWriter()); |
| 1075 | traceStream.open(traceFile.c_str(), std::ios::out | std::ios::trunc); |
| 1076 | if (!traceStream.good()) { |
| 1077 | throw std::runtime_error(std::string("Unable to open: ") + traceFile); |
| 1078 | } |
| 1079 | traceStream << "["; |
| 1080 | |
| 1081 | // Append trace events from single snippets. Prefer writing to the output |
| 1082 | // stream incrementally over building up a Json::arrayValue in memory for |
| 1083 | // large traces. |
| 1084 | std::vector<uint64_t> workers = std::vector<uint64_t>(); |
| 1085 | Json::Value traceEvent; |
| 1086 | Json::Value snippetData; |
| 1087 | for (size_t i = 0; i < snippets.size(); i++) { |
| 1088 | snippetData = this->ReadJsonSnippet(snippets[i]); |
| 1089 | traceEvent = this->BuildTraceEvent(workers, snippetData); |
| 1090 | try { |
| 1091 | if (i > 0) { |
| 1092 | traceStream << ","; |
| 1093 | } |
| 1094 | jsonWriter->write(traceEvent, &traceStream); |
| 1095 | if (i % 50 == 0 || i == snippets.size() - 1) { |
| 1096 | traceStream.flush(); |
| 1097 | traceStream.clear(); |
| 1098 | } |
| 1099 | } catch (std::ios_base::failure& fail) { |
no test coverage detected