summaryrefslogtreecommitdiff
path: root/ractor.c
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2020-12-05 06:15:17 +0900
committerKoichi Sasada <ko1@atdot.net>2020-12-07 08:28:36 +0900
commit307732ccee7f9f28f8422bab2f839da021d8cdec (patch)
treef39ec33d41cbcbaf07bcc1a8d34dc3047357ca6e /ractor.c
parentb67b24d0f5e78481e6a306881b6858f0dec996ba (diff)
cancel theap on multi-ractors
accessing theap needs complicating synchronization but it reduce performance on multi-ractor mode. So simply stop using theap on multi-ractor mode. In future, theap should be replaced with more cleaver memory strategy.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/3842
Diffstat (limited to 'ractor.c')
-rw-r--r--ractor.c39
1 files changed, 25 insertions, 14 deletions
diff --git a/ractor.c b/ractor.c
index 1ed0272616..49a92a2661 100644
--- a/ractor.c
+++ b/ractor.c
@@ -14,6 +14,7 @@
#include "internal/struct.h"
#include "variable.h"
#include "gc.h"
+#include "transient_heap.h"
VALUE rb_cRactor;
static VALUE rb_eRactorError;
@@ -1127,16 +1128,33 @@ ractor_next_id(void)
}
static void
-vm_insert_ractor0(rb_vm_t *vm, rb_ractor_t *r)
+vm_insert_ractor0(rb_vm_t *vm, rb_ractor_t *r, bool single_ractor_mode)
{
RUBY_DEBUG_LOG("r:%u ractor.cnt:%u++", r->id, vm->ractor.cnt);
- VM_ASSERT(!rb_multi_ractor_p() || RB_VM_LOCKED_P());
+ VM_ASSERT(single_ractor_mode || RB_VM_LOCKED_P());
list_add_tail(&vm->ractor.set, &r->vmlr_node);
vm->ractor.cnt++;
}
static void
+cancel_single_ractor_mode(void)
+{
+ // enable multi-ractor mode
+ RUBY_DEBUG_LOG("enable multi-ractor mode", 0);
+
+ rb_gc_start();
+ rb_transient_heap_evacuate();
+
+ if (rb_warning_category_enabled_p(RB_WARN_CATEGORY_EXPERIMENTAL)) {
+ rb_warn("Ractor is experimental, and the behavior may change in future versions of Ruby! "
+ "Also there are many implementation issues.");
+ }
+
+ ruby_single_main_ractor = NULL;
+}
+
+static void
vm_insert_ractor(rb_vm_t *vm, rb_ractor_t *r)
{
VM_ASSERT(ractor_status_p(r, ractor_created));
@@ -1144,29 +1162,22 @@ vm_insert_ractor(rb_vm_t *vm, rb_ractor_t *r)
if (rb_multi_ractor_p()) {
RB_VM_LOCK();
{
- vm_insert_ractor0(vm, r);
+ vm_insert_ractor0(vm, r, false);
vm_ractor_blocking_cnt_inc(vm, r, __FILE__, __LINE__);
}
RB_VM_UNLOCK();
}
else {
- vm_insert_ractor0(vm, r);
-
- if (vm->ractor.cnt == 1) {
+ if (vm->ractor.cnt == 0) {
// main ractor
+ vm_insert_ractor0(vm, r, true);
ractor_status_set(r, ractor_blocking);
ractor_status_set(r, ractor_running);
}
else {
+ cancel_single_ractor_mode();
+ vm_insert_ractor0(vm, r, true);
vm_ractor_blocking_cnt_inc(vm, r, __FILE__, __LINE__);
-
- // enable multi-ractor mode
- RUBY_DEBUG_LOG("enable multi-ractor mode", 0);
- ruby_single_main_ractor = NULL;
-
- if (rb_warning_category_enabled_p(RB_WARN_CATEGORY_EXPERIMENTAL)) {
- rb_warn("Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues.");
- }
}
}
}