77#ifndef SECP256K1_BENCH_H
88#define SECP256K1_BENCH_H
99
10+ #if defined(_WIN32 )
11+ #include <windows.h>
12+ #else
13+ #define _POSIX_C_SOURCE 199309L /* needs to be before any include */
14+ #include <time.h>
15+ #include <sys/time.h>
16+ #endif
17+
1018#include <stdlib.h>
1119#include <stdint.h>
1220#include <stdio.h>
1321#include <string.h>
1422
15- #if (defined(_MSC_VER ) && _MSC_VER >= 1900 )
16- # include <time.h>
17- #else
18- # include <sys/time.h>
19- #endif
23+ /* TODO: lock cpu to a single core */
24+
25+ static int64_t gettime_us (void ) {
2026
21- static int64_t gettime_i64 (void ) {
22- #if (defined(_MSC_VER ) && _MSC_VER >= 1900 )
23- /* C11 way to get wallclock time */
24- struct timespec tv ;
25- if (!timespec_get (& tv , TIME_UTC )) {
26- fputs ("timespec_get failed!" , stderr );
27- exit (EXIT_FAILURE );
27+ #if defined(_WIN32 )
28+ FILETIME creation , exit , kernel , user ;
29+
30+ if (GetProcessTimes (GetCurrentProcess (), & creation , & exit , & kernel , & user ) != 0 ) {
31+ return 0 ;
2832 }
29- return (int64_t )tv .tv_nsec / 1000 + (int64_t )tv .tv_sec * 1000000LL ;
30- #else
33+
34+ ULARGE_INTEGER k , u ;
35+ k .LowPart = kernel .dwLowDateTime ;
36+ k .HighPart = kernel .dwHighDateTime ;
37+ u .LowPart = user .dwLowDateTime ;
38+ u .HighPart = user .dwHighDateTime ;
39+
40+ return (int64_t )((k .QuadPart + u .QuadPart ) / 10 );
41+ #else /* POSIX */
42+
43+ # if defined(CLOCK_PROCESS_CPUTIME_ID )
44+ /* CLOCK_PROCESS_CPUTIME_ID is only useful if the process is locked to a core. see https://linux.die.net/man/3/clock_gettime */
45+ struct timespec ts ;
46+ if (clock_gettime (CLOCK_PROCESS_CPUTIME_ID , & ts ) != 0 ) {
47+ return 0 ;
48+ }
49+ return (int64_t )ts .tv_sec * 1000000 + ts .tv_nsec / 1000 ;
50+ # elif defined(CLOCK_MONOTONIC )
51+ /* WARN: timer is influenced by environvment (OS, scheduling, interrupts...) */
52+ struct timespec ts ;
53+ if (clock_gettime (CLOCK_MONOTONIC , & ts ) != 0 ) {
54+ return 0 ;
55+ }
56+ return (int64_t )ts .tv_sec * 1000000 + ts .tv_nsec / 1000 ;
57+ # elif defined(CLOCK_REALTIME )
58+ /* WARN: timer is influenced by environvment (OS, scheduling, interrupts...) */
59+ struct timespec ts ;
60+ if (clock_gettime (CLOCK_REALTIME , & ts ) != 0 ) {
61+ return 0 ;
62+ }
63+ return (int64_t )ts .tv_sec * 1000000 + ts .tv_nsec / 1000 ;
64+ # else
65+ /* WARN: timer is influenced by environvment (OS, scheduling, interrupts...) */
3166 struct timeval tv ;
32- gettimeofday (& tv , NULL );
33- return (int64_t )tv .tv_usec + (int64_t )tv .tv_sec * 1000000LL ;
67+ gettimeofday ((struct timeval * )& tv , NULL );
68+ return (int64_t )tv .tv_sec * 1000000 + tv .tv_usec ;
69+ # endif
70+
3471#endif
3572}
3673
@@ -44,9 +81,9 @@ static void run_benchmark(char *name, void (*benchmark)(void*, int), void (*setu
4481 if (setup != NULL ) {
4582 setup (data );
4683 }
47- begin = gettime_i64 ();
84+ begin = gettime_us ();
4885 benchmark (data , iter );
49- total = gettime_i64 () - begin ;
86+ total = gettime_us () - begin ;
5087 if (teardown != NULL ) {
5188 teardown (data , iter );
5289 }
0 commit comments