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


dbussink (Dirkjan Bussink) wrote:
> I highly doubt the neverending complaints case, since this I think people using CAS would usually know what they are doing (at least my experience with using constructs like this). The overhead is actually bigger for the numeric case where a CAS would work for example for Fixnum on MRI and Rubinius without the extra checks. That could of course be optimized in implementations for those platforms. 

You may be right about complaints...I use atomics all the time but I'm unusual. Skewed viewpoint, perhaps.

I'm not sure what you mean by "the overhead is actually bigger". It's a kind_of? type check at worst...is that expensive in Rubinius?

Also, Fixnum will *not* work consistently on MRI or Rubinius without extra checks if any of the values are close to the Fixnum boundary. Optimization specific to those impls would still have to confirm the Fixnum is within a certain range. Perhaps working with Fixnums that are at the failover point into Bignum is not common, but you can't just omit those checks. And you have to know you're dealing with a Fixnum anyway...so you have to check every time.

My justification for doing it unconditionally for all numerics is largely because of the overflow into Bignum. Ruby pretends that integers are one continuum, but only part of that continuum (varying across impls and architectures) is actually idempotent. As a result, all integers would need some portion of the equality checking logic on every implementation.

> If you're worried about confusion between equality and identity, we could also have an equality based CAS be the default and have the possibility of using an identity based version if people know that is what they want.

That's not a bad option, I guess. The main problem here is that I feel like people expect numerics of equal value to essentially be identical, and that's not the case for most numerics on most implementations. If people think they're essentially identical, they might expect CAS to work properly. I don't believe people would have that expectation of non-numerics, so extending equality CAS to all types seems like overkill.
----------------------------------------
Feature #8259: Atomic attributes accessors
https://bugs.ruby-lang.org/issues/8259#change-38664

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/