summaryrefslogtreecommitdiff
path: root/vm_sync.c
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2020-10-14 02:03:21 +0900
committerKoichi Sasada <ko1@atdot.net>2020-10-14 14:02:06 +0900
commitc3ba3fa8d01aa3970dc1f4e3dc0090ae171e9e35 (patch)
tree7aaff45d1eb07dc41297d1661f528a5449609469 /vm_sync.c
parentd7de342e414b29bea7eff444ae33e44445afb9a5 (diff)
support exception when lock_rec > 0
If a ractor getting a VM lock (monitor) raises an exception, unlock can be skipped. To release VM lock correctly on exception (or other jumps with JUMP_TAG), EC_POP_TAG() releases VM lock.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/3654
Diffstat (limited to 'vm_sync.c')
-rw-r--r--vm_sync.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/vm_sync.c b/vm_sync.c
index e3d0ffed15..6b17ce83b5 100644
--- a/vm_sync.c
+++ b/vm_sync.c
@@ -246,3 +246,25 @@ rb_vm_barrier(void)
}
}
}
+
+void
+rb_ec_vm_lock_rec_release(rb_execution_context_t *ec, int recorded_lock_rec)
+{
+ int current_lock_rec = rb_ec_vm_lock_rec(ec);
+ unsigned int lev;
+
+ bp();
+
+ if (recorded_lock_rec > current_lock_rec) {
+ for (; recorded_lock_rec > current_lock_rec; current_lock_rec++) {
+ RB_VM_LOCK_ENTER_LEV(&lev);
+ }
+ }
+ else {
+ for (; recorded_lock_rec < current_lock_rec; current_lock_rec--) {
+ RB_VM_LOCK_LEAVE_LEV(&lev);
+ }
+ }
+
+ VM_ASSERT(recorded_lock_rec == rb_ec_vm_lock_rec(ec));
+}