Skip to content

Commit 023b0ab

Browse files
jdantonioalexdowad
authored andcommitted
Counter in ReadWriteLock is now an AtomicFixnum
1 parent 1ae93a0 commit 023b0ab

File tree

2 files changed

+28
-28
lines changed

2 files changed

+28
-28
lines changed

lib/concurrent/atomic/read_write_lock.rb

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
require 'thread'
2-
require 'concurrent/atomic/atomic_reference'
2+
require 'concurrent/atomic/atomic_fixnum'
33
require 'concurrent/errors'
44
require 'concurrent/synchronization'
55

@@ -33,7 +33,7 @@ class ReadWriteLock < Synchronization::Object
3333
WAITING_WRITER = 1 << 15
3434

3535
# @!visibility private
36-
RUNNING_WRITER = 1 << 30
36+
RUNNING_WRITER = 1 << 29
3737

3838
# @!visibility private
3939
MAX_READERS = WAITING_WRITER - 1
@@ -50,11 +50,11 @@ class ReadWriteLock < Synchronization::Object
5050
# Each reader increments the counter by 1 when acquiring a read lock
5151
# (and decrements by 1 when releasing the read lock)
5252
# The counter is increased by (1 << 15) for each writer waiting to acquire the
53-
# write lock, and by (1 << 30) if the write lock is taken
53+
# write lock, and by (1 << 29) if the write lock is taken
5454

5555
# Create a new `ReadWriteLock` in the unlocked state.
5656
def initialize
57-
@Counter = AtomicReference.new(0) # single integer which represents lock state
57+
@Counter = AtomicFixnum.new(0) # single integer which represents lock state
5858
@ReadLock = Synchronization::Lock.new
5959
@WriteLock = Synchronization::Lock.new
6060
ensure_ivar_visibility!
@@ -122,11 +122,11 @@ def acquire_read_lock
122122
if running_writer?(c)
123123
@ReadLock.wait_until { !running_writer? }
124124
else
125-
return if @Counter.compare_and_swap(c, c+1)
125+
return if @Counter.compare_and_set(c, c+1)
126126
end
127127
end
128128
else
129-
break if @Counter.compare_and_swap(c, c+1)
129+
break if @Counter.compare_and_set(c, c+1)
130130
end
131131
end
132132
true
@@ -138,7 +138,7 @@ def acquire_read_lock
138138
def release_read_lock
139139
while true
140140
c = @Counter.value
141-
if @Counter.compare_and_swap(c, c-1)
141+
if @Counter.compare_and_set(c, c-1)
142142
# If one or more writers were waiting, and we were the last reader, wake a writer up
143143
if waiting_writer?(c) && running_readers(c) == 1
144144
@WriteLock.signal
@@ -162,8 +162,8 @@ def acquire_write_lock
162162

163163
if c == 0 # no readers OR writers running
164164
# if we successfully swap the RUNNING_WRITER bit on, then we can go ahead
165-
break if @Counter.compare_and_swap(0, RUNNING_WRITER)
166-
elsif @Counter.compare_and_swap(c, c+WAITING_WRITER)
165+
break if @Counter.compare_and_set(0, RUNNING_WRITER)
166+
elsif @Counter.compare_and_set(c, c+WAITING_WRITER)
167167
while true
168168
# Now we have successfully incremented, so no more readers will be able to increment
169169
# (they will wait instead)
@@ -180,7 +180,7 @@ def acquire_write_lock
180180
# Then we are OK to stop waiting and go ahead
181181
# Otherwise go back and wait again
182182
c = @Counter.value
183-
break if !running_writer?(c) && !running_readers?(c) && @Counter.compare_and_swap(c, c+RUNNING_WRITER-WAITING_WRITER)
183+
break if !running_writer?(c) && !running_readers?(c) && @Counter.compare_and_set(c, c+RUNNING_WRITER-WAITING_WRITER)
184184
end
185185
break
186186
end

spec/concurrent/atomic/read_write_lock_spec.rb

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,8 @@ module Concurrent
142142
end
143143

144144
it 'raises an exception if maximum lock limit is exceeded' do
145-
counter = Concurrent::AtomicReference.new(ReadWriteLock::MAX_READERS)
146-
allow(Concurrent::AtomicReference).to receive(:new).with(anything).and_return(counter)
145+
counter = Concurrent::AtomicFixnum.new(ReadWriteLock::MAX_READERS)
146+
allow(Concurrent::AtomicFixnum).to receive(:new).with(anything).and_return(counter)
147147
expect {
148148
subject.with_read_lock { nil }
149149
}.to raise_error(Concurrent::ResourceLimitError)
@@ -183,8 +183,8 @@ module Concurrent
183183
end
184184

185185
it 'raises an exception if maximum lock limit is exceeded' do
186-
counter = Concurrent::AtomicReference.new(ReadWriteLock::MAX_WRITERS)
187-
allow(Concurrent::AtomicReference).to receive(:new).with(anything).and_return(counter)
186+
counter = Concurrent::AtomicFixnum.new(ReadWriteLock::MAX_WRITERS)
187+
allow(Concurrent::AtomicFixnum).to receive(:new).with(anything).and_return(counter)
188188
expect {
189189
subject.with_write_lock { nil }
190190
}.to raise_error(Concurrent::ResourceLimitError)
@@ -202,8 +202,8 @@ module Concurrent
202202
context '#acquire_read_lock' do
203203

204204
it 'increments the lock count' do
205-
counter = Concurrent::AtomicReference.new(0)
206-
allow(Concurrent::AtomicReference).to receive(:new).with(anything).and_return(counter)
205+
counter = Concurrent::AtomicFixnum.new(0)
206+
allow(Concurrent::AtomicFixnum).to receive(:new).with(anything).and_return(counter)
207207
subject.acquire_read_lock
208208
expect(counter.value).to eq 1
209209
end
@@ -243,8 +243,8 @@ module Concurrent
243243
end
244244

245245
it 'does not wait for any running readers' do
246-
counter = Concurrent::AtomicReference.new(0)
247-
allow(Concurrent::AtomicReference).to receive(:new).with(anything).and_return(counter)
246+
counter = Concurrent::AtomicFixnum.new(0)
247+
allow(Concurrent::AtomicFixnum).to receive(:new).with(anything).and_return(counter)
248248

249249
latch_1 = Concurrent::CountDownLatch.new(1)
250250
latch_2 = Concurrent::CountDownLatch.new(1)
@@ -282,8 +282,8 @@ module Concurrent
282282
end
283283

284284
it 'raises an exception if maximum lock limit is exceeded' do
285-
counter = Concurrent::AtomicReference.new(ReadWriteLock::MAX_WRITERS)
286-
allow(Concurrent::AtomicReference).to receive(:new).with(anything).and_return(counter)
285+
counter = Concurrent::AtomicFixnum.new(ReadWriteLock::MAX_WRITERS)
286+
allow(Concurrent::AtomicFixnum).to receive(:new).with(anything).and_return(counter)
287287
expect {
288288
subject.acquire_write_lock { nil }
289289
}.to raise_error(Concurrent::ResourceLimitError)
@@ -297,8 +297,8 @@ module Concurrent
297297
context '#release_read_lock' do
298298

299299
it 'decrements the counter' do
300-
counter = Concurrent::AtomicReference.new(0)
301-
allow(Concurrent::AtomicReference).to receive(:new).with(anything).and_return(counter)
300+
counter = Concurrent::AtomicFixnum.new(0)
301+
allow(Concurrent::AtomicFixnum).to receive(:new).with(anything).and_return(counter)
302302
subject.acquire_read_lock
303303
expect(counter.value).to eq 1
304304
subject.release_read_lock
@@ -340,8 +340,8 @@ module Concurrent
340340
context '#acquire_write_lock' do
341341

342342
it 'increments the lock count' do
343-
counter = Concurrent::AtomicReference.new(0)
344-
allow(Concurrent::AtomicReference).to receive(:new).with(anything).and_return(counter)
343+
counter = Concurrent::AtomicFixnum.new(0)
344+
allow(Concurrent::AtomicFixnum).to receive(:new).with(anything).and_return(counter)
345345
subject.acquire_write_lock
346346
expect(counter.value).to be > 1
347347
end
@@ -415,8 +415,8 @@ module Concurrent
415415
end
416416

417417
it 'raises an exception if maximum lock limit is exceeded' do
418-
counter = Concurrent::AtomicReference.new(ReadWriteLock::MAX_WRITERS)
419-
allow(Concurrent::AtomicReference).to receive(:new).with(anything).and_return(counter)
418+
counter = Concurrent::AtomicFixnum.new(ReadWriteLock::MAX_WRITERS)
419+
allow(Concurrent::AtomicFixnum).to receive(:new).with(anything).and_return(counter)
420420
expect {
421421
subject.acquire_write_lock { nil }
422422
}.to raise_error(Concurrent::ResourceLimitError)
@@ -430,8 +430,8 @@ module Concurrent
430430
context '#release_write_lock' do
431431

432432
it 'decrements the counter' do
433-
counter = Concurrent::AtomicReference.new(0)
434-
allow(Concurrent::AtomicReference).to receive(:new).with(anything).and_return(counter)
433+
counter = Concurrent::AtomicFixnum.new(0)
434+
allow(Concurrent::AtomicFixnum).to receive(:new).with(anything).and_return(counter)
435435
subject.acquire_write_lock
436436
expect(counter.value).to be > 1
437437
subject.release_write_lock

0 commit comments

Comments
 (0)