Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
Merge pull request #1432 from smolt/ticksPerSecOSXFixStable
Browse files Browse the repository at this point in the history
Fix issue 15334 - OS X core.time ticksPerSecond calculation is incorrect
  • Loading branch information
schveiguy committed Nov 16, 2015
2 parents 82715d0 + a557191 commit fdad9f5
Showing 1 changed file with 23 additions and 22 deletions.
45 changes: 23 additions & 22 deletions src/core/time.d
Expand Up @@ -2682,18 +2682,14 @@ extern(C) void _d_initMonoTime()
}
else version(OSX)
{
mach_timebase_info_data_t info;
if(mach_timebase_info(&info) == 0)
immutable long ticksPerSecond = machTicksPerSecond();
foreach(i, typeStr; __traits(allMembers, ClockType))
{
long ticksPerSecond = 1_000_000_000L * info.numer / info.denom;
foreach(i, typeStr; __traits(allMembers, ClockType))
{
// ensure we are only writing immutable data once
if(tps[i] != 0)
// should only be called once
assert(0);
tps[i] = ticksPerSecond;
}
// ensure we are only writing immutable data once
if(tps[i] != 0)
// should only be called once
assert(0);
tps[i] = ticksPerSecond;
}
}
else version(Posix)
Expand Down Expand Up @@ -2993,17 +2989,7 @@ struct TickDuration
}
else version(OSX)
{
static if(is(typeof(mach_absolute_time)))
{
mach_timebase_info_data_t info;

if(mach_timebase_info(&info))
ticksPerSec = 0;
else
ticksPerSec = (1_000_000_000L * info.denom) / info.numer;
}
else
ticksPerSec = 1_000_000;
ticksPerSec = machTicksPerSecond();
}
else version(Posix)
{
Expand Down Expand Up @@ -4732,6 +4718,21 @@ unittest
static assert(!__traits(compiles, nextLargerTimeUnits!"years"));
}

version(OSX)
long machTicksPerSecond()
{
// Be optimistic that ticksPerSecond (1e9*denom/numer) is integral. So far
// so good on Darwin based platforms OS X, iOS.
import core.internal.abort : abort;
mach_timebase_info_data_t info;
if(mach_timebase_info(&info) != 0)
abort("Failed in mach_timebase_info().");

long scaledDenom = 1_000_000_000L * info.denom;
if(scaledDenom % info.numer != 0)
abort("Non integral ticksPerSecond from mach_timebase_info.");
return scaledDenom / info.numer;
}

/+
Local version of abs, since std.math.abs is in Phobos, not druntime.
Expand Down

0 comments on commit fdad9f5

Please sign in to comment.