Repository navigation
Expand file tree
/
Copy pathmimalloc-profile.h
More file actions
97 lines (75 loc) · 5.36 KB
/
Copy pathmimalloc-profile.h
File metadata and controls
97 lines (75 loc) · 5.36 KB
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
/* ----------------------------------------------------------------------------
Copyright (c) 2024-2026, Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
-----------------------------------------------------------------------------*/
#pragma once
#ifndef MIMALLOC_PROFILE_H
#define MIMALLOC_PROFILE_H
#include <mimalloc.h>
#include <stdbool.h> // bool
#include <stdint.h> // uint64_t
//---------------------------------------------------------------------------
// Initial support for profiling hooks; still experimental
//---------------------------------------------------------------------------
#define MI_PROFILE_SAMPLE_DATA_MAX_SIZE (1024)
// User defined profiler; see `test_profile.c` for an example.
typedef struct mi_profiler_s mi_profiler_t;
// Profiler data is stored together with each sampled allocation (unless the `on_free` field in the profiler is NULL.)
typedef struct mi_profiler_sample_data_s {
size_t user_data_size; // size of the user_data (should be the `mi_profiler_t.sample_data_size`)
void* user_data[1]; // default, but can be less or more (up to 1KiB), depending on `sample_data_size`
} mi_profiler_sample_data_t;
// Profiling callback invoked on each sampled allocation.
// If `profiler_data!=NULL` (i.e. when `on_free` is not NULL), then `profiler_data->requested_size == requested_size`.
typedef size_t (mi_cdecl mi_profiler_on_alloc_fun)(mi_profiler_t* profiler, mi_profiler_sample_data_t* profiler_data, void* ptr, size_t requested_size, size_t bytes_sample_rate, uint64_t bytes_since_last_sample, mi_heap_t* heap);
// Profiling callback invoked on each sampled in-place re-allocation.
typedef size_t (mi_cdecl mi_profiler_on_realloc_inplace_fun)(mi_profiler_t* profiler, mi_profiler_sample_data_t* profiler_data, void* ptr, size_t old_size, mi_heap_t* heap);
// Profiling callback invoked on a previously sampled allocation.
typedef void (mi_cdecl mi_profiler_on_free_fun)(mi_profiler_t* profiler, mi_profiler_sample_data_t* profiler_data, void* ptr, mi_heap_t* heap);
// Profiling callback invoked on mi_profiler_snapshot()
typedef void (mi_cdecl mi_profiler_on_snapshot_fun)(mi_profiler_t* profiler);
// A profiler
// All fields are considered immutable such that they can be copied and accessed concurrently. All fields can be NULL/0.
struct mi_profiler_s {
void* reserved; // opaque; reserved by mimalloc
size_t sample_data_size; // size of required profiler data for each sampled allocation (or zero for no data)
size_t initial_sample_rate;// initial sample rate in bytes (set to at least 1 or higher) (can be adjusted by `on_alloc`)
mi_profiler_on_alloc_fun* on_alloc; // called on a sampled allocation (may be called concurrently)
mi_profiler_on_free_fun* on_free; // called on when previous sampled allocation is freed (may be called concurrently)
mi_profiler_on_realloc_inplace_fun* on_realloc_inplace; // (as yet unused) called on in-place reallocation of a previous sampled allocation (may be called concurrently)
mi_profiler_on_snapshot_fun* on_snapshot; // called on mi_profiler_snapshot() (only one thread at a time)
// ... more user fields allowed
};
// Exported definitions
#ifdef __cplusplus
extern "C" {
#endif
// attach a profiler to a particular heap only.
mi_decl_export bool mi_heap_profile(mi_heap_t* heap, mi_profiler_t* profiler);
// disable profiling for a particular heap; useful for a heap that the profiler uses itself for metadata.
mi_decl_export void mi_heap_profile_disable(mi_heap_t* heap);
// attach a profiler to any (current and future) heaps in a sub-process (unless those heaps disabled profiling)
mi_decl_export bool mi_subproc_profile(mi_subproc_id_t subproc_id, mi_profiler_t* profiler);
// attach a profiler to any heaps in the main sub-process (use NULL to detach)
mi_decl_export bool mi_profile(mi_profiler_t* profiler);
// start sampling
mi_decl_export bool mi_profiler_start(mi_profiler_t* profiler);
// end sampling
mi_decl_export bool mi_profiler_stop(mi_profiler_t* profiler);
// snapshot the current profile (may be called concurrently but only one thread will actually call the snapshot callback)
mi_decl_export void mi_profiler_snapshot(mi_profiler_t* profiler);
// builtin pprof compatible profiler
// the builtin profiler can also be activated using environment variables (see [`pprof.c`](/src/profile/pprof.c))
// `base_file_name` selects the text snapshot format if it ends in `.heap` or `.text` (the extension is
// stripped); any other extension, or none, uses the default (protobuf) snapshot format.
// `alloc_interval_size`, if >0, automatically snapshots every that many allocated bytes.
// `inuse_interval_size`, if >0, automatically snapshots every time the in-use bytes grow by that many bytes.
// `time_interval_secs`, if >0, automatically snapshots every that many seconds (checked from allocation events).
mi_decl_export mi_profiler_t* mi_pprof_profiler_new(size_t initial_threshold, const char* base_file_name, size_t alloc_interval_size, size_t inuse_interval_size, size_t time_interval_secs);
mi_decl_export void mi_pprof_profiler_delete(mi_profiler_t* profiler);
#ifdef __cplusplus
}
#endif
#endif // MIMALLOC_PROFILE_H