Files
ternfs-XTXMarkets/cpp/core/Time.cpp
2023-07-11 12:13:22 +00:00

67 lines
2.0 KiB
C++

// #include <bits/types/struct_timespec.h>
#include <cstdio>
#include <time.h>
#include <chrono>
#include <thread>
#include "Exception.hpp"
#include "Time.hpp"
#include "Assert.hpp"
std::ostream& operator<<(std::ostream& out, Duration d) {
if (d.ns < 1'000) {
out << d.ns << "ns";
} else if (d.ns < 1'000'000) {
out << d.ns/1'000 << "." << d.ns%1'000 << "us";
} else if (d.ns < 1'000'000'000) {
out << d.ns/1'000'000 << "." << d.ns%1'000'000 << "ms";
} else if (d.ns < 1'000'000'000ull*60) {
out << d.ns/1'000'000'000 << "." << d.ns%1'000'000'000 << "s";
} else if (d.ns < 1'000'000'000ull*60*60) {
out << d.ns/(1'000'000'000ull*60) << "." << d.ns%(1'000'000'000ull*60) << "m";
} else {
out << d.ns/(1'000'000'000ull*60*60) << "." << d.ns%(1'000'000'000ull*60*60) << "h";
}
return out;
}
__attribute__((constructor))
static void checkClockRes() {
struct timespec ts;
if (clock_getres(CLOCK_REALTIME, &ts) != 0) {
throw SYSCALL_EXCEPTION("clock_getres");
}
if (ts.tv_sec != 0 || ts.tv_nsec != 1) {
throw EGGS_EXCEPTION("expected nanosecond precisions, got %s,%s", ts.tv_sec, ts.tv_nsec);
}
}
EggsTime eggsNow() {
struct timespec now;
if (clock_gettime(CLOCK_REALTIME, &now) != 0) {
throw SYSCALL_EXCEPTION("clock_gettime");
}
return EggsTime(((uint64_t)now.tv_nsec + ((uint64_t)now.tv_sec * 1'000'000'000ull)));
}
std::ostream& operator<<(std::ostream& out, EggsTime eggst) {
time_t secs = eggst.ns / 1'000'000'000ull;
uint64_t nsecs = eggst.ns % 1'000'000'000ull;
struct tm tm;
if (gmtime_r(&secs, &tm) == nullptr) {
throw SYSCALL_EXCEPTION("gmtime_r");
}
// "2006-01-02T15:04:05.999999999"
char buf[31];
ALWAYS_ASSERT(strftime(buf, 29, "%Y-%m-%dT%H:%M:%S.", &tm) == 20);
ALWAYS_ASSERT(snprintf(buf+20, 10, "%09lu", nsecs) == 9);
buf[30] = '\0';
out << buf;
return out;
}
void sleepFor(Duration dt) {
std::this_thread::sleep_for(std::chrono::nanoseconds(dt.ns));
}