atomic-ruby 0.14.0 → 0.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5a0461b3ac6fd6dbc7674cf028f8fb3727cad76da32ad2c6054a92a2818fe25f
4
- data.tar.gz: 6f20eabbb25f29f6c43c166cbe240c1ddf2a6def437317c392a53fe86699a6b8
3
+ metadata.gz: 1310b5db37f97fe6e8a8e9da89083554f2bc5cd4500027e853e268d99db15cc6
4
+ data.tar.gz: 94039f36f8c248fc2bbc60529deff3c72d933d6c6e638d6f70136f64ad798825
5
5
  SHA512:
6
- metadata.gz: 8e29e25f0790c2c3f3417efae11440a5f0500e0e943ce4c4a903f7fc4180342e832319cfe82712284449c876c70aa29ea22899480668bb1f35cc02c9369f8a6c
7
- data.tar.gz: f26bc0f694a0e00cc84c9988761a1cf56c50c89d499bd70eb88b3fb896749ba36465d53d16e03d5ad636c8e8cd59b5b1f179bca827cd85c9a59397951bcd6013
6
+ metadata.gz: 9ad6f1cefcf6a6f39635baa7e2d384e6d6a4e273927c9a442bcb4a63036172dcc1c222fb4fd02d61878205db8163f91f70b4a8a753c48c2de760bc74950987f7
7
+ data.tar.gz: 448588150ab485b7a1cb6f7dfe892feba5b15c7b32d6d766570ef4097ec48a3ee0a7fbdc20fa92e9875d7701ee42e31660df9c759d24243f250a7987357d870b
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.14.1] - 2026-08-20
4
+
5
+ - Fix O(n) in `AtomicThreadPool#length` by tracking the alive count
6
+
3
7
  ## [0.14.0] - 2026-08-15
4
8
 
5
9
  - Replace the `AtomicConditionVariable` waiter list with a native doubly-linked list
data/README.md CHANGED
@@ -256,7 +256,7 @@ puts "Atomic Ruby Atomic Bank Account: #{results[2].real.round(6)} seconds"
256
256
 
257
257
  ruby version: ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +YJIT +PRISM [arm64-darwin23]
258
258
  concurrent-ruby version: 1.3.6
259
- atomic-ruby version: 0.14.0
259
+ atomic-ruby version: 0.14.1
260
260
 
261
261
  Balances:
262
262
  Synchronized Bank Account Balance: 975
@@ -347,7 +347,7 @@ end
347
347
 
348
348
  ruby version: ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +YJIT +PRISM [arm64-darwin23]
349
349
  concurrent-ruby version: 1.3.6
350
- atomic-ruby version: 0.14.0
350
+ atomic-ruby version: 0.14.1
351
351
 
352
352
  Warming up --------------------------------------
353
353
  Synchronized Boolean Toggle 157.000 i/100ms
@@ -430,7 +430,7 @@ end
430
430
  > bundle exec rake clobber && bundle exec rake compile && bundle exec ruby examples/atomic_condition_variable_benchmark.rb
431
431
 
432
432
  ruby version: ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +YJIT +PRISM [arm64-darwin23]
433
- atomic-ruby version: 0.14.0
433
+ atomic-ruby version: 0.14.1
434
434
 
435
435
  Warming up --------------------------------------
436
436
  Synchronized Condition Variable Wait/Signal 3.977k i/100ms
@@ -505,7 +505,7 @@ end
505
505
  > bundle exec rake clobber && bundle exec rake compile && bundle exec ruby examples/atomic_queue_benchmark.rb
506
506
 
507
507
  ruby version: ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +YJIT +PRISM [arm64-darwin23]
508
- atomic-ruby version: 0.14.0
508
+ atomic-ruby version: 0.14.1
509
509
 
510
510
  Warming up --------------------------------------
511
511
  Synchronized Queue Push/Pop 181.000 i/100ms
@@ -574,12 +574,12 @@ puts "Atomic Ruby Atomic Thread Pool: #{results[1].real.round(6)} seconds"
574
574
  > bundle exec rake clobber && bundle exec rake compile && bundle exec ruby examples/atomic_thread_pool_benchmark.rb
575
575
 
576
576
  ruby version: ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +YJIT +PRISM [arm64-darwin23]
577
- concurrent-ruby version: 1.3.6
578
- atomic-ruby version: 0.14.0
577
+ concurrent-ruby version: 1.3.8
578
+ atomic-ruby version: 0.14.1
579
579
 
580
580
  Benchmark Results:
581
- Concurrent Ruby Thread Pool: 5.078227 seconds
582
- Atomic Ruby Atomic Thread Pool: 4.824681 seconds
581
+ Concurrent Ruby Thread Pool: 5.046895 seconds
582
+ Atomic Ruby Atomic Thread Pool: 4.717221 seconds
583
583
  ```
584
584
 
585
585
  </details>
@@ -87,7 +87,7 @@ module AtomicRuby
87
87
  @queue = AtomicQueue.new
88
88
  @shutdown = AtomicBoolean.new(false)
89
89
  @work_available = AtomicConditionVariable.new
90
- @started_thread_count = Atom.new(0)
90
+ @alive_thread_count = Atom.new(0)
91
91
  @active_thread_count = Atom.new(0)
92
92
  @threads = []
93
93
 
@@ -140,7 +140,7 @@ module AtomicRuby
140
140
  #
141
141
  # @rbs () -> Integer
142
142
  def length
143
- @threads.select(&:alive?).length
143
+ @alive_thread_count.value
144
144
  end
145
145
  # Alias for {#length}.
146
146
  #
@@ -244,39 +244,43 @@ module AtomicRuby
244
244
  thread_name << " for #{@name}" if @name
245
245
  Thread.current.name = thread_name
246
246
 
247
- @started_thread_count.swap { |current_count| current_count + 1 }
247
+ @alive_thread_count.swap { |current_count| current_count + 1 }
248
248
 
249
- loop do
250
- work = nil
251
- should_shutdown = false
249
+ begin
250
+ loop do
251
+ work = nil
252
+ should_shutdown = false
252
253
 
253
- @work_available.wait do
254
- work = @queue.pop
255
- should_shutdown = @shutdown.true? && @queue.empty? unless work
256
- work || should_shutdown
257
- end
254
+ @work_available.wait do
255
+ work = @queue.pop
256
+ should_shutdown = @shutdown.true? && @queue.empty? unless work
257
+ work || should_shutdown
258
+ end
258
259
 
259
- break if should_shutdown
260
+ break if should_shutdown
260
261
 
261
- @active_thread_count.swap { |current_count| current_count + 1 }
262
- begin
263
- work.call
264
- rescue => err
265
- if @on_error
266
- @on_error.call(err)
267
- else
268
- warn "#{thread_name} rescued:"
269
- warn err.full_message
262
+ @active_thread_count.swap { |current_count| current_count + 1 }
263
+ begin
264
+ work.call
265
+ rescue => err
266
+ if @on_error
267
+ @on_error.call(err)
268
+ else
269
+ warn "#{thread_name} rescued:"
270
+ warn err.full_message
271
+ end
272
+ ensure
273
+ @active_thread_count.swap { |current_count| current_count - 1 }
270
274
  end
271
- ensure
272
- @active_thread_count.swap { |current_count| current_count - 1 }
273
275
  end
276
+ ensure
277
+ @alive_thread_count.swap { |current_count| current_count - 1 }
274
278
  end
275
279
  end
276
280
  end
277
281
  @threads.freeze
278
282
 
279
- Thread.pass until @started_thread_count.value == @size
283
+ Thread.pass until @alive_thread_count.value == @size
280
284
  end
281
285
  end
282
286
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AtomicRuby
4
- VERSION = "0.14.0"
4
+ VERSION = "0.14.1"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: atomic-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.0
4
+ version: 0.14.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Young