wip: Use clock_gettime for NIODeadline.now() (#2119)
* wip: Use clock_gettime for NIODeadline.now() Signed-off-by: Si Beaumont <beaumont@apple.com> * fixup: Add #if os(Linux) for clock_gettime use * fixup: Add doc comments Signed-off-by: Si Beaumont <beaumont@apple.com>
This commit is contained in:
parent
9294f8da3b
commit
92d20d92b0
|
@ -26,6 +26,7 @@ void CNIOLinux_i_do_nothing_just_working_around_a_darwin_toolchain_bug(void) {}
|
|||
#include <sys/prctl.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
|
||||
_Static_assert(sizeof(CNIOLinux_mmsghdr) == sizeof(struct mmsghdr),
|
||||
"sizes of CNIOLinux_mmsghdr and struct mmsghdr differ");
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
|
||||
import NIOConcurrencyHelpers
|
||||
import Dispatch
|
||||
#if os(Linux)
|
||||
import CNIOLinux
|
||||
#endif // os(Linux)
|
||||
|
||||
/// Returned once a task was scheduled on the `EventLoop` for later execution.
|
||||
///
|
||||
|
@ -478,8 +481,33 @@ public struct NIODeadline: Equatable, Hashable, NIOSendable {
|
|||
self._uptimeNanoseconds = nanoseconds
|
||||
}
|
||||
|
||||
|
||||
/// Getting the time is a very common operation so it warrants optimization.
|
||||
///
|
||||
/// Prior to this function, NIO relied on `DispatchTime.now()`, on all platforms. In addition to
|
||||
/// the overhead of making a library call, the underlying implementation has a lot of branches
|
||||
/// because `libdispatch` supports many more usecases than we are making use of here.
|
||||
///
|
||||
/// On Linux, `DispachTime.now()` _always_ results in a simple call to `clock_gettime(3)` and so
|
||||
/// we make that call here, directly from NIO.
|
||||
///
|
||||
/// - TODO: Investigate optimizing the call to `DispatchTime.now()` away on other platforms too.
|
||||
@inline(__always)
|
||||
private static func timeNow() -> UInt64 {
|
||||
#if os(Linux)
|
||||
var ts = timespec()
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts)
|
||||
/// We use unsafe arithmetic here because `UInt64.max` nanoseconds is more than 580 years,
|
||||
/// and the odds that this code will still be running 530 years from now is very, very low,
|
||||
/// so as a practical matter this will never overflow.
|
||||
return UInt64(ts.tv_sec) &* 1_000_000_000 &+ UInt64(ts.tv_nsec)
|
||||
#else // os(Linux)
|
||||
return DispatchTime.now().uptimeNanoseconds
|
||||
#endif // os(Linux)
|
||||
}
|
||||
|
||||
public static func now() -> NIODeadline {
|
||||
return NIODeadline.uptimeNanoseconds(DispatchTime.now().uptimeNanoseconds)
|
||||
return NIODeadline.uptimeNanoseconds(timeNow())
|
||||
}
|
||||
|
||||
public static func uptimeNanoseconds(_ nanoseconds: UInt64) -> NIODeadline {
|
||||
|
|
Loading…
Reference in New Issue