commonware-allocator 2026.9.0

Allocate and manage memory.
Documentation
/* ----------------------------------------------------------------------------
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, const 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, const 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, const mi_heap_t* heap);

// 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)
  // ... 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 
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);

#ifdef __cplusplus
}
#endif

#endif // MIMALLOC_PROFILE_H