Add mi_heap_page_utilization

This commit is contained in:
githubzilla 2024-05-06 07:40:42 +00:00
parent 479edc9b85
commit 89dc53eca9
3 changed files with 42 additions and 1 deletions

View file

@ -285,6 +285,9 @@ mi_decl_export bool mi_manage_os_memory(void* start, size_t size, bool is_commit
mi_decl_export void mi_debug_show_arenas(void) mi_attr_noexcept;
mi_decl_export bool mi_heap_page_is_underutilized(mi_heap_t* heap, void* p, float ratio) mi_attr_noexcept;
mi_decl_export float mi_heap_page_utilization(mi_heap_t* heap, void* p) mi_attr_noexcept;
// Experimental: heaps associated with specific memory arena's
typedef int mi_arena_id_t;
mi_decl_export void* mi_arena_area(mi_arena_id_t arena_id, size_t* size);

View file

@ -85,7 +85,7 @@ terms of the MIT license. A copy of the license can be found in the file
// Encoded free lists allow detection of corrupted free lists
// and can detect buffer overflows, modify after free, and double `free`s.
#if (MI_SECURE>=3 || MI_DEBUG>=1)
#define MI_ENCODE_FREELIST 1
//#define MI_ENCODE_FREELIST 1
#endif

View file

@ -1044,6 +1044,44 @@ mi_decl_nodiscard void* mi_new_reallocn(void* p, size_t newcount, size_t size) {
}
}
float mi_heap_page_utilization(mi_heap_t* heap, void* p) mi_attr_noexcept {
mi_page_t* page = _mi_ptr_page(p); // get the page that this belongs to
mi_heap_t* page_heap = (mi_heap_t*)(mi_atomic_load_acquire(&(page)->xheap));
// the heap id matches and it is not a full page
if (mi_likely(page_heap == heap && page->flags.x.in_full == 0)) {
// first in the list, meaning it's the head of page queue, thus being used for malloc
if (page->prev == NULL)
return 1.0;
// this page belong to this heap and is not first in the page queue. Lets check its
// utilization.
float ratio = (float)page->used / (float)page->capacity;
mi_assert_internal(ratio <= 1.0);
return ratio;
}
return 1.0;
}
bool mi_heap_page_is_underutilized(mi_heap_t* heap, void* p, float ratio) mi_attr_noexcept {
mi_page_t* page = _mi_ptr_page(p); // get the page that this belongs to
mi_heap_t* page_heap = (mi_heap_t*)(mi_atomic_load_acquire(&(page)->xheap));
// the heap id matches and it is not a full page
if (mi_likely(page_heap == heap && page->flags.x.in_full == 0)) {
// first in the list, meaning it's the head of page queue, thus being used for malloc
if (page->prev == NULL)
return false;
// this page belong to this heap and is not first in the page queue. Lets check its
// utilization.
return page->used <= (unsigned)(page->capacity * ratio);
}
return false;
}
// ------------------------------------------------------
// ensure explicit external inline definitions are emitted!
// ------------------------------------------------------