Issue #8259 has been updated by headius (Charles Nutter).


dbussink (Dirkjan Bussink) wrote:
> What I'm wondering is, do we want to enforce the overhead of numeric CAS for all applications of CAS? Also in the case of numeric handling, the pattern in which I've used CAS most often is that I base the old value on the existing one, which of course still works fine for CAS operations on references.

To be clear, in the Ruby impls of numeric CAS, the only additional cost for non-numerics is a kind_of? check.

In JRuby, it's an instanceof check, which is pretty darn fast.

> What I see from this discussion is perhaps two API's. One that is basically identity based and one that is equality based. Wouldn't it be a better idea to provide these two api's separate? That case we don't have to special case numeric handling and people also get equality like handling for non-Numeric classes which would work like the numeric logic here. People can then decide which kind of CAS they need based which kind if comparison they need.

That would certainly avoid overhead in the non-numeric case, but I worry it would lead to too much confusion. People would forget about the equality CAS and use the other one and get weird bugs because they didn't have the same numeric object in hand. It's also hard to track whether you actually have the same object, since most impls emulate the same value / same object_id behavior from MRI.

In the Atomic gem, I still think it's valid to explicitly have AtomicInteger and AtomicFloat to speed up how those are handled (we can use native CAS against 64-bit long and double rather than against the object reference), but this is a case where it seems like everyone would expect numbers to CAS based on equality rather than reference identity, and not doing it will lead to neverending complaints. I could be wrong.
----------------------------------------
Feature #8259: Atomic attributes accessors
https://bugs.ruby-lang.org/issues/8259#change-38657

Author: funny_falcon (Yura Sokolov)
Status: Open
Priority: Normal
Assignee: 
Category: 
Target version: 


=begin
Motivated by this gist ((<URL:https://gist.github.com/jstorimer/5298581>)) and atomic gem

I propose Class.attr_atomic which will add methods for atomic swap and CAS:

  class MyNode
    attr_accessor :item
    attr_atomic :successor

    def initialize(item, successor)
      @item = item
      @successor = successor
    end
  end
  node = MyNode.new(i, other_node)

  # attr_atomic ensures at least #{attr} reader method exists. May be, it should
  # be sure it does volatile access.
  node.successor

  # #{attr}_cas(old_value, new_value) do CAS: atomic compare and swap
  if node.successor_cas(other_node, new_node)
    print "there were no interleaving with other threads"
  end

  # #{attr}_swap atomically swaps value and returns old value.
  # It ensures that no other thread interleaves getting old value and setting
  # new one by cas (or other primitive if exists, like in Java 8)
  node.successor_swap(new_node)

It will be very simple for MRI cause of GIL, and it will use atomic primitives for
other implementations.

Note: both (({#{attr}_swap})) and (({#{attr}_cas})) should raise an error if instance variable were not explicitly set before.

Example for nonblocking queue: ((<URL:https://gist.github.com/funny-falcon/5370416>))

Something similar should be proposed for Structs. May be override same method as (({Struct.attr_atomic}))

Open question for reader:
should (({attr_atomic :my_attr})) ensure that #my_attr reader method exists?
Should it guarantee that (({#my_attr})) provides 'volatile' access?
May be, (({attr_reader :my_attr})) already ought to provide 'volatile' semantic?
May be, semantic of (({@my_attr})) should have volatile semantic (i doubt for that)?
=end



-- 
http://bugs.ruby-lang.org/