aboutsummaryrefslogtreecommitdiff
path: root/lib/WinRpMalloc/src/rpmalloc.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/WinRpMalloc/src/rpmalloc.h')
-rw-r--r--lib/WinRpMalloc/src/rpmalloc.h592
1 files changed, 296 insertions, 296 deletions
diff --git a/lib/WinRpMalloc/src/rpmalloc.h b/lib/WinRpMalloc/src/rpmalloc.h
index 3806653..111ff27 100644
--- a/lib/WinRpMalloc/src/rpmalloc.h
+++ b/lib/WinRpMalloc/src/rpmalloc.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2022 Vaughn Nugent
+* Copyright (c) 2023 Vaughn Nugent
*
* Library: VNLib
* Package: WinRpMalloc
@@ -70,8 +70,8 @@ extern "C" {
# define RPMALLOC_CDECL
#endif
-//! Define RPMALLOC_CONFIGURABLE to enable configuring sizes. Will introduce
-// a very small overhead due to some size calculations not being compile time constants
+ //! Define RPMALLOC_CONFIGURABLE to enable configuring sizes. Will introduce
+ // a very small overhead due to some size calculations not being compile time constants
#ifndef RPMALLOC_CONFIGURABLE
#define RPMALLOC_CONFIGURABLE 0
#endif
@@ -89,302 +89,302 @@ extern "C" {
// a new block).
#define RPMALLOC_GROW_OR_FAIL 2
-typedef struct rpmalloc_global_statistics_t {
- //! Current amount of virtual memory mapped, all of which might not have been committed (only if ENABLE_STATISTICS=1)
- size_t mapped;
- //! Peak amount of virtual memory mapped, all of which might not have been committed (only if ENABLE_STATISTICS=1)
- size_t mapped_peak;
- //! Current amount of memory in global caches for small and medium sizes (<32KiB)
- size_t cached;
- //! Current amount of memory allocated in huge allocations, i.e larger than LARGE_SIZE_LIMIT which is 2MiB by default (only if ENABLE_STATISTICS=1)
- size_t huge_alloc;
- //! Peak amount of memory allocated in huge allocations, i.e larger than LARGE_SIZE_LIMIT which is 2MiB by default (only if ENABLE_STATISTICS=1)
- size_t huge_alloc_peak;
- //! Total amount of memory mapped since initialization (only if ENABLE_STATISTICS=1)
- size_t mapped_total;
- //! Total amount of memory unmapped since initialization (only if ENABLE_STATISTICS=1)
- size_t unmapped_total;
-} rpmalloc_global_statistics_t;
-
-typedef struct rpmalloc_thread_statistics_t {
- //! Current number of bytes available in thread size class caches for small and medium sizes (<32KiB)
- size_t sizecache;
- //! Current number of bytes available in thread span caches for small and medium sizes (<32KiB)
- size_t spancache;
- //! Total number of bytes transitioned from thread cache to global cache (only if ENABLE_STATISTICS=1)
- size_t thread_to_global;
- //! Total number of bytes transitioned from global cache to thread cache (only if ENABLE_STATISTICS=1)
- size_t global_to_thread;
- //! Per span count statistics (only if ENABLE_STATISTICS=1)
- struct {
- //! Currently used number of spans
- size_t current;
- //! High water mark of spans used
- size_t peak;
- //! Number of spans transitioned to global cache
- size_t to_global;
- //! Number of spans transitioned from global cache
- size_t from_global;
- //! Number of spans transitioned to thread cache
- size_t to_cache;
- //! Number of spans transitioned from thread cache
- size_t from_cache;
- //! Number of spans transitioned to reserved state
- size_t to_reserved;
- //! Number of spans transitioned from reserved state
- size_t from_reserved;
- //! Number of raw memory map calls (not hitting the reserve spans but resulting in actual OS mmap calls)
- size_t map_calls;
- } span_use[64];
- //! Per size class statistics (only if ENABLE_STATISTICS=1)
- struct {
- //! Current number of allocations
- size_t alloc_current;
- //! Peak number of allocations
- size_t alloc_peak;
- //! Total number of allocations
- size_t alloc_total;
- //! Total number of frees
- size_t free_total;
- //! Number of spans transitioned to cache
- size_t spans_to_cache;
- //! Number of spans transitioned from cache
- size_t spans_from_cache;
- //! Number of spans transitioned from reserved state
- size_t spans_from_reserved;
- //! Number of raw memory map calls (not hitting the reserve spans but resulting in actual OS mmap calls)
- size_t map_calls;
- } size_use[128];
-} rpmalloc_thread_statistics_t;
-
-typedef struct rpmalloc_config_t {
- //! Map memory pages for the given number of bytes. The returned address MUST be
- // aligned to the rpmalloc span size, which will always be a power of two.
- // Optionally the function can store an alignment offset in the offset variable
- // in case it performs alignment and the returned pointer is offset from the
- // actual start of the memory region due to this alignment. The alignment offset
- // will be passed to the memory unmap function. The alignment offset MUST NOT be
- // larger than 65535 (storable in an uint16_t), if it is you must use natural
- // alignment to shift it into 16 bits. If you set a memory_map function, you
- // must also set a memory_unmap function or else the default implementation will
- // be used for both. This function must be thread safe, it can be called by
- // multiple threads simultaneously.
- void* (*memory_map)(size_t size, size_t* offset);
- //! Unmap the memory pages starting at address and spanning the given number of bytes.
- // If release is set to non-zero, the unmap is for an entire span range as returned by
- // a previous call to memory_map and that the entire range should be released. The
- // release argument holds the size of the entire span range. If release is set to 0,
- // the unmap is a partial decommit of a subset of the mapped memory range.
- // If you set a memory_unmap function, you must also set a memory_map function or
- // else the default implementation will be used for both. This function must be thread
- // safe, it can be called by multiple threads simultaneously.
- void (*memory_unmap)(void* address, size_t size, size_t offset, size_t release);
- //! Called when an assert fails, if asserts are enabled. Will use the standard assert()
- // if this is not set.
- void (*error_callback)(const char* message);
- //! Called when a call to map memory pages fails (out of memory). If this callback is
- // not set or returns zero the library will return a null pointer in the allocation
- // call. If this callback returns non-zero the map call will be retried. The argument
- // passed is the number of bytes that was requested in the map call. Only used if
- // the default system memory map function is used (memory_map callback is not set).
- int (*map_fail_callback)(size_t size);
- //! Size of memory pages. The page size MUST be a power of two. All memory mapping
- // requests to memory_map will be made with size set to a multiple of the page size.
- // Used if RPMALLOC_CONFIGURABLE is defined to 1, otherwise system page size is used.
- size_t page_size;
- //! Size of a span of memory blocks. MUST be a power of two, and in [4096,262144]
- // range (unless 0 - set to 0 to use the default span size). Used if RPMALLOC_CONFIGURABLE
- // is defined to 1.
- size_t span_size;
- //! Number of spans to map at each request to map new virtual memory blocks. This can
- // be used to minimize the system call overhead at the cost of virtual memory address
- // space. The extra mapped pages will not be written until actually used, so physical
- // committed memory should not be affected in the default implementation. Will be
- // aligned to a multiple of spans that match memory page size in case of huge pages.
- size_t span_map_count;
- //! Enable use of large/huge pages. If this flag is set to non-zero and page size is
- // zero, the allocator will try to enable huge pages and auto detect the configuration.
- // If this is set to non-zero and page_size is also non-zero, the allocator will
- // assume huge pages have been configured and enabled prior to initializing the
- // allocator.
- // For Windows, see https://docs.microsoft.com/en-us/windows/desktop/memory/large-page-support
- // For Linux, see https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt
- int enable_huge_pages;
- //! Respectively allocated pages and huge allocated pages names for systems
- // supporting it to be able to distinguish among anonymous regions.
- const char *page_name;
- const char *huge_page_name;
-} rpmalloc_config_t;
-
-//! Initialize allocator with default configuration
-RPMALLOC_EXPORT int
-rpmalloc_initialize(void);
-
-//! Initialize allocator with given configuration
-RPMALLOC_EXPORT int
-rpmalloc_initialize_config(const rpmalloc_config_t* config);
-
-//! Get allocator configuration
-RPMALLOC_EXPORT const rpmalloc_config_t*
-rpmalloc_config(void);
-
-//! Finalize allocator
-RPMALLOC_EXPORT void
-rpmalloc_finalize(void);
-
-//! Initialize allocator for calling thread
-RPMALLOC_EXPORT void
-rpmalloc_thread_initialize(void);
-
-//! Finalize allocator for calling thread
-RPMALLOC_EXPORT void
-rpmalloc_thread_finalize(int release_caches);
-
-//! Perform deferred deallocations pending for the calling thread heap
-RPMALLOC_EXPORT void
-rpmalloc_thread_collect(void);
-
-//! Query if allocator is initialized for calling thread
-RPMALLOC_EXPORT int
-rpmalloc_is_thread_initialized(void);
-
-//! Get per-thread statistics
-RPMALLOC_EXPORT void
-rpmalloc_thread_statistics(rpmalloc_thread_statistics_t* stats);
-
-//! Get global statistics
-RPMALLOC_EXPORT void
-rpmalloc_global_statistics(rpmalloc_global_statistics_t* stats);
-
-//! Dump all statistics in human readable format to file (should be a FILE*)
-RPMALLOC_EXPORT void
-rpmalloc_dump_statistics(void* file);
-
-//! Allocate a memory block of at least the given size
-RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
-rpmalloc(size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(1);
-
-//! Free the given memory block
-RPMALLOC_EXPORT void
-rpfree(void* ptr);
-
-//! Allocate a memory block of at least the given size and zero initialize it
-RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
-rpcalloc(size_t num, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE2(1, 2);
-
-//! Reallocate the given block to at least the given size
-RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
-rprealloc(void* ptr, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(2);
-
-//! Reallocate the given block to at least the given size and alignment,
-// with optional control flags (see RPMALLOC_NO_PRESERVE).
-// Alignment must be a power of two and a multiple of sizeof(void*),
-// and should ideally be less than memory page size. A caveat of rpmalloc
-// internals is that this must also be strictly less than the span size (default 64KiB)
-RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
-rpaligned_realloc(void* ptr, size_t alignment, size_t size, size_t oldsize, unsigned int flags) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(3);
-
-//! Allocate a memory block of at least the given size and alignment.
-// Alignment must be a power of two and a multiple of sizeof(void*),
-// and should ideally be less than memory page size. A caveat of rpmalloc
-// internals is that this must also be strictly less than the span size (default 64KiB)
-RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
-rpaligned_alloc(size_t alignment, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(2);
-
-//! Allocate a memory block of at least the given size and alignment, and zero initialize it.
-// Alignment must be a power of two and a multiple of sizeof(void*),
-// and should ideally be less than memory page size. A caveat of rpmalloc
-// internals is that this must also be strictly less than the span size (default 64KiB)
-RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
-rpaligned_calloc(size_t alignment, size_t num, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE2(2, 3);
-
-//! Allocate a memory block of at least the given size and alignment.
-// Alignment must be a power of two and a multiple of sizeof(void*),
-// and should ideally be less than memory page size. A caveat of rpmalloc
-// internals is that this must also be strictly less than the span size (default 64KiB)
-RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
-rpmemalign(size_t alignment, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(2);
-
-//! Allocate a memory block of at least the given size and alignment.
-// Alignment must be a power of two and a multiple of sizeof(void*),
-// and should ideally be less than memory page size. A caveat of rpmalloc
-// internals is that this must also be strictly less than the span size (default 64KiB)
-RPMALLOC_EXPORT int
-rpposix_memalign(void** memptr, size_t alignment, size_t size);
-
-//! Query the usable size of the given memory block (from given pointer to the end of block)
-RPMALLOC_EXPORT size_t
-rpmalloc_usable_size(void* ptr);
-
-//! Dummy empty function for forcing linker symbol inclusion
-RPMALLOC_EXPORT void
-rpmalloc_linker_reference(void);
+ typedef struct rpmalloc_global_statistics_t {
+ //! Current amount of virtual memory mapped, all of which might not have been committed (only if ENABLE_STATISTICS=1)
+ size_t mapped;
+ //! Peak amount of virtual memory mapped, all of which might not have been committed (only if ENABLE_STATISTICS=1)
+ size_t mapped_peak;
+ //! Current amount of memory in global caches for small and medium sizes (<32KiB)
+ size_t cached;
+ //! Current amount of memory allocated in huge allocations, i.e larger than LARGE_SIZE_LIMIT which is 2MiB by default (only if ENABLE_STATISTICS=1)
+ size_t huge_alloc;
+ //! Peak amount of memory allocated in huge allocations, i.e larger than LARGE_SIZE_LIMIT which is 2MiB by default (only if ENABLE_STATISTICS=1)
+ size_t huge_alloc_peak;
+ //! Total amount of memory mapped since initialization (only if ENABLE_STATISTICS=1)
+ size_t mapped_total;
+ //! Total amount of memory unmapped since initialization (only if ENABLE_STATISTICS=1)
+ size_t unmapped_total;
+ } rpmalloc_global_statistics_t;
+
+ typedef struct rpmalloc_thread_statistics_t {
+ //! Current number of bytes available in thread size class caches for small and medium sizes (<32KiB)
+ size_t sizecache;
+ //! Current number of bytes available in thread span caches for small and medium sizes (<32KiB)
+ size_t spancache;
+ //! Total number of bytes transitioned from thread cache to global cache (only if ENABLE_STATISTICS=1)
+ size_t thread_to_global;
+ //! Total number of bytes transitioned from global cache to thread cache (only if ENABLE_STATISTICS=1)
+ size_t global_to_thread;
+ //! Per span count statistics (only if ENABLE_STATISTICS=1)
+ struct {
+ //! Currently used number of spans
+ size_t current;
+ //! High water mark of spans used
+ size_t peak;
+ //! Number of spans transitioned to global cache
+ size_t to_global;
+ //! Number of spans transitioned from global cache
+ size_t from_global;
+ //! Number of spans transitioned to thread cache
+ size_t to_cache;
+ //! Number of spans transitioned from thread cache
+ size_t from_cache;
+ //! Number of spans transitioned to reserved state
+ size_t to_reserved;
+ //! Number of spans transitioned from reserved state
+ size_t from_reserved;
+ //! Number of raw memory map calls (not hitting the reserve spans but resulting in actual OS mmap calls)
+ size_t map_calls;
+ } span_use[64];
+ //! Per size class statistics (only if ENABLE_STATISTICS=1)
+ struct {
+ //! Current number of allocations
+ size_t alloc_current;
+ //! Peak number of allocations
+ size_t alloc_peak;
+ //! Total number of allocations
+ size_t alloc_total;
+ //! Total number of frees
+ size_t free_total;
+ //! Number of spans transitioned to cache
+ size_t spans_to_cache;
+ //! Number of spans transitioned from cache
+ size_t spans_from_cache;
+ //! Number of spans transitioned from reserved state
+ size_t spans_from_reserved;
+ //! Number of raw memory map calls (not hitting the reserve spans but resulting in actual OS mmap calls)
+ size_t map_calls;
+ } size_use[128];
+ } rpmalloc_thread_statistics_t;
+
+ typedef struct rpmalloc_config_t {
+ //! Map memory pages for the given number of bytes. The returned address MUST be
+ // aligned to the rpmalloc span size, which will always be a power of two.
+ // Optionally the function can store an alignment offset in the offset variable
+ // in case it performs alignment and the returned pointer is offset from the
+ // actual start of the memory region due to this alignment. The alignment offset
+ // will be passed to the memory unmap function. The alignment offset MUST NOT be
+ // larger than 65535 (storable in an uint16_t), if it is you must use natural
+ // alignment to shift it into 16 bits. If you set a memory_map function, you
+ // must also set a memory_unmap function or else the default implementation will
+ // be used for both. This function must be thread safe, it can be called by
+ // multiple threads simultaneously.
+ void* (*memory_map)(size_t size, size_t* offset);
+ //! Unmap the memory pages starting at address and spanning the given number of bytes.
+ // If release is set to non-zero, the unmap is for an entire span range as returned by
+ // a previous call to memory_map and that the entire range should be released. The
+ // release argument holds the size of the entire span range. If release is set to 0,
+ // the unmap is a partial decommit of a subset of the mapped memory range.
+ // If you set a memory_unmap function, you must also set a memory_map function or
+ // else the default implementation will be used for both. This function must be thread
+ // safe, it can be called by multiple threads simultaneously.
+ void (*memory_unmap)(void* address, size_t size, size_t offset, size_t release);
+ //! Called when an assert fails, if asserts are enabled. Will use the standard assert()
+ // if this is not set.
+ void (*error_callback)(const char* message);
+ //! Called when a call to map memory pages fails (out of memory). If this callback is
+ // not set or returns zero the library will return a null pointer in the allocation
+ // call. If this callback returns non-zero the map call will be retried. The argument
+ // passed is the number of bytes that was requested in the map call. Only used if
+ // the default system memory map function is used (memory_map callback is not set).
+ int (*map_fail_callback)(size_t size);
+ //! Size of memory pages. The page size MUST be a power of two. All memory mapping
+ // requests to memory_map will be made with size set to a multiple of the page size.
+ // Used if RPMALLOC_CONFIGURABLE is defined to 1, otherwise system page size is used.
+ size_t page_size;
+ //! Size of a span of memory blocks. MUST be a power of two, and in [4096,262144]
+ // range (unless 0 - set to 0 to use the default span size). Used if RPMALLOC_CONFIGURABLE
+ // is defined to 1.
+ size_t span_size;
+ //! Number of spans to map at each request to map new virtual memory blocks. This can
+ // be used to minimize the system call overhead at the cost of virtual memory address
+ // space. The extra mapped pages will not be written until actually used, so physical
+ // committed memory should not be affected in the default implementation. Will be
+ // aligned to a multiple of spans that match memory page size in case of huge pages.
+ size_t span_map_count;
+ //! Enable use of large/huge pages. If this flag is set to non-zero and page size is
+ // zero, the allocator will try to enable huge pages and auto detect the configuration.
+ // If this is set to non-zero and page_size is also non-zero, the allocator will
+ // assume huge pages have been configured and enabled prior to initializing the
+ // allocator.
+ // For Windows, see https://docs.microsoft.com/en-us/windows/desktop/memory/large-page-support
+ // For Linux, see https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt
+ int enable_huge_pages;
+ //! Respectively allocated pages and huge allocated pages names for systems
+ // supporting it to be able to distinguish among anonymous regions.
+ const char* page_name;
+ const char* huge_page_name;
+ } rpmalloc_config_t;
+
+ //! Initialize allocator with default configuration
+ RPMALLOC_EXPORT int
+ rpmalloc_initialize(void);
+
+ //! Initialize allocator with given configuration
+ RPMALLOC_EXPORT int
+ rpmalloc_initialize_config(const rpmalloc_config_t* config);
+
+ //! Get allocator configuration
+ RPMALLOC_EXPORT const rpmalloc_config_t*
+ rpmalloc_config(void);
+
+ //! Finalize allocator
+ RPMALLOC_EXPORT void
+ rpmalloc_finalize(void);
+
+ //! Initialize allocator for calling thread
+ RPMALLOC_EXPORT void
+ rpmalloc_thread_initialize(void);
+
+ //! Finalize allocator for calling thread
+ RPMALLOC_EXPORT void
+ rpmalloc_thread_finalize(int release_caches);
+
+ //! Perform deferred deallocations pending for the calling thread heap
+ RPMALLOC_EXPORT void
+ rpmalloc_thread_collect(void);
+
+ //! Query if allocator is initialized for calling thread
+ RPMALLOC_EXPORT int
+ rpmalloc_is_thread_initialized(void);
+
+ //! Get per-thread statistics
+ RPMALLOC_EXPORT void
+ rpmalloc_thread_statistics(rpmalloc_thread_statistics_t* stats);
+
+ //! Get global statistics
+ RPMALLOC_EXPORT void
+ rpmalloc_global_statistics(rpmalloc_global_statistics_t* stats);
+
+ //! Dump all statistics in human readable format to file (should be a FILE*)
+ RPMALLOC_EXPORT void
+ rpmalloc_dump_statistics(void* file);
+
+ //! Allocate a memory block of at least the given size
+ RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
+ rpmalloc(size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(1);
+
+ //! Free the given memory block
+ RPMALLOC_EXPORT void
+ rpfree(void* ptr);
+
+ //! Allocate a memory block of at least the given size and zero initialize it
+ RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
+ rpcalloc(size_t num, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE2(1, 2);
+
+ //! Reallocate the given block to at least the given size
+ RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
+ rprealloc(void* ptr, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(2);
+
+ //! Reallocate the given block to at least the given size and alignment,
+ // with optional control flags (see RPMALLOC_NO_PRESERVE).
+ // Alignment must be a power of two and a multiple of sizeof(void*),
+ // and should ideally be less than memory page size. A caveat of rpmalloc
+ // internals is that this must also be strictly less than the span size (default 64KiB)
+ RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
+ rpaligned_realloc(void* ptr, size_t alignment, size_t size, size_t oldsize, unsigned int flags) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(3);
+
+ //! Allocate a memory block of at least the given size and alignment.
+ // Alignment must be a power of two and a multiple of sizeof(void*),
+ // and should ideally be less than memory page size. A caveat of rpmalloc
+ // internals is that this must also be strictly less than the span size (default 64KiB)
+ RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
+ rpaligned_alloc(size_t alignment, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(2);
+
+ //! Allocate a memory block of at least the given size and alignment, and zero initialize it.
+ // Alignment must be a power of two and a multiple of sizeof(void*),
+ // and should ideally be less than memory page size. A caveat of rpmalloc
+ // internals is that this must also be strictly less than the span size (default 64KiB)
+ RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
+ rpaligned_calloc(size_t alignment, size_t num, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE2(2, 3);
+
+ //! Allocate a memory block of at least the given size and alignment.
+ // Alignment must be a power of two and a multiple of sizeof(void*),
+ // and should ideally be less than memory page size. A caveat of rpmalloc
+ // internals is that this must also be strictly less than the span size (default 64KiB)
+ RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
+ rpmemalign(size_t alignment, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(2);
+
+ //! Allocate a memory block of at least the given size and alignment.
+ // Alignment must be a power of two and a multiple of sizeof(void*),
+ // and should ideally be less than memory page size. A caveat of rpmalloc
+ // internals is that this must also be strictly less than the span size (default 64KiB)
+ RPMALLOC_EXPORT int
+ rpposix_memalign(void** memptr, size_t alignment, size_t size);
+
+ //! Query the usable size of the given memory block (from given pointer to the end of block)
+ RPMALLOC_EXPORT size_t
+ rpmalloc_usable_size(void* ptr);
+
+ //! Dummy empty function for forcing linker symbol inclusion
+ RPMALLOC_EXPORT void
+ rpmalloc_linker_reference(void);
#if RPMALLOC_FIRST_CLASS_HEAPS
-//! Heap type
-typedef struct heap_t rpmalloc_heap_t;
-
-//! Acquire a new heap. Will reuse existing released heaps or allocate memory for a new heap
-// if none available. Heap API is implemented with the strict assumption that only one single
-// thread will call heap functions for a given heap at any given time, no functions are thread safe.
-RPMALLOC_EXPORT rpmalloc_heap_t*
-rpmalloc_heap_acquire(void);
-
-//! Release a heap (does NOT free the memory allocated by the heap, use rpmalloc_heap_free_all before destroying the heap).
-// Releasing a heap will enable it to be reused by other threads. Safe to pass a null pointer.
-RPMALLOC_EXPORT void
-rpmalloc_heap_release(rpmalloc_heap_t* heap);
-
-//! Allocate a memory block of at least the given size using the given heap.
-RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
-rpmalloc_heap_alloc(rpmalloc_heap_t* heap, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(2);
-
-//! Allocate a memory block of at least the given size using the given heap. The returned
-// block will have the requested alignment. Alignment must be a power of two and a multiple of sizeof(void*),
-// and should ideally be less than memory page size. A caveat of rpmalloc
-// internals is that this must also be strictly less than the span size (default 64KiB).
-RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
-rpmalloc_heap_aligned_alloc(rpmalloc_heap_t* heap, size_t alignment, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(3);
-
-//! Allocate a memory block of at least the given size using the given heap and zero initialize it.
-RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
-rpmalloc_heap_calloc(rpmalloc_heap_t* heap, size_t num, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE2(2, 3);
-
-//! Allocate a memory block of at least the given size using the given heap and zero initialize it. The returned
-// block will have the requested alignment. Alignment must either be zero, or a power of two and a multiple of sizeof(void*),
-// and should ideally be less than memory page size. A caveat of rpmalloc
-// internals is that this must also be strictly less than the span size (default 64KiB).
-RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
-rpmalloc_heap_aligned_calloc(rpmalloc_heap_t* heap, size_t alignment, size_t num, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE2(2, 3);
-
-//! Reallocate the given block to at least the given size. The memory block MUST be allocated
-// by the same heap given to this function.
-RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
-rpmalloc_heap_realloc(rpmalloc_heap_t* heap, void* ptr, size_t size, unsigned int flags) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(3);
-
-//! Reallocate the given block to at least the given size. The memory block MUST be allocated
-// by the same heap given to this function. The returned block will have the requested alignment.
-// Alignment must be either zero, or a power of two and a multiple of sizeof(void*), and should ideally be
-// less than memory page size. A caveat of rpmalloc internals is that this must also be strictly less than
-// the span size (default 64KiB).
-RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
-rpmalloc_heap_aligned_realloc(rpmalloc_heap_t* heap, void* ptr, size_t alignment, size_t size, unsigned int flags) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(4);
-
-//! Free the given memory block from the given heap. The memory block MUST be allocated
-// by the same heap given to this function.
-RPMALLOC_EXPORT void
-rpmalloc_heap_free(rpmalloc_heap_t* heap, void* ptr);
-
-//! Free all memory allocated by the heap
-RPMALLOC_EXPORT void
-rpmalloc_heap_free_all(rpmalloc_heap_t* heap);
-
-//! Set the given heap as the current heap for the calling thread. A heap MUST only be current heap
-// for a single thread, a heap can never be shared between multiple threads. The previous
-// current heap for the calling thread is released to be reused by other threads.
-RPMALLOC_EXPORT void
-rpmalloc_heap_thread_set_current(rpmalloc_heap_t* heap);
+ //! Heap type
+ typedef struct heap_t rpmalloc_heap_t;
+
+ //! Acquire a new heap. Will reuse existing released heaps or allocate memory for a new heap
+ // if none available. Heap API is implemented with the strict assumption that only one single
+ // thread will call heap functions for a given heap at any given time, no functions are thread safe.
+ RPMALLOC_EXPORT rpmalloc_heap_t*
+ rpmalloc_heap_acquire(void);
+
+ //! Release a heap (does NOT free the memory allocated by the heap, use rpmalloc_heap_free_all before destroying the heap).
+ // Releasing a heap will enable it to be reused by other threads. Safe to pass a null pointer.
+ RPMALLOC_EXPORT void
+ rpmalloc_heap_release(rpmalloc_heap_t* heap);
+
+ //! Allocate a memory block of at least the given size using the given heap.
+ RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
+ rpmalloc_heap_alloc(rpmalloc_heap_t* heap, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(2);
+
+ //! Allocate a memory block of at least the given size using the given heap. The returned
+ // block will have the requested alignment. Alignment must be a power of two and a multiple of sizeof(void*),
+ // and should ideally be less than memory page size. A caveat of rpmalloc
+ // internals is that this must also be strictly less than the span size (default 64KiB).
+ RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
+ rpmalloc_heap_aligned_alloc(rpmalloc_heap_t* heap, size_t alignment, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(3);
+
+ //! Allocate a memory block of at least the given size using the given heap and zero initialize it.
+ RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
+ rpmalloc_heap_calloc(rpmalloc_heap_t* heap, size_t num, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE2(2, 3);
+
+ //! Allocate a memory block of at least the given size using the given heap and zero initialize it. The returned
+ // block will have the requested alignment. Alignment must either be zero, or a power of two and a multiple of sizeof(void*),
+ // and should ideally be less than memory page size. A caveat of rpmalloc
+ // internals is that this must also be strictly less than the span size (default 64KiB).
+ RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
+ rpmalloc_heap_aligned_calloc(rpmalloc_heap_t* heap, size_t alignment, size_t num, size_t size) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE2(2, 3);
+
+ //! Reallocate the given block to at least the given size. The memory block MUST be allocated
+ // by the same heap given to this function.
+ RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
+ rpmalloc_heap_realloc(rpmalloc_heap_t* heap, void* ptr, size_t size, unsigned int flags) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(3);
+
+ //! Reallocate the given block to at least the given size. The memory block MUST be allocated
+ // by the same heap given to this function. The returned block will have the requested alignment.
+ // Alignment must be either zero, or a power of two and a multiple of sizeof(void*), and should ideally be
+ // less than memory page size. A caveat of rpmalloc internals is that this must also be strictly less than
+ // the span size (default 64KiB).
+ RPMALLOC_EXPORT RPMALLOC_ALLOCATOR void*
+ rpmalloc_heap_aligned_realloc(rpmalloc_heap_t* heap, void* ptr, size_t alignment, size_t size, unsigned int flags) RPMALLOC_ATTRIB_MALLOC RPMALLOC_ATTRIB_ALLOC_SIZE(4);
+
+ //! Free the given memory block from the given heap. The memory block MUST be allocated
+ // by the same heap given to this function.
+ RPMALLOC_EXPORT void
+ rpmalloc_heap_free(rpmalloc_heap_t* heap, void* ptr);
+
+ //! Free all memory allocated by the heap
+ RPMALLOC_EXPORT void
+ rpmalloc_heap_free_all(rpmalloc_heap_t* heap);
+
+ //! Set the given heap as the current heap for the calling thread. A heap MUST only be current heap
+ // for a single thread, a heap can never be shared between multiple threads. The previous
+ // current heap for the calling thread is released to be reused by other threads.
+ RPMALLOC_EXPORT void
+ rpmalloc_heap_thread_set_current(rpmalloc_heap_t* heap);
#endif