Skip to content

Commit

Permalink
Add Crystal::System::Time.ticks
Browse files Browse the repository at this point in the history
Returns the current time as per the monotonic clock in nanoseconds.
Doesn't fail (i.e. doesn't raise) and doesn't allocate into the GC
HEAP, so we can use it in tight contexts.
  • Loading branch information
ysbaddaden committed May 23, 2024
1 parent 6b33390 commit 426d54d
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/crystal/system/time.cr
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ module Crystal::System::Time
# nanoseconds}`.
# def self.monotonic : {Int64, Int32}

# Returns the current time from the monotonic clock in nanoseconds.
# Doesn't raise nor allocates GC HEAP memory.
# def self.ticks : UInt64

# Returns a list of paths where time zone data should be looked up.
# def self.zone_sources : Enumerable(String)

Expand Down
10 changes: 10 additions & 0 deletions src/crystal/system/unix/time.cr
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ module Crystal::System::Time
{% end %}
end

def self.ticks : UInt64
{% if flag?(:darwin) %}
info = mach_timebase_info
LibC.mach_absolute_time &* info.numer // info.denom
{% else %}
LibC.clock_gettime(LibC::CLOCK_MONOTONIC, out tp)
tp.tv_sec.to_u64! &* NANOSECONDS_PER_SECOND &+ tp.tv_nsec.to_u64!
{% end %}
end

def self.to_timespec(time : ::Time)
t = uninitialized LibC::Timespec
t.tv_sec = typeof(t.tv_sec).new(time.to_unix)
Expand Down
4 changes: 4 additions & 0 deletions src/crystal/system/win32/time.cr
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,11 @@ module Crystal::System::Time
LibC.QueryPerformanceCounter(out ticks)
frequency = performance_frequency
{ticks // frequency, (ticks.remainder(frequency) * NANOSECONDS_PER_SECOND / frequency).to_i32}
end

def self.ticks : UInt64
LibC.QueryPerformanceCounter(out ticks)
ticks.to_u64! &* (NANOSECONDS_PER_SECOND // performance_frequency)
end

def self.load_localtime : ::Time::Location?
Expand Down

0 comments on commit 426d54d

Please sign in to comment.