wingo pushed a commit to branch wip-whippet
in repository guile.

commit 05e8aba462202278b2dcce233e7df2de2994059e
Author: Andy Wingo <wi...@igalia.com>
AuthorDate: Fri Mar 14 09:44:18 2025 +0100

    Add gc_allocation_counter API
---
 api/gc-api.h              |  2 ++
 src/adaptive-heap-sizer.h | 25 ++++++++++++++-----------
 src/bdw.c                 |  4 ++++
 src/mmc.c                 | 17 +++++++++++++++--
 src/pcc.c                 | 17 +++++++++++++++--
 src/semi.c                |  4 ++++
 6 files changed, 54 insertions(+), 15 deletions(-)

diff --git a/api/gc-api.h b/api/gc-api.h
index 245784b33..78d8b2bdb 100644
--- a/api/gc-api.h
+++ b/api/gc-api.h
@@ -31,6 +31,8 @@ GC_API_ int gc_init(const struct gc_options *options,
                     struct gc_event_listener event_listener,
                     void *event_listener_data);
 
+GC_API_ uint64_t gc_allocation_counter(struct gc_heap *heap);
+
 GC_API_ struct gc_heap* gc_mutator_heap(struct gc_mutator *mut);
 
 GC_API_ uintptr_t gc_small_object_nursery_low_address(struct gc_heap *heap);
diff --git a/src/adaptive-heap-sizer.h b/src/adaptive-heap-sizer.h
index 6d3db05bb..225b44baf 100644
--- a/src/adaptive-heap-sizer.h
+++ b/src/adaptive-heap-sizer.h
@@ -109,17 +109,20 @@ gc_adaptive_heap_sizer_background_task(void *data) {
   gc_adaptive_heap_sizer_lock(sizer);
   uint64_t bytes_allocated =
     sizer->get_allocation_counter(sizer->heap);
-  uint64_t heartbeat = gc_platform_monotonic_nanoseconds();
-  double rate = (double) (bytes_allocated - sizer->last_bytes_allocated) /
-    (double) (heartbeat - sizer->last_heartbeat);
-  // Just smooth the rate, under the assumption that the denominator is almost
-  // always 1.
-  sizer->smoothed_allocation_rate *= 1.0 - sizer->allocation_smoothing_factor;
-  sizer->smoothed_allocation_rate += rate * sizer->allocation_smoothing_factor;
-  sizer->last_heartbeat = heartbeat;
-  sizer->last_bytes_allocated = bytes_allocated;
-  sizer->set_heap_size(sizer->heap,
-                       gc_adaptive_heap_sizer_calculate_size(sizer));
+  // bytes_allocated being 0 means the request failed; retry later.
+  if (bytes_allocated) {
+    uint64_t heartbeat = gc_platform_monotonic_nanoseconds();
+    double rate = (double) (bytes_allocated - sizer->last_bytes_allocated) /
+      (double) (heartbeat - sizer->last_heartbeat);
+    // Just smooth the rate, under the assumption that the denominator is 
almost
+    // always 1.
+    sizer->smoothed_allocation_rate *= 1.0 - 
sizer->allocation_smoothing_factor;
+    sizer->smoothed_allocation_rate += rate * 
sizer->allocation_smoothing_factor;
+    sizer->last_heartbeat = heartbeat;
+    sizer->last_bytes_allocated = bytes_allocated;
+    sizer->set_heap_size(sizer->heap,
+                         gc_adaptive_heap_sizer_calculate_size(sizer));
+  }
   gc_adaptive_heap_sizer_unlock(sizer);
 }
 
diff --git a/src/bdw.c b/src/bdw.c
index 332e4a7ec..18d1b893b 100644
--- a/src/bdw.c
+++ b/src/bdw.c
@@ -505,6 +505,10 @@ static void on_heap_resize(GC_word size) {
   HEAP_EVENT(heap_resized, size);
 }
 
+uint64_t gc_allocation_counter(struct gc_heap *heap) {
+  return GC_get_total_bytes();
+}
+
 int gc_init(const struct gc_options *options, struct gc_stack_addr *stack_base,
             struct gc_heap **heap, struct gc_mutator **mutator,
             struct gc_event_listener event_listener,
diff --git a/src/mmc.c b/src/mmc.c
index 081d7b83a..661b7084b 100644
--- a/src/mmc.c
+++ b/src/mmc.c
@@ -1080,12 +1080,25 @@ gc_options_parse_and_set(struct gc_options *options, 
int option,
   return gc_common_options_parse_and_set(&options->common, option, value);
 }
 
-static uint64_t allocation_counter_from_thread(struct gc_heap *heap) {
+// with heap lock
+static uint64_t allocation_counter(struct gc_heap *heap) {
   uint64_t ret = heap->total_allocated_bytes_at_last_gc;
-  if (pthread_mutex_trylock(&heap->lock)) return ret;
   nofl_space_add_to_allocation_counter(heap_nofl_space(heap), &ret);
   large_object_space_add_to_allocation_counter(heap_large_object_space(heap),
                                                &ret);
+  return ret;
+}
+
+uint64_t gc_allocation_counter(struct gc_heap *heap) {
+  pthread_mutex_lock(&heap->lock);
+  uint64_t ret = allocation_counter(heap);
+  pthread_mutex_unlock(&heap->lock);
+  return ret;
+}
+
+static uint64_t allocation_counter_from_thread(struct gc_heap *heap) {
+  if (pthread_mutex_trylock(&heap->lock)) return 0;
+  uint64_t ret = allocation_counter(heap);
   pthread_mutex_unlock(&heap->lock);
   return ret;
 }
diff --git a/src/pcc.c b/src/pcc.c
index b605eb762..ca8be1c11 100644
--- a/src/pcc.c
+++ b/src/pcc.c
@@ -1149,12 +1149,25 @@ int gc_options_parse_and_set(struct gc_options 
*options, int option,
   return gc_common_options_parse_and_set(&options->common, option, value);
 }
 
-static uint64_t allocation_counter_from_thread(struct gc_heap *heap) {
+// with heap lock
+static uint64_t allocation_counter(struct gc_heap *heap) {
   uint64_t ret = heap->total_allocated_bytes_at_last_gc;
-  if (pthread_mutex_trylock(&heap->lock)) return ret;
   copy_space_add_to_allocation_counter(heap_allocation_space(heap), &ret);
   large_object_space_add_to_allocation_counter(heap_large_object_space(heap),
                                                &ret);
+  return ret;
+}
+
+uint64_t gc_allocation_counter(struct gc_heap *heap) {
+  pthread_mutex_lock(&heap->lock);
+  uint64_t ret = allocation_counter(heap);
+  pthread_mutex_unlock(&heap->lock);
+  return ret;
+}
+
+static uint64_t allocation_counter_from_thread(struct gc_heap *heap) {
+  if (pthread_mutex_trylock(&heap->lock)) return 0;
+  uint64_t ret = allocation_counter(heap);
   pthread_mutex_unlock(&heap->lock);
   return ret;
 }
diff --git a/src/semi.c b/src/semi.c
index 0626e02b0..6f902534d 100644
--- a/src/semi.c
+++ b/src/semi.c
@@ -618,6 +618,10 @@ static uint64_t get_allocation_counter(struct gc_heap 
*heap) {
   return heap->total_allocated_bytes_at_last_gc;
 }
 
+uint64_t gc_allocation_counter(struct gc_heap *heap) {
+  return get_allocation_counter(heap);
+}
+
 static void ignore_async_heap_size_adjustment(struct gc_heap *heap,
                                               size_t size) {
 }

Reply via email to