concurrent-ruby 1.1.10 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -1
- data/Gemfile +0 -1
- data/README.md +21 -20
- data/Rakefile +46 -57
- data/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java +10 -25
- data/lib/concurrent-ruby/concurrent/agent.rb +2 -1
- data/lib/concurrent-ruby/concurrent/array.rb +0 -10
- data/lib/concurrent-ruby/concurrent/atom.rb +1 -1
- data/lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb +5 -4
- data/lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb +5 -4
- data/lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb +3 -0
- data/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb +81 -151
- data/lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb +1 -1
- data/lib/concurrent-ruby/concurrent/atomic/event.rb +1 -1
- data/lib/concurrent-ruby/concurrent/atomic/fiber_local_var.rb +109 -0
- data/lib/concurrent-ruby/concurrent/atomic/java_count_down_latch.rb +1 -0
- data/lib/concurrent-ruby/concurrent/atomic/locals.rb +188 -0
- data/lib/concurrent-ruby/concurrent/atomic/lock_local_var.rb +28 -0
- data/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_boolean.rb +11 -5
- data/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_fixnum.rb +11 -5
- data/lib/concurrent-ruby/concurrent/atomic/mutex_count_down_latch.rb +1 -1
- data/lib/concurrent-ruby/concurrent/atomic/mutex_semaphore.rb +1 -1
- data/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb +2 -1
- data/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb +5 -3
- data/lib/concurrent-ruby/concurrent/atomic/semaphore.rb +6 -9
- data/lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb +96 -89
- data/lib/concurrent-ruby/concurrent/atomic_reference/atomic_direct_update.rb +37 -0
- data/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb +15 -4
- data/lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb +1 -1
- data/lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb +1 -1
- data/lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb +2 -0
- data/lib/concurrent-ruby/concurrent/concern/logging.rb +86 -2
- data/lib/concurrent-ruby/concurrent/concurrent_ruby.jar +0 -0
- data/lib/concurrent-ruby/concurrent/configuration.rb +4 -87
- data/lib/concurrent-ruby/concurrent/delay.rb +2 -2
- data/lib/concurrent-ruby/concurrent/errors.rb +5 -0
- data/lib/concurrent-ruby/concurrent/exchanger.rb +1 -0
- data/lib/concurrent-ruby/concurrent/executor/abstract_executor_service.rb +1 -1
- data/lib/concurrent-ruby/concurrent/executor/java_executor_service.rb +2 -2
- data/lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb +1 -1
- data/lib/concurrent-ruby/concurrent/executor/serialized_execution.rb +1 -1
- data/lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb +4 -1
- data/lib/concurrent-ruby/concurrent/hash.rb +0 -9
- data/lib/concurrent-ruby/concurrent/immutable_struct.rb +1 -1
- data/lib/concurrent-ruby/concurrent/ivar.rb +2 -1
- data/lib/concurrent-ruby/concurrent/map.rb +9 -8
- data/lib/concurrent-ruby/concurrent/maybe.rb +1 -1
- data/lib/concurrent-ruby/concurrent/mutable_struct.rb +1 -1
- data/lib/concurrent-ruby/concurrent/mvar.rb +1 -1
- data/lib/concurrent-ruby/concurrent/promise.rb +1 -1
- data/lib/concurrent-ruby/concurrent/promises.rb +7 -6
- data/lib/concurrent-ruby/concurrent/re_include.rb +2 -0
- data/lib/concurrent-ruby/concurrent/scheduled_task.rb +1 -1
- data/lib/concurrent-ruby/concurrent/set.rb +0 -10
- data/lib/concurrent-ruby/concurrent/settable_struct.rb +2 -2
- data/lib/concurrent-ruby/concurrent/synchronization/abstract_lockable_object.rb +5 -1
- data/lib/concurrent-ruby/concurrent/synchronization/abstract_object.rb +1 -3
- data/lib/concurrent-ruby/concurrent/synchronization/condition.rb +2 -0
- data/lib/concurrent-ruby/concurrent/synchronization/full_memory_barrier.rb +29 -0
- data/lib/concurrent-ruby/concurrent/synchronization/jruby_lockable_object.rb +3 -1
- data/lib/concurrent-ruby/concurrent/synchronization/lock.rb +2 -0
- data/lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb +5 -2
- data/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb +6 -5
- data/lib/concurrent-ruby/concurrent/synchronization/object.rb +12 -44
- data/lib/concurrent-ruby/concurrent/synchronization/safe_initialization.rb +36 -0
- data/lib/concurrent-ruby/concurrent/synchronization/volatile.rb +77 -12
- data/lib/concurrent-ruby/concurrent/synchronization.rb +1 -18
- data/lib/concurrent-ruby/concurrent/thread_safe/synchronized_delegator.rb +36 -39
- data/lib/concurrent-ruby/concurrent/thread_safe/util/cheap_lockable.rb +2 -39
- data/lib/concurrent-ruby/concurrent/thread_safe/util/data_structures.rb +1 -37
- data/lib/concurrent-ruby/concurrent/tuple.rb +1 -5
- data/lib/concurrent-ruby/concurrent/tvar.rb +2 -1
- data/lib/concurrent-ruby/concurrent/utility/engine.rb +5 -16
- data/lib/concurrent-ruby/concurrent/utility/monotonic_time.rb +3 -74
- data/lib/concurrent-ruby/concurrent/utility/native_extension_loader.rb +8 -10
- data/lib/concurrent-ruby/concurrent/utility/native_integer.rb +1 -0
- data/lib/concurrent-ruby/concurrent/utility/processor_counter.rb +34 -54
- data/lib/concurrent-ruby/concurrent/version.rb +1 -1
- metadata +13 -15
- data/lib/concurrent-ruby/concurrent/atomic/abstract_thread_local_var.rb +0 -66
- data/lib/concurrent-ruby/concurrent/atomic/java_thread_local_var.rb +0 -37
- data/lib/concurrent-ruby/concurrent/atomic/ruby_thread_local_var.rb +0 -181
- data/lib/concurrent-ruby/concurrent/synchronization/jruby_object.rb +0 -45
- data/lib/concurrent-ruby/concurrent/synchronization/mri_object.rb +0 -44
- data/lib/concurrent-ruby/concurrent/synchronization/rbx_lockable_object.rb +0 -71
- data/lib/concurrent-ruby/concurrent/synchronization/rbx_object.rb +0 -49
- data/lib/concurrent-ruby/concurrent/synchronization/truffleruby_object.rb +0 -47
@@ -2,49 +2,46 @@ require 'delegate'
|
|
2
2
|
require 'monitor'
|
3
3
|
|
4
4
|
module Concurrent
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
Thread.abort_on_exception = true
|
27
|
-
end
|
5
|
+
# This class provides a trivial way to synchronize all calls to a given object
|
6
|
+
# by wrapping it with a `Delegator` that performs `Monitor#enter/exit` calls
|
7
|
+
# around the delegated `#send`. Example:
|
8
|
+
#
|
9
|
+
# array = [] # not thread-safe on many impls
|
10
|
+
# array = SynchronizedDelegator.new([]) # thread-safe
|
11
|
+
#
|
12
|
+
# A simple `Monitor` provides a very coarse-grained way to synchronize a given
|
13
|
+
# object, in that it will cause synchronization for methods that have no need
|
14
|
+
# for it, but this is a trivial way to get thread-safety where none may exist
|
15
|
+
# currently on some implementations.
|
16
|
+
#
|
17
|
+
# This class is currently being considered for inclusion into stdlib, via
|
18
|
+
# https://bugs.ruby-lang.org/issues/8556
|
19
|
+
#
|
20
|
+
# @!visibility private
|
21
|
+
class SynchronizedDelegator < SimpleDelegator
|
22
|
+
def setup
|
23
|
+
@old_abort = Thread.abort_on_exception
|
24
|
+
Thread.abort_on_exception = true
|
25
|
+
end
|
28
26
|
|
29
|
-
|
30
|
-
|
31
|
-
|
27
|
+
def teardown
|
28
|
+
Thread.abort_on_exception = @old_abort
|
29
|
+
end
|
32
30
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
31
|
+
def initialize(obj)
|
32
|
+
__setobj__(obj)
|
33
|
+
@monitor = Monitor.new
|
34
|
+
end
|
37
35
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
end
|
36
|
+
def method_missing(method, *args, &block)
|
37
|
+
monitor = @monitor
|
38
|
+
begin
|
39
|
+
monitor.enter
|
40
|
+
super
|
41
|
+
ensure
|
42
|
+
monitor.exit
|
46
43
|
end
|
47
|
-
|
48
44
|
end
|
45
|
+
|
49
46
|
end
|
50
47
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'concurrent/thread_safe/util'
|
2
2
|
require 'concurrent/thread_safe/util/volatile'
|
3
|
+
require 'concurrent/utility/engine'
|
3
4
|
|
4
5
|
module Concurrent
|
5
6
|
|
@@ -32,45 +33,7 @@ module Concurrent
|
|
32
33
|
# @!visibility private
|
33
34
|
module CheapLockable
|
34
35
|
private
|
35
|
-
|
36
|
-
if engine == 'rbx'
|
37
|
-
# Making use of the Rubinius' ability to lock via object headers to avoid the overhead of the extra Mutex objects.
|
38
|
-
def cheap_synchronize
|
39
|
-
Rubinius.lock(self)
|
40
|
-
begin
|
41
|
-
yield
|
42
|
-
ensure
|
43
|
-
Rubinius.unlock(self)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def cheap_wait
|
48
|
-
wchan = Rubinius::Channel.new
|
49
|
-
|
50
|
-
begin
|
51
|
-
waiters = @waiters ||= []
|
52
|
-
waiters.push wchan
|
53
|
-
Rubinius.unlock(self)
|
54
|
-
signaled = wchan.receive_timeout nil
|
55
|
-
ensure
|
56
|
-
Rubinius.lock(self)
|
57
|
-
|
58
|
-
unless signaled or waiters.delete(wchan)
|
59
|
-
# we timed out, but got signaled afterwards (e.g. while waiting to
|
60
|
-
# acquire @lock), so pass that signal on to the next waiter
|
61
|
-
waiters.shift << true unless waiters.empty?
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
self
|
66
|
-
end
|
67
|
-
|
68
|
-
def cheap_broadcast
|
69
|
-
waiters = @waiters ||= []
|
70
|
-
waiters.shift << true until waiters.empty?
|
71
|
-
self
|
72
|
-
end
|
73
|
-
elsif engine == 'jruby'
|
36
|
+
if Concurrent.on_jruby?
|
74
37
|
# Use Java's native synchronized (this) { wait(); notifyAll(); } to avoid the overhead of the extra Mutex objects
|
75
38
|
require 'jruby'
|
76
39
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'concurrent/thread_safe/util'
|
2
|
+
require 'concurrent/utility/engine'
|
2
3
|
|
3
4
|
# Shim for TruffleRuby.synchronized
|
4
5
|
if Concurrent.on_truffleruby? && !TruffleRuby.respond_to?(:synchronized)
|
@@ -37,43 +38,6 @@ module Concurrent
|
|
37
38
|
end
|
38
39
|
end
|
39
40
|
|
40
|
-
def self.make_synchronized_on_rbx(klass)
|
41
|
-
klass.class_eval do
|
42
|
-
private
|
43
|
-
|
44
|
-
def _mon_initialize
|
45
|
-
@_monitor ||= Monitor.new # avoid double initialisation
|
46
|
-
end
|
47
|
-
|
48
|
-
def self.new(*args)
|
49
|
-
obj = super(*args)
|
50
|
-
obj.send(:_mon_initialize)
|
51
|
-
obj
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
klass.superclass.instance_methods(false).each do |method|
|
56
|
-
case method
|
57
|
-
when :new_range, :new_reserved
|
58
|
-
klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
59
|
-
def #{method}(*args)
|
60
|
-
obj = super
|
61
|
-
obj.send(:_mon_initialize)
|
62
|
-
obj
|
63
|
-
end
|
64
|
-
RUBY
|
65
|
-
else
|
66
|
-
klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
67
|
-
def #{method}(*args)
|
68
|
-
monitor = @_monitor
|
69
|
-
monitor or raise("BUG: Internal monitor was not properly initialized. Please report this to the concurrent-ruby developers.")
|
70
|
-
monitor.synchronize { super }
|
71
|
-
end
|
72
|
-
RUBY
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
41
|
def self.make_synchronized_on_truffleruby(klass)
|
78
42
|
klass.superclass.instance_methods(false).each do |method|
|
79
43
|
klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
@@ -23,16 +23,12 @@ module Concurrent
|
|
23
23
|
# The (fixed) size of the tuple.
|
24
24
|
attr_reader :size
|
25
25
|
|
26
|
-
# @!visibility private
|
27
|
-
Tuple = defined?(Rubinius::Tuple) ? Rubinius::Tuple : ::Array
|
28
|
-
private_constant :Tuple
|
29
|
-
|
30
26
|
# Create a new tuple of the given size.
|
31
27
|
#
|
32
28
|
# @param [Integer] size the number of elements in the tuple
|
33
29
|
def initialize(size)
|
34
30
|
@size = size
|
35
|
-
@tuple = tuple =
|
31
|
+
@tuple = tuple = ::Array.new(size)
|
36
32
|
i = 0
|
37
33
|
while i < size
|
38
34
|
tuple[i] = Concurrent::AtomicReference.new
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'set'
|
2
|
-
require 'concurrent/synchronization'
|
2
|
+
require 'concurrent/synchronization/object'
|
3
3
|
|
4
4
|
module Concurrent
|
5
5
|
|
@@ -149,6 +149,7 @@ module Concurrent
|
|
149
149
|
|
150
150
|
private
|
151
151
|
|
152
|
+
# @!visibility private
|
152
153
|
class Transaction
|
153
154
|
|
154
155
|
ABORTED = ::Object.new
|
@@ -1,26 +1,19 @@
|
|
1
1
|
module Concurrent
|
2
|
+
# @!visibility private
|
2
3
|
module Utility
|
3
4
|
|
4
5
|
# @!visibility private
|
5
6
|
module EngineDetector
|
6
|
-
def on_jruby?
|
7
|
-
ruby_engine == 'jruby'
|
8
|
-
end
|
9
|
-
|
10
|
-
def on_jruby_9000?
|
11
|
-
on_jruby? && ruby_version(JRUBY_VERSION, :>=, 9, 0, 0)
|
12
|
-
end
|
13
|
-
|
14
7
|
def on_cruby?
|
15
|
-
|
8
|
+
RUBY_ENGINE == 'ruby'
|
16
9
|
end
|
17
10
|
|
18
|
-
def
|
19
|
-
|
11
|
+
def on_jruby?
|
12
|
+
RUBY_ENGINE == 'jruby'
|
20
13
|
end
|
21
14
|
|
22
15
|
def on_truffleruby?
|
23
|
-
|
16
|
+
RUBY_ENGINE == 'truffleruby'
|
24
17
|
end
|
25
18
|
|
26
19
|
def on_windows?
|
@@ -35,10 +28,6 @@ module Concurrent
|
|
35
28
|
!(RbConfig::CONFIG['host_os'] =~ /linux/).nil?
|
36
29
|
end
|
37
30
|
|
38
|
-
def ruby_engine
|
39
|
-
defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
|
40
|
-
end
|
41
|
-
|
42
31
|
def ruby_version(version = RUBY_VERSION, comparison, major, minor, patch)
|
43
32
|
result = (version.split('.').map(&:to_i) <=> [major, minor, patch])
|
44
33
|
comparisons = { :== => [0],
|
@@ -1,10 +1,8 @@
|
|
1
|
-
require 'concurrent/synchronization'
|
2
|
-
|
3
1
|
module Concurrent
|
4
2
|
|
5
3
|
# @!macro monotonic_get_time
|
6
4
|
#
|
7
|
-
# Returns the current time
|
5
|
+
# Returns the current time as tracked by the application monotonic clock.
|
8
6
|
#
|
9
7
|
# @param [Symbol] unit the time unit to be returned, can be either
|
10
8
|
# :float_second, :float_millisecond, :float_microsecond, :second,
|
@@ -14,77 +12,8 @@ module Concurrent
|
|
14
12
|
# starting point
|
15
13
|
#
|
16
14
|
# @!macro monotonic_clock_warning
|
17
|
-
|
18
|
-
|
19
|
-
def monotonic_time(unit = :float_second)
|
20
|
-
Process.clock_gettime(Process::CLOCK_MONOTONIC, unit)
|
21
|
-
end
|
22
|
-
|
23
|
-
elsif Concurrent.on_jruby?
|
24
|
-
|
25
|
-
# @!visibility private
|
26
|
-
TIME_UNITS = Hash.new { |_hash, key| raise ArgumentError, "unexpected unit: #{key}" }.compare_by_identity
|
27
|
-
TIME_UNITS.merge!(
|
28
|
-
second: 1_000_000_000,
|
29
|
-
millisecond: 1_000_000,
|
30
|
-
microsecond: 1_000,
|
31
|
-
nanosecond: 1,
|
32
|
-
float_second: 1_000_000_000.0,
|
33
|
-
float_millisecond: 1_000_000.0,
|
34
|
-
float_microsecond: 1_000.0,
|
35
|
-
)
|
36
|
-
TIME_UNITS.freeze
|
37
|
-
private_constant :TIME_UNITS
|
38
|
-
|
39
|
-
def monotonic_time(unit = :float_second)
|
40
|
-
java.lang.System.nanoTime() / TIME_UNITS[unit]
|
41
|
-
end
|
42
|
-
|
43
|
-
else
|
44
|
-
|
45
|
-
class_definition = Class.new(Synchronization::LockableObject) do
|
46
|
-
def initialize
|
47
|
-
@last_time = Time.now.to_f
|
48
|
-
@time_units = Hash.new { |_hash, key| raise ArgumentError, "unexpected unit: #{key}" }.compare_by_identity
|
49
|
-
@time_units.merge!(
|
50
|
-
second: [nil, true],
|
51
|
-
millisecond: [1_000, true],
|
52
|
-
microsecond: [1_000_000, true],
|
53
|
-
nanosecond: [1_000_000_000, true],
|
54
|
-
float_second: [nil, false],
|
55
|
-
float_millisecond: [1_000.0, false],
|
56
|
-
float_microsecond: [1_000_000.0, false],
|
57
|
-
)
|
58
|
-
super()
|
59
|
-
end
|
60
|
-
|
61
|
-
# @!visibility private
|
62
|
-
def get_time(unit)
|
63
|
-
synchronize do
|
64
|
-
now = Time.now.to_f
|
65
|
-
if @last_time < now
|
66
|
-
@last_time = now
|
67
|
-
else # clock has moved back in time
|
68
|
-
@last_time += 0.000_001
|
69
|
-
end
|
70
|
-
scale, to_int = @time_units[unit]
|
71
|
-
now *= scale if scale
|
72
|
-
now = now.to_i if to_int
|
73
|
-
now
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
# Clock that cannot be set and represents monotonic time since
|
79
|
-
# some unspecified starting point.
|
80
|
-
#
|
81
|
-
# @!visibility private
|
82
|
-
GLOBAL_MONOTONIC_CLOCK = class_definition.new
|
83
|
-
private_constant :GLOBAL_MONOTONIC_CLOCK
|
84
|
-
|
85
|
-
def monotonic_time(unit = :float_second)
|
86
|
-
GLOBAL_MONOTONIC_CLOCK.get_time(unit)
|
87
|
-
end
|
15
|
+
def monotonic_time(unit = :float_second)
|
16
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC, unit)
|
88
17
|
end
|
89
18
|
module_function :monotonic_time
|
90
19
|
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'concurrent/utility/engine'
|
2
|
+
# Synchronization::AbstractObject must be defined before loading the extension
|
3
|
+
require 'concurrent/synchronization/abstract_object'
|
2
4
|
|
3
5
|
module Concurrent
|
4
|
-
|
6
|
+
# @!visibility private
|
5
7
|
module Utility
|
6
|
-
|
7
8
|
# @!visibility private
|
8
9
|
module NativeExtensionLoader
|
9
10
|
|
@@ -15,15 +16,7 @@ module Concurrent
|
|
15
16
|
defined?(@c_extensions_loaded) && @c_extensions_loaded
|
16
17
|
end
|
17
18
|
|
18
|
-
def java_extensions_loaded?
|
19
|
-
defined?(@java_extensions_loaded) && @java_extensions_loaded
|
20
|
-
end
|
21
|
-
|
22
19
|
def load_native_extensions
|
23
|
-
unless defined? Synchronization::AbstractObject
|
24
|
-
raise 'native_extension_loader loaded before Synchronization::AbstractObject'
|
25
|
-
end
|
26
|
-
|
27
20
|
if Concurrent.on_cruby? && !c_extensions_loaded?
|
28
21
|
['concurrent/concurrent_ruby_ext',
|
29
22
|
"concurrent/#{RUBY_VERSION[0..2]}/concurrent_ruby_ext"
|
@@ -54,6 +47,10 @@ module Concurrent
|
|
54
47
|
@c_extensions_loaded = true
|
55
48
|
end
|
56
49
|
|
50
|
+
def java_extensions_loaded?
|
51
|
+
defined?(@java_extensions_loaded) && @java_extensions_loaded
|
52
|
+
end
|
53
|
+
|
57
54
|
def set_java_extensions_loaded
|
58
55
|
@java_extensions_loaded = true
|
59
56
|
end
|
@@ -77,3 +74,4 @@ module Concurrent
|
|
77
74
|
extend Utility::NativeExtensionLoader
|
78
75
|
end
|
79
76
|
|
77
|
+
Concurrent.load_native_extensions
|
@@ -3,6 +3,7 @@ require 'rbconfig'
|
|
3
3
|
require 'concurrent/delay'
|
4
4
|
|
5
5
|
module Concurrent
|
6
|
+
# @!visibility private
|
6
7
|
module Utility
|
7
8
|
|
8
9
|
# @!visibility private
|
@@ -12,64 +13,10 @@ module Concurrent
|
|
12
13
|
@physical_processor_count = Delay.new { compute_physical_processor_count }
|
13
14
|
end
|
14
15
|
|
15
|
-
# Number of processors seen by the OS and used for process scheduling. For
|
16
|
-
# performance reasons the calculated value will be memoized on the first
|
17
|
-
# call.
|
18
|
-
#
|
19
|
-
# When running under JRuby the Java runtime call
|
20
|
-
# `java.lang.Runtime.getRuntime.availableProcessors` will be used. According
|
21
|
-
# to the Java documentation this "value may change during a particular
|
22
|
-
# invocation of the virtual machine... [applications] should therefore
|
23
|
-
# occasionally poll this property." Subsequently the result will NOT be
|
24
|
-
# memoized under JRuby.
|
25
|
-
#
|
26
|
-
# Ruby's Etc.nprocessors will be used if available (MRI 2.2+).
|
27
|
-
#
|
28
|
-
# On Windows the Win32 API will be queried for the
|
29
|
-
# `NumberOfLogicalProcessors from Win32_Processor`. This will return the
|
30
|
-
# total number "logical processors for the current instance of the
|
31
|
-
# processor", which taked into account hyperthreading.
|
32
|
-
#
|
33
|
-
# * AIX: /usr/sbin/pmcycles (AIX 5+), /usr/sbin/lsdev
|
34
|
-
# * Alpha: /usr/bin/nproc (/proc/cpuinfo exists but cannot be used)
|
35
|
-
# * BSD: /sbin/sysctl
|
36
|
-
# * Cygwin: /proc/cpuinfo
|
37
|
-
# * Darwin: /usr/bin/hwprefs, /usr/sbin/sysctl
|
38
|
-
# * HP-UX: /usr/sbin/ioscan
|
39
|
-
# * IRIX: /usr/sbin/sysconf
|
40
|
-
# * Linux: /proc/cpuinfo
|
41
|
-
# * Minix 3+: /proc/cpuinfo
|
42
|
-
# * Solaris: /usr/sbin/psrinfo
|
43
|
-
# * Tru64 UNIX: /usr/sbin/psrinfo
|
44
|
-
# * UnixWare: /usr/sbin/psrinfo
|
45
|
-
#
|
46
|
-
# @return [Integer] number of processors seen by the OS or Java runtime
|
47
|
-
#
|
48
|
-
# @see https://github.com/grosser/parallel/blob/4fc8b89d08c7091fe0419ca8fba1ec3ce5a8d185/lib/parallel.rb
|
49
|
-
#
|
50
|
-
# @see http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html#availableProcessors()
|
51
|
-
# @see http://msdn.microsoft.com/en-us/library/aa394373(v=vs.85).aspx
|
52
16
|
def processor_count
|
53
17
|
@processor_count.value
|
54
18
|
end
|
55
19
|
|
56
|
-
# Number of physical processor cores on the current system. For performance
|
57
|
-
# reasons the calculated value will be memoized on the first call.
|
58
|
-
#
|
59
|
-
# On Windows the Win32 API will be queried for the `NumberOfCores from
|
60
|
-
# Win32_Processor`. This will return the total number "of cores for the
|
61
|
-
# current instance of the processor." On Unix-like operating systems either
|
62
|
-
# the `hwprefs` or `sysctl` utility will be called in a subshell and the
|
63
|
-
# returned value will be used. In the rare case where none of these methods
|
64
|
-
# work or an exception is raised the function will simply return 1.
|
65
|
-
#
|
66
|
-
# @return [Integer] number physical processor cores on the current system
|
67
|
-
#
|
68
|
-
# @see https://github.com/grosser/parallel/blob/4fc8b89d08c7091fe0419ca8fba1ec3ce5a8d185/lib/parallel.rb
|
69
|
-
#
|
70
|
-
# @see http://msdn.microsoft.com/en-us/library/aa394373(v=vs.85).aspx
|
71
|
-
# @see http://www.unix.com/man-page/osx/1/HWPREFS/
|
72
|
-
# @see http://linux.die.net/man/8/sysctl
|
73
20
|
def physical_processor_count
|
74
21
|
@physical_processor_count.value
|
75
22
|
end
|
@@ -120,10 +67,43 @@ module Concurrent
|
|
120
67
|
@processor_counter = Utility::ProcessorCounter.new
|
121
68
|
singleton_class.send :attr_reader, :processor_counter
|
122
69
|
|
70
|
+
# Number of processors seen by the OS and used for process scheduling. For
|
71
|
+
# performance reasons the calculated value will be memoized on the first
|
72
|
+
# call.
|
73
|
+
#
|
74
|
+
# When running under JRuby the Java runtime call
|
75
|
+
# `java.lang.Runtime.getRuntime.availableProcessors` will be used. According
|
76
|
+
# to the Java documentation this "value may change during a particular
|
77
|
+
# invocation of the virtual machine... [applications] should therefore
|
78
|
+
# occasionally poll this property." Subsequently the result will NOT be
|
79
|
+
# memoized under JRuby.
|
80
|
+
#
|
81
|
+
# Otherwise Ruby's Etc.nprocessors will be used.
|
82
|
+
#
|
83
|
+
# @return [Integer] number of processors seen by the OS or Java runtime
|
84
|
+
#
|
85
|
+
# @see http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html#availableProcessors()
|
123
86
|
def self.processor_count
|
124
87
|
processor_counter.processor_count
|
125
88
|
end
|
126
89
|
|
90
|
+
# Number of physical processor cores on the current system. For performance
|
91
|
+
# reasons the calculated value will be memoized on the first call.
|
92
|
+
#
|
93
|
+
# On Windows the Win32 API will be queried for the `NumberOfCores from
|
94
|
+
# Win32_Processor`. This will return the total number "of cores for the
|
95
|
+
# current instance of the processor." On Unix-like operating systems either
|
96
|
+
# the `hwprefs` or `sysctl` utility will be called in a subshell and the
|
97
|
+
# returned value will be used. In the rare case where none of these methods
|
98
|
+
# work or an exception is raised the function will simply return 1.
|
99
|
+
#
|
100
|
+
# @return [Integer] number physical processor cores on the current system
|
101
|
+
#
|
102
|
+
# @see https://github.com/grosser/parallel/blob/4fc8b89d08c7091fe0419ca8fba1ec3ce5a8d185/lib/parallel.rb
|
103
|
+
#
|
104
|
+
# @see http://msdn.microsoft.com/en-us/library/aa394373(v=vs.85).aspx
|
105
|
+
# @see http://www.unix.com/man-page/osx/1/HWPREFS/
|
106
|
+
# @see http://linux.die.net/man/8/sysctl
|
127
107
|
def self.physical_processor_count
|
128
108
|
processor_counter.physical_processor_count
|
129
109
|
end
|
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: concurrent-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jerry D'Antonio
|
8
8
|
- Petr Chalupa
|
9
9
|
- The Ruby Concurrency Team
|
10
|
-
autorequire:
|
10
|
+
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2023-01-23 00:00:00.000000000 Z
|
14
14
|
dependencies: []
|
15
15
|
description: |
|
16
16
|
Modern concurrency tools including agents, futures, promises, thread pools, actors, supervisors, and more.
|
@@ -49,7 +49,6 @@ files:
|
|
49
49
|
- lib/concurrent-ruby/concurrent/array.rb
|
50
50
|
- lib/concurrent-ruby/concurrent/async.rb
|
51
51
|
- lib/concurrent-ruby/concurrent/atom.rb
|
52
|
-
- lib/concurrent-ruby/concurrent/atomic/abstract_thread_local_var.rb
|
53
52
|
- lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb
|
54
53
|
- lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb
|
55
54
|
- lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb
|
@@ -57,17 +56,19 @@ files:
|
|
57
56
|
- lib/concurrent-ruby/concurrent/atomic/count_down_latch.rb
|
58
57
|
- lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb
|
59
58
|
- lib/concurrent-ruby/concurrent/atomic/event.rb
|
59
|
+
- lib/concurrent-ruby/concurrent/atomic/fiber_local_var.rb
|
60
60
|
- lib/concurrent-ruby/concurrent/atomic/java_count_down_latch.rb
|
61
|
-
- lib/concurrent-ruby/concurrent/atomic/
|
61
|
+
- lib/concurrent-ruby/concurrent/atomic/locals.rb
|
62
|
+
- lib/concurrent-ruby/concurrent/atomic/lock_local_var.rb
|
62
63
|
- lib/concurrent-ruby/concurrent/atomic/mutex_atomic_boolean.rb
|
63
64
|
- lib/concurrent-ruby/concurrent/atomic/mutex_atomic_fixnum.rb
|
64
65
|
- lib/concurrent-ruby/concurrent/atomic/mutex_count_down_latch.rb
|
65
66
|
- lib/concurrent-ruby/concurrent/atomic/mutex_semaphore.rb
|
66
67
|
- lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb
|
67
68
|
- lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb
|
68
|
-
- lib/concurrent-ruby/concurrent/atomic/ruby_thread_local_var.rb
|
69
69
|
- lib/concurrent-ruby/concurrent/atomic/semaphore.rb
|
70
70
|
- lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb
|
71
|
+
- lib/concurrent-ruby/concurrent/atomic_reference/atomic_direct_update.rb
|
71
72
|
- lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb
|
72
73
|
- lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb
|
73
74
|
- lib/concurrent-ruby/concurrent/atomics.rb
|
@@ -135,16 +136,13 @@ files:
|
|
135
136
|
- lib/concurrent-ruby/concurrent/synchronization/abstract_object.rb
|
136
137
|
- lib/concurrent-ruby/concurrent/synchronization/abstract_struct.rb
|
137
138
|
- lib/concurrent-ruby/concurrent/synchronization/condition.rb
|
139
|
+
- lib/concurrent-ruby/concurrent/synchronization/full_memory_barrier.rb
|
138
140
|
- lib/concurrent-ruby/concurrent/synchronization/jruby_lockable_object.rb
|
139
|
-
- lib/concurrent-ruby/concurrent/synchronization/jruby_object.rb
|
140
141
|
- lib/concurrent-ruby/concurrent/synchronization/lock.rb
|
141
142
|
- lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb
|
142
|
-
- lib/concurrent-ruby/concurrent/synchronization/mri_object.rb
|
143
143
|
- lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb
|
144
144
|
- lib/concurrent-ruby/concurrent/synchronization/object.rb
|
145
|
-
- lib/concurrent-ruby/concurrent/synchronization/
|
146
|
-
- lib/concurrent-ruby/concurrent/synchronization/rbx_object.rb
|
147
|
-
- lib/concurrent-ruby/concurrent/synchronization/truffleruby_object.rb
|
145
|
+
- lib/concurrent-ruby/concurrent/synchronization/safe_initialization.rb
|
148
146
|
- lib/concurrent-ruby/concurrent/synchronization/volatile.rb
|
149
147
|
- lib/concurrent-ruby/concurrent/thread_safe/synchronized_delegator.rb
|
150
148
|
- lib/concurrent-ruby/concurrent/thread_safe/util.rb
|
@@ -170,7 +168,7 @@ licenses:
|
|
170
168
|
metadata:
|
171
169
|
source_code_uri: https://github.com/ruby-concurrency/concurrent-ruby
|
172
170
|
changelog_uri: https://github.com/ruby-concurrency/concurrent-ruby/blob/master/CHANGELOG.md
|
173
|
-
post_install_message:
|
171
|
+
post_install_message:
|
174
172
|
rdoc_options: []
|
175
173
|
require_paths:
|
176
174
|
- lib/concurrent-ruby
|
@@ -178,15 +176,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
178
176
|
requirements:
|
179
177
|
- - ">="
|
180
178
|
- !ruby/object:Gem::Version
|
181
|
-
version: '2.
|
179
|
+
version: '2.3'
|
182
180
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
183
181
|
requirements:
|
184
182
|
- - ">="
|
185
183
|
- !ruby/object:Gem::Version
|
186
184
|
version: '0'
|
187
185
|
requirements: []
|
188
|
-
rubygems_version: 3.3.
|
189
|
-
signing_key:
|
186
|
+
rubygems_version: 3.3.26
|
187
|
+
signing_key:
|
190
188
|
specification_version: 4
|
191
189
|
summary: Modern concurrency tools for Ruby. Inspired by Erlang, Clojure, Scala, Haskell,
|
192
190
|
F#, C#, Java, and classic concurrency patterns.
|