Skip to content

Commit 3ea4af2

Browse files
committed
AtomicFixnum is now a Synchronization::Object.
1 parent 0631fc9 commit 3ea4af2

File tree

3 files changed

+53
-76
lines changed

3 files changed

+53
-76
lines changed

examples/benchmark_atomic_fixnum.rb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
require 'benchmark'
77
require 'rbconfig'
88

9+
THREADS = 1
10+
TESTS = 10_000_000
11+
912
def atomic_test(clazz, opts = {})
1013
threads = opts.fetch(:threads, 5)
1114
tests = opts.fetch(:tests, 100)
@@ -29,10 +32,10 @@ def atomic_test(clazz, opts = {})
2932

3033
puts "Testing with #{RbConfig::CONFIG['ruby_install_name']} #{RUBY_VERSION}"
3134

32-
atomic_test(Concurrent::MutexAtomicFixnum, threads: 10, tests: 1_000_000)
35+
atomic_test(Concurrent::MutexAtomicFixnum, threads: THREADS, tests: TESTS)
3336

3437
if defined? Concurrent::CAtomicFixnum
35-
atomic_test(Concurrent::CAtomicFixnum, threads: 10, tests: 1_000_000)
38+
atomic_test(Concurrent::CAtomicFixnum, threads: THREADS, tests: TESTS)
3639
elsif RUBY_PLATFORM == 'java'
37-
atomic_test(Concurrent::JavaAtomicFixnum, threads: 10, tests: 1_000_000)
40+
atomic_test(Concurrent::JavaAtomicFixnum, threads: THREADS, tests: TESTS)
3841
end

lib/concurrent/atomic/atomic_fixnum.rb

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require 'concurrent/native_extensions'
2+
require 'concurrent/synchronization'
23

34
module Concurrent
45

@@ -21,7 +22,7 @@ module Concurrent
2122
# 4.520000 0.030000 4.550000 ( 1.187000)
2223
#
2324
# @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicLong.html java.util.concurrent.atomic.AtomicLong
24-
class MutexAtomicFixnum
25+
class MutexAtomicFixnum < Synchronization::Object
2526

2627
# http://stackoverflow.com/questions/535721/ruby-max-integer
2728
MIN_VALUE = -(2**(0.size * 8 - 2))
@@ -33,10 +34,9 @@ class MutexAtomicFixnum
3334
#
3435
# @param [Fixnum] init the initial value
3536
# @raise [ArgumentError] if the initial value is not a `Fixnum`
36-
def initialize(init = 0)
37-
raise ArgumentError.new('initial value must be a Fixnum') unless init.is_a?(Fixnum)
38-
@value = init
39-
@mutex = Mutex.new
37+
def initialize(initial = 0)
38+
raise ArgumentError.new('initial value must be a Fixnum') unless initial.is_a?(Fixnum)
39+
super(initial)
4040
end
4141

4242
# @!macro [attach] atomic_fixnum_method_value_get
@@ -45,10 +45,7 @@ def initialize(init = 0)
4545
#
4646
# @return [Fixnum] the current value
4747
def value
48-
@mutex.lock
49-
@value
50-
ensure
51-
@mutex.unlock
48+
synchronize { @value }
5249
end
5350

5451
# @!macro [attach] atomic_fixnum_method_value_set
@@ -62,10 +59,7 @@ def value
6259
# @raise [ArgumentError] if the new value is not a `Fixnum`
6360
def value=(value)
6461
raise ArgumentError.new('value must be a Fixnum') unless value.is_a?(Fixnum)
65-
@mutex.lock
66-
@value = value
67-
ensure
68-
@mutex.unlock
62+
synchronize { @value = value }
6963
end
7064

7165
# @!macro [attach] atomic_fixnum_method_increment
@@ -74,10 +68,7 @@ def value=(value)
7468
#
7569
# @return [Fixnum] the current value after incrementation
7670
def increment
77-
@mutex.lock
78-
@value += 1
79-
ensure
80-
@mutex.unlock
71+
synchronize { @value += 1 }
8172
end
8273

8374
alias_method :up, :increment
@@ -88,10 +79,7 @@ def increment
8879
#
8980
# @return [Fixnum] the current value after decrementation
9081
def decrement
91-
@mutex.lock
92-
@value -= 1
93-
ensure
94-
@mutex.unlock
82+
synchronize { @value -= 1 }
9583
end
9684

9785
alias_method :down, :decrement
@@ -106,15 +94,20 @@ def decrement
10694
#
10795
# @return [Boolean] true if the value was updated else false
10896
def compare_and_set(expect, update)
109-
@mutex.lock
110-
if @value == expect
111-
@value = update
112-
true
113-
else
114-
false
97+
synchronize do
98+
if @value == expect
99+
@value = update
100+
true
101+
else
102+
false
103+
end
115104
end
116-
ensure
117-
@mutex.unlock
105+
end
106+
107+
protected
108+
109+
def ns_initialize(initial)
110+
@value = initial
118111
end
119112
end
120113

spec/concurrent/atomic/atomic_fixnum_spec.rb

Lines changed: 25 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -116,50 +116,31 @@ module Concurrent
116116

117117
it_should_behave_like :atomic_fixnum
118118

119-
specify 'construction is synchronized' do
120-
mutex = double('mutex')
121-
expect(Mutex).to receive(:new).once.with(no_args).and_return(mutex)
122-
described_class.new
123-
end
124-
125-
specify 'value is synchronized' do
126-
mutex = double('mutex')
127-
allow(Mutex).to receive(:new).with(no_args).and_return(mutex)
128-
expect(mutex).to receive(:lock)
129-
expect(mutex).to receive(:unlock)
130-
described_class.new.value
131-
end
132-
133-
specify 'value= is synchronized' do
134-
mutex = double('mutex')
135-
allow(Mutex).to receive(:new).with(no_args).and_return(mutex)
136-
expect(mutex).to receive(:lock)
137-
expect(mutex).to receive(:unlock)
138-
described_class.new.value = 10
139-
end
140-
141-
specify 'increment is synchronized' do
142-
mutex = double('mutex')
143-
allow(Mutex).to receive(:new).with(no_args).and_return(mutex)
144-
expect(mutex).to receive(:lock)
145-
expect(mutex).to receive(:unlock)
146-
described_class.new.increment
147-
end
148-
149-
specify 'decrement is synchronized' do
150-
mutex = double('mutex')
151-
allow(Mutex).to receive(:new).with(no_args).and_return(mutex)
152-
expect(mutex).to receive(:lock)
153-
expect(mutex).to receive(:unlock)
154-
described_class.new.decrement
155-
end
156-
157-
specify 'compare_and_set is synchronized' do
158-
mutex = double('mutex')
159-
allow(Mutex).to receive(:new).with(no_args).and_return(mutex)
160-
expect(mutex).to receive(:lock)
161-
expect(mutex).to receive(:unlock)
162-
described_class.new(14).compare_and_set(14, 2)
119+
context 'instance methods' do
120+
121+
before(:each) do
122+
expect(subject).to receive(:synchronize).with(no_args).and_return(10)
123+
end
124+
125+
specify 'value is synchronized' do
126+
subject.value
127+
end
128+
129+
specify 'value= is synchronized' do
130+
subject.value = 10
131+
end
132+
133+
specify 'increment is synchronized' do
134+
subject.increment
135+
end
136+
137+
specify 'decrement is synchronized' do
138+
subject.decrement
139+
end
140+
141+
specify 'compare_and_set is synchronized' do
142+
subject.compare_and_set(14, 2)
143+
end
163144
end
164145
end
165146

0 commit comments

Comments
 (0)