[Rd] Moderating consequences of garbage collection when in C

dhinds at sonic.net dhinds at sonic.net
Tue Nov 15 00:33:36 CET 2011


Martin Morgan <mtmorgan at fhcrc.org> wrote:

> > Do you know if this is all happening inside a C function that could
> > handle disabling and enabling GC?  Or would it require doing this at
> > the R level?  For testing, I am turning GC on and off at the R level

> Generally complicated operations across multiple function calls. 
> Something like

>    f = function() {
>      state <- gcdisable(TRUE)
>      on.exit(gcdisable(state))
>      as.character(1:10000000)
>    }

> might be used.

Here is how I've implemented the core part of this (for discussion,
not a complete patch)

-- Dave




--- memory.c.orig       2011-04-04 15:05:04.000000000 -0700
+++ memory.c    2011-11-14 15:21:42.000000000 -0800
@@ -98,6 +98,7 @@
 */
 
 static int gc_reporting = 0;
+static int gc_disabled = 0;
 static int gc_count = 0;
 
 #ifdef TESTING_WRITE_BARRIER
@@ -2467,6 +2468,17 @@
     R_gc_internal(size_needed);
 }
 
+SEXP attribute_hidden do_gcdisable(SEXP call, SEXP op, SEXP args,
SEXP rho)
+{
+    int i;
+    SEXP old = ScalarLogical(gc_disabled);
+    checkArity(op, args);
+    i = asLogical(CAR(args));
+    if (i != NA_LOGICAL)
+	gc_disabled = i;
+    return old;
+}
+
 #ifdef _R_HAVE_TIMING_
 double R_getClockIncrement(void);
 void R_getProcTime(double *data);
@@ -2541,6 +2553,14 @@
     SEXP first_bad_sexp_type_sexp = NULL;
     int first_bad_sexp_type_line = 0;
 
+    if (gc_disabled) {
+	AdjustHeapSize(size_needed);
+	if (NO_FREE_NODES() || VHEAP_FREE() < size_needed) {
+	    gc_disabled = 0;
+	    error("Heap adjustment failed -- enabling GC");
+	} else return;
+    }
+
  again:
 
     gc_count++;



More information about the R-devel mailing list