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/