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) { }