| Age | Commit message (Collapse) | Author |
|
[Bug #17516]
`fork(2)` only leave the calling thread alive in the child.
Because of this forking from the non-main ractor can easily
leave the VM in a corrupted state.
It may be possible in the future to carefully allow forking from non-main
Ractor, but shot term it's preferable to add this restriction.
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/13611
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/13531
|
|
Now that class fields have been deletated to a T_IMEMO/class_fields
when we're in multi-ractor mode, we can read and write class instance
variable in an atomic way using Read-Copy-Update (RCU).
Note when in multi-ractor mode, we always use RCU. In theory
we don't need to, instead if we ensured the field is written
before the shape is updated it would be safe.
Benchmark:
```ruby
Warning[:experimental] = false
class Foo
@foo = 1
@bar = 2
@baz = 3
@egg = 4
@spam = 5
class << self
attr_reader :foo, :bar, :baz, :egg, :spam
end
end
ractors = 8.times.map do
Ractor.new do
1_000_000.times do
Foo.bar + Foo.baz * Foo.egg - Foo.spam
end
end
end
if Ractor.method_defined?(:value)
ractors.each(&:value)
else
ractors.each(&:take)
end
```
This branch vs Ruby 3.4:
```bash
$ hyperfine -w 1 'ruby --disable-all ../test.rb' './miniruby ../test.rb'
Benchmark 1: ruby --disable-all ../test.rb
Time (mean ± σ): 3.162 s ± 0.071 s [User: 2.783 s, System: 10.809 s]
Range (min … max): 3.093 s … 3.337 s 10 runs
Benchmark 2: ./miniruby ../test.rb
Time (mean ± σ): 208.7 ms ± 4.6 ms [User: 889.7 ms, System: 6.9 ms]
Range (min … max): 202.8 ms … 222.0 ms 14 runs
Summary
./miniruby ../test.rb ran
15.15 ± 0.47 times faster than ruby --disable-all ../test.rb
```
Notes:
Merged: https://github.com/ruby/ruby/pull/13594
|
|
* Added `Ractor::Port`
* `Ractor::Port#receive` (support multi-threads)
* `Rcator::Port#close`
* `Ractor::Port#closed?`
* Added some methods
* `Ractor#join`
* `Ractor#value`
* `Ractor#monitor`
* `Ractor#unmonitor`
* Removed some methods
* `Ractor#take`
* `Ractor.yield`
* Change the spec
* `Racotr.select`
You can wait for multiple sequences of messages with `Ractor::Port`.
```ruby
ports = 3.times.map{ Ractor::Port.new }
ports.map.with_index do |port, ri|
Ractor.new port,ri do |port, ri|
3.times{|i| port << "r#{ri}-#{i}"}
end
end
p ports.each{|port| pp 3.times.map{port.receive}}
```
In this example, we use 3 ports, and 3 Ractors send messages to them respectively.
We can receive a series of messages from each port.
You can use `Ractor#value` to get the last value of a Ractor's block:
```ruby
result = Ractor.new do
heavy_task()
end.value
```
You can wait for the termination of a Ractor with `Ractor#join` like this:
```ruby
Ractor.new do
some_task()
end.join
```
`#value` and `#join` are similar to `Thread#value` and `Thread#join`.
To implement `#join`, `Ractor#monitor` (and `Ractor#unmonitor`) is introduced.
This commit changes `Ractor.select()` method.
It now only accepts ports or Ractors, and returns when a port receives a message or a Ractor terminates.
We removes `Ractor.yield` and `Ractor#take` because:
* `Ractor::Port` supports most of similar use cases in a simpler manner.
* Removing them significantly simplifies the code.
We also change the internal thread scheduler code (thread_pthread.c):
* During barrier synchronization, we keep the `ractor_sched` lock to avoid deadlocks.
This lock is released by `rb_ractor_sched_barrier_end()`
which is called at the end of operations that require the barrier.
* fix potential deadlock issues by checking interrupts just before setting UBF.
https://bugs.ruby-lang.org/issues/21262
Notes:
Merged: https://github.com/ruby/ruby/pull/13445
|
|
If you catch an error that was raised from a file you required in
a ractor, that error did not have its belonging reset from the main
ractor to the current ractor, so you hit assertion errors in debug
mode.
Notes:
Merged: https://github.com/ruby/ruby/pull/13428
|
|
Previously the object was used directly, which calls `to_s` if defined.
We should use rb_inspect to get a value suitable for display to the
programmer.
Notes:
Merged: https://github.com/ruby/ruby/pull/13389
|
|
[Bug #17506]
`Thread.current.group` isn't shareable so it shouldn't be inherited
by the main thread of a new Ractor.
This cause an extra allocation when spawning a ractor, which could
be elided with a bit of extra work, but not sure if it's worth
the effort.
Notes:
Merged: https://github.com/ruby/ruby/pull/13013
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/12977
|