summaryrefslogtreecommitdiff
path: root/bootstraptest
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2023-02-24 18:46:17 +0900
committerKoichi Sasada <ko1@atdot.net>2023-03-02 14:31:54 +0900
commita4421bd73c286253311c2cdf8c78ed258f8cff44 (patch)
tree3ebec079d5ed19429148726e2f5e60597d1df988 /bootstraptest
parent1abec43b5d3290ef2229ceb64014ed91410a6381 (diff)
downloadruby-a4421bd73c286253311c2cdf8c78ed258f8cff44.tar.gz
Rewrite Ractor synchronization mechanism
This patch rewrites Ractor synchronization mechanism, send/receive and take/yield. * API * Ractor::Selector is introduced for lightweight waiting for many ractors. * Data structure * remove `struct rb_ractor_waiting_list` and use `struct rb_ractor_queue takers_queue` to manage takers. * remove `rb_ractor_t::yield_atexit` and use `rb_ractor_t::sync::will_basket::type` to check the will. * add `rb_ractor_basket::p.take` to represent a taking ractor. * Synchronization protocol * For the Ractor local GC, `take` can not make a copy object directly so ask to generate the copy from the yielding ractor. * The following steps shows what `r1.take` does on `r0`. * step1: (r0) register `r0` into `r1`'s takers. * step2: (r0) check `r1`'s status and wakeup r0 if `r1` is waiting for yielding a value. * step3: (r0) sleep until `r1` wakes up `r0`. * The following steps shows what `Ractor.yield(v)` on `r1`. * step1: (r1) check first takers of `r1` and if there is (`r0`), make a copy object of `v` and pass it to `r0` and wakes up `r0`. * step2: (r1) if there is no taker ractors, sleep until another ractor try to take.
Diffstat (limited to 'bootstraptest')
-rw-r--r--bootstraptest/test_ractor.rb14
1 files changed, 10 insertions, 4 deletions
diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb
index 459ba260e9..6898edc677 100644
--- a/bootstraptest/test_ractor.rb
+++ b/bootstraptest/test_ractor.rb
@@ -518,9 +518,9 @@ assert_equal '[true, true, true]', %q{
end
}
received = []
- take = []
+ taken = []
yielded = []
- until rs.empty?
+ until received.size == RN && taken.size == RN && yielded.size == RN
r, v = Ractor.select(CR, *rs, yield_value: 'yield')
case r
when :receive
@@ -528,11 +528,17 @@ assert_equal '[true, true, true]', %q{
when :yield
yielded << v
else
- take << v
+ taken << v
rs.delete r
end
end
- [received.all?('sendyield'), yielded.all?(nil), take.all?('take')]
+ r = [received == ['sendyield'] * RN,
+ yielded == [nil] * RN,
+ taken == ['take'] * RN,
+ ]
+
+ STDERR.puts [received, yielded, taken].inspect
+ r
}
# multiple Ractors can send to one Ractor