test: add chrono.

This commit is contained in:
Leo Yuriev 2017-04-11 19:00:26 +03:00
parent 2a80ad67fb
commit 8b42b8bfd4
5 changed files with 174 additions and 0 deletions

View File

@ -22,6 +22,8 @@ src/tools/mdbx_stat.1
src/tools/mdbx_stat.c
test/actor.cc
test/base.h
test/chrono.cc
test/chrono.h
test/config.h
test/dead.cc
test/hill.cc

View File

@ -34,6 +34,12 @@
#include <string.h>
#include <time.h>
#if defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS)
#else
#include <sys/param.h>
#include <sys/time.h>
#endif
#ifdef _BSD_SOURCE
#include <endian.h>
#endif

90
test/chrono.cc Normal file
View File

@ -0,0 +1,90 @@
/*
* Copyright 2017 Leonid Yuriev <leo@yuriev.ru>
* and other libmdbx authors: please see AUTHORS file.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted only as authorized by the OpenLDAP
* Public License.
*
* A copy of this license is available in the file LICENSE in the
* top-level directory of the distribution or, alternatively, at
* <http://www.OpenLDAP.org/license.html>.
*/
#include "test.h"
namespace chrono {
#define NSEC_PER_SEC 1000000000u
uint32_t ns2fractional(uint32_t ns) {
assert(ns < NSEC_PER_SEC);
/* LY: здесь и далее используется "длинное деление", которое
* для ясности кода оставлено как есть (без ручной оптимизации). Так как
* GCC, Clang и даже MSVC сами давно умеют конвертировать деление на
* константу в быструю reciprocal-форму. */
return ((uint64_t)ns << 32) / NSEC_PER_SEC;
}
uint32_t fractional2ns(uint32_t fractional) {
return (fractional * (uint64_t)NSEC_PER_SEC) >> 32;
}
#define USEC_PER_SEC 1000000u
uint32_t us2fractional(uint32_t us) {
assert(us < USEC_PER_SEC);
return ((uint64_t)us << 32) / USEC_PER_SEC;
}
uint32_t fractional2us(uint32_t fractional) {
return (fractional * (uint64_t)USEC_PER_SEC) >> 32;
}
#define MSEC_PER_SEC 1000u
uint32_t ms2fractional(uint32_t ms) {
assert(ms < MSEC_PER_SEC);
return ((uint64_t)ms << 32) / MSEC_PER_SEC;
}
uint32_t fractional2ms(uint32_t fractional) {
return (fractional * (uint64_t)MSEC_PER_SEC) >> 32;
}
time from_ns(uint64_t ns) {
time result;
result.fixedpoint = ((ns / NSEC_PER_SEC) << 32) |
ns2fractional((uint32_t)(ns % NSEC_PER_SEC));
return result;
}
time from_us(uint64_t us) {
time result;
result.fixedpoint = ((us / USEC_PER_SEC) << 32) |
us2fractional((uint32_t)(us % USEC_PER_SEC));
return result;
}
time from_ms(uint64_t ms) {
time result;
result.fixedpoint = ((ms / MSEC_PER_SEC) << 32) |
ms2fractional((uint32_t)(ms % MSEC_PER_SEC));
return result;
}
time now() {
#if defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS)
FILETIME filetime;
GetSystemTimeAsFileTime(&filetime);
uint64_t ns =
(uint64_t)filetime.dwHighDateTime << 32 | filetime.dwLowDateTime;
return from_ns(ns);
#else
struct timespec ts;
if (unlikely(clock_gettime(CLOCK_REALTIME, &ts)))
failure_perror("clock_gettime(CLOCK_REALTIME", errno);
return from_timespec(ts);
#endif
}
} /* namespace chrono */

75
test/chrono.h Normal file
View File

@ -0,0 +1,75 @@
/*
* Copyright 2017 Leonid Yuriev <leo@yuriev.ru>
* and other libmdbx authors: please see AUTHORS file.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted only as authorized by the OpenLDAP
* Public License.
*
* A copy of this license is available in the file LICENSE in the
* top-level directory of the distribution or, alternatively, at
* <http://www.OpenLDAP.org/license.html>.
*/
#pragma once
#include "base.h"
#include "log.h"
#include "utils.h"
namespace chrono {
typedef union time {
uint64_t fixedpoint;
struct __packed {
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
uint32_t fractional;
uint32_t utc;
#else
uint32_t utc;
uint32_t fractional;
#endif
};
} time;
uint32_t ns2fractional(uint32_t);
uint32_t fractional2ns(uint32_t);
uint32_t us2fractional(uint32_t);
uint32_t fractional2us(uint32_t);
uint32_t ms2fractional(uint32_t);
uint32_t fractional2ms(uint32_t);
time from_ns(uint64_t us);
time from_us(uint64_t ns);
time from_ms(uint64_t ms);
inline time from_utc(time_t utc) {
assert(utc < UINT32_MAX);
time result;
result.fixedpoint = ((uint64_t)utc) << 32;
return result;
}
#if defined(HAVE_TIMESPEC_TV_NSEC) || defined(__timespec_defined) || \
defined(CLOCK_REALTIME)
inline time from_timespec(const struct timespec &ts) {
time result;
result.fixedpoint =
((uint64_t)ts.tv_sec << 32) | ns2fractional((uint32_t)ts.tv_nsec);
return result;
}
#endif /* HAVE_TIMESPEC_TV_NSEC */
#if defined(HAVE_TIMEVAL_TV_USEC) || defined(_STRUCT_TIMEVAL)
inline time from_timeval(const struct timeval &tv) {
time result;
result.fixedpoint =
((uint64_t)tv.tv_sec << 32) | us2fractional((uint32_t)tv.tv_usec);
return result;
}
#endif /* HAVE_TIMEVAL_TV_USEC */
time now();
} /* namespace chrono */

View File

@ -15,6 +15,7 @@
#pragma once
#include "base.h"
#include "chrono.h"
#include "config.h"
#include "keygen.h"
#include "log.h"