@@ -168,22 +168,23 @@ bool _mi_os_secure_guard_page_reset_before(void* addr, mi_memid_t memid) {
168168 Free memory
169169-------------------------------------------------------------- */
170170
171- static void mi_os_free_huge_os_pages (void * p , size_t size );
171+ static void mi_os_free_huge_os_pages (void * p , size_t size , mi_subproc_t * subproc );
172172
173- static void mi_os_prim_free (void * addr , size_t size , size_t commit_size ) {
173+ static void mi_os_prim_free (void * addr , size_t size , size_t commit_size , mi_subproc_t * subproc ) {
174174 mi_assert_internal ((size % _mi_os_page_size ()) == 0 );
175175 if (addr == NULL ) return ; // || _mi_os_is_huge_reserved(addr)
176176 int err = _mi_prim_free (addr , size ); // allow size==0 (issue #1041)
177177 if (err != 0 ) {
178178 _mi_warning_message ("unable to free OS memory (error: %d (0x%x), size: 0x%zx bytes, address: %p)\n" , err , err , size , addr );
179179 }
180+ if (subproc == NULL ) { subproc = _mi_subproc (); } // from `mi_arenas_unsafe_destroy` we pass subproc_main explicitly as we can no longer use the heap pointer
180181 if (commit_size > 0 ) {
181- mi_os_stat_decrease ( committed , commit_size );
182+ mi_subproc_stat_decrease ( subproc , committed , commit_size );
182183 }
183- mi_os_stat_decrease ( reserved , size );
184+ mi_subproc_stat_decrease ( subproc , reserved , size );
184185}
185186
186- void _mi_os_free_ex (void * addr , size_t size , bool still_committed , mi_memid_t memid ) {
187+ void _mi_os_free_ex (void * addr , size_t size , bool still_committed , mi_memid_t memid , mi_subproc_t * subproc /* can be NULL */ ) {
187188 if (mi_memkind_is_os (memid .memkind )) {
188189 size_t csize = memid .mem .os .size ;
189190 if (csize == 0 ) { csize = _mi_os_good_alloc_size (size ); }
@@ -204,10 +205,10 @@ void _mi_os_free_ex(void* addr, size_t size, bool still_committed, mi_memid_t me
204205 // free it
205206 if (memid .memkind == MI_MEM_OS_HUGE ) {
206207 mi_assert (memid .is_pinned );
207- mi_os_free_huge_os_pages (base , csize );
208+ mi_os_free_huge_os_pages (base , csize , subproc );
208209 }
209210 else {
210- mi_os_prim_free (base , csize , (still_committed ? commit_size : 0 ));
211+ mi_os_prim_free (base , csize , (still_committed ? commit_size : 0 ), subproc );
211212 }
212213 }
213214 else {
@@ -217,7 +218,7 @@ void _mi_os_free_ex(void* addr, size_t size, bool still_committed, mi_memid_t me
217218}
218219
219220void _mi_os_free (void * p , size_t size , mi_memid_t memid ) {
220- _mi_os_free_ex (p , size , true, memid );
221+ _mi_os_free_ex (p , size , true, memid , NULL );
221222}
222223
223224
@@ -292,7 +293,7 @@ static void* mi_os_prim_alloc_aligned(size_t size, size_t alignment, bool commit
292293 _mi_warning_message ("unable to allocate aligned OS memory directly, fall back to over-allocation (size: 0x%zx bytes, address: %p, alignment: 0x%zx, commit: %d)\n" , size , p , alignment , commit );
293294 }
294295 #endif
295- if (p != NULL ) { mi_os_prim_free (p , size , (commit ? size : 0 )); }
296+ if (p != NULL ) { mi_os_prim_free (p , size , (commit ? size : 0 ), NULL ); }
296297 if (size >= (SIZE_MAX - alignment )) return NULL ; // overflow
297298 const size_t over_size = size + alignment ;
298299
@@ -310,7 +311,7 @@ static void* mi_os_prim_alloc_aligned(size_t size, size_t alignment, bool commit
310311 // explicitly commit only the aligned part
311312 if (commit ) {
312313 if (!_mi_os_commit (p , size , NULL )) {
313- mi_os_prim_free (* base , over_size , 0 );
314+ mi_os_prim_free (* base , over_size , 0 , NULL );
314315 return NULL ;
315316 }
316317 }
@@ -326,8 +327,8 @@ static void* mi_os_prim_alloc_aligned(size_t size, size_t alignment, bool commit
326327 size_t mid_size = _mi_align_up (size , _mi_os_page_size ());
327328 size_t post_size = over_size - pre_size - mid_size ;
328329 mi_assert_internal (pre_size < over_size && post_size < over_size && mid_size >= size );
329- if (pre_size > 0 ) { mi_os_prim_free (p , pre_size , (commit ? pre_size : 0 )); }
330- if (post_size > 0 ) { mi_os_prim_free ((uint8_t * )aligned_p + mid_size , post_size , (commit ? post_size : 0 )); }
330+ if (pre_size > 0 ) { mi_os_prim_free (p , pre_size , (commit ? pre_size : 0 ), NULL ); }
331+ if (post_size > 0 ) { mi_os_prim_free ((uint8_t * )aligned_p + mid_size , post_size , (commit ? post_size : 0 ), NULL ); }
331332 // we can return the aligned pointer on `mmap` systems
332333 p = aligned_p ;
333334 * base = aligned_p ; // since we freed the pre part, `*base == p`.
@@ -668,7 +669,7 @@ void* _mi_os_alloc_huge_os_pages(size_t pages, int numa_node, mi_msecs_t max_mse
668669 // no success, issue a warning and break
669670 if (p != NULL ) {
670671 _mi_warning_message ("could not allocate contiguous huge OS page %zu at %p\n" , page , addr );
671- mi_os_prim_free (p , MI_HUGE_OS_PAGE_SIZE , MI_HUGE_OS_PAGE_SIZE );
672+ mi_os_prim_free (p , MI_HUGE_OS_PAGE_SIZE , MI_HUGE_OS_PAGE_SIZE , NULL );
672673 }
673674 break ;
674675 }
@@ -710,11 +711,11 @@ void* _mi_os_alloc_huge_os_pages(size_t pages, int numa_node, mi_msecs_t max_mse
710711
711712// free every huge page in a range individually (as we allocated per page)
712713// note: needed with VirtualAlloc but could potentially be done in one go on mmap'd systems.
713- static void mi_os_free_huge_os_pages (void * p , size_t size ) {
714+ static void mi_os_free_huge_os_pages (void * p , size_t size , mi_subproc_t * subproc ) {
714715 if (p == NULL || size == 0 ) return ;
715716 uint8_t * base = (uint8_t * )p ;
716717 while (size >= MI_HUGE_OS_PAGE_SIZE ) {
717- mi_os_prim_free (base , MI_HUGE_OS_PAGE_SIZE , MI_HUGE_OS_PAGE_SIZE );
718+ mi_os_prim_free (base , MI_HUGE_OS_PAGE_SIZE , MI_HUGE_OS_PAGE_SIZE , subproc );
718719 size -= MI_HUGE_OS_PAGE_SIZE ;
719720 base += MI_HUGE_OS_PAGE_SIZE ;
720721 }
0 commit comments