@@ -126,6 +126,7 @@ void _mi_strlcpy(char* dest, const char* src, size_t dest_size);
126126void _mi_strlcat (char * dest, const char * src, size_t dest_size);
127127size_t _mi_strlen (const char * s);
128128size_t _mi_strnlen (const char * s, size_t max_len);
129+ char * _mi_strnstr (char * s, size_t max_len, const char * pat);
129130bool _mi_getenv (const char * name, char * result, size_t result_size);
130131
131132// "options.c"
@@ -184,6 +185,7 @@ size_t _mi_os_good_alloc_size(size_t size);
184185bool _mi_os_has_overcommit (void );
185186bool _mi_os_has_virtual_reserve (void );
186187size_t _mi_os_virtual_address_bits (void );
188+ size_t _mi_os_minimal_purge_size (void );
187189
188190bool _mi_os_reset (void * addr, size_t size);
189191bool _mi_os_decommit (void * addr, size_t size);
@@ -208,7 +210,7 @@ void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, b
208210void * _mi_os_alloc_aligned_at_offset (size_t size, size_t alignment, size_t align_offset, bool commit, bool allow_large, mi_memid_t * memid);
209211
210212void * _mi_os_get_aligned_hint (size_t try_alignment, size_t size);
211- bool _mi_os_use_large_page (size_t size, size_t alignment);
213+ bool _mi_os_canuse_large_page (size_t size, size_t alignment);
212214size_t _mi_os_large_page_size (void );
213215void * _mi_os_alloc_huge_os_pages (size_t pages, int numa_node, mi_msecs_t max_secs, size_t * pages_reserved, size_t * psize, mi_memid_t * memid);
214216
@@ -245,7 +247,7 @@ mi_page_t* _mi_safe_ptr_page(const void* p);
245247void _mi_page_map_unsafe_destroy (mi_subproc_t * subproc);
246248
247249// "page.c"
248- void * _mi_malloc_generic (mi_heap_t * heap, size_t size, bool zero, size_t huge_alignment) mi_attr_noexcept mi_attr_malloc;
250+ void * _mi_malloc_generic (mi_heap_t * heap, size_t size, bool zero, size_t huge_alignment, size_t * usable ) mi_attr_noexcept mi_attr_malloc;
249251
250252void _mi_page_retire (mi_page_t * page) mi_attr_noexcept; // free the page if there are no other pages with many free blocks
251253void _mi_page_unfull (mi_page_t * page);
@@ -289,12 +291,12 @@ mi_msecs_t _mi_clock_end(mi_msecs_t start);
289291mi_msecs_t _mi_clock_start (void );
290292
291293// "alloc.c"
292- void * _mi_page_malloc_zero (mi_heap_t * heap, mi_page_t * page, size_t size, bool zero) mi_attr_noexcept; // called from `_mi_malloc_generic`
294+ void * _mi_page_malloc_zero (mi_heap_t * heap, mi_page_t * page, size_t size, bool zero, size_t * usable ) mi_attr_noexcept; // called from `_mi_malloc_generic`
293295void * _mi_page_malloc (mi_heap_t * heap, mi_page_t * page, size_t size) mi_attr_noexcept; // called from `_mi_heap_malloc_aligned`
294296void * _mi_page_malloc_zeroed (mi_heap_t * heap, mi_page_t * page, size_t size) mi_attr_noexcept; // called from `_mi_heap_malloc_aligned`
295297void * _mi_heap_malloc_zero (mi_heap_t * heap, size_t size, bool zero) mi_attr_noexcept;
296- void * _mi_heap_malloc_zero_ex (mi_heap_t * heap, size_t size, bool zero, size_t huge_alignment) mi_attr_noexcept; // called from `_mi_heap_malloc_aligned`
297- void * _mi_heap_realloc_zero (mi_heap_t * heap, void * p, size_t newsize, bool zero) mi_attr_noexcept;
298+ void * _mi_heap_malloc_zero_ex (mi_heap_t * heap, size_t size, bool zero, size_t huge_alignment, size_t * usable ) mi_attr_noexcept; // called from `_mi_heap_malloc_aligned`
299+ void * _mi_heap_realloc_zero (mi_heap_t * heap, void * p, size_t newsize, bool zero, size_t * usable_pre, size_t * usable_post ) mi_attr_noexcept;
298300mi_block_t * _mi_page_ptr_unalign (const mi_page_t * page, const void * p);
299301void _mi_padding_shrink (const mi_page_t * page, const mi_block_t * block, const size_t min_size);
300302
@@ -814,7 +816,7 @@ static inline void mi_page_set_heap(mi_page_t* page, mi_heap_t* heap) {
814816 }
815817 const mi_threadid_t tid = (heap == NULL ? MI_THREADID_ABANDONED : heap->tld ->thread_id );
816818 mi_assert_internal ((tid & MI_PAGE_FLAG_MASK) == 0 );
817-
819+
818820 // we need to use an atomic cas since a concurrent thread may still set the MI_PAGE_HAS_INTERIOR_POINTERS flag (see `alloc_aligned.c`).
819821 mi_threadid_t xtid_old = mi_page_xthread_id (page);
820822 mi_threadid_t xtid;
@@ -868,50 +870,17 @@ static inline bool mi_page_has_any_available(const mi_page_t* page) {
868870 return (page->used < page->reserved || (mi_page_thread_free (page) != NULL ));
869871}
870872
871-
872873// Owned?
873874static inline bool mi_page_is_owned (const mi_page_t * page) {
874875 return mi_tf_is_owned (mi_atomic_load_relaxed (&((mi_page_t *)page)->xthread_free ));
875876}
876877
877- // Unown a page that is currently owned
878- static inline void _mi_page_unown_unconditional (mi_page_t * page) {
879- mi_assert_internal (mi_page_is_owned (page));
880- mi_assert_internal (mi_page_thread_id (page)==0 );
881- const uintptr_t old = mi_atomic_and_acq_rel (&page->xthread_free , ~((uintptr_t )1 ));
882- mi_assert_internal ((old&1 )==1 ); MI_UNUSED (old);
883- }
884-
885878// get ownership if it is not yet owned
886879static inline bool mi_page_try_claim_ownership (mi_page_t * page) {
887880 const uintptr_t old = mi_atomic_or_acq_rel (&page->xthread_free , 1 );
888881 return ((old&1 )==0 );
889882}
890883
891- // release ownership of a page. This may free the page if all blocks were concurrently
892- // freed in the meantime. Returns true if the page was freed.
893- static inline bool _mi_page_unown (mi_page_t * page) {
894- mi_assert_internal (mi_page_is_owned (page));
895- mi_assert_internal (mi_page_is_abandoned (page));
896- mi_thread_free_t tf_new;
897- mi_thread_free_t tf_old = mi_atomic_load_relaxed (&page->xthread_free );
898- do {
899- mi_assert_internal (mi_tf_is_owned (tf_old));
900- while mi_unlikely (mi_tf_block (tf_old) != NULL ) {
901- _mi_page_free_collect (page, false ); // update used
902- if (mi_page_all_free (page)) { // it may become free just before unowning it
903- _mi_arenas_page_unabandon (page);
904- _mi_arenas_page_free (page,NULL );
905- return true ;
906- }
907- tf_old = mi_atomic_load_relaxed (&page->xthread_free );
908- }
909- mi_assert_internal (mi_tf_block (tf_old)==NULL );
910- tf_new = mi_tf_create (NULL , false );
911- } while (!mi_atomic_cas_weak_acq_rel (&page->xthread_free , &tf_old, tf_new));
912- return false ;
913- }
914-
915884
916885/* -------------------------------------------------------------------
917886 Guarded objects
0 commit comments