Skip to content

Commit 00be418

Browse files
committed
Implemented pure-Ruby monotonic clock.
1 parent 2b81909 commit 00be418

File tree

7 files changed

+58
-31
lines changed

7 files changed

+58
-31
lines changed

lib/concurrent/atomic/condition.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
require 'concurrent/utility/clock_time'
1+
require 'concurrent/utility/monotonic_time'
22

33
module Concurrent
44

@@ -44,13 +44,13 @@ def initialize
4444
# @param [Object] timeout nil means no timeout
4545
# @return [Result]
4646
def wait(mutex, timeout = nil)
47-
start_time = Concurrent::clock_time
47+
start_time = Concurrent.monotonic_time
4848
@condition.wait(mutex, timeout)
4949

5050
if timeout.nil?
5151
Result.new(nil)
5252
else
53-
Result.new(start_time + timeout - Concurrent::clock_time)
53+
Result.new(start_time + timeout - Concurrent.monotonic_time)
5454
end
5555
end
5656

lib/concurrent/executor/ruby_thread_pool_executor.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
require 'concurrent/atomic/event'
44
require 'concurrent/executor/executor'
55
require 'concurrent/executor/ruby_thread_pool_worker'
6-
require 'concurrent/utility/clock_time'
6+
require 'concurrent/utility/monotonic_time'
77

88
module Concurrent
99

@@ -92,7 +92,7 @@ def initialize(opts = {})
9292
@largest_length = 0
9393

9494
@gc_interval = opts.fetch(:gc_interval, 1).to_i # undocumented
95-
@last_gc_time = Concurrent::clock_time - [1.0, (@gc_interval * 2.0)].max
95+
@last_gc_time = Concurrent.monotonic_time - [1.0, (@gc_interval * 2.0)].max
9696
end
9797

9898
# @!macro executor_module_method_can_overflow_question
@@ -226,13 +226,13 @@ def ensure_capacity?
226226
#
227227
# @!visibility private
228228
def prune_pool
229-
if Concurrent::clock_time - @gc_interval >= @last_gc_time
229+
if Concurrent.monotonic_time - @gc_interval >= @last_gc_time
230230
@pool.delete_if { |worker| worker.dead? }
231231
# send :stop for each thread over idletime
232232
@pool.
233-
select { |worker| @idletime != 0 && Concurrent::clock_time - @idletime > worker.last_activity }.
233+
select { |worker| @idletime != 0 && Concurrent.monotonic_time - @idletime > worker.last_activity }.
234234
each { @queue << :stop }
235-
@last_gc_time = Concurrent::clock_time
235+
@last_gc_time = Concurrent.monotonic_time
236236
end
237237
end
238238

lib/concurrent/executor/ruby_thread_pool_worker.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
require 'thread'
22
require 'concurrent/logging'
3-
require 'concurrent/utility/clock_time'
3+
require 'concurrent/utility/monotonic_time'
44

55
module Concurrent
66

@@ -13,7 +13,7 @@ def initialize(queue, parent)
1313
@queue = queue
1414
@parent = parent
1515
@mutex = Mutex.new
16-
@last_activity = Concurrent::clock_time
16+
@last_activity = Concurrent.monotonic_time
1717
@thread = nil
1818
end
1919

@@ -65,7 +65,7 @@ def run(thread = Thread.current)
6565
# let it fail
6666
log DEBUG, ex
6767
ensure
68-
@last_activity = Concurrent::clock_time
68+
@last_activity = Concurrent.monotonic_time
6969
@parent.on_end_task
7070
end
7171
end

lib/concurrent/utilities.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
require 'concurrent/utility/clock_time'
1+
require 'concurrent/utility/monotonic_time'
22
require 'concurrent/utility/processor_count'
33
require 'concurrent/utility/timeout'
44
require 'concurrent/utility/timer'

lib/concurrent/utility/clock_time.rb

Lines changed: 0 additions & 18 deletions
This file was deleted.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
module Concurrent
2+
3+
if defined?(Process::CLOCK_MONOTONIC)
4+
def monotonic_time
5+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
6+
end
7+
elsif RUBY_PLATFORM == 'java'
8+
def monotonic_time
9+
java.lang.System.nanoTime() / 1_000_000_000.0
10+
end
11+
else
12+
13+
require 'thread'
14+
class << self
15+
16+
# @!visibility private
17+
@@global_monotonic_clock = Class.new {
18+
def initialize
19+
@mutex = Mutex.new
20+
@correction = 0
21+
@last_time = Time.now.to_f
22+
end
23+
def get_time
24+
@mutex.synchronize do
25+
@correction ||= 0 # compensating any back time shifts
26+
now = Time.now.to_f
27+
corrected_now = now + @correction
28+
if @last_time < corrected_now
29+
return @last_time = corrected_now
30+
else
31+
@correction += @last_time - corrected_now + 0.000_001
32+
return @last_time = @correction + now
33+
end
34+
end
35+
end
36+
}.new
37+
end
38+
39+
def monotonic_time
40+
@@global_monotonic_clock.get_time
41+
end
42+
end
43+
44+
module_function :monotonic_time
45+
end

yardoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Subproject commit db7483b80f6efb7df9930f0031508d7e2eb6bad0
1+
Subproject commit 5aff4706f70d757c15830edd66d74759ff364eda

0 commit comments

Comments
 (0)