o-concurrent-ruby 1.1.11

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.
Files changed (142) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +542 -0
  3. data/Gemfile +37 -0
  4. data/LICENSE.txt +21 -0
  5. data/README.md +404 -0
  6. data/Rakefile +307 -0
  7. data/ext/concurrent-ruby/ConcurrentRubyService.java +17 -0
  8. data/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java +175 -0
  9. data/ext/concurrent-ruby/com/concurrent_ruby/ext/JRubyMapBackendLibrary.java +248 -0
  10. data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicBooleanLibrary.java +93 -0
  11. data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicFixnumLibrary.java +113 -0
  12. data/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaSemaphoreLibrary.java +189 -0
  13. data/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java +307 -0
  14. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMap.java +31 -0
  15. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMapV8.java +3863 -0
  16. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/LongAdder.java +203 -0
  17. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/Striped64.java +342 -0
  18. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/ConcurrentHashMapV8.java +3800 -0
  19. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/LongAdder.java +204 -0
  20. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/Striped64.java +291 -0
  21. data/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166y/ThreadLocalRandom.java +199 -0
  22. data/lib/concurrent-ruby/concurrent/agent.rb +587 -0
  23. data/lib/concurrent-ruby/concurrent/array.rb +66 -0
  24. data/lib/concurrent-ruby/concurrent/async.rb +449 -0
  25. data/lib/concurrent-ruby/concurrent/atom.rb +222 -0
  26. data/lib/concurrent-ruby/concurrent/atomic/abstract_thread_local_var.rb +66 -0
  27. data/lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb +126 -0
  28. data/lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb +143 -0
  29. data/lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb +164 -0
  30. data/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb +205 -0
  31. data/lib/concurrent-ruby/concurrent/atomic/count_down_latch.rb +100 -0
  32. data/lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb +128 -0
  33. data/lib/concurrent-ruby/concurrent/atomic/event.rb +109 -0
  34. data/lib/concurrent-ruby/concurrent/atomic/java_count_down_latch.rb +42 -0
  35. data/lib/concurrent-ruby/concurrent/atomic/java_thread_local_var.rb +37 -0
  36. data/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_boolean.rb +62 -0
  37. data/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_fixnum.rb +75 -0
  38. data/lib/concurrent-ruby/concurrent/atomic/mutex_count_down_latch.rb +44 -0
  39. data/lib/concurrent-ruby/concurrent/atomic/mutex_semaphore.rb +131 -0
  40. data/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb +254 -0
  41. data/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb +377 -0
  42. data/lib/concurrent-ruby/concurrent/atomic/ruby_thread_local_var.rb +181 -0
  43. data/lib/concurrent-ruby/concurrent/atomic/semaphore.rb +166 -0
  44. data/lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb +104 -0
  45. data/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb +56 -0
  46. data/lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb +28 -0
  47. data/lib/concurrent-ruby/concurrent/atomics.rb +10 -0
  48. data/lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb +107 -0
  49. data/lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb +111 -0
  50. data/lib/concurrent-ruby/concurrent/collection/java_non_concurrent_priority_queue.rb +84 -0
  51. data/lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb +158 -0
  52. data/lib/concurrent-ruby/concurrent/collection/map/atomic_reference_map_backend.rb +927 -0
  53. data/lib/concurrent-ruby/concurrent/collection/map/mri_map_backend.rb +66 -0
  54. data/lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb +140 -0
  55. data/lib/concurrent-ruby/concurrent/collection/map/synchronized_map_backend.rb +82 -0
  56. data/lib/concurrent-ruby/concurrent/collection/map/truffleruby_map_backend.rb +14 -0
  57. data/lib/concurrent-ruby/concurrent/collection/non_concurrent_priority_queue.rb +143 -0
  58. data/lib/concurrent-ruby/concurrent/collection/ruby_non_concurrent_priority_queue.rb +160 -0
  59. data/lib/concurrent-ruby/concurrent/concern/deprecation.rb +34 -0
  60. data/lib/concurrent-ruby/concurrent/concern/dereferenceable.rb +73 -0
  61. data/lib/concurrent-ruby/concurrent/concern/logging.rb +32 -0
  62. data/lib/concurrent-ruby/concurrent/concern/obligation.rb +220 -0
  63. data/lib/concurrent-ruby/concurrent/concern/observable.rb +110 -0
  64. data/lib/concurrent-ruby/concurrent/configuration.rb +188 -0
  65. data/lib/concurrent-ruby/concurrent/constants.rb +8 -0
  66. data/lib/concurrent-ruby/concurrent/dataflow.rb +81 -0
  67. data/lib/concurrent-ruby/concurrent/delay.rb +199 -0
  68. data/lib/concurrent-ruby/concurrent/errors.rb +69 -0
  69. data/lib/concurrent-ruby/concurrent/exchanger.rb +352 -0
  70. data/lib/concurrent-ruby/concurrent/executor/abstract_executor_service.rb +131 -0
  71. data/lib/concurrent-ruby/concurrent/executor/cached_thread_pool.rb +62 -0
  72. data/lib/concurrent-ruby/concurrent/executor/executor_service.rb +185 -0
  73. data/lib/concurrent-ruby/concurrent/executor/fixed_thread_pool.rb +220 -0
  74. data/lib/concurrent-ruby/concurrent/executor/immediate_executor.rb +66 -0
  75. data/lib/concurrent-ruby/concurrent/executor/indirect_immediate_executor.rb +44 -0
  76. data/lib/concurrent-ruby/concurrent/executor/java_executor_service.rb +103 -0
  77. data/lib/concurrent-ruby/concurrent/executor/java_single_thread_executor.rb +30 -0
  78. data/lib/concurrent-ruby/concurrent/executor/java_thread_pool_executor.rb +140 -0
  79. data/lib/concurrent-ruby/concurrent/executor/ruby_executor_service.rb +82 -0
  80. data/lib/concurrent-ruby/concurrent/executor/ruby_single_thread_executor.rb +21 -0
  81. data/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb +368 -0
  82. data/lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb +35 -0
  83. data/lib/concurrent-ruby/concurrent/executor/serial_executor_service.rb +34 -0
  84. data/lib/concurrent-ruby/concurrent/executor/serialized_execution.rb +107 -0
  85. data/lib/concurrent-ruby/concurrent/executor/serialized_execution_delegator.rb +28 -0
  86. data/lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb +100 -0
  87. data/lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb +57 -0
  88. data/lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb +88 -0
  89. data/lib/concurrent-ruby/concurrent/executor/timer_set.rb +172 -0
  90. data/lib/concurrent-ruby/concurrent/executors.rb +20 -0
  91. data/lib/concurrent-ruby/concurrent/future.rb +141 -0
  92. data/lib/concurrent-ruby/concurrent/hash.rb +59 -0
  93. data/lib/concurrent-ruby/concurrent/immutable_struct.rb +101 -0
  94. data/lib/concurrent-ruby/concurrent/ivar.rb +207 -0
  95. data/lib/concurrent-ruby/concurrent/map.rb +346 -0
  96. data/lib/concurrent-ruby/concurrent/maybe.rb +229 -0
  97. data/lib/concurrent-ruby/concurrent/mutable_struct.rb +239 -0
  98. data/lib/concurrent-ruby/concurrent/mvar.rb +242 -0
  99. data/lib/concurrent-ruby/concurrent/options.rb +42 -0
  100. data/lib/concurrent-ruby/concurrent/promise.rb +580 -0
  101. data/lib/concurrent-ruby/concurrent/promises.rb +2167 -0
  102. data/lib/concurrent-ruby/concurrent/re_include.rb +58 -0
  103. data/lib/concurrent-ruby/concurrent/scheduled_task.rb +331 -0
  104. data/lib/concurrent-ruby/concurrent/set.rb +74 -0
  105. data/lib/concurrent-ruby/concurrent/settable_struct.rb +139 -0
  106. data/lib/concurrent-ruby/concurrent/synchronization/abstract_lockable_object.rb +98 -0
  107. data/lib/concurrent-ruby/concurrent/synchronization/abstract_object.rb +24 -0
  108. data/lib/concurrent-ruby/concurrent/synchronization/abstract_struct.rb +171 -0
  109. data/lib/concurrent-ruby/concurrent/synchronization/condition.rb +60 -0
  110. data/lib/concurrent-ruby/concurrent/synchronization/jruby_lockable_object.rb +13 -0
  111. data/lib/concurrent-ruby/concurrent/synchronization/jruby_object.rb +45 -0
  112. data/lib/concurrent-ruby/concurrent/synchronization/lock.rb +36 -0
  113. data/lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb +72 -0
  114. data/lib/concurrent-ruby/concurrent/synchronization/mri_object.rb +44 -0
  115. data/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb +88 -0
  116. data/lib/concurrent-ruby/concurrent/synchronization/object.rb +183 -0
  117. data/lib/concurrent-ruby/concurrent/synchronization/rbx_lockable_object.rb +71 -0
  118. data/lib/concurrent-ruby/concurrent/synchronization/rbx_object.rb +49 -0
  119. data/lib/concurrent-ruby/concurrent/synchronization/truffleruby_object.rb +47 -0
  120. data/lib/concurrent-ruby/concurrent/synchronization/volatile.rb +36 -0
  121. data/lib/concurrent-ruby/concurrent/synchronization.rb +30 -0
  122. data/lib/concurrent-ruby/concurrent/thread_safe/synchronized_delegator.rb +50 -0
  123. data/lib/concurrent-ruby/concurrent/thread_safe/util/adder.rb +74 -0
  124. data/lib/concurrent-ruby/concurrent/thread_safe/util/cheap_lockable.rb +118 -0
  125. data/lib/concurrent-ruby/concurrent/thread_safe/util/data_structures.rb +88 -0
  126. data/lib/concurrent-ruby/concurrent/thread_safe/util/power_of_two_tuple.rb +38 -0
  127. data/lib/concurrent-ruby/concurrent/thread_safe/util/striped64.rb +246 -0
  128. data/lib/concurrent-ruby/concurrent/thread_safe/util/volatile.rb +75 -0
  129. data/lib/concurrent-ruby/concurrent/thread_safe/util/xor_shift_random.rb +50 -0
  130. data/lib/concurrent-ruby/concurrent/thread_safe/util.rb +16 -0
  131. data/lib/concurrent-ruby/concurrent/timer_task.rb +311 -0
  132. data/lib/concurrent-ruby/concurrent/tuple.rb +86 -0
  133. data/lib/concurrent-ruby/concurrent/tvar.rb +221 -0
  134. data/lib/concurrent-ruby/concurrent/utility/engine.rb +56 -0
  135. data/lib/concurrent-ruby/concurrent/utility/monotonic_time.rb +90 -0
  136. data/lib/concurrent-ruby/concurrent/utility/native_extension_loader.rb +79 -0
  137. data/lib/concurrent-ruby/concurrent/utility/native_integer.rb +53 -0
  138. data/lib/concurrent-ruby/concurrent/utility/processor_counter.rb +130 -0
  139. data/lib/concurrent-ruby/concurrent/version.rb +3 -0
  140. data/lib/concurrent-ruby/concurrent-ruby.rb +5 -0
  141. data/lib/concurrent-ruby/concurrent.rb +134 -0
  142. metadata +192 -0
@@ -0,0 +1,90 @@
1
+ require 'concurrent/synchronization'
2
+
3
+ module Concurrent
4
+
5
+ # @!macro monotonic_get_time
6
+ #
7
+ # Returns the current time a tracked by the application monotonic clock.
8
+ #
9
+ # @param [Symbol] unit the time unit to be returned, can be either
10
+ # :float_second, :float_millisecond, :float_microsecond, :second,
11
+ # :millisecond, :microsecond, or :nanosecond default to :float_second.
12
+ #
13
+ # @return [Float] The current monotonic time since some unspecified
14
+ # starting point
15
+ #
16
+ # @!macro monotonic_clock_warning
17
+ if defined?(Process::CLOCK_MONOTONIC)
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
88
+ end
89
+ module_function :monotonic_time
90
+ end
@@ -0,0 +1,79 @@
1
+ require 'concurrent/utility/engine'
2
+
3
+ module Concurrent
4
+
5
+ module Utility
6
+
7
+ # @!visibility private
8
+ module NativeExtensionLoader
9
+
10
+ def allow_c_extensions?
11
+ Concurrent.on_cruby?
12
+ end
13
+
14
+ def c_extensions_loaded?
15
+ defined?(@c_extensions_loaded) && @c_extensions_loaded
16
+ end
17
+
18
+ def java_extensions_loaded?
19
+ defined?(@java_extensions_loaded) && @java_extensions_loaded
20
+ end
21
+
22
+ def load_native_extensions
23
+ unless defined? Synchronization::AbstractObject
24
+ raise 'native_extension_loader loaded before Synchronization::AbstractObject'
25
+ end
26
+
27
+ if Concurrent.on_cruby? && !c_extensions_loaded?
28
+ ['concurrent/concurrent_ruby_ext',
29
+ "concurrent/#{RUBY_VERSION[0..2]}/concurrent_ruby_ext"
30
+ ].each { |p| try_load_c_extension p }
31
+ end
32
+
33
+ if Concurrent.on_jruby? && !java_extensions_loaded?
34
+ begin
35
+ require 'concurrent/concurrent_ruby.jar'
36
+ set_java_extensions_loaded
37
+ rescue LoadError => e
38
+ raise e, "Java extensions are required for JRuby.\n" + e.message, e.backtrace
39
+ end
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def load_error_path(error)
46
+ if error.respond_to? :path
47
+ error.path
48
+ else
49
+ error.message.split(' -- ').last
50
+ end
51
+ end
52
+
53
+ def set_c_extensions_loaded
54
+ @c_extensions_loaded = true
55
+ end
56
+
57
+ def set_java_extensions_loaded
58
+ @java_extensions_loaded = true
59
+ end
60
+
61
+ def try_load_c_extension(path)
62
+ require path
63
+ set_c_extensions_loaded
64
+ rescue LoadError => e
65
+ if load_error_path(e) == path
66
+ # move on with pure-Ruby implementations
67
+ # TODO (pitr-ch 12-Jul-2018): warning on verbose?
68
+ else
69
+ raise e
70
+ end
71
+ end
72
+
73
+ end
74
+ end
75
+
76
+ # @!visibility private
77
+ extend Utility::NativeExtensionLoader
78
+ end
79
+
@@ -0,0 +1,53 @@
1
+ module Concurrent
2
+ module Utility
3
+ # @private
4
+ module NativeInteger
5
+ # http://stackoverflow.com/questions/535721/ruby-max-integer
6
+ MIN_VALUE = -(2**(0.size * 8 - 2))
7
+ MAX_VALUE = (2**(0.size * 8 - 2) - 1)
8
+
9
+ def ensure_upper_bound(value)
10
+ if value > MAX_VALUE
11
+ raise RangeError.new("#{value} is greater than the maximum value of #{MAX_VALUE}")
12
+ end
13
+ value
14
+ end
15
+
16
+ def ensure_lower_bound(value)
17
+ if value < MIN_VALUE
18
+ raise RangeError.new("#{value} is less than the maximum value of #{MIN_VALUE}")
19
+ end
20
+ value
21
+ end
22
+
23
+ def ensure_integer(value)
24
+ unless value.is_a?(Integer)
25
+ raise ArgumentError.new("#{value} is not an Integer")
26
+ end
27
+ value
28
+ end
29
+
30
+ def ensure_integer_and_bounds(value)
31
+ ensure_integer value
32
+ ensure_upper_bound value
33
+ ensure_lower_bound value
34
+ end
35
+
36
+ def ensure_positive(value)
37
+ if value < 0
38
+ raise ArgumentError.new("#{value} cannot be negative")
39
+ end
40
+ value
41
+ end
42
+
43
+ def ensure_positive_and_no_zero(value)
44
+ if value < 1
45
+ raise ArgumentError.new("#{value} cannot be negative or zero")
46
+ end
47
+ value
48
+ end
49
+
50
+ extend self
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,130 @@
1
+ require 'etc'
2
+ require 'rbconfig'
3
+ require 'concurrent/delay'
4
+
5
+ module Concurrent
6
+ module Utility
7
+
8
+ # @!visibility private
9
+ class ProcessorCounter
10
+ def initialize
11
+ @processor_count = Delay.new { compute_processor_count }
12
+ @physical_processor_count = Delay.new { compute_physical_processor_count }
13
+ end
14
+
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
+ def processor_count
53
+ @processor_count.value
54
+ end
55
+
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
+ def physical_processor_count
74
+ @physical_processor_count.value
75
+ end
76
+
77
+ private
78
+
79
+ def compute_processor_count
80
+ if Concurrent.on_jruby?
81
+ java.lang.Runtime.getRuntime.availableProcessors
82
+ else
83
+ Etc.nprocessors
84
+ end
85
+ end
86
+
87
+ def compute_physical_processor_count
88
+ ppc = case RbConfig::CONFIG["target_os"]
89
+ when /darwin\d\d/
90
+ IO.popen("/usr/sbin/sysctl -n hw.physicalcpu", &:read).to_i
91
+ when /linux/
92
+ cores = {} # unique physical ID / core ID combinations
93
+ phy = 0
94
+ IO.read("/proc/cpuinfo").scan(/^physical id.*|^core id.*/) do |ln|
95
+ if ln.start_with?("physical")
96
+ phy = ln[/\d+/]
97
+ elsif ln.start_with?("core")
98
+ cid = phy + ":" + ln[/\d+/]
99
+ cores[cid] = true if not cores[cid]
100
+ end
101
+ end
102
+ cores.count
103
+ when /mswin|mingw/
104
+ require 'win32ole'
105
+ result_set = WIN32OLE.connect("winmgmts://").ExecQuery(
106
+ "select NumberOfCores from Win32_Processor")
107
+ result_set.to_enum.collect(&:NumberOfCores).reduce(:+)
108
+ else
109
+ processor_count
110
+ end
111
+ # fall back to logical count if physical info is invalid
112
+ ppc > 0 ? ppc : processor_count
113
+ rescue
114
+ return 1
115
+ end
116
+ end
117
+ end
118
+
119
+ # create the default ProcessorCounter on load
120
+ @processor_counter = Utility::ProcessorCounter.new
121
+ singleton_class.send :attr_reader, :processor_counter
122
+
123
+ def self.processor_count
124
+ processor_counter.processor_count
125
+ end
126
+
127
+ def self.physical_processor_count
128
+ processor_counter.physical_processor_count
129
+ end
130
+ end
@@ -0,0 +1,3 @@
1
+ module Concurrent
2
+ VERSION = '1.1.11'
3
+ end
@@ -0,0 +1,5 @@
1
+ # This file is here so that there is a file with the same name as the gem that
2
+ # can be required by Bundler.require. Applications should normally
3
+ # require 'concurrent'.
4
+
5
+ require_relative "concurrent"
@@ -0,0 +1,134 @@
1
+ require 'concurrent/version'
2
+ require 'concurrent/constants'
3
+ require 'concurrent/errors'
4
+ require 'concurrent/configuration'
5
+
6
+ require 'concurrent/atomics'
7
+ require 'concurrent/executors'
8
+ require 'concurrent/synchronization'
9
+
10
+ require 'concurrent/atomic/atomic_markable_reference'
11
+ require 'concurrent/atomic/atomic_reference'
12
+ require 'concurrent/agent'
13
+ require 'concurrent/atom'
14
+ require 'concurrent/array'
15
+ require 'concurrent/hash'
16
+ require 'concurrent/set'
17
+ require 'concurrent/map'
18
+ require 'concurrent/tuple'
19
+ require 'concurrent/async'
20
+ require 'concurrent/dataflow'
21
+ require 'concurrent/delay'
22
+ require 'concurrent/exchanger'
23
+ require 'concurrent/future'
24
+ require 'concurrent/immutable_struct'
25
+ require 'concurrent/ivar'
26
+ require 'concurrent/maybe'
27
+ require 'concurrent/mutable_struct'
28
+ require 'concurrent/mvar'
29
+ require 'concurrent/promise'
30
+ require 'concurrent/scheduled_task'
31
+ require 'concurrent/settable_struct'
32
+ require 'concurrent/timer_task'
33
+ require 'concurrent/tvar'
34
+ require 'concurrent/promises'
35
+
36
+ require 'concurrent/thread_safe/synchronized_delegator'
37
+ require 'concurrent/thread_safe/util'
38
+
39
+ require 'concurrent/options'
40
+
41
+ # @!macro internal_implementation_note
42
+ #
43
+ # @note **Private Implementation:** This abstraction is a private, internal
44
+ # implementation detail. It should never be used directly.
45
+
46
+ # @!macro monotonic_clock_warning
47
+ #
48
+ # @note Time calculations on all platforms and languages are sensitive to
49
+ # changes to the system clock. To alleviate the potential problems
50
+ # associated with changing the system clock while an application is running,
51
+ # most modern operating systems provide a monotonic clock that operates
52
+ # independently of the system clock. A monotonic clock cannot be used to
53
+ # determine human-friendly clock times. A monotonic clock is used exclusively
54
+ # for calculating time intervals. Not all Ruby platforms provide access to an
55
+ # operating system monotonic clock. On these platforms a pure-Ruby monotonic
56
+ # clock will be used as a fallback. An operating system monotonic clock is both
57
+ # faster and more reliable than the pure-Ruby implementation. The pure-Ruby
58
+ # implementation should be fast and reliable enough for most non-realtime
59
+ # operations. At this time the common Ruby platforms that provide access to an
60
+ # operating system monotonic clock are MRI 2.1 and above and JRuby (all versions).
61
+ #
62
+ # @see http://linux.die.net/man/3/clock_gettime Linux clock_gettime(3)
63
+
64
+ # @!macro copy_options
65
+ #
66
+ # ## Copy Options
67
+ #
68
+ # Object references in Ruby are mutable. This can lead to serious
69
+ # problems when the {#value} of an object is a mutable reference. Which
70
+ # is always the case unless the value is a `Fixnum`, `Symbol`, or similar
71
+ # "primitive" data type. Each instance can be configured with a few
72
+ # options that can help protect the program from potentially dangerous
73
+ # operations. Each of these options can be optionally set when the object
74
+ # instance is created:
75
+ #
76
+ # * `:dup_on_deref` When true the object will call the `#dup` method on
77
+ # the `value` object every time the `#value` method is called
78
+ # (default: false)
79
+ # * `:freeze_on_deref` When true the object will call the `#freeze`
80
+ # method on the `value` object every time the `#value` method is called
81
+ # (default: false)
82
+ # * `:copy_on_deref` When given a `Proc` object the `Proc` will be run
83
+ # every time the `#value` method is called. The `Proc` will be given
84
+ # the current `value` as its only argument and the result returned by
85
+ # the block will be the return value of the `#value` call. When `nil`
86
+ # this option will be ignored (default: nil)
87
+ #
88
+ # When multiple deref options are set the order of operations is strictly defined.
89
+ # The order of deref operations is:
90
+ # * `:copy_on_deref`
91
+ # * `:dup_on_deref`
92
+ # * `:freeze_on_deref`
93
+ #
94
+ # Because of this ordering there is no need to `#freeze` an object created by a
95
+ # provided `:copy_on_deref` block. Simply set `:freeze_on_deref` to `true`.
96
+ # Setting both `:dup_on_deref` to `true` and `:freeze_on_deref` to `true` is
97
+ # as close to the behavior of a "pure" functional language (like Erlang, Clojure,
98
+ # or Haskell) as we are likely to get in Ruby.
99
+
100
+ # @!macro deref_options
101
+ #
102
+ # @option opts [Boolean] :dup_on_deref (false) Call `#dup` before
103
+ # returning the data from {#value}
104
+ # @option opts [Boolean] :freeze_on_deref (false) Call `#freeze` before
105
+ # returning the data from {#value}
106
+ # @option opts [Proc] :copy_on_deref (nil) When calling the {#value}
107
+ # method, call the given proc passing the internal value as the sole
108
+ # argument then return the new value returned from the proc.
109
+
110
+ # @!macro executor_and_deref_options
111
+ #
112
+ # @param [Hash] opts the options used to define the behavior at update and deref
113
+ # and to specify the executor on which to perform actions
114
+ # @option opts [Executor] :executor when set use the given `Executor` instance.
115
+ # Three special values are also supported: `:io` returns the global pool for
116
+ # long, blocking (IO) tasks, `:fast` returns the global pool for short, fast
117
+ # operations, and `:immediate` returns the global `ImmediateExecutor` object.
118
+ # @!macro deref_options
119
+
120
+ # @!macro warn.edge
121
+ # @api Edge
122
+ # @note **Edge Features** are under active development and may change frequently.
123
+ #
124
+ # - Deprecations are not added before incompatible changes.
125
+ # - Edge version: _major_ is always 0, _minor_ bump means incompatible change,
126
+ # _patch_ bump means compatible change.
127
+ # - Edge features may also lack tests and documentation.
128
+ # - Features developed in `concurrent-ruby-edge` are expected to move
129
+ # to `concurrent-ruby` when finalised.
130
+
131
+
132
+ # {include:file:README.md}
133
+ module Concurrent
134
+ end