mirror of https://github.com/KLayout/klayout.git
Trying to fix builds
This commit is contained in:
parent
6aa66830e8
commit
448ebcc8c6
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
TEMPLATE = lib
|
||||
DESTDIR = $$OUT_PWD/../../../../..
|
||||
INCLUDEPATH =
|
||||
|
||||
include($$PWD/../../lstream.pri)
|
||||
include($$PWD/capnp.pri)
|
||||
|
|
@ -10,7 +11,6 @@ SOURCES = $$CAPNP_SOURCES
|
|||
HEADERS = $$CAPNP_HEADERS
|
||||
|
||||
DEFINES += CAPNP_LITE
|
||||
INCLUDEPATH = $$PWD/../kj
|
||||
LIBS =
|
||||
QT =
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
# DO NOT EDIT!
|
||||
# (SEE ../capnp.pro)
|
||||
|
||||
|
||||
TEMPLATE = lib
|
||||
DESTDIR = $$OUT_PWD/../../../../..
|
||||
|
|
|
|||
|
|
@ -25,8 +25,15 @@ mkdir capnp/capnp/compat
|
|||
cp $tmp/{LICENSE,CONTRIBUTORS} kj
|
||||
cp $tmp/{LICENSE,CONTRIBUTORS} capnp
|
||||
|
||||
cp kj.pro kj
|
||||
cp capnp.pro capnp
|
||||
echo "# DO NOT EDIT!" >kj/kj.pro
|
||||
echo "# (SEE ../kj.pro)" >>kj/kj.pro
|
||||
echo "" >>kj/kj.pro
|
||||
cat kj.pro >>kj/kj.pro
|
||||
|
||||
echo "# DO NOT EDIT!" >capnp/capnp.pro
|
||||
echo "# (SEE ../capnp.pro)" >>capnp/capnp.pro
|
||||
echo "" >>capnp/capnp.pro
|
||||
cat capnp.pro >>capnp/capnp.pro
|
||||
|
||||
capnp_sources_lite=(
|
||||
c++.capnp.c++
|
||||
|
|
@ -78,7 +85,6 @@ capnp_compat_headers=(
|
|||
|
||||
kj_sources_lite=(
|
||||
array.c++
|
||||
cidr.c++
|
||||
list.c++
|
||||
common.c++
|
||||
debug.c++
|
||||
|
|
@ -95,10 +101,10 @@ kj_sources_lite=(
|
|||
arena.c++
|
||||
units.c++
|
||||
encoding.c++
|
||||
time.c++
|
||||
)
|
||||
|
||||
kj_headers=(
|
||||
cidr.h
|
||||
common.h
|
||||
units.h
|
||||
memory.h
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
TEMPLATE = lib
|
||||
DESTDIR = $$OUT_PWD/../../../../..
|
||||
INCLUDEPATH =
|
||||
|
||||
include($$PWD/../../lstream.pri)
|
||||
include($$PWD/kj.pri)
|
||||
|
|
@ -10,7 +11,6 @@ SOURCES = $$KJ_SOURCES
|
|||
HEADERS = $$KJ_HEADERS
|
||||
|
||||
DEFINES = CAPNP_LITE
|
||||
INCLUDEPATH =
|
||||
LIBS =
|
||||
QT =
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
KJ_SOURCES=\
|
||||
kj/array.cc \
|
||||
kj/cidr.cc \
|
||||
kj/list.cc \
|
||||
kj/common.cc \
|
||||
kj/debug.cc \
|
||||
|
|
@ -18,9 +17,9 @@ KJ_SOURCES=\
|
|||
kj/arena.cc \
|
||||
kj/units.cc \
|
||||
kj/encoding.cc \
|
||||
kj/time.cc \
|
||||
|
||||
KJ_HEADERS=\
|
||||
kj/cidr.h \
|
||||
kj/common.h \
|
||||
kj/units.h \
|
||||
kj/memory.h \
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
# DO NOT EDIT!
|
||||
# (SEE ../kj.pro)
|
||||
|
||||
|
||||
TEMPLATE = lib
|
||||
DESTDIR = $$OUT_PWD/../../../../..
|
||||
|
|
|
|||
|
|
@ -1,175 +0,0 @@
|
|||
// Copyright (c) 2013-2017 Sandstorm Development Group, Inc. and contributors
|
||||
// Licensed under the MIT License:
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#if _WIN32
|
||||
// Request Vista-level APIs.
|
||||
#include <kj/win32-api-version.h>
|
||||
#endif
|
||||
|
||||
#include "debug.h"
|
||||
#include "cidr.h"
|
||||
|
||||
#if _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2ipdef.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <kj/windows-sanity.h>
|
||||
#define inet_pton InetPtonA
|
||||
#define inet_ntop InetNtopA
|
||||
#include <io.h>
|
||||
#define dup _dup
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
namespace kj {
|
||||
|
||||
CidrRange::CidrRange(StringPtr pattern) {
|
||||
size_t slashPos = KJ_REQUIRE_NONNULL(pattern.findFirst('/'), "invalid CIDR", pattern);
|
||||
|
||||
bitCount = pattern.slice(slashPos + 1).parseAs<uint>();
|
||||
|
||||
KJ_STACK_ARRAY(char, addr, slashPos + 1, 128, 128);
|
||||
memcpy(addr.begin(), pattern.begin(), slashPos);
|
||||
addr[slashPos] = '\0';
|
||||
|
||||
if (pattern.findFirst(':') == nullptr) {
|
||||
family = AF_INET;
|
||||
KJ_REQUIRE(bitCount <= 32, "invalid CIDR", pattern);
|
||||
} else {
|
||||
family = AF_INET6;
|
||||
KJ_REQUIRE(bitCount <= 128, "invalid CIDR", pattern);
|
||||
}
|
||||
|
||||
KJ_ASSERT(inet_pton(family, addr.begin(), bits) > 0, "invalid CIDR", pattern);
|
||||
zeroIrrelevantBits();
|
||||
}
|
||||
|
||||
CidrRange::CidrRange(int family, ArrayPtr<const byte> bits, uint bitCount)
|
||||
: family(family), bitCount(bitCount) {
|
||||
if (family == AF_INET) {
|
||||
KJ_REQUIRE(bitCount <= 32);
|
||||
} else {
|
||||
KJ_REQUIRE(bitCount <= 128);
|
||||
}
|
||||
KJ_REQUIRE(bits.size() * 8 >= bitCount);
|
||||
size_t byteCount = (bitCount + 7) / 8;
|
||||
memcpy(this->bits, bits.begin(), byteCount);
|
||||
memset(this->bits + byteCount, 0, sizeof(this->bits) - byteCount);
|
||||
|
||||
zeroIrrelevantBits();
|
||||
}
|
||||
|
||||
CidrRange CidrRange::inet4(ArrayPtr<const byte> bits, uint bitCount) {
|
||||
return CidrRange(AF_INET, bits, bitCount);
|
||||
}
|
||||
CidrRange CidrRange::inet6(
|
||||
ArrayPtr<const uint16_t> prefix, ArrayPtr<const uint16_t> suffix,
|
||||
uint bitCount) {
|
||||
KJ_REQUIRE(prefix.size() + suffix.size() <= 8);
|
||||
|
||||
byte bits[16] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, };
|
||||
|
||||
for (size_t i: kj::indices(prefix)) {
|
||||
bits[i * 2] = prefix[i] >> 8;
|
||||
bits[i * 2 + 1] = prefix[i] & 0xff;
|
||||
}
|
||||
|
||||
byte* suffixBits = bits + (16 - suffix.size() * 2);
|
||||
for (size_t i: kj::indices(suffix)) {
|
||||
suffixBits[i * 2] = suffix[i] >> 8;
|
||||
suffixBits[i * 2 + 1] = suffix[i] & 0xff;
|
||||
}
|
||||
|
||||
return CidrRange(AF_INET6, bits, bitCount);
|
||||
}
|
||||
|
||||
bool CidrRange::matches(const struct sockaddr* addr) const {
|
||||
const byte* otherBits;
|
||||
|
||||
switch (family) {
|
||||
case AF_INET:
|
||||
if (addr->sa_family == AF_INET6) {
|
||||
otherBits = reinterpret_cast<const struct sockaddr_in6*>(addr)->sin6_addr.s6_addr;
|
||||
static constexpr byte V6MAPPED[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
|
||||
if (memcmp(otherBits, V6MAPPED, sizeof(V6MAPPED)) == 0) {
|
||||
// We're an ipv4 range and the address is ipv6, but it's a "v6 mapped" address, meaning
|
||||
// it's equivalent to an ipv4 address. Try to match against the ipv4 part.
|
||||
otherBits = otherBits + sizeof(V6MAPPED);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else if (addr->sa_family == AF_INET) {
|
||||
otherBits = reinterpret_cast<const byte*>(
|
||||
&reinterpret_cast<const struct sockaddr_in*>(addr)->sin_addr.s_addr);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case AF_INET6:
|
||||
if (addr->sa_family != AF_INET6) return false;
|
||||
|
||||
otherBits = reinterpret_cast<const struct sockaddr_in6*>(addr)->sin6_addr.s6_addr;
|
||||
break;
|
||||
|
||||
default:
|
||||
KJ_UNREACHABLE;
|
||||
}
|
||||
|
||||
if (memcmp(bits, otherBits, bitCount / 8) != 0) return false;
|
||||
|
||||
return bitCount == 128 ||
|
||||
bits[bitCount / 8] == (otherBits[bitCount / 8] & (0xff00 >> (bitCount % 8)));
|
||||
}
|
||||
|
||||
bool CidrRange::matchesFamily(int family) const {
|
||||
switch (family) {
|
||||
case AF_INET:
|
||||
return this->family == AF_INET;
|
||||
case AF_INET6:
|
||||
// Even if we're a v4 CIDR, we can match v6 addresses in the v4-mapped range.
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
String CidrRange::toString() const {
|
||||
char result[128];
|
||||
KJ_ASSERT(inet_ntop(family, (void*)bits, result, sizeof(result)) == result);
|
||||
return kj::str(result, '/', bitCount);
|
||||
}
|
||||
|
||||
void CidrRange::zeroIrrelevantBits() {
|
||||
// Mask out insignificant bits of partial byte.
|
||||
if (bitCount < 128) {
|
||||
bits[bitCount / 8] &= 0xff00 >> (bitCount % 8);
|
||||
|
||||
// Zero the remaining bytes.
|
||||
size_t n = bitCount / 8 + 1;
|
||||
memset(bits + n, 0, sizeof(bits) - n);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace kj
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
|
||||
// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
|
||||
// Licensed under the MIT License:
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
#include <cstdint>
|
||||
|
||||
KJ_BEGIN_HEADER
|
||||
|
||||
struct sockaddr;
|
||||
|
||||
namespace kj {
|
||||
|
||||
class CidrRange {
|
||||
public:
|
||||
CidrRange(StringPtr pattern);
|
||||
|
||||
static CidrRange inet4(ArrayPtr<const byte> bits, uint bitCount);
|
||||
static CidrRange inet6(ArrayPtr<const uint16_t> prefix, ArrayPtr<const uint16_t> suffix,
|
||||
uint bitCount);
|
||||
// Zeros are inserted between `prefix` and `suffix` to extend the address to 128 bits.
|
||||
|
||||
uint getSpecificity() const { return bitCount; }
|
||||
|
||||
bool matches(const struct sockaddr* addr) const;
|
||||
bool matchesFamily(int family) const;
|
||||
|
||||
String toString() const;
|
||||
|
||||
private:
|
||||
int family;
|
||||
byte bits[16];
|
||||
uint bitCount; // how many bits in `bits` need to match
|
||||
|
||||
CidrRange(int family, ArrayPtr<const byte> bits, uint bitCount);
|
||||
|
||||
void zeroIrrelevantBits();
|
||||
};
|
||||
|
||||
} // namespace kj
|
||||
|
||||
KJ_END_HEADER
|
||||
|
|
@ -0,0 +1,321 @@
|
|||
// Copyright (c) 2014 Google Inc. (contributed by Remy Blank <rblank@google.com>)
|
||||
// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
|
||||
// Licensed under the MIT License:
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#if _WIN32
|
||||
#include "win32-api-version.h"
|
||||
#endif
|
||||
|
||||
#include "time.h"
|
||||
#include "debug.h"
|
||||
#include <set>
|
||||
|
||||
#if _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
namespace kj {
|
||||
|
||||
const Clock& nullClock() {
|
||||
class NullClock final: public Clock {
|
||||
public:
|
||||
Date now() const override { return UNIX_EPOCH; }
|
||||
};
|
||||
static KJ_CONSTEXPR(const) NullClock NULL_CLOCK = NullClock();
|
||||
return NULL_CLOCK;
|
||||
}
|
||||
|
||||
#if _WIN32
|
||||
|
||||
namespace {
|
||||
|
||||
static constexpr int64_t WIN32_EPOCH_OFFSET = 116444736000000000ull;
|
||||
// Number of 100ns intervals from Jan 1, 1601 to Jan 1, 1970.
|
||||
|
||||
static Date toKjDate(FILETIME t) {
|
||||
int64_t value = (static_cast<uint64_t>(t.dwHighDateTime) << 32) | t.dwLowDateTime;
|
||||
return (value - WIN32_EPOCH_OFFSET) * (100 * kj::NANOSECONDS) + UNIX_EPOCH;
|
||||
}
|
||||
|
||||
class Win32CoarseClock: public Clock {
|
||||
public:
|
||||
Date now() const override {
|
||||
FILETIME ft;
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
return toKjDate(ft);
|
||||
}
|
||||
};
|
||||
|
||||
class Win32PreciseClock: public Clock {
|
||||
typedef VOID WINAPI GetSystemTimePreciseAsFileTimeFunc(LPFILETIME);
|
||||
public:
|
||||
Date now() const override {
|
||||
static GetSystemTimePreciseAsFileTimeFunc* const getSystemTimePreciseAsFileTimePtr =
|
||||
getGetSystemTimePreciseAsFileTime();
|
||||
FILETIME ft;
|
||||
if (getSystemTimePreciseAsFileTimePtr == nullptr) {
|
||||
// We can't use QueryPerformanceCounter() to get any more precision because we have no way
|
||||
// of knowing when the calendar clock jumps. So I guess we're stuck.
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
} else {
|
||||
getSystemTimePreciseAsFileTimePtr(&ft);
|
||||
}
|
||||
return toKjDate(ft);
|
||||
}
|
||||
|
||||
private:
|
||||
static GetSystemTimePreciseAsFileTimeFunc* getGetSystemTimePreciseAsFileTime() {
|
||||
// Dynamically look up the function GetSystemTimePreciseAsFileTimeFunc(). This was only
|
||||
// introduced as of Windows 8, so it might be missing.
|
||||
#if __GNUC__ && !__clang__ && __GNUC__ >= 8
|
||||
// GCC 8 warns that our reinterpret_cast of a function pointer below is casting between
|
||||
// incompatible types. Yes, GCC, we know that. This is the nature of GetProcAddress(); it returns
|
||||
// everything as `long long int (*)()` and we have to cast to the actual type.
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
#endif
|
||||
return reinterpret_cast<GetSystemTimePreciseAsFileTimeFunc*>(GetProcAddress(
|
||||
GetModuleHandleA("kernel32.dll"),
|
||||
"GetSystemTimePreciseAsFileTime"));
|
||||
}
|
||||
};
|
||||
|
||||
class Win32CoarseMonotonicClock: public MonotonicClock {
|
||||
public:
|
||||
TimePoint now() const override {
|
||||
return kj::origin<TimePoint>() + GetTickCount64() * kj::MILLISECONDS;
|
||||
}
|
||||
};
|
||||
|
||||
class Win32PreciseMonotonicClock: public MonotonicClock {
|
||||
// Precise clock implemented using QueryPerformanceCounter().
|
||||
//
|
||||
// TODO(someday): Windows 10 has QueryUnbiasedInterruptTime() and
|
||||
// QueryUnbiasedInterruptTimePrecise(), a new API for monotonic timing that isn't as difficult.
|
||||
// Is there any benefit to dynamically checking for these and using them if available?
|
||||
|
||||
public:
|
||||
TimePoint now() const override {
|
||||
static const QpcProperties props;
|
||||
|
||||
LARGE_INTEGER now;
|
||||
QueryPerformanceCounter(&now);
|
||||
uint64_t adjusted = now.QuadPart - props.origin;
|
||||
uint64_t ns = mulDiv64(adjusted, 1'000'000'000, props.frequency);
|
||||
return kj::origin<TimePoint>() + ns * kj::NANOSECONDS;
|
||||
}
|
||||
|
||||
private:
|
||||
struct QpcProperties {
|
||||
uint64_t origin;
|
||||
// What QueryPerformanceCounter() would have returned at the time when GetTickCount64() returned
|
||||
// zero. Used to ensure that the coarse and precise timers return similar values.
|
||||
|
||||
uint64_t frequency;
|
||||
// From QueryPerformanceFrequency().
|
||||
|
||||
QpcProperties() {
|
||||
LARGE_INTEGER now, freqLi;
|
||||
uint64_t ticks = GetTickCount64();
|
||||
QueryPerformanceCounter(&now);
|
||||
|
||||
QueryPerformanceFrequency(&freqLi);
|
||||
frequency = freqLi.QuadPart;
|
||||
|
||||
// Convert the millisecond tick count into performance counter ticks.
|
||||
uint64_t ticksAsQpc = mulDiv64(ticks, freqLi.QuadPart, 1000);
|
||||
|
||||
origin = now.QuadPart - ticksAsQpc;
|
||||
}
|
||||
};
|
||||
|
||||
static inline uint64_t mulDiv64(uint64_t value, uint64_t numer, uint64_t denom) {
|
||||
// Inspired by:
|
||||
// https://github.com/rust-lang/rust/pull/22788/files#diff-24f054cd23f65af3b574c6ce8aa5a837R54
|
||||
// Computes (value*numer)/denom without overflow, as long as both
|
||||
// (numer*denom) and the overall result fit into 64 bits.
|
||||
uint64_t q = value / denom;
|
||||
uint64_t r = value % denom;
|
||||
return q * numer + r * numer / denom;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
const Clock& systemCoarseCalendarClock() {
|
||||
static constexpr Win32CoarseClock clock;
|
||||
return clock;
|
||||
}
|
||||
const Clock& systemPreciseCalendarClock() {
|
||||
static constexpr Win32PreciseClock clock;
|
||||
return clock;
|
||||
}
|
||||
|
||||
const MonotonicClock& systemCoarseMonotonicClock() {
|
||||
static constexpr Win32CoarseMonotonicClock clock;
|
||||
return clock;
|
||||
}
|
||||
const MonotonicClock& systemPreciseMonotonicClock() {
|
||||
static constexpr Win32PreciseMonotonicClock clock;
|
||||
return clock;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
namespace {
|
||||
|
||||
class PosixClock: public Clock {
|
||||
public:
|
||||
constexpr PosixClock(clockid_t clockId): clockId(clockId) {}
|
||||
|
||||
Date now() const override {
|
||||
struct timespec ts;
|
||||
KJ_SYSCALL(clock_gettime(clockId, &ts));
|
||||
return UNIX_EPOCH + ts.tv_sec * kj::SECONDS + ts.tv_nsec * kj::NANOSECONDS;
|
||||
}
|
||||
|
||||
private:
|
||||
clockid_t clockId;
|
||||
};
|
||||
|
||||
class PosixMonotonicClock: public MonotonicClock {
|
||||
public:
|
||||
constexpr PosixMonotonicClock(clockid_t clockId): clockId(clockId) {}
|
||||
|
||||
TimePoint now() const override {
|
||||
struct timespec ts;
|
||||
KJ_SYSCALL(clock_gettime(clockId, &ts));
|
||||
return kj::origin<TimePoint>() + ts.tv_sec * kj::SECONDS + ts.tv_nsec * kj::NANOSECONDS;
|
||||
}
|
||||
|
||||
private:
|
||||
clockid_t clockId;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
// FreeBSD has "_PRECISE", but Linux just defaults to precise.
|
||||
#ifndef CLOCK_REALTIME_PRECISE
|
||||
#define CLOCK_REALTIME_PRECISE CLOCK_REALTIME
|
||||
#endif
|
||||
|
||||
#ifndef CLOCK_MONOTONIC_PRECISE
|
||||
#define CLOCK_MONOTONIC_PRECISE CLOCK_MONOTONIC
|
||||
#endif
|
||||
|
||||
// FreeBSD has "_FAST", Linux has "_COARSE".
|
||||
// MacOS has an "_APPROX" but only for CLOCK_MONOTONIC_RAW, which isn't helpful.
|
||||
#ifndef CLOCK_REALTIME_COARSE
|
||||
#ifdef CLOCK_REALTIME_FAST
|
||||
#define CLOCK_REALTIME_COARSE CLOCK_REALTIME_FAST
|
||||
#else
|
||||
#define CLOCK_REALTIME_COARSE CLOCK_REALTIME
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CLOCK_MONOTONIC_COARSE
|
||||
#ifdef CLOCK_MONOTONIC_FAST
|
||||
#define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC_FAST
|
||||
#else
|
||||
#define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
const Clock& systemCoarseCalendarClock() {
|
||||
static constexpr PosixClock clock(CLOCK_REALTIME_COARSE);
|
||||
return clock;
|
||||
}
|
||||
const Clock& systemPreciseCalendarClock() {
|
||||
static constexpr PosixClock clock(CLOCK_REALTIME_PRECISE);
|
||||
return clock;
|
||||
}
|
||||
|
||||
const MonotonicClock& systemCoarseMonotonicClock() {
|
||||
static constexpr PosixMonotonicClock clock(CLOCK_MONOTONIC_COARSE);
|
||||
return clock;
|
||||
}
|
||||
const MonotonicClock& systemPreciseMonotonicClock() {
|
||||
static constexpr PosixMonotonicClock clock(CLOCK_MONOTONIC_PRECISE);
|
||||
return clock;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
CappedArray<char, _::TIME_STR_LEN> KJ_STRINGIFY(TimePoint t) {
|
||||
return kj::toCharSequence(t - kj::origin<TimePoint>());
|
||||
}
|
||||
CappedArray<char, _::TIME_STR_LEN> KJ_STRINGIFY(Date d) {
|
||||
return kj::toCharSequence(d - UNIX_EPOCH);
|
||||
}
|
||||
CappedArray<char, _::TIME_STR_LEN> KJ_STRINGIFY(Duration d) {
|
||||
bool negative = d < 0 * kj::SECONDS;
|
||||
uint64_t ns = d / kj::NANOSECONDS;
|
||||
if (negative) {
|
||||
ns = -ns;
|
||||
}
|
||||
|
||||
auto digits = kj::toCharSequence(ns);
|
||||
ArrayPtr<char> arr = digits;
|
||||
|
||||
size_t point;
|
||||
kj::StringPtr suffix;
|
||||
kj::Duration unit;
|
||||
if (digits.size() > 9) {
|
||||
point = arr.size() - 9;
|
||||
suffix = "s";
|
||||
unit = kj::SECONDS;
|
||||
} else if (digits.size() > 6) {
|
||||
point = arr.size() - 6;
|
||||
suffix = "ms";
|
||||
unit = kj::MILLISECONDS;
|
||||
} else if (digits.size() > 3) {
|
||||
point = arr.size() - 3;
|
||||
suffix = "μs";
|
||||
unit = kj::MICROSECONDS;
|
||||
} else {
|
||||
point = arr.size();
|
||||
suffix = "ns";
|
||||
unit = kj::NANOSECONDS;
|
||||
}
|
||||
|
||||
CappedArray<char, _::TIME_STR_LEN> result;
|
||||
char* begin = result.begin();
|
||||
char* end;
|
||||
if (negative) {
|
||||
*begin++ = '-';
|
||||
}
|
||||
if (d % unit == 0 * kj::NANOSECONDS) {
|
||||
end = _::fillLimited(begin, result.end(), arr.slice(0, point), suffix);
|
||||
} else {
|
||||
while (arr.back() == '0') {
|
||||
arr = arr.slice(0, arr.size() - 1);
|
||||
}
|
||||
KJ_DASSERT(arr.size() > point);
|
||||
end = _::fillLimited(begin, result.end(), arr.slice(0, point), "."_kj,
|
||||
arr.slice(point, arr.size()), suffix);
|
||||
}
|
||||
result.setSize(end - result.begin());
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace kj
|
||||
Loading…
Reference in New Issue