Coverage Report

Created: 2026-09-14 06:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmInstrumentation.h
Line
Count
Source
1
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2
   file LICENSE.rst or https://cmake.org/licensing for details.  */
3
#pragma once
4
5
#include "cmConfigure.h" // IWYU pragma: keep
6
7
#include <chrono>
8
#include <functional>
9
#include <map>
10
#include <set>
11
#include <string>
12
#include <vector>
13
14
#include <cm/memory>
15
#include <cm/optional>
16
17
#include <cm3p/json/value.h>
18
#include <stddef.h>
19
#include <stdint.h>
20
21
#ifndef CMAKE_BOOTSTRAP
22
#  include <cmsys/SystemInformation.hxx>
23
#endif
24
25
#include "cmFileLock.h"
26
#include "cmInstrumentationQuery.h"
27
28
class cmGlobalGenerator;
29
30
namespace cm {
31
enum class TargetType;
32
} // namespace cm
33
34
class cmInstrumentation
35
{
36
public:
37
  using Callback = cmInstrumentationQuery::Callback;
38
39
  enum class LoadQueriesAfter
40
  {
41
    Yes,
42
    No
43
  };
44
  cmInstrumentation(std::string const& binary_dir,
45
                    LoadQueriesAfter loadQueries = LoadQueriesAfter::Yes);
46
  void LoadQueries();
47
  void CheckCDashVariable();
48
  struct TimeValue
49
  {
50
    long tv_sec;
51
    long tv_usec;
52
  };
53
54
  struct ProcessMetrics
55
  {
56
    TimeValue ru_utime{};
57
    TimeValue ru_stime{};
58
    long ru_maxrss = 0;
59
60
#ifndef CMAKE_BOOTSTRAP
61
    ProcessMetrics() = default;
62
    ProcessMetrics(cmsys::SystemInformation::ProcessResourceUsage const& usage)
63
      : ru_utime{ usage.ru_utime.tv_sec, usage.ru_utime.tv_usec }
64
      , ru_stime{ usage.ru_stime.tv_sec, usage.ru_stime.tv_usec }
65
      , ru_maxrss(usage.ru_maxrss)
66
0
    {
67
0
    }
68
#endif
69
  };
70
71
  struct CommandResult
72
  {
73
    int ExitCode;
74
    cm::optional<std::string> StdOut;
75
    cm::optional<std::string> StdErr;
76
    cm::optional<ProcessMetrics> ChildResourceUsage;
77
  };
78
79
  int InstrumentCommand(
80
    std::string command_type, std::vector<std::string> const& command,
81
    std::function<CommandResult()> const& callback,
82
    cm::optional<std::map<std::string, std::string>> options = cm::nullopt,
83
    cm::optional<std::map<std::string, std::string>> arrayOptions =
84
      cm::nullopt,
85
    LoadQueriesAfter reloadQueriesAfterCommand = LoadQueriesAfter::No);
86
  std::string InstrumentTest(
87
    std::string const& name, std::string const& command,
88
    std::vector<std::string> const& args, int64_t result,
89
    std::chrono::steady_clock::time_point steadyStart,
90
    std::chrono::system_clock::time_point systemStart, std::string config,
91
    cm::optional<std::string> output = cm::nullopt,
92
    cm::optional<ProcessMetrics> processMetrics = cm::nullopt);
93
  void GetPreTestStats();
94
  bool HasQuery() const;
95
  bool HasOption(cmInstrumentationQuery::Option option) const;
96
  bool HasHook(cmInstrumentationQuery::Hook hook) const;
97
  bool ReadJSONQueries(std::string const& directory);
98
  void ReadJSONQuery(std::string const& file);
99
  void WriteJSONQuery(cmInstrumentationQuery::Version dataVersion,
100
                      std::set<cmInstrumentationQuery::Option> const& options,
101
                      std::set<cmInstrumentationQuery::Hook> const& hooks,
102
                      std::vector<std::vector<std::string>> const& callback);
103
  void AddCustomContent(std::string const& name, Json::Value const& contents);
104
  void WriteCMakeContent(std::unique_ptr<cmGlobalGenerator> const& gg);
105
  Json::Value DumpTargets(std::unique_ptr<cmGlobalGenerator> const& gg);
106
  void ClearGeneratedQueries();
107
  int CollectTimingData(cmInstrumentationQuery::Hook hook);
108
  int SpawnBuildDaemon();
109
  bool LockBuildDaemon();
110
  bool LockIndexing();
111
  int CollectTimingAfterBuild(int ppid);
112
  void AddHook(cmInstrumentationQuery::Hook hook);
113
  void AddOption(cmInstrumentationQuery::Option option);
114
  bool HasErrors() const;
115
  std::string const& GetCDashDir() const;
116
  std::string const& GetDataDir() const;
117
  enum LatestOrOldest
118
  {
119
    Latest,
120
    Oldest
121
  };
122
  std::string GetFileByTimestamp(LatestOrOldest latestOrOldest,
123
                                 std::string const& dataSubdir,
124
                                 std::string const& exclude = "");
125
126
private:
127
  Json::Value ReadJsonSnippet(std::string const& file_name);
128
  bool AcquireLock(std::string const& lock_file, cmFileLock& lock,
129
                   unsigned long timeout);
130
  enum class Atomic
131
  {
132
    No,
133
    Yes,
134
  };
135
  void WriteInstrumentationJson(cmInstrumentationQuery::Version version,
136
                                Json::Value& index,
137
                                std::string const& directory,
138
                                std::string const& file_name,
139
                                Atomic atomic = Atomic::No);
140
  void InsertStaticSystemInformation(Json::Value& index);
141
  void GetDynamicSystemInformation(double& memory, double& load);
142
  void InsertDynamicSystemInformation(Json::Value& index,
143
                                      std::string const& instant);
144
  void InsertTimingData(Json::Value& root,
145
                        std::chrono::steady_clock::time_point steadyStart,
146
                        std::chrono::system_clock::time_point systemStart);
147
  bool HasQueryFile(std::string const& file);
148
  static std::string GetCommandStr(std::vector<std::string> const& args);
149
  static std::string ComputeSuffixHash(std::string const& command_str);
150
  static std::string ComputeSuffixTime(
151
    cm::optional<std::chrono::system_clock::time_point> time = cm::nullopt);
152
  static bool IsInstrumentableTargetType(cm::TargetType type);
153
  static Json::Value ResourceUsageToJSON(ProcessMetrics const& usage);
154
  void PrepareDataForCDash(std::string const& data_dir,
155
                           std::string const& index_path);
156
  std::string GetCompileTraceFile(std::vector<std::string> const& command,
157
                                  Json::Value const& outputs,
158
                                  std::string const& workingDir);
159
  void CollectCompileTraceFile(Json::Value& root, std::string traceFile,
160
                               long int oldTimestamp,
161
                               std::string const& commandHash,
162
                               std::string const& suffixTime);
163
  void RemoveCompileTraceFile(Json::Value const& snippetData);
164
  void RemoveOldFiles(std::string const& dataSubdir);
165
  void WriteTraceFile(Json::Value const& index, std::string const& trace_name);
166
  Json::Value BuildTraceEvent(std::vector<uint64_t>& workers,
167
                              Json::Value const& snippetData);
168
  size_t AssignTargetToTraceThread(std::vector<uint64_t>& workers,
169
                                   uint64_t timeStart, uint64_t duration);
170
  void ResetQueries();
171
  std::string binaryDir;
172
  std::string timingDirv1;
173
  std::string userTimingDirv1;
174
  std::string cdashDir;
175
  std::string dataDir;
176
  std::set<cmInstrumentationQuery::Option> options;
177
  std::set<cmInstrumentationQuery::Hook> hooks;
178
  std::vector<Callback> callbacks;
179
  std::vector<std::string> queryFiles;
180
  static std::map<std::string, std::string> cdashSnippetsMap;
181
  Json::Value preTestStats;
182
  std::string errorMsg;
183
  bool hasQuery = false;
184
  bool ranSystemChecks = false;
185
  bool ranOSCheck = false;
186
  Json::Value customContent = Json::objectValue;
187
  std::map<std::string, Json::Value> configureSnippetData;
188
#ifndef CMAKE_BOOTSTRAP
189
  std::unique_ptr<cmsys::SystemInformation> systemInformation;
190
  cmsys::SystemInformation& GetSystemInformation();
191
#endif
192
  int writtenJsonQueries = 0;
193
  cmFileLock buildLock; // non-blocking
194
  cmFileLock indexLock; // never held alongside buildLock
195
};