Open swift-ci opened 3 years ago
@swift-ci create
Fixed in apple/swift-corelibs-foundation#3004.
Unfortunately, this fix may not be complete since we needed to roll the fix back. The conditions which demonstrated this bug no longer hold, unfortunately, so a proper fix may need to be revisited in future by future porters if needed.
Additional Detail from JIRA
| | | |------------------|-----------------| |Votes | 0 | |Component/s | Foundation | |Labels | Bug | |Assignee | None | |Priority | Medium | md5: 5562f0c8b2baa9b93e8beb0f428cabc4Issue Description:
There are several assumptions in CFRunLoop that assume that the units obtained from
mach_absolute_time()
and __CFTimeIntervalToTSR are commensurate.mach_absolute_time()
, on non-Windows platforms, is the value ofCLOCK_MONOTONIC
converted into nanosecond units.In
CFDate.c
, whenclock_getres
indicates thatCLOCK_MONOTONIC
has 1 ns resolution, __CFTSRRate is 1000000000 (the number of nanoseconds in 1 second). __CFTimeIntervalToTSR multiplies theCFTimeInterval
– which is adouble
of fractional seconds – by __CFTSRRate. In other words, when __CFTSRRate is 1000000000, __CFTimeIntervalToTSR essentially converts fractional seconds to nanoseconds, and TSR units are identical to nanosecond units.However, if
clock_getres
indicates thatCLOCK_MONOTONIC
has greater than 1 ns resolution, this no longer holds. __CFTSRRate will be set to that resolution multiplied by 1000000000. In this case, this means __CFTimeIntervalToTSR multiplies fractional seconds by the granularity and 1000000000. TSR units now are not equal to nanosecond units.Therefore, performing arithmetic with
mach_absolute_time()
and TSR units is incorrect as currently written.It is a simple task to write a __CFNanosecondsToTSR that returns its input on platforms with a 1ns clock resolution, and otherwise converts the nanosecond input to a
CFTimeInterval
before converting with __CFTimeIntervalToTSR.However, it is not quite obvious that the TSR calculations in
CFDate.c
are what is necessarily intended. If, for example, I want to know how manyCLOCK_MONOTONIC
ticks are in a given number seconds, I want to convert this to nanoseconds, then divide by the resolution to get clock-granular units.This isn't how clock-granular units are actually used in
CFRunLoop
, in the alternative, it may instead be reasonable to instead remove theclock_getres
calculations altogether and instead treat TSR units as synonymous to nanosecond conversions for the purposes of this module; indeed, TSR units are only publicly used inCFRunLoop
.