Skip to content

Commit f3f7292

Browse files
committed
Move AtomicMarkableReference to Edge module
1 parent 28f90ab commit f3f7292

File tree

3 files changed

+186
-180
lines changed

3 files changed

+186
-180
lines changed
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
require 'concurrent/atomic_reference/mutex_markable_atomic'
22

33
# @!macro atomic_markable_reference
4-
module Concurrent
5-
class AtomicMarkableReference < MutexAtomicMarkableReference; end
4+
module Edge
5+
module Concurrent
6+
class AtomicMarkableReference < MutexAtomicMarkableReference; end
7+
end
68
end
Lines changed: 121 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -1,139 +1,141 @@
11
require 'thread'
22
require 'concurrent/atomic_reference/numeric_cas_wrapper'
33

4-
module Concurrent
5-
# @!macro atomic_markable_reference
6-
class MutexAtomicMarkableReference
7-
include AtomicNumericCompareAndSetWrapper
8-
9-
# @!macro [attach] atomic_markable_reference_method_initialize
10-
def initialize(value = nil, marked = false)
11-
@mutex = Mutex.new
12-
@value, @marked = value, marked
13-
end
4+
module Edge
5+
module Concurrent
6+
# @!macro atomic_markable_reference
7+
class MutexAtomicMarkableReference
8+
include ::Concurrent::AtomicNumericCompareAndSetWrapper
9+
10+
# @!macro [attach] atomic_markable_reference_method_initialize
11+
def initialize(value = nil, marked = false)
12+
@mutex = Mutex.new
13+
@value, @marked = value, marked
14+
end
1415

15-
# @!macro [attach] atomic_markable_reference_method_get
16-
#
17-
# Gets the current reference and marked values.
18-
#
19-
# @return [Array] the current reference and marked values
20-
def get
21-
@mutex.synchronize { [@value, @marked] }
22-
end
16+
# @!macro [attach] atomic_markable_reference_method_get
17+
#
18+
# Gets the current reference and marked values.
19+
#
20+
# @return [Array] the current reference and marked values
21+
def get
22+
@mutex.synchronize { [@value, @marked] }
23+
end
2324

24-
# @!macro [attach] atomic_markable_reference_method_value
25-
#
26-
# Gets the current value of the reference
27-
#
28-
# @return [Object] the current value of the reference
29-
def value
30-
@mutex.synchronize { @value }
31-
end
25+
# @!macro [attach] atomic_markable_reference_method_value
26+
#
27+
# Gets the current value of the reference
28+
#
29+
# @return [Object] the current value of the reference
30+
def value
31+
@mutex.synchronize { @value }
32+
end
3233

33-
# @!macro [attach] atomic_markable_reference_method_marked?
34-
#
35-
# Gets the current marked value
36-
#
37-
# @return [Boolean] the current marked value
38-
def marked?
39-
@mutex.synchronize { @marked }
40-
end
41-
alias_method :marked, :marked?
42-
43-
# @!macro [attach] atomic_markable_reference_method_set
44-
#
45-
# Sets to the given value of both the reference and the mark.
46-
#
47-
# @param [Object] new_val the new value
48-
# @param [Boolean] new_mark the new mark
49-
#
50-
# @return [Array] both the new value and the new mark
51-
def set(new_val, new_mark)
52-
@mutex.synchronize do
53-
@value, @marked = new_val, new_mark
54-
55-
[@value, @marked]
34+
# @!macro [attach] atomic_markable_reference_method_marked?
35+
#
36+
# Gets the current marked value
37+
#
38+
# @return [Boolean] the current marked value
39+
def marked?
40+
@mutex.synchronize { @marked }
41+
end
42+
alias_method :marked, :marked?
43+
44+
# @!macro [attach] atomic_markable_reference_method_set
45+
#
46+
# Sets to the given value of both the reference and the mark.
47+
#
48+
# @param [Object] new_val the new value
49+
# @param [Boolean] new_mark the new mark
50+
#
51+
# @return [Array] both the new value and the new mark
52+
def set(new_val, new_mark)
53+
@mutex.synchronize do
54+
@value, @marked = new_val, new_mark
55+
56+
[@value, @marked]
57+
end
5658
end
57-
end
5859

59-
# @!macro [attach] atomic_markable_reference_method_update
60-
#
61-
# Pass the current value and marked state to the given block, replacing it
62-
# with the block's results. May retry if the value changes during the
63-
# block's execution.
64-
#
65-
# @yield [Object] Calculate a new value and marked state for the atomic
66-
# reference using given (old) value and (old) marked
67-
# @yieldparam [Object] old_val the starting value of the atomic reference
68-
# @yieldparam [Boolean] old_mark the starting state of marked
69-
#
70-
# @return [Array] the new value and new mark
71-
def update
72-
loop do
60+
# @!macro [attach] atomic_markable_reference_method_update
61+
#
62+
# Pass the current value and marked state to the given block, replacing it
63+
# with the block's results. May retry if the value changes during the
64+
# block's execution.
65+
#
66+
# @yield [Object] Calculate a new value and marked state for the atomic
67+
# reference using given (old) value and (old) marked
68+
# @yieldparam [Object] old_val the starting value of the atomic reference
69+
# @yieldparam [Boolean] old_mark the starting state of marked
70+
#
71+
# @return [Array] the new value and new mark
72+
def update
73+
loop do
74+
old_val, old_mark = value, marked?
75+
new_val, new_mark = yield old_val, old_mark
76+
77+
if compare_and_set old_val, new_val, old_mark, new_mark
78+
return [new_val, new_mark]
79+
end
80+
end
81+
end
82+
83+
# @!macro [attach] atomic_markable_reference_method_try_update
84+
#
85+
# Pass the current value to the given block, replacing it
86+
# with the block's result. Raise an exception if the update
87+
# fails.
88+
#
89+
# @yield [Object] Calculate a new value and marked state for the atomic
90+
# reference using given (old) value and (old) marked
91+
# @yieldparam [Object] old_val the starting value of the atomic reference
92+
# @yieldparam [Boolean] old_mark the starting state of marked
93+
#
94+
# @return [Array] the new value and marked state
95+
#
96+
# @raise [Concurrent::ConcurrentUpdateError] if the update fails
97+
def try_update
7398
old_val, old_mark = value, marked?
7499
new_val, new_mark = yield old_val, old_mark
75100

76-
if compare_and_set old_val, new_val, old_mark, new_mark
77-
return [new_val, new_mark]
101+
unless compare_and_set old_val, new_val, old_mark, new_mark
102+
err = [::Concurrent::ConcurrentUpdateError, 'Update failed']
103+
err << ::Concurrent::ConcurrentUpdateError::CONC_UP_ERR_BACKTRACE if $VERBOSE
104+
105+
fail(*err)
78106
end
79-
end
80-
end
81107

82-
# @!macro [attach] atomic_markable_reference_method_try_update
83-
#
84-
# Pass the current value to the given block, replacing it
85-
# with the block's result. Raise an exception if the update
86-
# fails.
87-
#
88-
# @yield [Object] Calculate a new value and marked state for the atomic
89-
# reference using given (old) value and (old) marked
90-
# @yieldparam [Object] old_val the starting value of the atomic reference
91-
# @yieldparam [Boolean] old_mark the starting state of marked
92-
#
93-
# @return [Array] the new value and marked state
94-
#
95-
# @raise [Concurrent::ConcurrentUpdateError] if the update fails
96-
def try_update
97-
old_val, old_mark = value, marked?
98-
new_val, new_mark = yield old_val, old_mark
99-
100-
unless compare_and_set old_val, new_val, old_mark, new_mark
101-
err = [ConcurrentUpdateError, 'Update failed']
102-
err << ConcurrentUpdateError::CONC_UP_ERR_BACKTRACE if $VERBOSE
103-
104-
fail(*err)
108+
[new_val, new_mark]
105109
end
106110

107-
[new_val, new_mark]
108-
end
111+
# @!macro [attach] atomic_markable_reference_method_compare_and_set
112+
#
113+
# Atomically sets the value and mark to the given updated value and
114+
# mark given both:
115+
# - the current value == the expected value &&
116+
# - the current mark == the expected mark
117+
#
118+
# @param [Object] old_val the expected value
119+
# @param [Object] new_val the new value
120+
# @param [Boolean] old_mark the expected mark
121+
# @param [Boolean] new_mark the new mark
122+
#
123+
# @return [Boolean] `true` if successful. A `false` return indicates
124+
# that the actual value was not equal to the expected value or the
125+
# actual mark was not equal to the expected mark
126+
def _compare_and_set(old_val, new_val, old_mark, new_mark) #:nodoc:
127+
return false unless @mutex.try_lock
128+
129+
begin
130+
return false unless @value.equal?(old_val) && @marked == old_mark
131+
132+
@value, @marked = new_val, new_mark
133+
ensure
134+
@mutex.unlock
135+
end
109136

110-
# @!macro [attach] atomic_markable_reference_method_compare_and_set
111-
#
112-
# Atomically sets the value and mark to the given updated value and
113-
# mark given both:
114-
# - the current value == the expected value &&
115-
# - the current mark == the expected mark
116-
#
117-
# @param [Object] old_val the expected value
118-
# @param [Object] new_val the new value
119-
# @param [Boolean] old_mark the expected mark
120-
# @param [Boolean] new_mark the new mark
121-
#
122-
# @return [Boolean] `true` if successful. A `false` return indicates
123-
# that the actual value was not equal to the expected value or the
124-
# actual mark was not equal to the expected mark
125-
def _compare_and_set(old_val, new_val, old_mark, new_mark) #:nodoc:
126-
return false unless @mutex.try_lock
127-
128-
begin
129-
return false unless @value.equal?(old_val) && @marked == old_mark
130-
131-
@value, @marked = new_val, new_mark
132-
ensure
133-
@mutex.unlock
137+
true
134138
end
135-
136-
true
137139
end
138140
end
139141
end

0 commit comments

Comments
 (0)