summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--alloc.c14
-rw-r--r--include/gc/gc.h4
-rw-r--r--tests/gctest.c3
3 files changed, 11 insertions, 10 deletions
diff --git a/alloc.c b/alloc.c
index 15749ca9..b9e1b933 100644
--- a/alloc.c
+++ b/alloc.c
@@ -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();
diff --git a/include/gc/gc.h b/include/gc/gc.h
index 3f0d0cc0..06048c6e 100644
--- a/include/gc/gc.h
+++ b/include/gc/gc.h
@@ -957,7 +957,9 @@ GC_API void GC_CALL GC_start_incremental_collection(void);
/* to marking from one page. May do more work if further */
/* progress requires it, e.g. if incremental collection is */
/* disabled. It is reasonable to call this in a wait loop */
-/* until it returns 0. */
+/* until it returns 0. If GC is disabled but the incremental */
+/* collection is already ongoing, then perform marking anyway */
+/* but not stopping the world (and without the reclaim phase). */
GC_API int GC_CALL GC_collect_a_little(void);
/* Allocate an object of size lb bytes. The client guarantees that as */
diff --git a/tests/gctest.c b/tests/gctest.c
index d50a9f61..9c5fe9d2 100644
--- a/tests/gctest.c
+++ b/tests/gctest.c
@@ -1972,8 +1972,7 @@ void check_heap_stats(void)
# endif
/* Garbage collect repeatedly so that all inaccessible objects */
/* can be finalized. */
- if (!GC_is_disabled())
- while (GC_collect_a_little()) { }
+ while (GC_collect_a_little()) { } /* should work even if disabled GC */
for (i = 0; i < 16; i++) {
GC_gcollect();
# ifndef GC_NO_FINALIZATION