[前][次][番号順一覧][スレッド一覧]

ruby-changes:9900

From: ko1 <ko1@a...>
Date: Mon, 12 Jan 2009 12:41:40 +0900 (JST)
Subject: [ruby-changes:9900] Ruby:r21441 (trunk): * gc.c (ruby_xmalloc, ruby_xrealloc, ruby_xfree):

ko1	2009-01-12 12:41:20 +0900 (Mon, 12 Jan 2009)

  New Revision: 21441

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=21441

  Log:
    * gc.c (ruby_xmalloc, ruby_xrealloc, ruby_xfree):
      enable to use them without GVL.
      if GC is invoked, acquire GVL during GC.
      if NoMemoryError is raised, acquire GVL and raise it.

  Modified files:
    trunk/ChangeLog
    trunk/gc.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 21440)
+++ ChangeLog	(revision 21441)
@@ -1,3 +1,10 @@
+Mon Jan 12 11:59:19 2009  Koichi Sasada  <ko1@a...>
+
+	* gc.c (ruby_xmalloc, ruby_xrealloc, ruby_xfree):
+	  enable to use them without GVL.
+	  if GC is invoked, acquire GVL during GC.
+	  if NoMemoryError is raised, acquire GVL and raise it.
+
 Mon Jan 12 12:39:56 2009  Nobuyoshi Nakada  <nobu@r...>
 
 	* instruby.rb (install_recursive): skips the directory if matched
Index: gc.c
===================================================================
--- gc.c	(revision 21440)
+++ gc.c	(revision 21441)
@@ -410,6 +410,31 @@
     rb_gc_register_address(var);
 }
 
+static void *
+ruby_memerror_body(void *dummy)
+{
+    rb_memerror();
+    return 0;
+}
+
+static void
+ruby_memerror(void)
+{
+    if (ruby_thread_has_gvl_p()) {
+	rb_memerror();
+    }
+    else {
+	if (ruby_native_thread_p()) {
+	    rb_thread_call_with_gvl(ruby_memerror_body, 0);
+	}
+	else {
+	    /* no ruby thread */
+	    fprintf(stderr, "[FATAL] failed to allocate memory\n");
+	    exit(EXIT_FAILURE);
+	}
+    }
+}
+
 void
 rb_memerror(void)
 {
@@ -531,12 +556,60 @@
 }
 
 static void *
+negative_size_allocation_error_with_gvl(void *ptr)
+{
+    rb_raise(rb_eNoMemError, (const char *)ptr);
+    return 0; /* should not be reached */
+}
+
+static void
+negative_size_allocation_error(const char *msg)
+{
+    if (ruby_thread_has_gvl_p()) {
+	rb_raise(rb_eNoMemError, msg);
+    }
+    else {
+	if (ruby_native_thread_p()) {
+	    rb_thread_call_with_gvl(negative_size_allocation_error_with_gvl, (void *)msg);
+	}
+	else {
+	    fprintf(stderr, "[FATAL] %s\n", msg);
+	    exit(EXIT_FAILURE);
+	}
+    }
+}
+
+static void *
+gc_with_gvl(void *ptr)
+{
+    return (void *)garbage_collect((rb_objspace_t *)ptr);
+}
+
+static int
+garbage_collect_with_gvl(rb_objspace_t *objspace)
+{
+    if (ruby_thread_has_gvl_p()) {
+	return garbage_collect(objspace);
+    }
+    else {
+	if (ruby_native_thread_p()) {
+	    return (int)rb_thread_call_with_gvl(gc_with_gvl, (void *)objspace);
+	}
+	else {
+	    /* no ruby thread */
+	    fprintf(stderr, "[FATAL] failed to allocate memory\n");
+	    exit(EXIT_FAILURE);
+	}
+    }
+}
+
+static void *
 vm_xmalloc(rb_objspace_t *objspace, size_t size)
 {
     void *mem;
 
     if (size < 0) {
-	rb_raise(rb_eNoMemError, "negative allocation size (or too big)");
+	negative_size_allocation_error("negative allocation size (or too big)");
     }
     if (size == 0) size = 1;
 
@@ -546,15 +619,15 @@
 
     if ((ruby_gc_stress && !ruby_disable_gc_stress) ||
 	(malloc_increase+size) > malloc_limit) {
-	garbage_collect(objspace);
+	garbage_collect_with_gvl(objspace);
     }
     mem = malloc(size);
     if (!mem) {
-	if (garbage_collect(objspace)) {
+	if (garbage_collect_with_gvl(objspace)) {
 	    mem = malloc(size);
 	}
 	if (!mem) {
-	    rb_memerror();
+	    ruby_memerror();
 	}
     }
     malloc_increase += size;
@@ -575,11 +648,12 @@
     void *mem;
 
     if (size < 0) {
-	rb_raise(rb_eArgError, "negative re-allocation size");
+	negative_size_allocation_error("negative re-allocation size");
     }
     if (!ptr) return ruby_xmalloc(size);
     if (size == 0) size = 1;
-    if (ruby_gc_stress && !ruby_disable_gc_stress) garbage_collect(objspace);
+    if (ruby_gc_stress && !ruby_disable_gc_stress)
+      garbage_collect_with_gvl(objspace);
 
 #if CALC_EXACT_MALLOC_SIZE
     size += sizeof(size_t);
@@ -589,11 +663,11 @@
 
     mem = realloc(ptr, size);
     if (!mem) {
-	if (garbage_collect(objspace)) {
+	if (garbage_collect_with_gvl(objspace)) {
 	    mem = realloc(ptr, size);
 	}
 	if (!mem) {
-	    rb_memerror();
+	    ruby_memerror();
         }
     }
     malloc_increase += size;

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]