Skip to content

Commit 38e0793

Browse files
chore(profiling): move echion to dd-trace-py (backport 4.0) (#15591)
## What does this PR do? This is a backport of #15136 to 4.0. More details in the original PR.
1 parent ea0af3e commit 38e0793

File tree

26 files changed

+4221
-26
lines changed

26 files changed

+4221
-26
lines changed
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
Language: Cpp
2+
BasedOnStyle: Google
3+
AccessModifierOffset: -4
4+
AlignAfterOpenBracket: Align
5+
AlignConsecutiveAssignments: false
6+
AlignConsecutiveDeclarations: false
7+
AlignEscapedNewlines: Left
8+
AlignOperands: true
9+
AlignTrailingComments: true
10+
AllowAllParametersOfDeclarationOnNextLine: true
11+
AllowShortBlocksOnASingleLine: false
12+
AllowShortCaseLabelsOnASingleLine: false
13+
AllowShortFunctionsOnASingleLine: Empty
14+
AllowShortIfStatementsOnASingleLine: false
15+
AllowShortLoopsOnASingleLine: false
16+
AlwaysBreakAfterDefinitionReturnType: None
17+
AlwaysBreakAfterReturnType: None
18+
AlwaysBreakBeforeMultilineStrings: false
19+
AlwaysBreakTemplateDeclarations: Yes
20+
BinPackArguments: true
21+
BinPackParameters: true
22+
BraceWrapping:
23+
AfterClass: true
24+
AfterControlStatement: true
25+
AfterEnum: true
26+
AfterFunction: true
27+
AfterNamespace: true
28+
AfterStruct: true
29+
AfterUnion: true
30+
BeforeCatch: true
31+
BeforeElse: true
32+
IndentBraces: false
33+
BreakBeforeBinaryOperators: None
34+
BreakBeforeBraces: Custom
35+
BreakBeforeInheritanceComma: false
36+
BreakInheritanceList: BeforeColon
37+
BreakBeforeTernaryOperators: true
38+
BreakConstructorInitializersBeforeComma: false
39+
BreakConstructorInitializers: BeforeColon
40+
BreakAfterJavaFieldAnnotations: false
41+
BreakStringLiterals: true
42+
ColumnLimit: 100
43+
CommentPragmas: '^ IWYU pragma:'
44+
CompactNamespaces: false
45+
ConstructorInitializerAllOnOneLineOrOnePerLine: true
46+
ConstructorInitializerIndentWidth: 4
47+
ContinuationIndentWidth: 4
48+
Cpp11BracedListStyle: true
49+
DerivePointerAlignment: false
50+
DisableFormat: false
51+
ExperimentalAutoDetectBinPacking: false
52+
FixNamespaceComments: true
53+
ForEachMacros:
54+
- foreach
55+
- Q_FOREACH
56+
- BOOST_FOREACH
57+
IncludeBlocks: Preserve
58+
IncludeCategories:
59+
- Regex: '^<.*\.h>'
60+
Priority: 1
61+
- Regex: '^<.*'
62+
Priority: 2
63+
- Regex: '.*'
64+
Priority: 3
65+
IncludeIsMainRegex: '([-_](test|unittest))?$'
66+
IndentCaseLabels: true
67+
IndentPPDirectives: None
68+
IndentWidth: 4
69+
IndentWrappedFunctionNames: false
70+
JavaScriptQuotes: Leave
71+
JavaScriptWrapImports: true
72+
KeepEmptyLinesAtTheStartOfBlocks: false
73+
MacroBlockBegin: ''
74+
MacroBlockEnd: ''
75+
MaxEmptyLinesToKeep: 2
76+
NamespaceIndentation: None
77+
ObjCBinPackProtocolList: Never
78+
ObjCBlockIndentWidth: 4
79+
ObjCSpaceAfterProperty: false
80+
ObjCSpaceBeforeProtocolList: true
81+
PenaltyBreakAssignment: 2
82+
PenaltyBreakBeforeFirstCallParameter: 1
83+
PenaltyBreakComment: 300
84+
PenaltyBreakFirstLessLess: 120
85+
PenaltyBreakString: 1000
86+
PenaltyBreakTemplateDeclaration: 10
87+
PenaltyExcessCharacter: 1000000
88+
PenaltyReturnTypeOnItsOwnLine: 200
89+
PointerAlignment: Left
90+
ReflowComments: true
91+
SortIncludes: true
92+
SortUsingDeclarations: true
93+
SpaceAfterCStyleCast: false
94+
SpaceAfterTemplateKeyword: true
95+
SpaceBeforeAssignmentOperators: true
96+
SpaceBeforeCpp11BracedList: false
97+
SpaceBeforeCtorInitializerColon: true
98+
SpaceBeforeInheritanceColon: true
99+
SpaceBeforeParens: ControlStatements
100+
SpaceBeforeRangeBasedForLoopColon: true
101+
SpaceInEmptyParentheses: false
102+
SpacesBeforeTrailingComments: 2
103+
SpacesInAngles: false
104+
SpacesInContainerLiterals: false
105+
SpacesInCStyleCastParentheses: false
106+
SpacesInParentheses: false
107+
SpacesInSquareBrackets: false
108+
Standard: Cpp11
109+
TabWidth: 4
110+
UseTab: Never

ddtrace/internal/datadog/profiling/stack_v2/CMakeLists.txt

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -54,30 +54,9 @@ if(NOT Threads_FOUND OR NOT CMAKE_USE_PTHREADS_INIT)
5454
message(FATAL_ERROR "pthread compatible library not found")
5555
endif()
5656

57-
# Add echion
58-
set(ECHION_COMMIT
59-
"43432c5c0a89617b06533215a15d0d6ffbbfd02b" # https://github.com/P403n1x87/echion/commit/43432c5c0a89617b06533215a15d0d6ffbbfd02b
60-
CACHE STRING "Commit hash of echion to use")
61-
FetchContent_Declare(
62-
echion
63-
GIT_REPOSITORY "https://github.com/P403n1x87/echion.git"
64-
GIT_TAG ${ECHION_COMMIT})
65-
FetchContent_GetProperties(echion)
66-
67-
if(NOT echion_POPULATED)
68-
FetchContent_Populate(echion)
69-
endif()
70-
7157
# Specify the target C-extension that we want to build
72-
add_library(
73-
${EXTENSION_NAME} SHARED
74-
${echion_SOURCE_DIR}/echion/frame.cc
75-
${echion_SOURCE_DIR}/echion/render.cc
76-
${echion_SOURCE_DIR}/echion/danger.cc
77-
src/sampler.cpp
78-
src/stack_renderer.cpp
79-
src/stack_v2.cpp
80-
src/thread_span_links.cpp)
58+
add_library(${EXTENSION_NAME} SHARED src/echion/danger.cc src/echion/frame.cc src/sampler.cpp src/stack_renderer.cpp
59+
src/stack_v2.cpp src/thread_span_links.cpp)
8160

8261
# Add common config
8362
add_ddup_config(${EXTENSION_NAME})
@@ -89,7 +68,6 @@ add_cppcheck_target(
8968
${CMAKE_CURRENT_SOURCE_DIR}/include
9069
${CMAKE_CURRENT_SOURCE_DIR}/include/util
9170
${CMAKE_CURRENT_SOURCE_DIR}/..
92-
${echion_SOURCE_DIR}
9371
SRC
9472
${CMAKE_CURRENT_SOURCE_DIR}/src)
9573

@@ -100,8 +78,8 @@ target_compile_definitions(${EXTENSION_NAME} PRIVATE UNWIND_NATIVE_DISABLE)
10078
target_include_directories(
10179
${EXTENSION_NAME} PRIVATE .. # include dd_wrapper from the root in order to make its paths transparent in the code
10280
include)
103-
target_include_directories(${EXTENSION_NAME} SYSTEM PRIVATE ${echion_SOURCE_DIR} ${Python3_INCLUDE_DIRS}
104-
include/vendored include/util)
81+
target_include_directories(${EXTENSION_NAME} SYSTEM PRIVATE ${Python3_INCLUDE_DIRS} echion include/vendored
82+
include/util)
10583

10684
# Echion sources need to be given the current platform
10785
if(APPLE)
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// This file is part of "echion" which is released under MIT.
2+
//
3+
// Copyright (c) 2023 Gabriele N. Tornetta <[email protected]>.
4+
5+
#pragma once
6+
7+
#include <functional>
8+
#include <list>
9+
#include <memory>
10+
#include <unordered_map>
11+
12+
#include <echion/errors.h>
13+
14+
#define CACHE_MAX_ENTRIES 2048
15+
16+
template<typename K, typename V>
17+
class LRUCache
18+
{
19+
public:
20+
LRUCache(size_t capacity)
21+
: capacity(capacity)
22+
{
23+
}
24+
25+
Result<std::reference_wrapper<V>> lookup(const K& k);
26+
27+
void store(const K& k, std::unique_ptr<V> v);
28+
29+
private:
30+
size_t capacity;
31+
std::list<std::pair<K, std::unique_ptr<V>>> items;
32+
std::unordered_map<K, typename std::list<std::pair<K, std::unique_ptr<V>>>::iterator> index;
33+
};
34+
35+
template<typename K, typename V>
36+
void
37+
LRUCache<K, V>::store(const K& k, std::unique_ptr<V> v)
38+
{
39+
// Check if cache is full
40+
if (items.size() >= capacity) {
41+
index.erase(items.back().first);
42+
items.pop_back();
43+
}
44+
45+
// Insert the new item at front of the list
46+
items.emplace_front(k, std::move(v));
47+
48+
// Insert in the map
49+
index[k] = items.begin();
50+
}
51+
52+
template<typename K, typename V>
53+
Result<std::reference_wrapper<V>>
54+
LRUCache<K, V>::lookup(const K& k)
55+
{
56+
auto itr = index.find(k);
57+
if (itr == index.end())
58+
return ErrorKind::LookupError;
59+
60+
// Move to the front of the list
61+
items.splice(items.begin(), items, itr->second);
62+
63+
return std::reference_wrapper<V>(*(itr->second->second.get()));
64+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// This file is part of "echion" which is released under MIT.
2+
//
3+
// Copyright (c) 2023 Gabriele N. Tornetta <[email protected]>.
4+
5+
#pragma once
6+
7+
#define PY_SSIZE_T_CLEAN
8+
#include <Python.h>
9+
10+
// Sampling interval
11+
inline unsigned int interval = 1000;
12+
13+
// CPU Time mode
14+
inline int cpu = 0;
15+
16+
// For cpu time mode, Echion only unwinds threads that're running by default.
17+
// Set this to false to unwind all threads.
18+
inline bool ignore_non_running_threads = true;
19+
20+
// Maximum number of frames to unwind
21+
inline unsigned int max_frames = 2048;
22+
23+
// ----------------------------------------------------------------------------
24+
static PyObject*
25+
set_interval(PyObject* Py_UNUSED(m), PyObject* args)
26+
{
27+
unsigned int new_interval;
28+
if (!PyArg_ParseTuple(args, "I", &new_interval))
29+
return NULL;
30+
31+
interval = new_interval;
32+
33+
Py_RETURN_NONE;
34+
}
35+
36+
// ----------------------------------------------------------------------------
37+
inline void
38+
_set_cpu(int new_cpu)
39+
{
40+
cpu = new_cpu;
41+
}
42+
43+
// ----------------------------------------------------------------------------
44+
inline void
45+
_set_ignore_non_running_threads(bool new_ignore_non_running_threads)
46+
{
47+
ignore_non_running_threads = new_ignore_non_running_threads;
48+
}
49+
50+
// ----------------------------------------------------------------------------
51+
static PyObject*
52+
set_cpu(PyObject* Py_UNUSED(m), PyObject* args)
53+
{
54+
int new_cpu;
55+
if (!PyArg_ParseTuple(args, "p", &new_cpu))
56+
return NULL;
57+
58+
_set_cpu(new_cpu);
59+
60+
Py_RETURN_NONE;
61+
}
62+
63+
// ----------------------------------------------------------------------------
64+
static PyObject*
65+
set_max_frames(PyObject* Py_UNUSED(m), PyObject* args)
66+
{
67+
unsigned int new_max_frames;
68+
if (!PyArg_ParseTuple(args, "I", &new_max_frames))
69+
return NULL;
70+
71+
max_frames = new_max_frames;
72+
73+
Py_RETURN_NONE;
74+
}

0 commit comments

Comments
 (0)