Skip to content

Commit 799a4c4

Browse files
committed
Atomic now extends platform-specific implementation; defaults to MutexAtomic.
1 parent 54b1092 commit 799a4c4

File tree

11 files changed

+70
-23
lines changed

11 files changed

+70
-23
lines changed

ext/com/concurrent_ruby/ext/AtomicReferenceLibrary.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
public class AtomicReferenceLibrary implements Library {
2626
public void load(Ruby runtime, boolean wrap) throws IOException {
2727
RubyModule concurrentMod = runtime.defineModule("Concurrent");
28-
RubyClass atomicCls = concurrentMod.defineClassUnder("Atomic", runtime.getObject(), JRUBYREFERENCE_ALLOCATOR);
28+
RubyClass atomicCls = concurrentMod.defineClassUnder("JavaAtomic", runtime.getObject(), JRUBYREFERENCE_ALLOCATOR);
2929
try {
3030
sun.misc.Unsafe.class.getMethod("getAndSetObject", Object.class);
3131
atomicCls.setAllocator(JRUBYREFERENCE8_ALLOCATOR);

ext/rb_concurrent.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ void Init_concurrent_cruby() {
1313

1414
// define modules and classes
1515
rb_mConcurrent = rb_define_module("Concurrent");
16-
rb_cAtomic = rb_define_class_under(rb_mConcurrent, "Atomic", rb_cObject);
16+
rb_cAtomic = rb_define_class_under(rb_mConcurrent, "CAtomic", rb_cObject);
1717

1818
// CAtomic
1919
rb_define_alloc_func(rb_cAtomic, ir_alloc);
@@ -24,6 +24,5 @@ void Init_concurrent_cruby() {
2424
rb_define_method(rb_cAtomic, "value=", ir_set, 1);
2525
rb_define_method(rb_cAtomic, "get_and_set", ir_get_and_set, 1);
2626
rb_define_method(rb_cAtomic, "swap", ir_get_and_set, 1);
27-
rb_define_method(rb_cAtomic, "compare_and_set", ir_compare_and_set, 2);
28-
rb_define_method(rb_cAtomic, "compare_and_swap", ir_compare_and_set, 2);
27+
rb_define_method(rb_cAtomic, "_compare_and_set", ir_compare_and_set, 2);
2928
}

lib/concurrent/atomic.rb

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,44 @@
1+
require 'concurrent/atomic_reference/concurrent_update_error'
2+
require 'concurrent/atomic_reference/mutex_atomic'
3+
14
begin
25
# force fallback impl with FORCE_ATOMIC_FALLBACK=1
36
if /[^0fF]/ =~ ENV['FORCE_ATOMIC_FALLBACK']
4-
ruby_engine = 'fallback'
7+
ruby_engine = 'mutex_atomic'
58
else
69
ruby_engine = defined?(RUBY_ENGINE)? RUBY_ENGINE : 'ruby'
710
end
811

912
require "concurrent/atomic_reference/#{ruby_engine}"
1013
rescue LoadError
1114
warn "#{__FILE__}:#{__LINE__}: unsupported Ruby engine `#{RUBY_ENGINE}', using less-efficient Atomic impl"
12-
require 'concurrent/atomic_reference/fallback'
15+
end
16+
17+
if RUBY_PLATFORM == 'java'
18+
19+
class Concurrent::Atomic < Concurrent::JavaAtomic
20+
end
21+
22+
elsif defined? Concurrent::CAtomic
23+
24+
class Concurrent::Atomic < Concurrent::CAtomic
25+
end
26+
27+
elsif defined? Concurrent::RbxAtomic
28+
29+
class Concurrent::Atomic < Concurrent::RbxAtomic
30+
end
31+
32+
else
33+
34+
class Concurrent::Atomic < Concurrent::MutexAtomic
35+
end
1336
end
1437

1538
class Atomic < Concurrent::Atomic
39+
40+
ConcurrentUpdateError = Class.new(Concurrent::ConcurrentUpdateError)
41+
1642
def initialize(*args)
1743
warn "[DEPRECATED] Please use Concurrent::Atomic instead."
1844
super
Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
module Concurrent
22

3-
class Atomic
4-
class ConcurrentUpdateError < ThreadError
5-
# frozen pre-allocated backtrace to speed ConcurrentUpdateError
6-
CONC_UP_ERR_BACKTRACE = ['backtrace elided; set verbose to enable'].freeze
7-
end
3+
class ConcurrentUpdateError < ThreadError
4+
# frozen pre-allocated backtrace to speed ConcurrentUpdateError
5+
CONC_UP_ERR_BACKTRACE = ['backtrace elided; set verbose to enable'].freeze
86
end
97
end

lib/concurrent/atomic_reference/direct_update.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
module Concurrent
44

55
# Define update methods that use direct paths
6-
class Atomic
6+
module AtomicDirectUpdate
77
# Pass the current value to the given block, replacing it
88
# with the block's result. May retry if the value changes
99
# during the block's execution.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,8 @@
11
require 'concurrent_jruby'
22
require 'concurrent/atomic_reference/direct_update'
3+
4+
module Concurrent
5+
class JavaAtomic
6+
include Concurrent::AtomicDirectUpdate
7+
end
8+
end

lib/concurrent/atomic_reference/fallback.rb renamed to lib/concurrent/atomic_reference/mutex_atomic.rb

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
require 'thread'
22
require 'concurrent/atomic_reference/direct_update'
3+
require 'concurrent/atomic_reference/numeric_cas_wrapper'
34

45
module Concurrent
56

67
# Portable/generic (but not very memory or scheduling-efficient) fallback
7-
class Atomic #:nodoc: all
8+
class MutexAtomic #:nodoc: all
9+
include Concurrent::AtomicDirectUpdate
10+
include Concurrent::AtomicNumericCompareAndSetWrapper
11+
812
def initialize(value = nil)
913
@mutex = Mutex.new
1014
@value = value
@@ -29,7 +33,7 @@ def get_and_set(new_value)
2933
end
3034
alias swap get_and_set
3135

32-
def compare_and_set(old_value, new_value)
36+
def _compare_and_set(old_value, new_value)
3337
return false unless @mutex.try_lock
3438
begin
3539
return false unless @value.equal? old_value
@@ -39,7 +43,5 @@ def compare_and_set(old_value, new_value)
3943
end
4044
true
4145
end
42-
43-
require 'concurrent/atomic_reference/numeric_cas_wrapper'
4446
end
4547
end

lib/concurrent/atomic_reference/numeric_cas_wrapper.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
module Concurrent
22

3-
class Atomic
4-
alias _compare_and_set compare_and_set
3+
module AtomicNumericCompareAndSetWrapper
4+
#alias _compare_and_set compare_and_set
5+
56
def compare_and_set(expected, new)
67
if expected.kind_of? Numeric
78
while true
Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1+
require 'concurrent/atomic_reference/direct_update'
2+
require 'concurrent/atomic_reference/numeric_cas_wrapper'
3+
14
module Concurrent
25

36
# extend Rubinius's version adding aliases and numeric logic
4-
class Atomic < Rubinius::AtomicReference
7+
class RbxAtomic < Rubinius::AtomicReference
8+
alias _compare_and_set compare_and_set
9+
include Concurrent::AtomicDirectUpdate
10+
include Concurrent::AtomicNumericCompareAndSetWrapper
11+
512
alias value get
613
alias value= set
714
alias swap get_and_set
815
end
9-
10-
require 'concurrent/atomic_reference/direct_update'
11-
require 'concurrent/atomic_reference/numeric_cas_wrapper'
1216
end
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
11
require 'concurrent_cruby'
22
require 'concurrent/atomic_reference/direct_update'
33
require 'concurrent/atomic_reference/numeric_cas_wrapper'
4+
5+
module Concurrent
6+
class CAtomic
7+
include Concurrent::AtomicDirectUpdate
8+
include Concurrent::AtomicNumericCompareAndSetWrapper
9+
end
10+
end

0 commit comments

Comments
 (0)