mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-02 12:19:54 -05:00
cmMakefileProfilingData: Refactor to use RAII
And add a more generic StartEntry() method.
This commit is contained in:
@@ -375,19 +375,15 @@ public:
|
|||||||
++this->Makefile->RecursionDepth;
|
++this->Makefile->RecursionDepth;
|
||||||
this->Makefile->ExecutionStatusStack.push_back(&status);
|
this->Makefile->ExecutionStatusStack.push_back(&status);
|
||||||
#if !defined(CMAKE_BOOTSTRAP)
|
#if !defined(CMAKE_BOOTSTRAP)
|
||||||
if (this->Makefile->GetCMakeInstance()->IsProfilingEnabled()) {
|
this->ProfilingDataRAII =
|
||||||
this->Makefile->GetCMakeInstance()->GetProfilingOutput().StartEntry(lff,
|
this->Makefile->GetCMakeInstance()->CreateProfilingEntry(lff, lfc);
|
||||||
lfc);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
~cmMakefileCall()
|
~cmMakefileCall()
|
||||||
{
|
{
|
||||||
#if !defined(CMAKE_BOOTSTRAP)
|
#if !defined(CMAKE_BOOTSTRAP)
|
||||||
if (this->Makefile->GetCMakeInstance()->IsProfilingEnabled()) {
|
this->ProfilingDataRAII.reset();
|
||||||
this->Makefile->GetCMakeInstance()->GetProfilingOutput().StopEntry();
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
this->Makefile->ExecutionStatusStack.pop_back();
|
this->Makefile->ExecutionStatusStack.pop_back();
|
||||||
--this->Makefile->RecursionDepth;
|
--this->Makefile->RecursionDepth;
|
||||||
@@ -399,6 +395,9 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
cmMakefile* Makefile;
|
cmMakefile* Makefile;
|
||||||
|
#if !defined(CMAKE_BOOTSTRAP)
|
||||||
|
cm::optional<cmMakefileProfilingData::RAII> ProfilingDataRAII;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
void cmMakefile::OnExecuteCommand(std::function<void()> callback)
|
void cmMakefile::OnExecuteCommand(std::function<void()> callback)
|
||||||
|
|||||||
@@ -4,8 +4,12 @@
|
|||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <cm/utility>
|
||||||
|
|
||||||
#include <cm3p/json/value.h>
|
#include <cm3p/json/value.h>
|
||||||
#include <cm3p/json/writer.h>
|
#include <cm3p/json/writer.h>
|
||||||
|
|
||||||
@@ -45,6 +49,23 @@ cmMakefileProfilingData::~cmMakefileProfilingData() noexcept
|
|||||||
|
|
||||||
void cmMakefileProfilingData::StartEntry(const cmListFileFunction& lff,
|
void cmMakefileProfilingData::StartEntry(const cmListFileFunction& lff,
|
||||||
cmListFileContext const& lfc)
|
cmListFileContext const& lfc)
|
||||||
|
{
|
||||||
|
cm::optional<Json::Value> argsValue(cm::in_place, Json::objectValue);
|
||||||
|
if (!lff.Arguments().empty()) {
|
||||||
|
std::string args;
|
||||||
|
for (auto const& a : lff.Arguments()) {
|
||||||
|
args = cmStrCat(args, args.empty() ? "" : " ", a.Value);
|
||||||
|
}
|
||||||
|
(*argsValue)["functionArgs"] = args;
|
||||||
|
}
|
||||||
|
(*argsValue)["location"] =
|
||||||
|
cmStrCat(lfc.FilePath, ':', std::to_string(lfc.Line));
|
||||||
|
this->StartEntry("cmake", lff.LowerCaseName(), std::move(argsValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmMakefileProfilingData::StartEntry(const std::string& category,
|
||||||
|
const std::string& name,
|
||||||
|
cm::optional<Json::Value> args)
|
||||||
{
|
{
|
||||||
/* Do not try again if we previously failed to write to output. */
|
/* Do not try again if we previously failed to write to output. */
|
||||||
if (!this->ProfileStream.good()) {
|
if (!this->ProfileStream.good()) {
|
||||||
@@ -58,24 +79,17 @@ void cmMakefileProfilingData::StartEntry(const cmListFileFunction& lff,
|
|||||||
cmsys::SystemInformation info;
|
cmsys::SystemInformation info;
|
||||||
Json::Value v;
|
Json::Value v;
|
||||||
v["ph"] = "B";
|
v["ph"] = "B";
|
||||||
v["name"] = lff.LowerCaseName();
|
v["name"] = name;
|
||||||
v["cat"] = "cmake";
|
v["cat"] = category;
|
||||||
v["ts"] = static_cast<Json::Value::UInt64>(
|
v["ts"] = static_cast<Json::Value::UInt64>(
|
||||||
std::chrono::duration_cast<std::chrono::microseconds>(
|
std::chrono::duration_cast<std::chrono::microseconds>(
|
||||||
std::chrono::steady_clock::now().time_since_epoch())
|
std::chrono::steady_clock::now().time_since_epoch())
|
||||||
.count());
|
.count());
|
||||||
v["pid"] = static_cast<int>(info.GetProcessId());
|
v["pid"] = static_cast<int>(info.GetProcessId());
|
||||||
v["tid"] = 0;
|
v["tid"] = 0;
|
||||||
Json::Value argsValue;
|
if (args) {
|
||||||
if (!lff.Arguments().empty()) {
|
v["args"] = *std::move(args);
|
||||||
std::string args;
|
|
||||||
for (auto const& a : lff.Arguments()) {
|
|
||||||
args += (args.empty() ? "" : " ") + a.Value;
|
|
||||||
}
|
|
||||||
argsValue["functionArgs"] = args;
|
|
||||||
}
|
}
|
||||||
argsValue["location"] = lfc.FilePath + ":" + std::to_string(lfc.Line);
|
|
||||||
v["args"] = argsValue;
|
|
||||||
|
|
||||||
this->JsonWriter->write(v, &this->ProfileStream);
|
this->JsonWriter->write(v, &this->ProfileStream);
|
||||||
} catch (std::ios_base::failure& fail) {
|
} catch (std::ios_base::failure& fail) {
|
||||||
@@ -112,3 +126,27 @@ void cmMakefileProfilingData::StopEntry()
|
|||||||
cmSystemTools::Error("Error writing profiling output!");
|
cmSystemTools::Error("Error writing profiling output!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmMakefileProfilingData::RAII::RAII(RAII&& other) noexcept
|
||||||
|
: Data(other.Data)
|
||||||
|
{
|
||||||
|
other.Data = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmMakefileProfilingData::RAII::~RAII()
|
||||||
|
{
|
||||||
|
if (this->Data) {
|
||||||
|
this->Data->StopEntry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cmMakefileProfilingData::RAII& cmMakefileProfilingData::RAII::operator=(
|
||||||
|
RAII&& other) noexcept
|
||||||
|
{
|
||||||
|
if (this->Data) {
|
||||||
|
this->Data->StopEntry();
|
||||||
|
}
|
||||||
|
this->Data = other.Data;
|
||||||
|
other.Data = nullptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include <cm/optional>
|
||||||
|
|
||||||
|
#include <cm3p/json/value.h> // IWYU pragma: keep
|
||||||
|
|
||||||
#include "cmsys/FStream.hxx"
|
#include "cmsys/FStream.hxx"
|
||||||
|
|
||||||
@@ -19,8 +24,33 @@ public:
|
|||||||
cmMakefileProfilingData(const std::string&);
|
cmMakefileProfilingData(const std::string&);
|
||||||
~cmMakefileProfilingData() noexcept;
|
~cmMakefileProfilingData() noexcept;
|
||||||
void StartEntry(const cmListFileFunction& lff, cmListFileContext const& lfc);
|
void StartEntry(const cmListFileFunction& lff, cmListFileContext const& lfc);
|
||||||
|
void StartEntry(const std::string& category, const std::string& name,
|
||||||
|
cm::optional<Json::Value> args = cm::nullopt);
|
||||||
void StopEntry();
|
void StopEntry();
|
||||||
|
|
||||||
|
class RAII
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RAII() = delete;
|
||||||
|
RAII(const RAII&) = delete;
|
||||||
|
RAII(RAII&&) noexcept;
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
RAII(cmMakefileProfilingData& data, Args&&... args)
|
||||||
|
: Data(&data)
|
||||||
|
{
|
||||||
|
this->Data->StartEntry(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
~RAII();
|
||||||
|
|
||||||
|
RAII& operator=(const RAII&) = delete;
|
||||||
|
RAII& operator=(RAII&&) noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
cmMakefileProfilingData* Data = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
cmsys::ofstream ProfileStream;
|
cmsys::ofstream ProfileStream;
|
||||||
std::unique_ptr<Json::StreamWriter> JsonWriter;
|
std::unique_ptr<Json::StreamWriter> JsonWriter;
|
||||||
|
|||||||
+12
-3
@@ -33,6 +33,7 @@
|
|||||||
# include <cm3p/json/value.h>
|
# include <cm3p/json/value.h>
|
||||||
|
|
||||||
# include "cmCMakePresetsGraph.h"
|
# include "cmCMakePresetsGraph.h"
|
||||||
|
# include "cmMakefileProfilingData.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class cmExternalMakefileProjectGeneratorFactory;
|
class cmExternalMakefileProjectGeneratorFactory;
|
||||||
@@ -41,9 +42,6 @@ class cmFileTimeCache;
|
|||||||
class cmGlobalGenerator;
|
class cmGlobalGenerator;
|
||||||
class cmGlobalGeneratorFactory;
|
class cmGlobalGeneratorFactory;
|
||||||
class cmMakefile;
|
class cmMakefile;
|
||||||
#if !defined(CMAKE_BOOTSTRAP)
|
|
||||||
class cmMakefileProfilingData;
|
|
||||||
#endif
|
|
||||||
class cmMessenger;
|
class cmMessenger;
|
||||||
class cmVariableWatch;
|
class cmVariableWatch;
|
||||||
struct cmBuildOptions;
|
struct cmBuildOptions;
|
||||||
@@ -628,6 +626,17 @@ public:
|
|||||||
#if !defined(CMAKE_BOOTSTRAP)
|
#if !defined(CMAKE_BOOTSTRAP)
|
||||||
cmMakefileProfilingData& GetProfilingOutput();
|
cmMakefileProfilingData& GetProfilingOutput();
|
||||||
bool IsProfilingEnabled() const;
|
bool IsProfilingEnabled() const;
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
cm::optional<cmMakefileProfilingData::RAII> CreateProfilingEntry(
|
||||||
|
Args&&... args)
|
||||||
|
{
|
||||||
|
if (this->IsProfilingEnabled()) {
|
||||||
|
return cm::make_optional<cmMakefileProfilingData::RAII>(
|
||||||
|
this->GetProfilingOutput(), std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
return cm::nullopt;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
Reference in New Issue
Block a user