Re[2]: [Gc] GC_get_bytes_since_gc locks

Ivan Maidanski ivmai at
Wed Sep 7 07:24:39 PDT 2011

Hi Juan and Hans,

I've finally did this work (after a long-term thinking of) - I've reverted these 5 heap info getters to v72.alpha1 state (i.e. remove locking code for compatibility (retaining old thread-unsafe behavior) with clients using them from a GC callback) adding one thread-safe function is a safe-and-easy-to-use alternative. Verbose commenting for these functions has been done.

Hope this would have considerably more positive effect than negative.

Below is a part of the patch (just to list changes in gc.h, see commit 42a4604b):

--- a/include/gc.h
+++ b/include/gc.h
@@ -517,24 +517,52 @@ GC_API GC_stop_func GC_CALL GC_get_stop_func(void);
 /* data structures.  Excludes the unmapped memory (returned to the OS). */
 /* Includes empty blocks and fragmentation loss.  Includes some pages   */
 /* that were allocated but never written.                               */
+/* This is an unsynchronized getter, so it should be called typically   */
+/* with the GC lock held to avoid data races on multiprocessors (the    */
+/* alternative is to use GC_get_heap_usage_safe API call instead).      */
+/* 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 bellow 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);
 /* Return a lower bound on the number of free bytes in the heap         */
-/* (excluding the unmapped memory space).                               */
+/* (excluding the unmapped memory space).  This is an unsynchronized    */
+/* getter (see GC_get_heap_size comment regarding thread-safety).       */
 GC_API size_t GC_CALL GC_get_free_bytes(void);
 /* Return the size (in bytes) of the unmapped memory (which is returned */
 /* to the OS but could be remapped back by the collector later unless   */
-/* the OS runs out of system/virtual memory).                           */
+/* the OS runs out of system/virtual memory). This is an unsynchronized */
+/* getter (see GC_get_heap_size comment regarding thread-safety).       */
 GC_API size_t GC_CALL GC_get_unmapped_bytes(void);
 /* Return the number of bytes allocated since the last collection.      */
+/* This is an unsynchronized getter (see GC_get_heap_size comment       */
+/* regarding thread-safety).                                            */
 GC_API size_t GC_CALL GC_get_bytes_since_gc(void);
 /* Return the total number of bytes allocated in this process.          */
-/* Never decreases, except due to wrapping.                             */
+/* Never decreases, except due to wrapping.  This is an unsynchronized  */
+/* getter (see GC_get_heap_size comment regarding thread-safety).       */
 GC_API size_t GC_CALL GC_get_total_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     */
+/* consistent result.)  Passing NULL pointer is allowed for any         */
+/* argument.  Returned (filled in) values are of word type.             */
+/* (This API function and the accompanying macro were introduced in     */
+/* GC v7.2alpha7 at the moment when GC_get_heap_size and the friends    */
+/* were made lock-free again.)                                          */
+GC_API void GC_CALL GC_get_heap_usage_safe(GC_word * /* pheap_size */,
+                                           GC_word * /* pfree_bytes */,
+                                           GC_word * /* punmapped_bytes */,
+                                           GC_word * /* pbytes_since_gc */,
+                                           GC_word * /* ptotal_bytes */);
 /* Disable garbage collection.  Even GC_gcollect calls will be          */
 /* ineffective.                                                         */
 GC_API void GC_CALL GC_disable(void);
diff --git a/include/gc_mark.h b/include/gc_mark.h
index d5594e6..34fedb5 100644
--- a/include/gc_mark.h
+++ b/include/gc_mark.h
@@ -207,10 +207,6 @@ GC_API void GC_CALL GC_register_describe_type_fn(int /* kind */,
                                 /* to be used when printing objects     */
                                 /* of a particular kind.                */
-/* See gc.h for the description of these "inner" functions.             */
-GC_API size_t GC_CALL GC_get_heap_size_inner(void);
-GC_API size_t GC_CALL GC_get_free_bytes_inner(void);


25 08 2011, 12:58 Juan Jose Garcia-Ripoll <juanjose.garciaripoll at>:
> On Thu, Aug 25, 2011 at 7:15 AM, Boehm, Hans <hans.boehm at> wrote:
>  I gather that introducing a weak reference to the _inner() version,
>  and calling the original version if it wasn't found, is not an option?
>  I was thinking linker games instead of autconf, but that's admittedly
>  somewhat Linux specific.
> It is not only Linux specific, but it will not work. All versions from the introduction of that patch will simply not work with our code, because GC_get... locks, so calling that function as a last resort is not an option: it will deadlock ECL.
> I gather that on our side we will have to do the following:
> * Detect the library version and refuse to build whenever the library is not suitable (will have to investigate CVS to see on which alpha release this was introduced, but currently we will refuse anything above 7.2.0)
>  * If some _inner() function is added or you decide to revert to the old behavior (which does not seem the case), then accept upstream sources again (again, via hardcoded #if/#else stuff)
> * In the mean time keep our own set of sources patched to remove the locking code.
> Juanjo
> -- 
> Instituto de Física Fundamental, CSIC
> c/ Serrano, 113b, Madrid 28006 (Spain) 
> _______________________________________________
>  Gc mailing list
> Gc at

More information about the Gc mailing list