@@ -550,16 +550,22 @@ static bool mi_arena_purge_range(mi_arena_t* arena, size_t idx, size_t startidx,
550550 return all_purged ;
551551}
552552
553- // returns true if anything was purged
554- static bool mi_arena_try_purge (mi_arena_t * arena , mi_msecs_t now , bool force )
553+ // returns
554+ // -1 = nothing was purged
555+ // 0 = nothing was purged yet because have not yet reached the expire time
556+ // 1 = some pages in the arena were purged
557+ static int mi_arena_try_purge (mi_arena_t * arena , mi_msecs_t now , bool force )
555558{
556559 // check pre-conditions
557- if (arena -> memid .is_pinned ) return false ;
560+ if (arena -> memid .is_pinned ) return -1 ;
558561
559562 // expired yet?
560563 mi_msecs_t expire = mi_atomic_loadi64_relaxed (& arena -> purge_expire );
561- if (!force && (expire == 0 || expire > now )) return false;
562-
564+ if (!force ) {
565+ if (expire == 0 ) return -1 ;
566+ if (expire > now ) return 0 ;
567+ }
568+
563569 // reset expire (if not already set concurrently)
564570 mi_atomic_casi64_strong_acq_rel (& arena -> purge_expire , & expire , (mi_msecs_t )0 );
565571 _mi_stat_counter_increase (& _mi_stats_main .arena_purges , 1 );
@@ -607,7 +613,7 @@ static bool mi_arena_try_purge(mi_arena_t* arena, mi_msecs_t now, bool force)
607613 mi_msecs_t expected = 0 ;
608614 mi_atomic_casi64_strong_acq_rel (& arena -> purge_expire ,& expected ,_mi_clock_now () + delay );
609615 }
610- return any_purged ;
616+ return ( any_purged ? 1 : -1 ) ;
611617}
612618
613619static void mi_arenas_try_purge ( bool force , bool visit_all )
@@ -630,20 +636,25 @@ static void mi_arenas_try_purge( bool force, bool visit_all )
630636 mi_atomic_storei64_release (& mi_arenas_purge_expire , now + mi_arena_purge_delay ());
631637 size_t max_purge_count = (visit_all ? max_arena : 2 );
632638 bool all_visited = true;
639+ bool any_purged = false;
633640 for (size_t i = 0 ; i < max_arena ; i ++ ) {
634641 mi_arena_t * arena = mi_atomic_load_ptr_acquire (mi_arena_t , & mi_arenas [i ]);
635642 if (arena != NULL ) {
636- if (mi_arena_try_purge (arena , now , force )) {
637- if (max_purge_count <= 1 ) {
638- all_visited = false;
639- break ;
643+ int purged = mi_arena_try_purge (arena , now , force );
644+ if (purged >= 0 ) { // purged, or not yet the expire-time reached
645+ any_purged = true;
646+ if (purged >= 1 ) { // purged at least one page
647+ if (max_purge_count <= 1 ) {
648+ all_visited = false;
649+ break ;
650+ }
651+ max_purge_count -- ;
640652 }
641- max_purge_count -- ;
642653 }
643654 }
644655 }
645- if (all_visited ) {
646- // all arena's were visited and purged: reset global expire
656+ if (all_visited && ! any_purged ) {
657+ // all arena's were visited and nothing needed to be purged: reset global expire
647658 mi_atomic_storei64_release (& mi_arenas_purge_expire , 0 );
648659 }
649660 }
0 commit comments