summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authork0kubun <k0kubun@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-06-21 14:04:05 +0000
committerk0kubun <k0kubun@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-06-21 14:04:05 +0000
commit0af19735d79535c3ada552b8caaf8c00610b4f88 (patch)
tree0908ddd665608003212cc517834a966744cf078f
parent48efa44719d03eb067d27b30c68cf821074aedce (diff)
mjit.c: RubyVM::MJIT.pause / RubyVM::MJIT.resume
[Feature #14830] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63710 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--mjit.c86
-rw-r--r--vm.c5
2 files changed, 73 insertions, 18 deletions
diff --git a/mjit.c b/mjit.c
index 3b7714306b..80ab299039 100644
--- a/mjit.c
+++ b/mjit.c
@@ -941,7 +941,9 @@ static int worker_stopped;
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)
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)
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)
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);
diff --git a/vm.c b/vm.c
index 7a40e79d6c..4827a3093c 100644
--- a/vm.c
+++ b/vm.c
@@ -2780,6 +2780,9 @@ mjit_enabled_p(void)
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)
/* 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