aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/Include/internal/pycore_tracemalloc.h
blob: d086adc61c319bcb4d6b490ee2a55f050eda8532 (plain) (blame)
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
#ifndef Py_INTERNAL_TRACEMALLOC_H
#define Py_INTERNAL_TRACEMALLOC_H
#ifdef __cplusplus
extern "C" {
#endif

#ifndef Py_BUILD_CORE
#  error "this header requires Py_BUILD_CORE define"
#endif

#include "pycore_hashtable.h"     // _Py_hashtable_t


/* Trace memory blocks allocated by PyMem_RawMalloc() */
#define TRACE_RAW_MALLOC


struct _PyTraceMalloc_Config {
    /* Module initialized?
       Variable protected by the GIL */
    enum {
        TRACEMALLOC_NOT_INITIALIZED,
        TRACEMALLOC_INITIALIZED,
        TRACEMALLOC_FINALIZED
    } initialized;

    /* Is tracemalloc tracing memory allocations?
       Variable protected by the GIL */
    int tracing;

    /* limit of the number of frames in a traceback, 1 by default.
       Variable protected by the GIL. */
    int max_nframe;
};


/* Pack the frame_t structure to reduce the memory footprint on 64-bit
   architectures: 12 bytes instead of 16. */
#if defined(_MSC_VER)
#pragma pack(push, 4)
#endif

struct
#ifdef __GNUC__
__attribute__((packed))
#endif
tracemalloc_frame {
    /* filename cannot be NULL: "<unknown>" is used if the Python frame
       filename is NULL */
    PyObject *filename;
    unsigned int lineno;
};
#ifdef _MSC_VER
#pragma pack(pop)
#endif

struct tracemalloc_traceback {
    Py_uhash_t hash;
    /* Number of frames stored */
    uint16_t nframe;
    /* Total number of frames the traceback had */
    uint16_t total_nframe;
    struct tracemalloc_frame frames[1];
};


struct _tracemalloc_runtime_state {
    struct _PyTraceMalloc_Config config;

    /* Protected by the GIL */
    struct {
        PyMemAllocatorEx mem;
        PyMemAllocatorEx raw;
        PyMemAllocatorEx obj;
    } allocators;

#if defined(TRACE_RAW_MALLOC)
    PyThread_type_lock tables_lock;
#endif
    /* Size in bytes of currently traced memory.
       Protected by TABLES_LOCK(). */
    size_t traced_memory;
    /* Peak size in bytes of traced memory.
       Protected by TABLES_LOCK(). */
    size_t peak_traced_memory;
    /* Hash table used as a set to intern filenames:
       PyObject* => PyObject*.
       Protected by the GIL */
    _Py_hashtable_t *filenames;
    /* Buffer to store a new traceback in traceback_new().
       Protected by the GIL. */
    struct tracemalloc_traceback *traceback;
    /* Hash table used as a set to intern tracebacks:
       traceback_t* => traceback_t*
       Protected by the GIL */
    _Py_hashtable_t *tracebacks;
    /* pointer (void*) => trace (trace_t*).
       Protected by TABLES_LOCK(). */
    _Py_hashtable_t *traces;
    /* domain (unsigned int) => traces (_Py_hashtable_t).
       Protected by TABLES_LOCK(). */
    _Py_hashtable_t *domains;

    struct tracemalloc_traceback empty_traceback;

    Py_tss_t reentrant_key;
};

#define _tracemalloc_runtime_state_INIT \
    { \
        .config = { \
            .initialized = TRACEMALLOC_NOT_INITIALIZED, \
            .tracing = 0, \
            .max_nframe = 1, \
        }, \
        .reentrant_key = Py_tss_NEEDS_INIT, \
    }


#ifdef __cplusplus
}
#endif
#endif  // !Py_INTERNAL_TRACEMALLOC_H