From: "headius (Charles Nutter)" Date: 2013-04-18T03:06:36+09:00 Subject: [ruby-core:54403] [CommonRuby - Feature #8259] Atomic attributes accessors Issue #8259 has been updated by headius (Charles Nutter). Having some discussions with dbussink on IRC... I think the most universally correct option is to have two different paths for reference CAS and value CAS, and rely upon users to choose the right one. As dbussink points out, the people who are going to use atomic ivars are much more likely to know what they're doing. We don't want to have an additional method for ever single atomic ivar, so perhaps a parameter? class MyClass atomic_accessor :foo # generates CAS accessor similar to... def foo_cas(old, new, compare_value = false) ... end end mc = MyClass.new mc.foo = 5 # fixnum, so we'll want value CAS ... # true causes value comparison CAS like I implemented in atomic gem # false does reference CAS as normal, with variable behavior for some numeric values. mc.foo_cas(5, 6, true) I can't imagine two separate methods getting approved but this form seems like it would be acceptable. ---------------------------------------- Feature #8259: Atomic attributes accessors https://bugs.ruby-lang.org/issues/8259#change-38665 Author: funny_falcon (Yura Sokolov) Status: Open Priority: Normal Assignee: Category: Target version: =begin Motivated by this gist (()) 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: (()) 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/