1/* 2 * $Id: bench.h,v 1.24 2008/02/04 14:13:05 bostic Exp $ 3 */ 4#ifndef _BENCH_H_ 5#define _BENCH_H_ 6#include "db_config.h" 7 8#include "db_int.h" 9 10#if DB_VERSION_MAJOR < 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 5 11/* 12 * Older releases of Berkeley DB don't include standard include files in 13 * db_int.h. 14 */ 15#ifdef DB_WIN32 16#define WIN32_LEAN_AND_MEAN 1 17#include <windows.h> 18#include <direct.h> 19#include <sys/timeb.h> 20#else 21#include <sys/stat.h> 22#include <sys/time.h> 23 24#include <limits.h> 25#include <stdlib.h> 26#include <string.h> 27#include <unistd.h> 28#endif 29#endif 30 31#define TESTDIR "TESTDIR" 32#define TESTFILE "test_micro.db" 33 34/* 35 * Implement a custom assert to allow consistent behavior across builds and 36 * platforms. 37 * 38 * The BDB library DB_ASSERT implementation is only enabled in diagnostic 39 * builds -- so is not suitable here. 40 */ 41#define DB_BENCH_ASSERT(e) do { \ 42 (e) ? (void)0 : \ 43 (fprintf(stderr, \ 44 "assert failure: %s/%d: \"%s\"\n", __FILE__, __LINE__, #e), \ 45 b_util_abort()); \ 46} while (0) 47 48#ifndef NS_PER_SEC 49#define NS_PER_SEC 1000000000 /* Nanoseconds in a second */ 50#endif 51#ifndef NS_PER_US 52#define NS_PER_US 1000 /* Nanoseconds in a microsecond */ 53#endif 54#ifndef MS_PER_NS 55#define MS_PER_NS 1000000 /* Milliseconds in a nanosecond */ 56#endif 57 58#ifdef DB_TIMEOUT_TO_TIMESPEC 59/* 60 * We have the timer routines in the Berkeley DB library after their conversion 61 * to the POSIX timespec interfaces. We'd rather use something that gives us 62 * better information than elapsed wallclock time, so use getrusage instead if 63 * it's available. 64 */ 65#ifdef HAVE_GETRUSAGE 66#include <sys/resource.h> 67 68#define SET_TIMER_FROM_GETRUSAGE(tp) do { \ 69 struct rusage __usage; \ 70 DB_BENCH_ASSERT(getrusage(RUSAGE_SELF, &__usage) == 0); \ 71 (tp)->tv_sec = \ 72 __usage.ru_utime.tv_sec + __usage.ru_stime.tv_sec; \ 73 (tp)->tv_nsec = NS_PER_US * \ 74 (__usage.ru_utime.tv_usec + __usage.ru_stime.tv_usec); \ 75} while (0); 76 77#define TIMER_START SET_TIMER_FROM_GETRUSAGE(&__start_time); 78#define TIMER_STOP SET_TIMER_FROM_GETRUSAGE(&__end_time); 79 80#elif defined(DB_WIN32) && !defined(DB_WINCE) 81 82#define SET_TIMER_FROM_GETPROCESSTIMES(tp) do { \ 83 FILETIME lpCreationTime, lpExitTime, lpKernelTime, lpUserTIme; \ 84 LARGE_INTEGER large_int; \ 85 LONGLONG __ns_since_epoch; \ 86 DB_BENCH_ASSERT( \ 87 GetProcessTimes(GetCurrentProcess(), &lpCreationTime, \ 88 &lpExitTime, &lpKernelTime, &lpUserTIme) != 0); \ 89 memcpy(&large_int, &lpKernelTime, sizeof(lpKernelTime)); \ 90 __ns_since_epoch = (large_int.QuadPart * 100); \ 91 (tp)->tv_sec = (time_t)(__ns_since_epoch / NS_PER_SEC); \ 92 (tp)->tv_nsec = (long)(__ns_since_epoch % NS_PER_SEC); \ 93 memcpy(&large_int, &lpUserTIme, sizeof(lpUserTIme)); \ 94 __ns_since_epoch = (large_int.QuadPart * 100); \ 95 (tp)->tv_sec += (time_t)(__ns_since_epoch / NS_PER_SEC); \ 96 (tp)->tv_nsec += (long)(__ns_since_epoch % NS_PER_SEC); \ 97} while (0); 98 99#define TIMER_START SET_TIMER_FROM_GETPROCESSTIMES(&__start_time); 100#define TIMER_STOP SET_TIMER_FROM_GETPROCESSTIMES(&__end_time); 101 102#else /* !HAVEGETRUSAGE && !DB_WIN32 */ 103 104#if DB_VERSION_MAJOR > 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 6 105#define TIMER_START __os_gettime(NULL, &__start_time, 1) 106#define TIMER_STOP __os_gettime(NULL, &__end_time, 1) 107#else 108#define TIMER_START __os_gettime(NULL, &__start_time) 109#define TIMER_STOP __os_gettime(NULL, &__end_time) 110#endif 111#endif /* !HAVE_GETRUSAGE */ 112 113#else /* !DB_TIMEOUT_TO_TIMESPEC */ 114 115#if defined(HAVE_CLOCK_GETTIME) 116typedef struct timespec db_timespec; 117#else 118typedef struct { 119 time_t tv_sec; /* seconds */ 120 long tv_nsec; /* nanoseconds */ 121} db_timespec; 122#endif 123 124#define timespecadd(vvp, uvp) \ 125 do { \ 126 (vvp)->tv_sec += (uvp)->tv_sec; \ 127 (vvp)->tv_nsec += (uvp)->tv_nsec; \ 128 if ((vvp)->tv_nsec >= NS_PER_SEC) { \ 129 (vvp)->tv_sec++; \ 130 (vvp)->tv_nsec -= NS_PER_SEC; \ 131 } \ 132 } while (0) 133#define timespecsub(vvp, uvp) \ 134 do { \ 135 (vvp)->tv_sec -= (uvp)->tv_sec; \ 136 (vvp)->tv_nsec -= (uvp)->tv_nsec; \ 137 if ((vvp)->tv_nsec < 0) { \ 138 (vvp)->tv_sec--; \ 139 (vvp)->tv_nsec += NS_PER_SEC; \ 140 } \ 141 } while (0) 142 143#define TIMER_START CLOCK(__start_time) 144#define TIMER_STOP CLOCK(__end_time) 145 146#if defined(HAVE_CLOCK_GETTIME) 147#define CLOCK(tm) do { \ 148 DB_BENCH_ASSERT(clock_gettime( \ 149 CLOCK_REALTIME, (struct timespec *)&(tm)) == 0); \ 150} while (0) 151#elif defined(DB_WIN32) 152#define CLOCK(tm) do { \ 153 struct _timeb __now; \ 154 _ftime(&__now); \ 155 (tm).tv_sec = __now.time; \ 156 (tm).tv_nsec = __now.millitm * MS_PER_NS; \ 157} while (0) 158#else 159#define CLOCK(tm) do { \ 160 struct timeval __tp; \ 161 DB_BENCH_ASSERT(gettimeofday(&__tp, NULL) == 0); \ 162 (tm).tv_sec = __tp.tv_sec; \ 163 (tm).tv_nsec = __tp.tv_usec * NS_PER_US; \ 164} while (0) 165#endif 166#endif /* !DB_TIMEOUT_TO_TIMESPEC */ 167 168db_timespec __start_time, __end_time; 169 170#define TIMER_GET(tm) do { \ 171 tm = __end_time; \ 172 timespecsub(&(tm), &__start_time); \ 173} while (0) 174#define TIMER_DISPLAY(ops) do { \ 175 db_timespec __tmp_time; \ 176 __tmp_time = __end_time; \ 177 timespecsub(&__tmp_time, &__start_time); \ 178 TIME_DISPLAY(ops, __tmp_time); \ 179} while (0) 180#define TIME_DISPLAY(ops, tm) do { \ 181 double __secs; \ 182 int __major, __minor, __patch; \ 183 __secs = (tm).tv_sec + (double)(tm).tv_nsec / NS_PER_SEC; \ 184 (void)db_version(&__major, &__minor, &__patch); \ 185 printf("%d.%d.%d\t%.2f\n", __major, __minor, __patch, \ 186 (__secs == 0) ? 0.0 : (ops) / __secs); \ 187} while (0) 188 189extern char *progname; /* program name */ 190 191int b_curalloc __P((int, char *[])); 192int b_curwalk __P((int, char *[])); 193int b_del __P((int, char *[])); 194int b_get __P((int, char *[])); 195int b_inmem __P((int, char *[])); 196int b_load __P((int, char *[])); 197int b_open __P((int, char *[])); 198int b_put __P((int, char *[])); 199int b_recover __P((int, char *[])); 200int b_txn __P((int, char *[])); 201int b_txn_write __P((int, char *[])); 202int b_uname __P((void)); 203void b_util_abort __P((void)); 204int b_util_dir_setup __P((void)); 205int b_util_dir_teardown __P((void)); 206int b_util_have_hash __P((void)); 207int b_util_have_queue __P((void)); 208int b_util_unlink __P((char *)); 209int b_workload __P((int, char *[])); 210 211#endif /* !_BENCH_H_ */ 212