-
Notifications
You must be signed in to change notification settings - Fork 4.8k
/
profiler.cc
130 lines (97 loc) · 3.44 KB
/
profiler.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include "source/common/profiler/profiler.h"
#include <string>
#include "source/common/common/thread.h"
#ifdef PROFILER_AVAILABLE
#include "gperftools/heap-profiler.h"
#include "gperftools/profiler.h"
namespace Envoy {
namespace Profiler {
bool Cpu::profilerEnabled() { return ProfilingIsEnabledForAllThreads(); }
bool Cpu::startProfiler(const std::string& output_path) {
return ProfilerStart(output_path.c_str());
}
void Cpu::stopProfiler() { ProfilerStop(); }
bool Heap::profilerEnabled() {
// determined by PROFILER_AVAILABLE
return true;
}
bool Heap::isProfilerStarted() { return IsHeapProfilerRunning(); }
bool Heap::startProfiler(const std::string& output_file_name_prefix) {
HeapProfilerStart(output_file_name_prefix.c_str());
return true;
}
bool Heap::stopProfiler() {
if (!IsHeapProfilerRunning()) {
return false;
}
HeapProfilerDump("stop and dump");
HeapProfilerStop();
return true;
}
} // namespace Profiler
} // namespace Envoy
#else
namespace Envoy {
namespace Profiler {
bool Cpu::profilerEnabled() { return false; }
bool Cpu::startProfiler(const std::string&) { return false; }
void Cpu::stopProfiler() {}
bool Heap::profilerEnabled() { return false; }
bool Heap::isProfilerStarted() { return false; }
bool Heap::startProfiler(const std::string&) { return false; }
bool Heap::stopProfiler() { return false; }
} // namespace Profiler
} // namespace Envoy
#endif // #ifdef PROFILER_AVAILABLE
#ifdef TCMALLOC
#include "tcmalloc/malloc_extension.h"
#include "tcmalloc/profile_marshaler.h"
namespace Envoy {
namespace Profiler {
static tcmalloc::MallocExtension::AllocationProfilingToken* alloc_profiler = nullptr;
absl::StatusOr<std::string> TcmallocProfiler::tcmallocHeapProfile() {
auto profile = tcmalloc::MallocExtension::SnapshotCurrent(tcmalloc::ProfileType::kHeap);
return tcmalloc::Marshal(profile);
}
absl::Status TcmallocProfiler::startAllocationProfile() {
ASSERT_IS_MAIN_OR_TEST_THREAD();
if (alloc_profiler != nullptr) {
return absl::Status(absl::StatusCode::kFailedPrecondition,
"Allocation profiler has already started");
}
alloc_profiler = new tcmalloc::MallocExtension::AllocationProfilingToken(
tcmalloc::MallocExtension::StartAllocationProfiling());
return absl::OkStatus();
}
absl::StatusOr<std::string> TcmallocProfiler::stopAllocationProfile() {
ASSERT_IS_MAIN_OR_TEST_THREAD();
if (!alloc_profiler) {
return absl::Status(absl::StatusCode::kFailedPrecondition,
"Allocation profiler is not started");
}
const auto profile = std::move(*alloc_profiler).Stop();
const auto result = tcmalloc::Marshal(profile);
delete alloc_profiler;
alloc_profiler = nullptr;
return result;
}
} // namespace Profiler
} // namespace Envoy
#else
namespace Envoy {
namespace Profiler {
absl::StatusOr<std::string> TcmallocProfiler::tcmallocHeapProfile() {
return absl::Status(absl::StatusCode::kUnimplemented,
"Heap profile is not implemented in current build");
}
absl::Status TcmallocProfiler::startAllocationProfile() {
return absl::Status(absl::StatusCode::kUnimplemented,
"Allocation profile is not implemented in current build");
}
absl::StatusOr<std::string> TcmallocProfiler::stopAllocationProfile() {
return absl::Status(absl::StatusCode::kUnimplemented,
"Allocation profile is not implemented in current build");
}
} // namespace Profiler
} // namespace Envoy
#endif // #ifdef TCMALLOC