diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2023-04-25 09:35:16 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2023-04-25 09:36:04 +0300 |
commit | 4bdf9b9c327673b71344a63e368d8b2386bae6af (patch) | |
tree | 32451d0a3b368b8c78db67fa34c794ac91bcff04 /alloc.c | |
parent | 2e5646ba3d954da3f45985630281aadfc686f55b (diff) | |
download | bdwgc-4bdf9b9c327673b71344a63e368d8b2386bae6af.tar.gz |
Do incremental mark some in GC_collect_a_little even if GC is disabled
Previous behavior was not documented but this API function did nothing
in this case. That might cause a deadlock in the client code if the
incremental collection was ongoing and the client called
GC_collect_a_little() repeatedly (while the result is true).
The new behavior, for the cause of disabled garbage collection, is to
perform some amount of marking if the incremental collection is
ongoing (but not stopping the world and, thus, not causing the memory
reclaim to start), returning true if there is something more to mark.
* alloc.c (GC_try_to_collect_inner): Change a loop to do-while one.
* alloc.c (GC_collect_a_little): Do not check GC_dont_gc (i.e. call
GC_collect_a_little_inner() unconditionally); add comment.
* include/gc/gc.h (GC_collect_a_little): Update comment (describe the
case when GC is disabled).
* tests/gctest.c (check_heap_stats): Do not call GC_is_disabled(); add
comment.
Diffstat (limited to 'alloc.c')
-rw-r--r-- | alloc.c | 14 |
1 files changed, 7 insertions, 7 deletions
@@ -553,7 +553,7 @@ GC_INNER GC_bool GC_try_to_collect_inner(GC_stop_func stop_func) GC_COND_LOG_PRINTF( "GC_try_to_collect_inner: finishing collection in progress\n"); /* Just finish collection already in progress. */ - while(GC_collection_in_progress()) { + do { if ((*stop_func)()) { /* TODO: Notify GC_EVENT_ABANDON */ return FALSE; @@ -561,7 +561,7 @@ GC_INNER GC_bool GC_try_to_collect_inner(GC_stop_func stop_func) ENTER_GC(); GC_collect_a_little_inner(1); EXIT_GC(); - } + } while (GC_collection_in_progress()); } GC_notify_full_gc(); # ifndef NO_CLOCK @@ -747,11 +747,11 @@ GC_API int GC_CALL GC_collect_a_little(void) if (!EXPECT(GC_is_initialized, TRUE)) GC_init(); LOCK(); - if (!GC_dont_gc) { - ENTER_GC(); - GC_collect_a_little_inner(1); - EXIT_GC(); - } + ENTER_GC(); + /* Note: if the collection is in progress, this may do marking (not */ + /* stopping the world) even in case of disabled GC. */ + GC_collect_a_little_inner(1); + EXIT_GC(); result = (int)GC_collection_in_progress(); UNLOCK(); if (!result && GC_debugging_started) GC_print_all_smashed(); |