From: Ivan Maidanski Date: Wed, 7 Nov 2012 03:05:49 +0000 (+0400) Subject: Add 'bytes reclaimed' counters to public GC_prof_stats_s X-Git-Tag: gc7_4_0~169 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2d4cdb8f442e49f7d8b559f2a18d7c08887bbb45;p=gc Add 'bytes reclaimed' counters to public GC_prof_stats_s * alloc.c (GC_finish_collection): Add GC_bytes_found value to GC_reclaimed_bytes_before_gc (if the former is non-negative and not GC_GET_HEAP_USAGE_NOT_NEEDED) before reseting GC_bytes_found. * include/gc.h (GC_prof_stats_s): Add bytes_reclaimed_since_gc and reclaimed_bytes_before_gc fields. * include/private/gc_priv.h (GC_reclaimed_bytes_before_gc): Declare new GC inner variable (only if not GC_GET_HEAP_USAGE_NOT_NEEDED). * misc.c (GC_reclaimed_bytes_before_gc): Define new variable (only if not GC_GET_HEAP_USAGE_NOT_NEEDED). * misc.c (fill_prof_stats): Fill in bytes_reclaimed_since_gc and reclaimed_bytes_before_gc fields. * tests/test.c (check_heap_stats): Invoke GC_get_heap_usage_safe, GC_get_prof_stats, GC_get_prof_stats_unsafe (only if not GC_GET_HEAP_USAGE_NOT_NEEDED). --- diff --git a/alloc.c b/alloc.c index 1befd32b..ef9d118f 100644 --- a/alloc.c +++ b/alloc.c @@ -846,6 +846,10 @@ STATIC void GC_finish_collection(void) GET_TIME(start_time); # endif +# ifndef GC_GET_HEAP_USAGE_NOT_NEEDED + if (GC_bytes_found > 0) + GC_reclaimed_bytes_before_gc += (word)GC_bytes_found; +# endif GC_bytes_found = 0; # if defined(LINUX) && defined(__ELF__) && !defined(SMALL_CONFIG) if (GETENV("GC_PRINT_ADDRESS_MAP") != 0) { diff --git a/include/gc.h b/include/gc.h index 49d3c373..bd35c0c4 100644 --- a/include/gc.h +++ b/include/gc.h @@ -633,6 +633,11 @@ struct GC_prof_stats_s { /* Number of marker threads (excluding the initiating one). */ /* Same as returned by GC_get_parallel (or 0 if the */ /* collector is single-threaded). */ + GC_word bytes_reclaimed_since_gc; + /* Approximate number of reclaimed bytes after recent GC. */ + GC_word reclaimed_bytes_before_gc; + /* Approximate number of bytes reclaimed before the recent */ + /* garbage collection. The value may wrap. */ }; /* Atomically get GC statistics (various global counters). Clients */ diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index 0f6d5148..5b8d8a86 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -2049,6 +2049,12 @@ GC_EXTERN signed_word GC_bytes_found; /* Number of reclaimed bytes after garbage collection; */ /* protected by GC lock; defined in reclaim.c. */ +#ifndef GC_GET_HEAP_USAGE_NOT_NEEDED + GC_EXTERN word GC_reclaimed_bytes_before_gc; + /* Number of bytes reclaimed before this */ + /* collection cycle; used for statistics only. */ +#endif + #ifdef USE_MUNMAP GC_EXTERN int GC_unmap_threshold; /* defined in allchblk.c */ GC_EXTERN GC_bool GC_force_unmap_on_gcollect; /* defined in misc.c */ diff --git a/misc.c b/misc.c index aae48c9e..353cb564 100644 --- a/misc.c +++ b/misc.c @@ -509,6 +509,8 @@ GC_API void GC_CALL GC_get_heap_usage_safe(GC_word *pheap_size, UNLOCK(); } + GC_INNER word GC_reclaimed_bytes_before_gc = 0; + /* Fill in GC statistics provided the destination is of enough size. */ static void fill_prof_stats(struct GC_prof_stats_s *pstats) { @@ -524,6 +526,9 @@ GC_API void GC_CALL GC_get_heap_usage_safe(GC_word *pheap_size, # else pstats->markers_m1 = 0; /* one marker */ # endif + pstats->bytes_reclaimed_since_gc = GC_bytes_found > 0 ? + (word)GC_bytes_found : 0; + pstats->reclaimed_bytes_before_gc = GC_reclaimed_bytes_before_gc; } # include /* for memset() */ diff --git a/tests/test.c b/tests/test.c index 0cb1d569..6e993a99 100644 --- a/tests/test.c +++ b/tests/test.c @@ -1442,6 +1442,19 @@ void check_heap_stats(void) (unsigned long)max_heap_sz); FAIL; } + +# ifndef GC_GET_HEAP_USAGE_NOT_NEEDED + /* Get global counters (just to check the functions work). */ + GC_get_heap_usage_safe(NULL, NULL, NULL, NULL, NULL); + { + struct GC_prof_stats_s stats; + (void)GC_get_prof_stats(&stats, sizeof(stats)); +# ifdef THREADS + (void)GC_get_prof_stats_unsafe(&stats, sizeof(stats)); +# endif + } +# endif + # ifdef THREADS GC_unregister_my_thread(); /* just to check it works (for main) */ # endif