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

ruby-changes:51500

From: k0kubun <ko1@a...>
Date: Thu, 21 Jun 2018 23:04:14 +0900 (JST)
Subject: [ruby-changes:51500] k0kubun:r63710 (trunk): mjit.c: RubyVM::MJIT.pause / RubyVM::MJIT.resume

k0kubun	2018-06-21 23:04:05 +0900 (Thu, 21 Jun 2018)

  New Revision: 63710

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=63710

  Log:
    mjit.c: RubyVM::MJIT.pause / RubyVM::MJIT.resume
    
    [Feature #14830]

  Modified files:
    trunk/mjit.c
    trunk/vm.c
Index: mjit.c
===================================================================
--- mjit.c	(revision 63709)
+++ mjit.c	(revision 63710)
@@ -941,7 +941,9 @@ static int worker_stopped; https://github.com/ruby/ruby/blob/trunk/mjit.c#L941
 static void
 worker(void)
 {
-    make_pch();
+    if (pch_status == PCH_NOT_READY) {
+        make_pch();
+    }
     if (pch_status == PCH_FAILED) {
         mjit_init_p = FALSE;
         CRITICAL_SECTION_START(3, "in worker to update worker_stopped");
@@ -1376,6 +1378,26 @@ system_tmpdir(void) https://github.com/ruby/ruby/blob/trunk/mjit.c#L1378
 
 extern const char ruby_description_with_jit[];
 
+/* Start MJIT worker. Return TRUE if worker is sucessfully started. */
+static int
+start_worker(void)
+{
+    stop_worker_p = FALSE;
+    worker_stopped = FALSE;
+
+    if (!rb_thread_create_mjit_thread(child_after_fork, worker)) {
+        mjit_init_p = FALSE;
+        rb_native_mutex_destroy(&mjit_engine_mutex);
+        rb_native_cond_destroy(&mjit_pch_wakeup);
+        rb_native_cond_destroy(&mjit_client_wakeup);
+        rb_native_cond_destroy(&mjit_worker_wakeup);
+        rb_native_cond_destroy(&mjit_gc_wakeup);
+        verbose(1, "Failure in MJIT thread initialization\n");
+        return FALSE;
+    }
+    return TRUE;
+}
+
 /* Initialize MJIT.  Start a thread creating the precompiled header and
    processing ISeqs.  The function should be called first for using MJIT.
    If everything is successfull, MJIT_INIT_P will be TRUE.  */
@@ -1438,17 +1460,51 @@ mjit_init(struct mjit_options *opts) https://github.com/ruby/ruby/blob/trunk/mjit.c#L1460
     rb_define_global_const("RUBY_DESCRIPTION", rb_obj_freeze(rb_description));
 
     /* Initialize worker thread */
-    stop_worker_p = FALSE;
-    worker_stopped = FALSE;
-    if (!rb_thread_create_mjit_thread(child_after_fork, worker)) {
-        mjit_init_p = FALSE;
-        rb_native_mutex_destroy(&mjit_engine_mutex);
-        rb_native_cond_destroy(&mjit_pch_wakeup);
-        rb_native_cond_destroy(&mjit_client_wakeup);
-        rb_native_cond_destroy(&mjit_worker_wakeup);
-        rb_native_cond_destroy(&mjit_gc_wakeup);
-        verbose(1, "Failure in MJIT thread initialization\n");
+    start_worker();
+}
+
+static void
+stop_worker(void)
+{
+    stop_worker_p = TRUE;
+    while (!worker_stopped) {
+        verbose(3, "Sending cancel signal to worker");
+        CRITICAL_SECTION_START(3, "in stop_worker");
+        rb_native_cond_broadcast(&mjit_worker_wakeup);
+        CRITICAL_SECTION_FINISH(3, "in stop_worker");
+    }
+}
+
+/* Stop JIT-compiling methods but compiled code is kept available. */
+VALUE
+mjit_pause(void)
+{
+    if (!mjit_init_p) {
+        rb_raise(rb_eRuntimeError, "MJIT is not enabled");
     }
+    if (worker_stopped) {
+        return Qfalse;
+    }
+
+    stop_worker();
+    return Qtrue;
+}
+
+/* Restart JIT-compiling methods after mjit_pause. */
+VALUE
+mjit_resume(void)
+{
+    if (!mjit_init_p) {
+        rb_raise(rb_eRuntimeError, "MJIT is not enabled");
+    }
+    if (!worker_stopped) {
+        return Qfalse;
+    }
+
+    if (!start_worker()) {
+        rb_raise(rb_eRuntimeError, "Failed to resume MJIT worker");
+    }
+    return Qtrue;
 }
 
 /* Finish the threads processing units and creating PCH, finalize
@@ -1475,13 +1531,7 @@ mjit_finish(void) https://github.com/ruby/ruby/blob/trunk/mjit.c#L1531
     CRITICAL_SECTION_FINISH(3, "in mjit_finish to wakeup from pch");
 
     /* Stop worker */
-    stop_worker_p = TRUE;
-    while (!worker_stopped) {
-        verbose(3, "Sending cancel signal to workers");
-        CRITICAL_SECTION_START(3, "in mjit_finish");
-        rb_native_cond_broadcast(&mjit_worker_wakeup);
-        CRITICAL_SECTION_FINISH(3, "in mjit_finish");
-    }
+    stop_worker();
 
     rb_native_mutex_destroy(&mjit_engine_mutex);
     rb_native_cond_destroy(&mjit_pch_wakeup);
Index: vm.c
===================================================================
--- vm.c	(revision 63709)
+++ vm.c	(revision 63710)
@@ -2780,6 +2780,9 @@ mjit_enabled_p(void) https://github.com/ruby/ruby/blob/trunk/vm.c#L2780
     return mjit_init_p ? Qtrue : Qfalse;
 }
 
+extern VALUE mjit_pause(void);
+extern VALUE mjit_resume(void);
+
 extern VALUE *rb_gc_stack_start;
 extern size_t rb_gc_stack_maxsize;
 #ifdef __ia64
@@ -2868,6 +2871,8 @@ Init_VM(void) https://github.com/ruby/ruby/blob/trunk/vm.c#L2871
     /* RubyVM::MJIT */
     mjit = rb_define_module_under(rb_cRubyVM, "MJIT");
     rb_define_singleton_method(mjit, "enabled?", mjit_enabled_p, 0);
+    rb_define_singleton_method(mjit, "pause", mjit_pause, 0);
+    rb_define_singleton_method(mjit, "resume", mjit_resume, 0);
 
     /*
      * Document-class: Thread

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

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