]> granicus.if.org Git - gc/commitdiff
Expose API to control rate and max prior attempts of collect_a_little
authorJonathan Chambers <joncham@gmail.com>
Tue, 10 Apr 2018 17:02:57 +0000 (13:02 -0400)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 24 Apr 2018 07:42:19 +0000 (10:42 +0300)
(a cherry-pick of commit d897344 from 'unity-release-7_4-incremental')

* alloc.c (GC_RATE): Update comment.
* alloc.c (GC_rate): New STATIC variable (initialized to GC_RATE).
* alloc.c (GC_set_rate, GC_get_rate, GC_set_max_prior_attempts,
GC_get_max_prior_attempts): New API function definition.
* alloc.c (max_prior_attempts): New static variable (initialized to
MAX_PRIOR_ATTEMPTS).
* alloc.c (GC_collect_a_little_inner): Replace GC_RATE to GC_rate;
declare max_deficit local variable and compute GC_rate*n once (per
a function call); replace MAX_PRIOR_ATTEMPTS to max_prior_attempts.
* include/gc.h (GC_set_rate, GC_get_rate, GC_set_max_prior_attempts,
GC_get_max_prior_attempts): New API function declaration.
* tests/test.c [GC_PTHREADS] (main): Call GC_set_rate, GC_get_rate,
GC_set_max_prior_attempts, GC_get_max_prior_attempts.

alloc.c
include/gc.h
tests/test.c

diff --git a/alloc.c b/alloc.c
index d26178af8a4e3e5f901df1f313f1907d60287400..b81d85022d5647f1a3d01f2f82c1fbfa4c16f59a 100644 (file)
--- a/alloc.c
+++ b/alloc.c
@@ -569,7 +569,7 @@ GC_INNER GC_bool GC_try_to_collect_inner(GC_stop_func stop_func)
 
 /*
  * Perform n units of garbage collection work.  A unit is intended to touch
- * roughly GC_RATE pages.  Every once in a while, we do more than that.
+ * roughly GC_rate pages.  Every once in a while, we do more than that.
  * This needs to be a fairly large number with our current incremental
  * GC strategy, since otherwise we allocate too much during GC, and the
  * cleanup gets expensive.
@@ -577,6 +577,7 @@ GC_INNER GC_bool GC_try_to_collect_inner(GC_stop_func stop_func)
 #ifndef GC_RATE
 # define GC_RATE 10
 #endif
+
 #ifndef MAX_PRIOR_ATTEMPTS
 # define MAX_PRIOR_ATTEMPTS 1
 #endif
@@ -588,6 +589,32 @@ GC_INNER GC_bool GC_try_to_collect_inner(GC_stop_func stop_func)
 STATIC int GC_deficit = 0;/* The number of extra calls to GC_mark_some  */
                           /* that we have made.                         */
 
+STATIC int GC_rate = GC_RATE;
+
+GC_API void GC_CALL GC_set_rate(int value)
+{
+    GC_ASSERT(value > 0);
+    GC_rate = value;
+}
+
+GC_API int GC_CALL GC_get_rate(void)
+{
+    return GC_rate;
+}
+
+static int max_prior_attempts = MAX_PRIOR_ATTEMPTS;
+
+GC_API void GC_CALL GC_set_max_prior_attempts(int value)
+{
+    GC_ASSERT(value >= 0);
+    max_prior_attempts = value;
+}
+
+GC_API int GC_CALL GC_get_max_prior_attempts(void)
+{
+    return max_prior_attempts;
+}
+
 GC_INNER void GC_collect_a_little_inner(int n)
 {
     IF_CANCEL(int cancel_state;)
@@ -598,8 +625,9 @@ GC_INNER void GC_collect_a_little_inner(int n)
     DISABLE_CANCEL(cancel_state);
     if (GC_incremental && GC_collection_in_progress()) {
         int i;
+        int max_deficit = GC_rate * n;
 
-        for (i = GC_deficit; i < GC_RATE*n; i++) {
+        for (i = GC_deficit; i < max_deficit; i++) {
             if (GC_mark_some((ptr_t)0)) {
                 /* Need to finish a collection */
 #               ifdef SAVE_CALL_CHAIN
@@ -609,7 +637,7 @@ GC_INNER void GC_collect_a_little_inner(int n)
                     if (GC_parallel)
                       GC_wait_for_reclaim();
 #               endif
-                if (GC_n_attempts < MAX_PRIOR_ATTEMPTS
+                if (GC_n_attempts < max_prior_attempts
                     && GC_time_limit != GC_TIME_UNLIMITED) {
 #                 ifndef NO_CLOCK
                     GET_TIME(GC_start_time);
@@ -627,8 +655,11 @@ GC_INNER void GC_collect_a_little_inner(int n)
                 break;
             }
         }
-        if (GC_deficit > 0) GC_deficit -= GC_RATE*n;
-        if (GC_deficit < 0) GC_deficit = 0;
+        if (GC_deficit > 0) {
+            GC_deficit -= max_deficit;
+            if (GC_deficit < 0)
+                GC_deficit = 0;
+        }
     } else {
         GC_maybe_gc();
     }
index 32f66f8c6bc3ccbe6b2b3e8de061f3fc604b4d36..5461987c786b0d4b861907e7bc729704e551f286 100644 (file)
@@ -433,6 +433,16 @@ GC_API int GC_CALL GC_get_pages_executable(void);
 GC_API void GC_CALL GC_set_min_bytes_allocd(size_t);
 GC_API size_t GC_CALL GC_get_min_bytes_allocd(void);
 
+/* Set/get the size in pages of units operated by GC_collect_a_little.  */
+/* The value should not be zero.  Not synchronized.                     */
+GC_API void GC_CALL GC_set_rate(int);
+GC_API int GC_CALL GC_get_rate(void);
+
+/* Set/get the maximum number of prior attempts at the world-stop       */
+/* marking.  Not synchronized.                                          */
+GC_API void GC_CALL GC_set_max_prior_attempts(int);
+GC_API int GC_CALL GC_get_max_prior_attempts(void);
+
 /* Overrides the default handle-fork mode.  Non-zero value means GC     */
 /* should install proper pthread_atfork handlers.  Has effect only if   */
 /* called before GC_INIT.  Clients should invoke GC_set_handle_fork     */
index 13fb90ea21d4e15b5df6d45aa6ad9ac27938fdba..e19ac0f7f255a519ab9f037d2d6c4314bebc9055 100644 (file)
@@ -2264,6 +2264,10 @@ int main(void)
     GC_set_min_bytes_allocd(1);
     if (GC_get_min_bytes_allocd() != 1)
         FAIL;
+    GC_set_rate(10);
+    GC_set_max_prior_attempts(1);
+    if (GC_get_rate() != 10 || GC_get_max_prior_attempts() != 1)
+        FAIL;
     GC_set_warn_proc(warn_proc);
     if ((code = pthread_key_create(&fl_key, 0)) != 0) {
         GC_printf("Key creation failed %d\n", code);