#ifndef _BENCH_H_
#define _BENCH_H_
#include "db_config.h"
#include "db_int.h"
#if DB_VERSION_MAJOR < 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 5
#ifdef DB_WIN32
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
#include <direct.h>
#include <sys/timeb.h>
#else
#include <sys/stat.h>
#include <sys/time.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#endif
#endif
#define TESTDIR "TESTDIR"
#define TESTFILE "test_micro.db"
#define DB_BENCH_ASSERT(e) do { \
(e) ? (void)0 : \
(fprintf(stderr, \
"assert failure: %s/%d: \"%s\"\n", __FILE__, __LINE__, #e), \
b_util_abort()); \
} while (0)
#ifndef NS_PER_SEC
#define NS_PER_SEC 1000000000
#endif
#ifndef NS_PER_US
#define NS_PER_US 1000
#endif
#ifndef MS_PER_NS
#define MS_PER_NS 1000000
#endif
#ifdef DB_TIMEOUT_TO_TIMESPEC
#ifdef HAVE_GETRUSAGE
#include <sys/resource.h>
#define SET_TIMER_FROM_GETRUSAGE(tp) do { \
struct rusage __usage; \
DB_BENCH_ASSERT(getrusage(RUSAGE_SELF, &__usage) == 0); \
(tp)->tv_sec = \
__usage.ru_utime.tv_sec + __usage.ru_stime.tv_sec; \
(tp)->tv_nsec = NS_PER_US * \
(__usage.ru_utime.tv_usec + __usage.ru_stime.tv_usec); \
} while (0);
#define TIMER_START SET_TIMER_FROM_GETRUSAGE(&__start_time);
#define TIMER_STOP SET_TIMER_FROM_GETRUSAGE(&__end_time);
#elif defined(DB_WIN32) && !defined(DB_WINCE)
#define SET_TIMER_FROM_GETPROCESSTIMES(tp) do { \
FILETIME lpCreationTime, lpExitTime, lpKernelTime, lpUserTIme; \
LARGE_INTEGER large_int; \
LONGLONG __ns_since_epoch; \
DB_BENCH_ASSERT( \
GetProcessTimes(GetCurrentProcess(), &lpCreationTime, \
&lpExitTime, &lpKernelTime, &lpUserTIme) != 0); \
memcpy(&large_int, &lpKernelTime, sizeof(lpKernelTime)); \
__ns_since_epoch = (large_int.QuadPart * 100); \
(tp)->tv_sec = (time_t)(__ns_since_epoch / NS_PER_SEC); \
(tp)->tv_nsec = (long)(__ns_since_epoch % NS_PER_SEC); \
memcpy(&large_int, &lpUserTIme, sizeof(lpUserTIme)); \
__ns_since_epoch = (large_int.QuadPart * 100); \
(tp)->tv_sec += (time_t)(__ns_since_epoch / NS_PER_SEC); \
(tp)->tv_nsec += (long)(__ns_since_epoch % NS_PER_SEC); \
} while (0);
#define TIMER_START SET_TIMER_FROM_GETPROCESSTIMES(&__start_time);
#define TIMER_STOP SET_TIMER_FROM_GETPROCESSTIMES(&__end_time);
#else
#if DB_VERSION_MAJOR > 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 6
#define TIMER_START __os_gettime(NULL, &__start_time, 1)
#define TIMER_STOP __os_gettime(NULL, &__end_time, 1)
#else
#define TIMER_START __os_gettime(NULL, &__start_time)
#define TIMER_STOP __os_gettime(NULL, &__end_time)
#endif
#endif
#else
#if defined(HAVE_CLOCK_GETTIME)
typedef struct timespec db_timespec;
#else
typedef struct {
time_t tv_sec;
long tv_nsec;
} db_timespec;
#endif
#define timespecadd(vvp, uvp) \
do { \
(vvp)->tv_sec += (uvp)->tv_sec; \
(vvp)->tv_nsec += (uvp)->tv_nsec; \
if ((vvp)->tv_nsec >= NS_PER_SEC) { \
(vvp)->tv_sec++; \
(vvp)->tv_nsec -= NS_PER_SEC; \
} \
} while (0)
#define timespecsub(vvp, uvp) \
do { \
(vvp)->tv_sec -= (uvp)->tv_sec; \
(vvp)->tv_nsec -= (uvp)->tv_nsec; \
if ((vvp)->tv_nsec < 0) { \
(vvp)->tv_sec--; \
(vvp)->tv_nsec += NS_PER_SEC; \
} \
} while (0)
#define TIMER_START CLOCK(__start_time)
#define TIMER_STOP CLOCK(__end_time)
#if defined(HAVE_CLOCK_GETTIME)
#define CLOCK(tm) do { \
DB_BENCH_ASSERT(clock_gettime( \
CLOCK_REALTIME, (struct timespec *)&(tm)) == 0); \
} while (0)
#elif defined(DB_WIN32)
#define CLOCK(tm) do { \
struct _timeb __now; \
_ftime(&__now); \
(tm).tv_sec = __now.time; \
(tm).tv_nsec = __now.millitm * MS_PER_NS; \
} while (0)
#else
#define CLOCK(tm) do { \
struct timeval __tp; \
DB_BENCH_ASSERT(gettimeofday(&__tp, NULL) == 0); \
(tm).tv_sec = __tp.tv_sec; \
(tm).tv_nsec = __tp.tv_usec * NS_PER_US; \
} while (0)
#endif
#endif
db_timespec __start_time, __end_time;
#define TIMER_GET(tm) do { \
tm = __end_time; \
timespecsub(&(tm), &__start_time); \
} while (0)
#define TIMER_DISPLAY(ops) do { \
db_timespec __tmp_time; \
__tmp_time = __end_time; \
timespecsub(&__tmp_time, &__start_time); \
TIME_DISPLAY(ops, __tmp_time); \
} while (0)
#define TIME_DISPLAY(ops, tm) do { \
double __secs; \
int __major, __minor, __patch; \
__secs = (tm).tv_sec + (double)(tm).tv_nsec / NS_PER_SEC; \
(void)db_version(&__major, &__minor, &__patch); \
printf("%d.%d.%d\t%.2f\n", __major, __minor, __patch, \
(__secs == 0) ? 0.0 : (ops) / __secs); \
} while (0)
extern char *progname;
int b_curalloc __P((int, char *[]));
int b_curwalk __P((int, char *[]));
int b_del __P((int, char *[]));
int b_get __P((int, char *[]));
int b_inmem __P((int, char *[]));
int b_load __P((int, char *[]));
int b_open __P((int, char *[]));
int b_put __P((int, char *[]));
int b_recover __P((int, char *[]));
int b_txn __P((int, char *[]));
int b_txn_write __P((int, char *[]));
int b_uname __P((void));
void b_util_abort __P((void));
int b_util_dir_setup __P((void));
int b_util_dir_teardown __P((void));
int b_util_have_hash __P((void));
int b_util_have_queue __P((void));
int b_util_unlink __P((char *));
int b_workload __P((int, char *[]));
#endif