Skip to content

Commit

Permalink
AtomicReference code cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
pitr-ch committed Aug 1, 2018
1 parent 0a51fb3 commit 5752ab5
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 72 deletions.
6 changes: 5 additions & 1 deletion lib/concurrent/atomic/atomic_reference.rb
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ class ConcurrentUpdateError < ThreadError
class CAtomicReference
include AtomicDirectUpdate
include AtomicNumericCompareAndSetWrapper
alias_method :compare_and_swap, :compare_and_set
end
CAtomicReference
when Concurrent.on_jruby?
Expand All @@ -156,6 +157,8 @@ class JavaAtomicReference
when Concurrent.on_truffleruby?
class TruffleRubyAtomicReference < Truffle::AtomicReference
include AtomicDirectUpdate
alias_method :compare_and_swap, :compare_and_set
alias_method :swap, :get_and_set
end
when Concurrent.on_rbx?
# @note Extends `Rubinius::AtomicReference` version adding aliases
Expand All @@ -164,12 +167,13 @@ class TruffleRubyAtomicReference < Truffle::AtomicReference
# @!visibility private
# @!macro internal_implementation_note
class RbxAtomicReference < Rubinius::AtomicReference
alias _compare_and_set compare_and_set
alias_method :_compare_and_set, :compare_and_set
include AtomicDirectUpdate
include AtomicNumericCompareAndSetWrapper
alias_method :value, :get
alias_method :value=, :set
alias_method :swap, :get_and_set
alias_method :compare_and_swap, :compare_and_set
end
RbxAtomicReference
else
Expand Down
1 change: 1 addition & 0 deletions lib/concurrent/atomic_reference/mutex_atomic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module Concurrent
class MutexAtomicReference < Synchronization::LockableObject
include AtomicDirectUpdate
include AtomicNumericCompareAndSetWrapper
alias_method :compare_and_swap, :compare_and_set

# @!macro atomic_reference_method_initialize
def initialize(value = nil)
Expand Down
2 changes: 1 addition & 1 deletion lib/concurrent/atomic_reference/numeric_cas_wrapper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ def compare_and_set(old_value, new_value)
_compare_and_set(old_value, new_value)
end
end
alias_method :compare_and_swap, :compare_and_set

end
end
4 changes: 2 additions & 2 deletions spec/concurrent/atomic/atomic_boolean_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ module Concurrent

if defined? Concurrent::CAtomicBoolean

RSpec.describe CAtomicBoolean, ext: true do
RSpec.describe CAtomicBoolean do
it_should_behave_like :atomic_boolean
end
end
Expand All @@ -166,7 +166,7 @@ module Concurrent
expect(AtomicBoolean.ancestors).to include(JavaAtomicBoolean)
end
elsif defined? Concurrent::CAtomicBoolean
it 'inherits from CAtomicBoolean', ext: true do
it 'inherits from CAtomicBoolean' do
expect(AtomicBoolean.ancestors).to include(CAtomicBoolean)
end
else
Expand Down
4 changes: 2 additions & 2 deletions spec/concurrent/atomic/atomic_fixnum_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ module Concurrent

if defined? Concurrent::CAtomicFixnum

RSpec.describe CAtomicFixnum, ext: true do
RSpec.describe CAtomicFixnum do
it_should_behave_like :atomic_fixnum
end
end
Expand All @@ -228,7 +228,7 @@ module Concurrent
expect(AtomicFixnum.ancestors).to include(JavaAtomicFixnum)
end
elsif defined? Concurrent::CAtomicFixnum
it 'inherits from CAtomicFixnum', ext: true do
it 'inherits from CAtomicFixnum' do
expect(AtomicFixnum.ancestors).to include(CAtomicFixnum)
end
else
Expand Down
105 changes: 39 additions & 66 deletions spec/concurrent/atomic/atomic_reference_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
end

specify :test_value do
atomic = described_class.new(0)
atomic = described_class.new(0)
atomic.value = 1

expect(atomic.value).to eq 1
Expand All @@ -18,7 +18,7 @@
specify :test_update do
# use a number outside JRuby's fixnum cache range, to ensure identity is preserved
atomic = described_class.new(1000)
res = atomic.update {|v| v + 1}
res = atomic.update { |v| v + 1 }

expect(atomic.value).to eq 1001
expect(res).to eq 1001
Expand All @@ -27,7 +27,7 @@
specify :test_try_update do
# use a number outside JRuby's fixnum cache range, to ensure identity is preserved
atomic = described_class.new(1000)
res = atomic.try_update {|v| v + 1}
res = atomic.try_update { |v| v + 1 }

expect(atomic.value).to eq 1001
expect(res).to eq 1001
Expand All @@ -36,15 +36,15 @@
specify :test_try_update_bang do
# use a number outside JRuby's fixnum cache range, to ensure identity is preserved
atomic = described_class.new(1000)
res = atomic.try_update! {|v| v + 1}
res = atomic.try_update! { |v| v + 1 }

expect(atomic.value).to eq 1001
expect(res).to eq 1001
end

specify :test_swap do
atomic = described_class.new(1000)
res = atomic.swap(1001)
res = atomic.swap(1001)

expect(atomic.value).to eq 1001
expect(res).to eq 1000
Expand All @@ -54,8 +54,8 @@
# use a number outside JRuby's fixnum cache range, to ensure identity is preserved
atomic = described_class.new(1000)
expect(
# assigning within block exploits implementation detail for test
atomic.try_update {|v| atomic.value = 1001 ; v + 1}
# assigning within block exploits implementation detail for test
atomic.try_update { |v| atomic.value = 1001; v + 1 }
).to be_falsey
end

Expand All @@ -64,7 +64,7 @@
atomic = described_class.new(1000)
expect {
# assigning within block exploits implementation detail for test
atomic.try_update! {|v| atomic.value = 1001 ; v + 1}
atomic.try_update! { |v| atomic.value = 1001; v + 1 }
}.to raise_error Concurrent::ConcurrentUpdateError
end

Expand All @@ -73,7 +73,7 @@
# use a number outside JRuby's fixnum cache range, to ensure identity is preserved
atomic = described_class.new(1000)
# assigning within block exploits implementation detail for test
atomic.update{|v| tries += 1 ; atomic.value = 1001 ; v + 1}
atomic.update { |v| tries += 1; atomic.value = 1001; v + 1 }

expect(tries).to eq 2
end
Expand All @@ -82,64 +82,64 @@
atomic = described_class.new(0)

# 9-bit idempotent Fixnum (JRuby)
max_8 = 2**256 - 1
min_8 = -(2**256)
max_8 = 2 ** 256 - 1
min_8 = -(2 ** 256)

atomic.set(max_8)
max_8.upto(max_8 + 2) do |i|
expect(atomic.compare_and_swap(i, i+1)).to be_truthy, "CAS failed for numeric #{i} => #{i + 1}"
expect(atomic.compare_and_swap(i, i + 1)).to be_truthy, "CAS failed for numeric #{i} => #{i + 1}"
end

atomic.set(min_8)
min_8.downto(min_8 - 2) do |i|
expect(atomic.compare_and_swap(i, i-1)).to be_truthy, "CAS failed for numeric #{i} => #{i - 1}"
expect(atomic.compare_and_swap(i, i - 1)).to be_truthy, "CAS failed for numeric #{i} => #{i - 1}"
end

# 64-bit idempotent Fixnum (MRI, Rubinius)
max_64 = 2**62 - 1
min_64 = -(2**62)
max_64 = 2 ** 62 - 1
min_64 = -(2 ** 62)

atomic.set(max_64)
max_64.upto(max_64 + 2) do |i|
expect(atomic.compare_and_swap(i, i+1)).to be_truthy, "CAS failed for numeric #{i} => #{i + 1}"
expect(atomic.compare_and_swap(i, i + 1)).to be_truthy, "CAS failed for numeric #{i} => #{i + 1}"
end

atomic.set(min_64)
min_64.downto(min_64 - 2) do |i|
expect(atomic.compare_and_swap(i, i-1)).to be_truthy, "CAS failed for numeric #{i} => #{i - 1}"
expect(atomic.compare_and_swap(i, i - 1)).to be_truthy, "CAS failed for numeric #{i} => #{i - 1}"
end

## 64-bit overflow into Bignum (JRuby)
max_64 = 2**63 - 1
min_64 = (-2**63)
max_64 = 2 ** 63 - 1
min_64 = (-2 ** 63)

atomic.set(max_64)
max_64.upto(max_64 + 2) do |i|
expect(atomic.compare_and_swap(i, i+1)).to be_truthy, "CAS failed for numeric #{i} => #{i + 1}"
expect(atomic.compare_and_swap(i, i + 1)).to be_truthy, "CAS failed for numeric #{i} => #{i + 1}"
end

atomic.set(min_64)
min_64.downto(min_64 - 2) do |i|
expect(atomic.compare_and_swap(i, i-1)).to be_truthy, "CAS failed for numeric #{i} => #{i - 1}"
expect(atomic.compare_and_swap(i, i - 1)).to be_truthy, "CAS failed for numeric #{i} => #{i - 1}"
end

# non-idempotent Float (JRuby, Rubinius, MRI < 2.0.0 or 32-bit)
atomic.set(1.0 + 0.1)
expect(atomic.compare_and_set(1.0 + 0.1, 1.2)).to be_truthy, "CAS failed for #{1.0 + 0.1} => 1.2"

# Bignum
atomic.set(2**100)
expect(atomic.compare_and_set(2**100, 0)).to be_truthy, "CAS failed for #{2**100} => 0"
atomic.set(2 ** 100)
expect(atomic.compare_and_set(2 ** 100, 0)).to be_truthy, "CAS failed for #{2 ** 100} => 0"

# Rational
require 'rational' unless ''.respond_to? :to_r
atomic.set(Rational(1,3))
expect(atomic.compare_and_set(Rational(1,3), 0)).to be_truthy, "CAS failed for #{Rational(1,3)} => 0"
atomic.set(Rational(1, 3))
expect(atomic.compare_and_set(Rational(1, 3), 0)).to be_truthy, "CAS failed for #{Rational(1, 3)} => 0"

# Complex
require 'complex' unless ''.respond_to? :to_c
atomic.set(Complex(1,2))
expect(atomic.compare_and_set(Complex(1,2), 0)).to be_truthy, "CAS failed for #{Complex(1,2)} => 0"
atomic.set(Complex(1, 2))
expect(atomic.compare_and_set(Complex(1, 2), 0)).to be_truthy, "CAS failed for #{Complex(1, 2)} => 0"
end
end

Expand All @@ -162,53 +162,22 @@ module Concurrent
end

if defined? Concurrent::CAtomicReference
RSpec.describe CAtomicReference, ext: true do
RSpec.describe CAtomicReference do
it_should_behave_like :atomic_reference
end
elsif defined? Concurrent::JavaAtomicReference
end
if defined? Concurrent::JavaAtomicReference
RSpec.describe JavaAtomicReference do
it_should_behave_like :atomic_reference
end
elsif defined? Concurrent::RbxAtomicReference
end
if defined? Concurrent::RbxAtomicReference
RSpec.describe RbxAtomicReference do
it_should_behave_like :atomic_reference
end
end

RSpec.describe AtomicReference do
if Concurrent.on_jruby?
it 'inherits from JavaAtomicReference' do
expect(AtomicReference.ancestors).to include(Concurrent::JavaAtomicReference)
end
elsif Concurrent.allow_c_extensions?
it 'inherits from CAtomicReference' do
expect(AtomicReference.ancestors).to include(Concurrent::CAtomicReference)
end
elsif Concurrent.on_rbx?
it 'inherits from RbxAtomicReference' do
expect(AtomicReference.ancestors).to include(Concurrent::RbxAtomicReference)
end
else
it 'inherits from MutexAtomicReference' do
expect(AtomicReference.ancestors).to include(Concurrent::MutexAtomicReference)
end
end
end

RSpec.describe MutexAtomicReference do
it_should_behave_like :atomic_reference
end

if defined? Concurrent::CAtomicReference
RSpec.describe CAtomicReference, ext: true do
it_should_behave_like :atomic_reference
end
elsif defined? Concurrent::JavaAtomicReference
RSpec.describe JavaAtomicReference do
it_should_behave_like :atomic_reference
end
elsif defined? Concurrent::RbxAtomicReference
RSpec.describe RbxAtomicReference do
if defined? Concurrent::TruffleRubyAtomicReference
RSpec.describe TruffleRubyAtomicReference do
it_should_behave_like :atomic_reference
end
end
Expand All @@ -219,13 +188,17 @@ module Concurrent
expect(described_class.ancestors).to include(Concurrent::JavaAtomicReference)
end
elsif Concurrent.allow_c_extensions?
it 'inherits from CAtomicReference', ext: true do
it 'inherits from CAtomicReference' do
expect(described_class.ancestors).to include(Concurrent::CAtomicReference)
end
elsif Concurrent.on_rbx?
it 'inherits from RbxAtomicReference' do
expect(described_class.ancestors).to include(Concurrent::RbxAtomicReference)
end
elsif Concurrent.on_truffleruby?
it 'inherits from TruffleRubyAtomicReference' do
expect(described_class.ancestors).to include(Concurrent::TruffleRubyAtomicReference)
end
else
it 'inherits from MutexAtomicReference' do
expect(described_class.ancestors).to include(Concurrent::MutexAtomicReference)
Expand Down
File renamed without changes.

0 comments on commit 5752ab5

Please sign in to comment.