Skip to content

Commit 8183171

Browse files
committed
Merge pull request #61 from jdantonio/atomic_optimization
Atomic optimization
2 parents 3c80ad3 + 92eeb85 commit 8183171

File tree

3 files changed

+75
-38
lines changed

3 files changed

+75
-38
lines changed

lib/concurrent/atomic/atomic_fixnum.rb

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@ def initialize(init = 0)
2828
#
2929
# @return [Fixnum] the current value
3030
def value
31-
@mutex.synchronize do
32-
@value
33-
end
31+
@mutex.lock
32+
result = @value
33+
@mutex.unlock
34+
35+
result
3436
end
3537

3638
# @!macro [attach] atomic_fixnum_method_value_eq
@@ -44,9 +46,11 @@ def value
4446
# @raise [ArgumentError] if the new value is not a `Fixnum`
4547
def value=(value)
4648
raise ArgumentError.new('value must be a Fixnum') unless value.is_a?(Fixnum)
47-
@mutex.synchronize do
48-
@value = value
49-
end
49+
@mutex.lock
50+
result = @value = value
51+
@mutex.unlock
52+
53+
result
5054
end
5155

5256
# @!macro [attach] atomic_fixnum_method_increment
@@ -55,10 +59,14 @@ def value=(value)
5559
#
5660
# @return [Fixnum] the current value after incrementation
5761
def increment
58-
@mutex.synchronize do
59-
@value += 1
60-
end
62+
@mutex.lock
63+
@value += 1
64+
result = @value
65+
@mutex.unlock
66+
67+
result
6168
end
69+
6270
alias_method :up, :increment
6371

6472
# @!macro [attach] atomic_fixnum_method_decrement
@@ -67,10 +75,14 @@ def increment
6775
#
6876
# @return [Fixnum] the current value after decrementation
6977
def decrement
70-
@mutex.synchronize do
71-
@value -= 1
72-
end
78+
@mutex.lock
79+
@value -= 1
80+
result = @value
81+
@mutex.unlock
82+
83+
result
7384
end
85+
7486
alias_method :down, :decrement
7587

7688
# @!macro [attach] atomic_fixnum_method_compare_and_set
@@ -83,14 +95,17 @@ def decrement
8395
#
8496
# @return [Boolean] true if the value was updated else false
8597
def compare_and_set(expect, update)
86-
@mutex.synchronize do
87-
if @value == expect
88-
@value = update
89-
true
90-
else
91-
false
92-
end
98+
99+
@mutex.lock
100+
if @value == expect
101+
@value = update
102+
result = true
103+
else
104+
result = false
93105
end
106+
@mutex.unlock
107+
108+
result
94109
end
95110
end
96111

@@ -124,13 +139,15 @@ def value=(value)
124139
def increment
125140
@atomic.increment_and_get
126141
end
142+
127143
alias_method :up, :increment
128144

129145
# @!macro atomic_fixnum_method_decrement
130146
#
131147
def decrement
132148
@atomic.decrement_and_get
133149
end
150+
134151
alias_method :down, :decrement
135152

136153
# @!macro atomic_fixnum_method_compare_and_set

lib/concurrent/atomic/event.rb

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,41 +28,52 @@ def initialize
2828
#
2929
# @return [Boolean] indicating whether or not the `Event` has been set
3030
def set?
31-
@mutex.synchronize do
32-
@set
33-
end
31+
@mutex.lock
32+
result = @set
33+
@mutex.unlock
34+
35+
result
3436
end
3537

3638
# Trigger the event, setting the state to `set` and releasing all threads
3739
# waiting on the event. Has no effect if the `Event` has already been set.
3840
#
3941
# @return [Boolean] should always return `true`
4042
def set
41-
@mutex.synchronize do
42-
return true if @set
43+
@mutex.lock
44+
unless @set
4345
@set = true
4446
@condition.broadcast
4547
end
48+
@mutex.unlock
4649

4750
true
4851
end
4952

5053
def try?
51-
@mutex.synchronize do
52-
return false if @set
54+
@mutex.lock
55+
56+
if @set
57+
result = false
58+
else
5359
@set = true
5460
@condition.broadcast
61+
result = true
5562
end
63+
64+
@mutex.unlock
65+
66+
result
5667
end
5768

5869
# Reset a previously set event back to the `unset` state.
5970
# Has no effect if the `Event` has not yet been set.
6071
#
6172
# @return [Boolean] should always return `true`
6273
def reset
63-
@mutex.synchronize do
64-
@set = false
65-
end
74+
@mutex.lock
75+
@set = false
76+
@mutex.unlock
6677

6778
true
6879
end
@@ -73,16 +84,20 @@ def reset
7384
#
7485
# @return [Boolean] true if the `Event` was set before timeout else false
7586
def wait(timeout = nil)
76-
@mutex.synchronize do
77-
return true if @set
87+
@mutex.lock
7888

89+
unless @set
7990
remaining = Condition::Result.new(timeout)
8091
while !@set && remaining.can_wait?
8192
remaining = @condition.wait(@mutex, remaining.remaining_time)
8293
end
83-
84-
@set
8594
end
95+
96+
result = @set
97+
98+
@mutex.unlock
99+
100+
result
86101
end
87102
end
88103
end

spec/concurrent/atomic/atomic_fixnum_spec.rb

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,35 +127,40 @@ module Concurrent
127127
specify 'value is synchronized' do
128128
mutex = double('mutex')
129129
Mutex.stub(:new).with(no_args).and_return(mutex)
130-
mutex.should_receive(:synchronize)
130+
mutex.should_receive(:lock)
131+
mutex.should_receive(:unlock)
131132
described_class.new.value
132133
end
133134

134135
specify 'value= is synchronized' do
135136
mutex = double('mutex')
136137
Mutex.stub(:new).with(no_args).and_return(mutex)
137-
mutex.should_receive(:synchronize)
138+
mutex.should_receive(:lock)
139+
mutex.should_receive(:unlock)
138140
described_class.new.value = 10
139141
end
140142

141143
specify 'increment is synchronized' do
142144
mutex = double('mutex')
143145
Mutex.stub(:new).with(no_args).and_return(mutex)
144-
mutex.should_receive(:synchronize)
146+
mutex.should_receive(:lock)
147+
mutex.should_receive(:unlock)
145148
described_class.new.increment
146149
end
147150

148151
specify 'decrement is synchronized' do
149152
mutex = double('mutex')
150153
Mutex.stub(:new).with(no_args).and_return(mutex)
151-
mutex.should_receive(:synchronize)
154+
mutex.should_receive(:lock)
155+
mutex.should_receive(:unlock)
152156
described_class.new.decrement
153157
end
154158

155159
specify 'compare_and_set is synchronized' do
156160
mutex = double('mutex')
157161
Mutex.stub(:new).with(no_args).and_return(mutex)
158-
mutex.should_receive(:synchronize)
162+
mutex.should_receive(:lock)
163+
mutex.should_receive(:unlock)
159164
described_class.new(14).compare_and_set(14, 2)
160165
end
161166
end

0 commit comments

Comments
 (0)