Hartley McGuire
1b60e94df1
[DOC] Fix Thread::Mutex#unlock doc
...
It was [previously][1] moved from C to Ruby, but the doc on the Ruby
method was copied from `#lock` while the correct doc was left in C.
[1]: 07b2356a6a
2026-07-06 10:02:34 -07:00
Jean Boussier
7e7a1db579
Define Thread::ConditionVariable in thread_sync.rb
...
It's more consistent with Mutex, but also the `#wait` method
benefits from receiving the execution context instead of having
to call `GET_EC`.
2025-12-12 10:07:39 +01:00
Jean Boussier
07b2356a6a
Mutex: avoid repeated calls to GET_EC
...
That call is surprisingly expensive, so trying doing it once
in `#synchronize` and then passing the EC to lock and unlock
saves quite a few cycles.
Before:
```
ruby 4.0.0dev (2025-12-10T09:30:18Z master c5608ab4d7 ) +YJIT +PRISM [arm64-darwin25]
Warming up --------------------------------------
Mutex 1.888M i/100ms
Monitor 1.633M i/100ms
Calculating -------------------------------------
Mutex 22.610M (± 0.2%) i/s (44.23 ns/i) - 113.258M in 5.009097s
Monitor 19.148M (± 0.3%) i/s (52.22 ns/i) - 96.366M in 5.032755s
```
After:
```
ruby 4.0.0dev (2025-12-10T10:40:07Z speedup-mutex 1c901cd4f8) +YJIT +PRISM [arm64-darwin25]
Warming up --------------------------------------
Mutex 2.095M i/100ms
Monitor 1.578M i/100ms
Calculating -------------------------------------
Mutex 24.456M (± 0.4%) i/s (40.89 ns/i) - 123.584M in 5.053418s
Monitor 19.176M (± 0.1%) i/s (52.15 ns/i) - 96.243M in 5.018977s
```
Bench:
```
require 'bundler/inline'
gemfile do
gem "benchmark-ips"
end
mutex = Mutex.new
require "monitor"
monitor = Monitor.new
Benchmark.ips do |x|
x.report("Mutex") { mutex.synchronize { } }
x.report("Monitor") { monitor.synchronize { } }
end
```
2025-12-11 23:25:57 +01:00
Jean Boussier
60defe0a68
thread_sync.c: Clarify and document the behavior of timeout == 0
...
[Feature #18982 ]
Instead of introducing an `exception: false` argument to have `non_block`
return nil rather than raise, we can clearly document that a timeout of 0
immediately returns.
The code is refactored a bit to avoid doing a time calculation in
such case.
2022-10-17 16:56:00 +02:00
Jean Boussier
fe61cad749
Implement SizedQueue#push(timeout: sec)
...
[Feature #18944 ]
If both `non_block=true` and `timeout:` are supplied, ArgumentError
is raised.
2022-08-18 10:07:37 +02:00
Jean Boussier
e3aabe93aa
Implement Queue#pop(timeout: sec)
...
[Feature #18774 ]
As well as `SizedQueue#pop(timeout: sec)`
If both `non_block=true` and `timeout:` are supplied, ArgumentError
is raised.
2022-08-02 11:04:28 +02:00