Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
3a0f411
chore(profiling): refactor lock profiler to use C++
danielsn Nov 12, 2025
a18a374
remove dead code from the array
danielsn Nov 12, 2025
aa95fd5
use vector for to_free list
danielsn Nov 12, 2025
fe14587
c++ify traceback_array
danielsn Nov 12, 2025
c5391c9
remove unneeded utils
danielsn Nov 12, 2025
b2b0fbb
refactored into C++
danielsn Nov 12, 2025
57a8eba
initial c++ for heap_tracker
danielsn Nov 12, 2025
d793423
gil guard
danielsn Nov 12, 2025
55bd38e
take maps by value
danielsn Nov 12, 2025
0dbd15d
cleanup need for init by moving to the constructor
danielsn Nov 12, 2025
6d95b12
added todo
danielsn Nov 12, 2025
3f7c639
Merge branch 'main' into dsn/use-cpp
danielsn Nov 12, 2025
fe4d6c1
don't reformat other code
danielsn Nov 12, 2025
fcddff5
remove dead code
danielsn Nov 12, 2025
5d9b104
proper iterator
danielsn Nov 12, 2025
ebd4500
format
danielsn Nov 12, 2025
daf864c
delete unused file
danielsn Nov 12, 2025
8151ed8
move extension to a better place in setup.py
danielsn Nov 13, 2025
36c7798
remove unneeded pimpl
danielsn Nov 13, 2025
24a7ba0
PR comment: use default when possible
danielsn Nov 13, 2025
ac81983
PR Comment: use nullptr
danielsn Nov 13, 2025
02069d9
PR comment: use c++ style system headers
danielsn Nov 13, 2025
b5cc5ec
pragma once
danielsn Nov 13, 2025
0b1dc78
RAII gil guard
danielsn Nov 13, 2025
b3e787a
PR comment: unique pointer
danielsn Nov 13, 2025
0692ece
don't support windows or 32 bit
danielsn Nov 14, 2025
d87f4ac
better deinit
danielsn Nov 14, 2025
19afb6e
Merge branch 'main' into dsn/use-cpp
danielsn Nov 14, 2025
94c5d68
Simplify iterator
danielsn Nov 14, 2025
40af2cd
Merge branch 'main' into dsn/use-cpp
danielsn Nov 14, 2025
3a53d37
Merge branch 'main' into dsn/use-cpp
danielsn Nov 14, 2025
4cd94f4
static instance
danielsn Nov 14, 2025
16cf814
small code cleanup
danielsn Nov 14, 2025
ecab195
RAII reentrancy guard
danielsn Nov 14, 2025
920c2fd
WIP traceback as a class
danielsn Nov 14, 2025
dbab684
feat(ffe): integrate datadog-ffe (#15241)
avara1986 Nov 14, 2025
d4506b7
chore: remove remaining aioredis references (#15275)
brettlangdon Nov 14, 2025
9bf8650
chore(writer): enable native writer by default (#15278)
VianneyRuhlmann Nov 14, 2025
155115a
traceback is now a class
danielsn Nov 14, 2025
f8c661d
removed unneeded atomic
danielsn Nov 14, 2025
e96fdee
removed unneeded headers
danielsn Nov 14, 2025
2df0b42
Merge branch 'main' into dsn/use-cpp
danielsn Nov 14, 2025
e6f10a8
don't init if we've already done so
danielsn Nov 14, 2025
f527e7e
cleanup how we handle missing frames
danielsn Nov 14, 2025
253a078
Unit tests as requested
danielsn Nov 14, 2025
eafa845
Merge branch 'main' into dsn/use-cpp
danielsn Nov 14, 2025
563d69c
fix format
danielsn Nov 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions ddtrace/profiling/collector/_memalloc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include "_memalloc_reentrant.h"
#include "_memalloc_tb.h"
#include "_pymacro.h"
#include "_utils.h"

typedef struct
{
Expand Down Expand Up @@ -135,7 +134,7 @@ memalloc_start(PyObject* Py_UNUSED(module), PyObject* args)
return NULL;
}

if (memalloc_tb_init(global_memalloc_ctx.max_nframe) < 0)
if (!traceback_t::init())
return NULL;

if (object_string == NULL) {
Expand All @@ -145,7 +144,8 @@ memalloc_start(PyObject* Py_UNUSED(module), PyObject* args)
PyUnicode_InternInPlace(&object_string);
}

memalloc_heap_tracker_init((uint32_t)heap_sample_size);
if (!memalloc_heap_tracker_init((uint32_t)heap_sample_size))
return NULL;

PyMemAllocatorEx alloc;

Expand Down Expand Up @@ -190,7 +190,7 @@ memalloc_stop(PyObject* Py_UNUSED(module), PyObject* Py_UNUSED(args))
memalloc_heap_tracker_deinit();

/* Finally, we know in-progress sampling won't use the buffer pool, so clear it out */
memalloc_tb_deinit();
traceback_t::deinit();

memalloc_enabled = false;

Expand Down
85 changes: 45 additions & 40 deletions ddtrace/profiling/collector/_memalloc_debug.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#ifndef _DDTRACE_MEMALLOC_DEBUG_H
#define _DDTRACE_MEMALLOC_DEBUG_H
#pragma once

#include <assert.h>
#include <stdbool.h>
#include <cassert>

#include <Python.h>

Expand All @@ -17,47 +15,54 @@ memalloc_debug_gil_release(void)
#endif
}

typedef struct
class memalloc_gil_debug_check_t
{
bool acquired;
} memalloc_gil_debug_check_t;
public:
memalloc_gil_debug_check_t() = default;

static void
memalloc_gil_debug_check_init(memalloc_gil_debug_check_t* c)
{
c->acquired = false;
}
bool acquired = false;
};

#ifndef NDEBUG
/* Annotate that we are beginning a critical section where we don't want other
* memalloc code to run. If compiled assertions enabled, this will check that the
* GIL is held and that the guard has not already been acquired elsewhere.
*
* This is a macro so we get file/line info where it's actually used */
#define MEMALLOC_GIL_DEBUG_CHECK_ACQUIRE(c) \
do { \
memalloc_gil_debug_check_t* p = c; \
assert(PyGILState_Check()); \
assert(!p->acquired); \
p->acquired = true; \
} while (0)

/* Annotate that we are ending a critical section where we don't want other
* memalloc code to run. If compiled assertions enabled, this will check that the
* guard is acquired.
*
* This is a macro so we get file/line info where it's actually used */
#define MEMALLOC_GIL_DEBUG_CHECK_RELEASE(c) \
do { \
memalloc_gil_debug_check_t* p = c; \
assert(p->acquired); \
p->acquired = false; \
} while (0)
#else
/* RAII guard for GIL debug checking. Automatically acquires the guard in the
* constructor and releases it in the destructor. */
class memalloc_gil_debug_guard_t
{
public:
explicit memalloc_gil_debug_guard_t(memalloc_gil_debug_check_t& guard)
: guard_(guard)
{
assert(PyGILState_Check());
assert(!guard_.acquired);
guard_.acquired = true;
}

#define MEMALLOC_GIL_DEBUG_CHECK_ACQUIRE(c)
#define MEMALLOC_GIL_DEBUG_CHECK_RELEASE(c)
~memalloc_gil_debug_guard_t()
{
assert(guard_.acquired);
guard_.acquired = false;
}

#endif
// Non-copyable, non-movable
memalloc_gil_debug_guard_t(const memalloc_gil_debug_guard_t&) = delete;
memalloc_gil_debug_guard_t& operator=(const memalloc_gil_debug_guard_t&) = delete;
memalloc_gil_debug_guard_t(memalloc_gil_debug_guard_t&&) = delete;
memalloc_gil_debug_guard_t& operator=(memalloc_gil_debug_guard_t&&) = delete;

private:
memalloc_gil_debug_check_t& guard_;
};
#else
/* In release builds, the guard is a no-op */
class memalloc_gil_debug_guard_t
{
public:
explicit memalloc_gil_debug_guard_t(memalloc_gil_debug_check_t&) {}

// Non-copyable, non-movable
memalloc_gil_debug_guard_t(const memalloc_gil_debug_guard_t&) = delete;
memalloc_gil_debug_guard_t& operator=(const memalloc_gil_debug_guard_t&) = delete;
memalloc_gil_debug_guard_t(memalloc_gil_debug_guard_t&&) = delete;
memalloc_gil_debug_guard_t& operator=(memalloc_gil_debug_guard_t&&) = delete;
};
#endif
Loading
Loading