Skip to content

Commit 5e340b4

Browse files
committed
Move out of Atomic namespace
1 parent c6ae994 commit 5e340b4

File tree

3 files changed

+139
-140
lines changed

3 files changed

+139
-140
lines changed
Lines changed: 138 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -1,163 +1,163 @@
11
module Concurrent
2-
module Atomic
3-
# An atomic reference which maintains an object reference along with a mark bit
4-
# that can be updated atomically.
5-
#
6-
# @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicMarkableReference.html
7-
# java.util.concurrent.atomic.AtomicMarkableReference
8-
class AtomicMarkableReference < ::Concurrent::Synchronization::Object
9-
10-
private(*attr_atomic(:reference))
2+
# An atomic reference which maintains an object reference along with a mark bit
3+
# that can be updated atomically.
4+
#
5+
# @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicMarkableReference.html
6+
# java.util.concurrent.atomic.AtomicMarkableReference
7+
class AtomicMarkableReference < ::Concurrent::Synchronization::Object
8+
9+
private(*attr_atomic(:reference))
10+
11+
def initialize(value = nil, mark = false)
12+
super()
13+
self.reference = immutable_array(value, mark)
14+
end
1115

12-
def initialize(value = nil, mark = false)
13-
super()
14-
self.reference = immutable_array(value, mark)
16+
# Atomically sets the value and mark to the given updated value and
17+
# mark given both:
18+
# - the current value == the expected value &&
19+
# - the current mark == the expected mark
20+
#
21+
# @param [Object] expected_val the expected value
22+
# @param [Object] new_val the new value
23+
# @param [Boolean] expected_mark the expected mark
24+
# @param [Boolean] new_mark the new mark
25+
#
26+
# @return [Boolean] `true` if successful. A `false` return indicates
27+
# that the actual value was not equal to the expected value or the
28+
# actual mark was not equal to the expected mark
29+
def compare_and_set(expected_val, new_val, expected_mark, new_mark)
30+
# Memoize a valid reference to the current AtomicReference for
31+
# later comparison.
32+
current = reference
33+
curr_val, curr_mark = current
34+
35+
# Ensure that that the expected marks match.
36+
return false unless expected_mark == curr_mark
37+
38+
if expected_val.is_a? Numeric
39+
# If the object is a numeric, we need to ensure we are comparing
40+
# the numerical values
41+
return false unless expected_val == curr_val
42+
else
43+
# Otherwise, we need to ensure we are comparing the object identity.
44+
# Theoretically, this could be incorrect if a user monkey-patched
45+
# `Object#equal?`, but they should know that they are playing with
46+
# fire at that point.
47+
return false unless expected_val.equal? curr_val
1548
end
1649

17-
# Atomically sets the value and mark to the given updated value and
18-
# mark given both:
19-
# - the current value == the expected value &&
20-
# - the current mark == the expected mark
21-
#
22-
# @param [Object] expected_val the expected value
23-
# @param [Object] new_val the new value
24-
# @param [Boolean] expected_mark the expected mark
25-
# @param [Boolean] new_mark the new mark
26-
#
27-
# @return [Boolean] `true` if successful. A `false` return indicates
28-
# that the actual value was not equal to the expected value or the
29-
# actual mark was not equal to the expected mark
30-
def compare_and_set(expected_val, new_val, expected_mark, new_mark)
31-
# Memoize a valid reference to the current AtomicReference for
32-
# later comparison.
33-
current = reference
34-
curr_val, curr_mark = current
35-
36-
# Ensure that that the expected marks match.
37-
return false unless expected_mark == curr_mark
38-
39-
if expected_val.is_a? Numeric
40-
# If the object is a numeric, we need to ensure we are comparing
41-
# the numerical values
42-
return false unless expected_val == curr_val
43-
else
44-
# Otherwise, we need to ensure we are comparing the object identity.
45-
# Theoretically, this could be incorrect if a user monkey-patched
46-
# `Object#equal?`, but they should know that they are playing with
47-
# fire at that point.
48-
return false unless expected_val.equal? curr_val
49-
end
50+
prospect = immutable_array(new_val, new_mark)
5051

51-
prospect = immutable_array(new_val, new_mark)
52+
compare_and_set_reference current, prospect
53+
end
5254

53-
compare_and_set_reference current, prospect
54-
end
55-
alias_method :compare_and_swap, :compare_and_set
55+
alias_method :compare_and_swap, :compare_and_set
5656

57-
# Gets the current reference and marked values.
58-
#
59-
# @return [Array] the current reference and marked values
60-
def get
61-
reference
62-
end
57+
# Gets the current reference and marked values.
58+
#
59+
# @return [Array] the current reference and marked values
60+
def get
61+
reference
62+
end
6363

64-
# Gets the current value of the reference
65-
#
66-
# @return [Object] the current value of the reference
67-
def value
68-
reference[0]
69-
end
64+
# Gets the current value of the reference
65+
#
66+
# @return [Object] the current value of the reference
67+
def value
68+
reference[0]
69+
end
7070

71-
# Gets the current marked value
72-
#
73-
# @return [Boolean] the current marked value
74-
def mark
75-
reference[1]
76-
end
77-
alias_method :marked?, :mark
78-
79-
# _Unconditionally_ sets to the given value of both the reference and
80-
# the mark.
81-
#
82-
# @param [Object] new_val the new value
83-
# @param [Boolean] new_mark the new mark
84-
#
85-
# @return [Array] both the new value and the new mark
86-
def set(new_val, new_mark)
87-
self.reference = immutable_array(new_val, new_mark)
88-
end
71+
# Gets the current marked value
72+
#
73+
# @return [Boolean] the current marked value
74+
def mark
75+
reference[1]
76+
end
8977

90-
# Pass the current value and marked state to the given block, replacing it
91-
# with the block's results. May retry if the value changes during the
92-
# block's execution.
93-
#
94-
# @yield [Object] Calculate a new value and marked state for the atomic
95-
# reference using given (old) value and (old) marked
96-
# @yieldparam [Object] old_val the starting value of the atomic reference
97-
# @yieldparam [Boolean] old_mark the starting state of marked
98-
#
99-
# @return [Array] the new value and new mark
100-
def update
101-
loop do
102-
old_val, old_mark = reference
103-
new_val, new_mark = yield old_val, old_mark
104-
105-
if compare_and_set old_val, new_val, old_mark, new_mark
106-
return immutable_array(new_val, new_mark)
107-
end
108-
end
109-
end
78+
alias_method :marked?, :mark
11079

111-
# Pass the current value to the given block, replacing it
112-
# with the block's result. Raise an exception if the update
113-
# fails.
114-
#
115-
# @yield [Object] Calculate a new value and marked state for the atomic
116-
# reference using given (old) value and (old) marked
117-
# @yieldparam [Object] old_val the starting value of the atomic reference
118-
# @yieldparam [Boolean] old_mark the starting state of marked
119-
#
120-
# @return [Array] the new value and marked state
121-
#
122-
# @raise [Concurrent::ConcurrentUpdateError] if the update fails
123-
def try_update!
80+
# _Unconditionally_ sets to the given value of both the reference and
81+
# the mark.
82+
#
83+
# @param [Object] new_val the new value
84+
# @param [Boolean] new_mark the new mark
85+
#
86+
# @return [Array] both the new value and the new mark
87+
def set(new_val, new_mark)
88+
self.reference = immutable_array(new_val, new_mark)
89+
end
90+
91+
# Pass the current value and marked state to the given block, replacing it
92+
# with the block's results. May retry if the value changes during the
93+
# block's execution.
94+
#
95+
# @yield [Object] Calculate a new value and marked state for the atomic
96+
# reference using given (old) value and (old) marked
97+
# @yieldparam [Object] old_val the starting value of the atomic reference
98+
# @yieldparam [Boolean] old_mark the starting state of marked
99+
#
100+
# @return [Array] the new value and new mark
101+
def update
102+
loop do
124103
old_val, old_mark = reference
125104
new_val, new_mark = yield old_val, old_mark
126105

127-
unless compare_and_set old_val, new_val, old_mark, new_mark
128-
fail ::Concurrent::ConcurrentUpdateError,
129-
'AtomicMarkableReference: Update failed due to race condition.',
130-
'Note: If you would like to guarantee an update, please use ' \
131-
'the `AtomicMarkableReference#update` method.'
106+
if compare_and_set old_val, new_val, old_mark, new_mark
107+
return immutable_array(new_val, new_mark)
132108
end
109+
end
110+
end
133111

134-
immutable_array(new_val, new_mark)
112+
# Pass the current value to the given block, replacing it
113+
# with the block's result. Raise an exception if the update
114+
# fails.
115+
#
116+
# @yield [Object] Calculate a new value and marked state for the atomic
117+
# reference using given (old) value and (old) marked
118+
# @yieldparam [Object] old_val the starting value of the atomic reference
119+
# @yieldparam [Boolean] old_mark the starting state of marked
120+
#
121+
# @return [Array] the new value and marked state
122+
#
123+
# @raise [Concurrent::ConcurrentUpdateError] if the update fails
124+
def try_update!
125+
old_val, old_mark = reference
126+
new_val, new_mark = yield old_val, old_mark
127+
128+
unless compare_and_set old_val, new_val, old_mark, new_mark
129+
fail ::Concurrent::ConcurrentUpdateError,
130+
'AtomicMarkableReference: Update failed due to race condition.',
131+
'Note: If you would like to guarantee an update, please use ' +
132+
'the `AtomicMarkableReference#update` method.'
135133
end
136134

137-
# Pass the current value to the given block, replacing it with the
138-
# block's result. Simply return nil if update fails.
139-
#
140-
# @yield [Object] Calculate a new value and marked state for the atomic
141-
# reference using given (old) value and (old) marked
142-
# @yieldparam [Object] old_val the starting value of the atomic reference
143-
# @yieldparam [Boolean] old_mark the starting state of marked
144-
#
145-
# @return [Array] the new value and marked state, or nil if
146-
# the update failed
147-
def try_update
148-
old_val, old_mark = reference
149-
new_val, new_mark = yield old_val, old_mark
135+
immutable_array(new_val, new_mark)
136+
end
137+
138+
# Pass the current value to the given block, replacing it with the
139+
# block's result. Simply return nil if update fails.
140+
#
141+
# @yield [Object] Calculate a new value and marked state for the atomic
142+
# reference using given (old) value and (old) marked
143+
# @yieldparam [Object] old_val the starting value of the atomic reference
144+
# @yieldparam [Boolean] old_mark the starting state of marked
145+
#
146+
# @return [Array] the new value and marked state, or nil if
147+
# the update failed
148+
def try_update
149+
old_val, old_mark = reference
150+
new_val, new_mark = yield old_val, old_mark
150151

151-
return unless compare_and_set old_val, new_val, old_mark, new_mark
152+
return unless compare_and_set old_val, new_val, old_mark, new_mark
152153

153-
immutable_array(new_val, new_mark)
154-
end
154+
immutable_array(new_val, new_mark)
155+
end
155156

156-
private
157+
private
157158

158-
def immutable_array(*args)
159-
args.freeze
160-
end
159+
def immutable_array(*args)
160+
args.freeze
161161
end
162162
end
163163
end

lib/concurrent/edge/lock_free_linked_set/node.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ module Edge
55
class LockFreeLinkedSet
66
class Node < Synchronization::Object
77
include Comparable
8-
include Concurrent::Atomic
98

109
safe_initialization!
1110

spec/concurrent/atomic/atomic_markable_reference_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
RSpec.describe Concurrent::Atomic::AtomicMarkableReference do
1+
RSpec.describe Concurrent::AtomicMarkableReference do
22
subject { described_class.new 1000, true }
33

44
describe '.initialize' do

0 commit comments

Comments
 (0)