Move Monoclock and strerror out of drvutil

This commit is contained in:
2023-05-25 20:21:27 -04:00
parent 7e25be10a4
commit b10b9a8b5b
8 changed files with 143 additions and 109 deletions

View File

@@ -101,6 +101,7 @@ OBJ_CORE=\
OBJ_DRV=\
obj/$(OS)/drv/driver.obj\
obj/$(OS)/drv/drvutil.obj\
obj/$(OS)/drv/osdrvutil.obj\
obj/$(OS)/drv/sslutil.obj\
obj/$(OS)/drv/readline.obj\

View File

@@ -1,6 +1,7 @@
#include "drvutil.hpp"
#include "osdrvutil.hpp"
#include "sslutil.hpp"
#include "readline.hpp"
#include "../core/enginewrapper.hpp"

View File

@@ -2,6 +2,7 @@
#define _WIN32_WINNT 0x0600
#include "drvutil.hpp"
#include "osdrvutil.hpp"
#include "sslutil.hpp"
#include "readline.hpp"
#include "../core/enginewrapper.hpp"

View File

@@ -3,20 +3,11 @@
#include <string_view>
#include <vector>
#include <cassert>
#include <sstream>
#include <fstream>
#include <string.h>
#include <iostream>
#include <filesystem>
#if defined(_WIN32)
#include <windows.h>
#include <profileapi.h>
#elif defined(__linux__)
#include <time.h>
#endif
namespace drvutil {
@@ -300,103 +291,5 @@ std::string package_lua_source(const std::filesystem::path &base, std::ostream *
return "";
}
// strerror has to be the most overcomplicated function imaginable. The simple
// version, 'strerror', is not thread-safe, and the improved versions are all
// incompatible from OS to OS. Even different versions of linux aren't
// compatible. A lot of conditional compilation is needed.
#if defined(__linux__)
inline static void strerror_helper(int status, int errnum, char errbuf[256]) {
if (status != 0) {
snprintf(errbuf, 256, "unknown errno %d", errnum);
}
}
inline static void strerror_helper(const char *result, int errnum, char errbuf[256]) {
if (result != errbuf) {
snprintf(errbuf, 256, "%s", result);
}
}
void strerror_safe(int errnum, char errbuf[256]) {
auto rval = strerror_r(errnum, errbuf, 256);
strerror_helper(rval, errnum, errbuf);
}
#elif defined(_WIN32)
void strerror_safe(int errnum, char errbuf[256]) {
int status = strerror_s(errbuf, 256, errnum);
if (status != 0) {
snprintf(errbuf, 256, "unknown errno %d", errnum);
}
}
#endif
std::string strerror_str(int errnum) {
char buf[256];
strerror_safe(errnum, buf);
return buf;
}
// The monotonic clock is required to start at zero at initialization time,
// advance steadily, and never go backwards. It is okay, however, if it is a
// little inaccurate, or if it drifts a little over time.
#if defined(__linux__)
class MonoClock {
private:
struct timespec base_;
public:
MonoClock() {
int status = clock_gettime(CLOCK_MONOTONIC, &base_);
assert(status == 0);
}
double get() {
struct timespec t;
int status = clock_gettime(CLOCK_MONOTONIC, &t);
assert(status == 0);
double tv_sec = t.tv_sec - base_.tv_sec;
double tv_nsec = t.tv_nsec - base_.tv_nsec;
return tv_sec + (tv_nsec * 1.0E-9);
}
};
#elif defined(_WIN32)
class MonoClock {
public:
double freq_;
LONGLONG base_;
inline LONGLONG qpc() {
LARGE_INTEGER x;
BOOL status = QueryPerformanceCounter(&x);
assert(status != 0);
return x.QuadPart;
}
MonoClock() {
LARGE_INTEGER x;
BOOL status = QueryPerformanceFrequency(&x);
assert(status != 0);
freq_ = 1.0 / double(x.QuadPart);
base_ = qpc();
}
double get() {
return (qpc() - base_) * freq_;
}
};
#else
#error "Only support __linux__ or _WIN32"
#endif
static MonoClock monoclock;
double get_monotonic_clock() {
return monoclock.get();
}
} // namespace drv

View File

@@ -0,0 +1,116 @@
#include "osdrvutil.hpp"
#if defined(__linux__)
#include <time.h>
#elif defined(_WIN32)
#include <windows.h>
#include <profileapi.h>
#else
#error "Only support __linux__ or _WIN32"
#endif
#include <string>
#include <cstring>
#include <cassert>
#include <cstdio>
// strerror has to be the most overcomplicated function imaginable. The simple
// version, 'strerror', is not thread-safe, and the improved versions are all
// incompatible from OS to OS. Even different versions of linux aren't
// compatible. A lot of conditional compilation is needed.
#if defined(__linux__)
inline static void strerror_helper(int status, int errnum, char errbuf[256]) {
if (status != 0) {
snprintf(errbuf, 256, "unknown errno %d", errnum);
}
}
inline static void strerror_helper(const char *result, int errnum, char errbuf[256]) {
if (result != errbuf) {
snprintf(errbuf, 256, "%s", result);
}
}
static void strerror_safe(int errnum, char errbuf[256]) {
auto rval = strerror_r(errnum, errbuf, 256);
strerror_helper(rval, errnum, errbuf);
}
#elif defined(_WIN32)
static void strerror_safe(int errnum, char errbuf[256]) {
int status = strerror_s(errbuf, 256, errnum);
if (status != 0) {
snprintf(errbuf, 256, "unknown errno %d", errnum);
}
}
#endif
// The monotonic clock is required to start at zero at initialization time,
// advance steadily, and never go backwards. It is okay, however, if it is a
// little inaccurate, or if it drifts a little over time.
#if defined(__linux__)
class MonoClock {
private:
struct timespec base_;
public:
MonoClock() {
int status = clock_gettime(CLOCK_MONOTONIC, &base_);
assert(status == 0);
}
double get() {
struct timespec t;
int status = clock_gettime(CLOCK_MONOTONIC, &t);
assert(status == 0);
double tv_sec = t.tv_sec - base_.tv_sec;
double tv_nsec = t.tv_nsec - base_.tv_nsec;
return tv_sec + (tv_nsec * 1.0E-9);
}
};
#elif defined(_WIN32)
class MonoClock {
public:
double freq_;
LONGLONG base_;
inline LONGLONG qpc() {
LARGE_INTEGER x;
BOOL status = QueryPerformanceCounter(&x);
assert(status != 0);
return x.QuadPart;
}
MonoClock() {
LARGE_INTEGER x;
BOOL status = QueryPerformanceFrequency(&x);
assert(status != 0);
freq_ = 1.0 / double(x.QuadPart);
base_ = qpc();
}
double get() {
return (qpc() - base_) * freq_;
}
};
#endif
namespace drvutil {
static MonoClock monoclock;
double get_monotonic_clock() {
return monoclock.get();
}
std::string strerror_str(int errnum) {
char buf[256];
strerror_safe(errnum, buf);
return buf;
}
} // namespace drvutil

View File

@@ -0,0 +1,23 @@
#ifndef OSDRVUTIL_HPP
#define OSDRVUTIL_HPP
#include <string>
namespace drvutil {
// Get a system error message, in an OS-independent manner.
//
std::string strerror_str(int errnum);
// Get the amount of time elapsed since program start.
//
// This is guaranteed to be monotonically increasing. It is not
// guaranteed to be accurate. Error could gradually accumulate over
// time.
//
double get_monotonic_clock();
} // namespace drvutil
#endif // OSDRVUTIL_HPP

View File

@@ -1,4 +1,5 @@
#include "drvutil.hpp"
#include "osdrvutil.hpp"
#include "sslutil.hpp"
#include <iostream>
#include <cassert>

View File

@@ -1,8 +1,6 @@
#ifndef SSLUTIL_HPP
#define SSLUTIL_HPP
#include "drvutil.hpp"
#include <openssl/ssl.h>
#include <openssl/rsa.h>
#include <openssl/x509.h>