summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2021-09-22 21:18:53 +0300
committerIvan Maidanski <ivmai@mail.ru>2021-09-22 21:23:28 +0300
commit46bed17695d8b49206ee66739eec2e87098d001b (patch)
tree9e6e0bc805475dcdb3d2f8a9e48794325a3298b9
parentfb89ec67f424bf46f00b67acaced89bee56cbb17 (diff)
downloadbdwgc-46bed17695d8b49206ee66739eec2e87098d001b.tar.gz
Declare API function and print amount of memory obtained from OS
Public GC_get_obtained_from_os_bytes() is introduced. * alloc.c [USE_MUNMAP] (GC_stopped_mark): Add assertion that GC_heapsize is not less than GC_unmapped_bytes. * alloc.c (GC_stopped_mark): Add assertion that GC_our_mem_bytes is not less than GC_heapsize; print GC_our_mem_bytes-GC_heapsize value (using GC_DBGLOG_PRINTF). * alloc.c [USE_PROC_FOR_LIBRARIES] (GC_add_to_our_memory): Update comment; increment GC_our_mem_bytes value (by bytes). * include/private/gc_priv.h (GC_add_to_our_memory): Likewise. * include/gc.h (GC_get_obtained_from_os_bytes): New API function declaration. * include/gc.h (GC_prof_stats_s.obtained_from_os_bytes): Declare new field. * include/private/gc_priv.h (_GC_arrays._our_mem_bytes): Likewise. * misc.c (GC_get_obtained_from_os_bytes): Implement. * misc.c [!GC_GET_HEAP_USAGE_NOT_NEEDED] (fill_prof_stats): Set obtained_from_os_bytes field. * tests/test.c (check_heap_stats): Print value returned by GC_get_obtained_from_os_bytes(). * tests/test.c [USE_MUNMAP] (check_heap_stats): Print value returned by GC_get_unmapped_bytes().
-rw-r--r--alloc.c14
-rw-r--r--include/gc.h8
-rw-r--r--include/private/gc_priv.h5
-rw-r--r--misc.c6
-rw-r--r--tests/test.c8
5 files changed, 35 insertions, 6 deletions
diff --git a/alloc.c b/alloc.c
index 02852ed2..3916396d 100644
--- a/alloc.c
+++ b/alloc.c
@@ -917,11 +917,17 @@ STATIC GC_bool GC_stopped_mark(GC_stop_func stop_func)
}
GC_gc_no++;
- GC_DBGLOG_PRINTF("GC #%lu freed %ld bytes, heap %lu KiB"
- IF_USE_MUNMAP(" (+ %lu KiB unmapped)") "\n",
+# ifdef USE_MUNMAP
+ GC_ASSERT(GC_heapsize >= GC_unmapped_bytes);
+# endif
+ GC_ASSERT(GC_our_mem_bytes >= GC_heapsize);
+ GC_DBGLOG_PRINTF("GC #%lu freed %ld bytes, heap %lu KiB ("
+ IF_USE_MUNMAP("+ %lu KiB unmapped ")
+ "+ %lu KiB internal)\n",
(unsigned long)GC_gc_no, (long)GC_bytes_found,
TO_KiB_UL(GC_heapsize - GC_unmapped_bytes) /*, */
- COMMA_IF_USE_MUNMAP(TO_KiB_UL(GC_unmapped_bytes)));
+ COMMA_IF_USE_MUNMAP(TO_KiB_UL(GC_unmapped_bytes)),
+ TO_KiB_UL(GC_our_mem_bytes - GC_heapsize));
/* Check all debugged objects for consistency */
if (GC_debugging_started) {
@@ -1331,7 +1337,6 @@ GC_API void GC_CALL GC_gcollect_and_unmap(void)
#ifdef USE_PROC_FOR_LIBRARIES
/* Add HBLKSIZE aligned, GET_MEM-generated block to GC_our_memory. */
- /* Defined to do nothing if USE_PROC_FOR_LIBRARIES not set. */
GC_INNER void GC_add_to_our_memory(ptr_t p, size_t bytes)
{
GC_ASSERT(p != NULL);
@@ -1340,6 +1345,7 @@ GC_API void GC_CALL GC_gcollect_and_unmap(void)
GC_our_memory[GC_n_memory].hs_start = p;
GC_our_memory[GC_n_memory].hs_bytes = bytes;
GC_n_memory++;
+ GC_our_mem_bytes += bytes;
}
#endif
diff --git a/include/gc.h b/include/gc.h
index e9bd1fb6..90385bed 100644
--- a/include/gc.h
+++ b/include/gc.h
@@ -729,7 +729,7 @@ GC_API GC_stop_func GC_CALL GC_get_stop_func(void);
/* This getter remains lock-free (unsynchronized) for compatibility */
/* reason since some existing clients call it from a GC callback */
/* holding the allocator lock. (This API function and the following */
-/* four ones below were made thread-safe in GC v7.2alpha1 and */
+/* four ones below were made thread-safe in GC v7.2alpha1 and */
/* reverted back in v7.2alpha7 for the reason described.) */
GC_API size_t GC_CALL GC_get_heap_size(void);
@@ -758,6 +758,10 @@ GC_API size_t GC_CALL GC_get_expl_freed_bytes_since_gc(void);
/* getter (see GC_get_heap_size comment regarding thread-safety). */
GC_API size_t GC_CALL GC_get_total_bytes(void);
+/* Return the total number of bytes obtained from OS. Includes the */
+/* unmapped memory. Never decreases. It is an unsynchronized getter. */
+GC_API size_t GC_CALL GC_get_obtained_from_os_bytes(void);
+
/* Return the heap usage information. This is a thread-safe (atomic) */
/* alternative for the five above getters. (This function acquires */
/* the allocator lock thus preventing data racing and returning the */
@@ -808,6 +812,8 @@ struct GC_prof_stats_s {
GC_word expl_freed_bytes_since_gc;
/* Number of bytes freed explicitly since the recent GC. */
/* Same as returned by GC_get_expl_freed_bytes_since_gc(). */
+ GC_word obtained_from_os_bytes;
+ /* Total amount of memory obtained from OS, in bytes. */
};
/* Atomically get GC statistics (various global counters). Clients */
diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h
index 54fd8173..be9590c6 100644
--- a/include/private/gc_priv.h
+++ b/include/private/gc_priv.h
@@ -1374,6 +1374,8 @@ struct _GC_arrays {
word _bytes_allocd_before_gc;
/* Number of bytes allocated before this */
/* collection cycle. */
+# define GC_our_mem_bytes GC_arrays._our_mem_bytes
+ word _our_mem_bytes;
# ifndef SEPARATE_GLOBALS
# define GC_bytes_allocd GC_arrays._bytes_allocd
word _bytes_allocd;
@@ -2262,7 +2264,8 @@ GC_INNER hdr * GC_find_header(ptr_t h);
GC_INNER void GC_add_to_our_memory(ptr_t p, size_t bytes);
/* Add a chunk to GC_our_memory. */
#else
-# define GC_add_to_our_memory(p, bytes) ((void)(p), (void)(bytes))
+# define GC_add_to_our_memory(p, bytes) \
+ (GC_our_mem_bytes += (bytes), (void)(p))
#endif
GC_INNER void GC_print_all_errors(void);
diff --git a/misc.c b/misc.c
index 1580c215..8bf27ce6 100644
--- a/misc.c
+++ b/misc.c
@@ -482,6 +482,11 @@ GC_API size_t GC_CALL GC_get_heap_size(void)
return (size_t)(GC_heapsize - GC_unmapped_bytes);
}
+GC_API size_t GC_CALL GC_get_obtained_from_os_bytes(void)
+{
+ return (size_t)GC_our_mem_bytes;
+}
+
GC_API size_t GC_CALL GC_get_free_bytes(void)
{
/* ignore the memory space returned to OS */
@@ -556,6 +561,7 @@ GC_API void GC_CALL GC_get_heap_usage_safe(GC_word *pheap_size,
(word)GC_bytes_found : 0;
pstats->reclaimed_bytes_before_gc = GC_reclaimed_bytes_before_gc;
pstats->expl_freed_bytes_since_gc = GC_bytes_freed; /* since gc-7.7 */
+ pstats->obtained_from_os_bytes = GC_our_mem_bytes; /* since gc-8.2 */
}
# include <string.h> /* for memset() */
diff --git a/tests/test.c b/tests/test.c
index ab590fea..5e02b788 100644
--- a/tests/test.c
+++ b/tests/test.c
@@ -1830,6 +1830,14 @@ void check_heap_stats(void)
(unsigned long)max_heap_sz);
FAIL;
}
+# ifdef USE_MUNMAP
+ GC_printf("Obtained %lu bytes from OS (of which %lu bytes unmapped)\n",
+ (unsigned long)GC_get_obtained_from_os_bytes(),
+ (unsigned long)GC_get_unmapped_bytes());
+# else
+ GC_printf("Obtained %lu bytes from OS\n",
+ (unsigned long)GC_get_obtained_from_os_bytes());
+# endif
GC_printf("Final number of reachable objects is %u\n", obj_count);
# ifndef GC_GET_HEAP_USAGE_NOT_NEEDED