Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a simple STM #19

Closed
chrisseaton opened this issue Feb 24, 2014 · 3 comments
Closed

Add a simple STM #19

chrisseaton opened this issue Feb 24, 2014 · 3 comments

Comments

@chrisseaton
Copy link
Member

Software transactional memory provides a simple model for updating multiple references with atomicity, isolation and consistency. Completely transparent STM in Ruby would require language modifications, but if we have a transactional variable object, we can do it quite easily. This is what Haskell did, with their TVar. Clojure's implementation is similar I believe.

account1 = TVar::new(100_000)
account2 = TVar::new(10)

def transfer(from, to, amount)
  atomically do
    from.modify { |x| x - ammount }
    to.modify { |x| x + amount }
  end
end

The action inside the atomically in transfer either completes or it does not - there's no chance of money being taken from the first account but not appearing in the second, and no chance of someone being able to observe the state where it's been taken from the first and not appeared in the second yet.

This transactional variable approach has a drawback in that we can't provide strong isolation - only weak isolation - that means that if you access the variables outside of an atomically it doesn't work. But don't do that then.

Thoughts?

@jdantonio
Copy link
Member

In a very early version of this gem I implemented an atomic function that used Ruby's Fiber to implement something simile. My version was very rudimentary and didn't work correctly on JRuby or Rubinius. Basically, it wasn't very good. I removed it from the gem. I'd love to see your version and include it. I'm OK with the restriction that modifying a TVar outside of atomically will be unsafe. As you said, there is only so mush we can do in Ruby.

@chrisseaton
Copy link
Member Author

We can implement the API right now, just by using a global lock for all atomically statements. Then we can go back and implement one of the real TM algorithms later on.

@chrisseaton
Copy link
Member Author

I've created a tvars branch for this. I've written a few paragraphs on why you would want to use a transactional memory in the documentation there https://github.com/jdantonio/concurrent-ruby/blob/tvars/md/tvar.md.

jdantonio pushed a commit that referenced this issue May 30, 2014
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants