Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

compare_and_set will not increment past 256 on JRuby #19

Closed
ileitch opened this Issue · 8 comments

2 participants

@ileitch

This is a strange one.

When I run the below code, it will not progress past 256. However If I set current_seq to 256 as returned by @sequence.get will continue. See the commented out line in the loop.

The output I see is {:get=>256, :current_seq=>256, :new_seq=>257}

Work as expected on Rubinius.

jruby 1.7.3 (1.9.3p385) 2013-02-21 dac429b on Java HotSpot(TM) 64-Bit Server VM 1.8.0-ea-b84 +indy [darwin-x86_64]
require 'rubygems'
require 'atomic'

class Sequence
  INITIAL_VALUE = 0

  def initialize(initial = INITIAL_VALUE)
    @sequence = Atomic.new(initial)
  end

  def get
    @sequence.get
  end

  def set(current_seq, new_seq)
    p [current_seq, new_seq]

    while !@sequence.compare_and_set(current_seq, new_seq)
      a = { :get => @sequence.get, :current_seq => current_seq, :new_seq => new_seq }
      p a

      # Uncomment this an it'll work.
      # current_seq = @sequence.get
    end
  end
end

s = Sequence.new(0)

300.times do |i|
  s.set(i, i + 1)
end
@headius
Owner
@headius headius closed this
@ileitch

Without AtomicInteger, how can I implement a method, that given a value waits for the Atomic to reach value - 1?

def set(value)
  while !@atomic.compare_and_set(value-1, value); end
end
>> a = Atomic.new(255)
=> #<Atomic:0xffaa6af>
>> a.compare_and_set(255, 256)
=> true
>> a.compare_and_set(256, 257)
=> false
@headius
Owner

I'm adding a special case for any Numeric types that will use a Ruby == plus normal CAS. It won't be as efficient as an AtomicInteger, etc, but it will make numerics work like most people expect.

@headius headius reopened this
@headius headius referenced this issue from a commit
@headius Partial fix for numeric idempotence differences across Rubies.
I have opted to make numerics succeed in CAS if they are == as far
as Ruby is concerned. This makes numeric CAS have a bit more
overhead, since we do (at least) two additional instanceof and an
additional == call, as well as looping until there's no contention
for reference equality, but it fits the spirit of what people want
better than strict reference equality.

See #19.
073b4c1
@headius
Owner

I have implemented the logic for JRuby and added some tests for at least Fixnums. More tests for other numeric types, as well as the same logic for the C ext, and we can call this fixed.

@headius
Owner

Added some additional numeric tests in e59e92b.

@ileitch

Awesome, thanks.

@headius
Owner

@ileitch Note that it still needs an MRI impl, and as a result the @travisci builds are failing.

@headius
Owner

I added Ruby impls of the numeric logic in ed84820.

atomic-1.1.8 is on rubygems.org.

@headius headius closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.