This avoids unconditionally using clock_gettime in {ecc,hogweed}-benchmark, falling back to clock() in these as well.
This makes building succeed on e.g. OS X. --- examples/Makefile.in | 16 +++--- examples/ecc-benchmark.c | 26 ++-------- examples/hogweed-benchmark.c | 26 ++-------- examples/nettle-benchmark.c | 69 ++------------------------ examples/timing.c | 110 ++++++++++++++++++++++++++++++++++++++++++ examples/timing.h | 30 ++++++++++++ 6 files changed, 162 insertions(+), 115 deletions(-) create mode 100644 examples/timing.c create mode 100644 examples/timing.h
diff --git a/examples/Makefile.in b/examples/Makefile.in index 3455a58..563d0dc 100644 --- a/examples/Makefile.in +++ b/examples/Makefile.in @@ -28,7 +28,7 @@ SOURCES = nettle-benchmark.c hogweed-benchmark.c ecc-benchmark.c \ nettle-openssl.c \ io.c read_rsa_key.c \ rsa-encrypt.c rsa-decrypt.c rsa-keygen.c rsa-sign.c rsa-verify.c \ - base16enc.c base16dec.c base64enc.c base64dec.c + base16enc.c base16dec.c base64enc.c base64dec.c timing.c
GETOPT_OBJS = ../getopt.$(OBJEXT) ../getopt1.$(OBJEXT) @@ -36,7 +36,7 @@ GETOPT_OBJS = ../getopt.$(OBJEXT) ../getopt1.$(OBJEXT) TS_ALL = rsa-sign-test rsa-verify-test rsa-encrypt-test
DISTFILES= $(SOURCES) Makefile.in $(TS_ALL) setup-env teardown-env \ - io.h rsa-session.h + io.h rsa-session.h timing.h
all: $(TARGETS)
@@ -102,16 +102,18 @@ eratosthenes$(EXEEXT): eratosthenes.$(OBJEXT) $(GETOPT_OBJS) $(LINK) eratosthenes.$(OBJEXT) $(GETOPT_OBJS) -o eratosthenes$(EXEEXT)
BENCH_OBJS = nettle-benchmark.$(OBJEXT) nettle-openssl.$(OBJEXT) \ - $(GETOPT_OBJS) ../nettle-internal.$(OBJEXT) + $(GETOPT_OBJS) ../nettle-internal.$(OBJEXT) timing.$(OBJEXT) nettle-benchmark$(EXEEXT): $(BENCH_OBJS) $(LINK) $(BENCH_OBJS) -lnettle $(BENCH_LIBS) $(OPENSSL_LIBFLAGS) -o nettle-benchmark$(EXEEXT)
-ecc-benchmark$(EXEEXT): ecc-benchmark.$(OBJEXT) - $(LINK) ecc-benchmark.$(OBJEXT) -lhogweed -lnettle $(BENCH_LIBS) $(LIBS) \ +ECC_BENCH_OBJS = ecc-benchmark.$(OBJEXT) timing.$(OBJEXT) +ecc-benchmark$(EXEEXT): $(ECC_BENCH_OBJS) + $(LINK) $(ECC_BENCH_OBJS) -lhogweed -lnettle $(BENCH_LIBS) $(LIBS) \ -o ecc-benchmark$(EXEEXT)
-hogweed-benchmark$(EXEEXT): hogweed-benchmark.$(OBJEXT) - $(LINK) hogweed-benchmark.$(OBJEXT) \ +HOGWEED_BENCH_OBJS = hogweed-benchmark.$(OBJEXT) timing.$(OBJEXT) +hogweed-benchmark$(EXEEXT): $(HOGWEED_BENCH_OBJS) + $(LINK) $(HOGWEED_BENCH_OBJS) \ -lhogweed -lnettle $(BENCH_LIBS) $(LIBS) $(OPENSSL_LIBFLAGS) \ -o hogweed-benchmark$(EXEEXT)
diff --git a/examples/ecc-benchmark.c b/examples/ecc-benchmark.c index 596b2ff..e14e55e 100644 --- a/examples/ecc-benchmark.c +++ b/examples/ecc-benchmark.c @@ -35,6 +35,8 @@
#include <time.h>
+#include "timing.h" + #include "../ecc.h" #include "../ecc-internal.h" #include "../gmp-glue.h" @@ -70,24 +72,6 @@ xalloc_limbs (mp_size_t size) return xalloc (size * sizeof(mp_limb_t)); }
-inline static void -time_start(struct timespec *start) -{ - if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, start) < 0) - die("clock_gettime failed: %s\n", strerror(errno)); -} - -static inline double -time_end(struct timespec *start) -{ - struct timespec end; - if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end) < 0) - die("clock_gettime failed: %s\n", strerror(errno)); - - return end.tv_sec - start->tv_sec - + 1e-9 * (end.tv_nsec - start->tv_nsec); -} - /* Returns second per function call */ static double time_function(void (*f)(void *arg), void *arg) @@ -100,12 +84,11 @@ time_function(void (*f)(void *arg), void *arg) for (ncalls = 10 ;;) { unsigned i; - struct timespec t;
- time_start(&t); + time_start(); for (i = 0; i < ncalls; i++) f(arg); - elapsed = time_end(&t); + elapsed = time_end(); if (elapsed > BENCH_INTERVAL) break; else if (elapsed < BENCH_INTERVAL / 10) @@ -293,6 +276,7 @@ main (int argc UNUSED, char **argv UNUSED) { unsigned i;
+ time_init(); printf ("%4s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s (us)\n", "size", "modp", "redc", "modq", "modinv", "mi_gcd", "dup_jj", "ad_jja", "ad_jjj", diff --git a/examples/hogweed-benchmark.c b/examples/hogweed-benchmark.c index f6ceda9..56860e0 100644 --- a/examples/hogweed-benchmark.c +++ b/examples/hogweed-benchmark.c @@ -34,6 +34,8 @@
#include <time.h>
+#include "timing.h" + #include "dsa.h" #include "rsa.h"
@@ -90,24 +92,6 @@ hash_string (const struct nettle_hash *hash, return digest; }
-inline static void -time_start(struct timespec *start) -{ - if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, start) < 0) - die("clock_gettime failed: %s\n", strerror(errno)); -} - -static inline double -time_end(struct timespec *start) -{ - struct timespec end; - if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end) < 0) - die("clock_gettime failed: %s\n", strerror(errno)); - - return end.tv_sec - start->tv_sec - + 1e-9 * (end.tv_nsec - start->tv_nsec); -} - struct alg { const char *name; unsigned size; @@ -129,12 +113,11 @@ time_function(void (*f)(void *arg), void *arg) for (ncalls = 10 ;;) { unsigned i; - struct timespec t;
- time_start(&t); + time_start(); for (i = 0; i < ncalls; i++) f(arg); - elapsed = time_end(&t); + elapsed = time_end(); if (elapsed > BENCH_INTERVAL) break; else if (elapsed < BENCH_INTERVAL / 10) @@ -625,6 +608,7 @@ main (int argc, char **argv) if (argc > 1) filter = argv[1];
+ time_init(); printf ("%15s %4s %9s %9s\n", "name", "size", "sign/ms", "verify/ms");
diff --git a/examples/nettle-benchmark.c b/examples/nettle-benchmark.c index 90d6c72..852baef 100644 --- a/examples/nettle-benchmark.c +++ b/examples/nettle-benchmark.c @@ -38,6 +38,8 @@
#include <time.h>
+#include "timing.h" + #include "aes.h" #include "arcfour.h" #include "blowfish.h" @@ -112,58 +114,6 @@ die(const char *format, ...)
static double overhead = 0.0;
-#if HAVE_CLOCK_GETTIME && defined CLOCK_PROCESS_CPUTIME_ID -#define TRY_CLOCK_GETTIME 1 -struct timespec cgt_start; - -static int -cgt_works_p(void) -{ - struct timespec now; - return clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &now) == 0; -} - -static void -cgt_time_start(void) -{ - if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &cgt_start) < 0) - die("clock_gettime failed: %s\n", strerror(errno)); -} - -static double -cgt_time_end(void) -{ - struct timespec end; - if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end) < 0) - die("clock_gettime failed: %s\n", strerror(errno)); - - return end.tv_sec - cgt_start.tv_sec - + 1e-9 * (end.tv_nsec - cgt_start.tv_nsec); -} - -static void (*time_start)(void); -static double (*time_end)(void); - -#else /* !HAVE_CLOCK_GETTIME */ -#define TRY_CLOCK_GETTIME 0 -#define time_start clock_time_start -#define time_end clock_time_end -#endif /* !HAVE_CLOCK_GETTIME */ - -static clock_t clock_start; - -static void -clock_time_start(void) -{ - clock_start = clock(); -} - -static double -clock_time_end(void) -{ - return (double) (clock() - (clock_start)) / CLOCKS_PER_SEC; -} - /* Returns second per function call */ static double time_function(void (*f)(void *arg), void *arg) @@ -700,20 +650,7 @@ main(int argc, char **argv)
alg = argv[optind];
- /* Choose timing function */ -#if TRY_CLOCK_GETTIME - if (cgt_works_p()) - { - time_start = cgt_time_start; - time_end = cgt_time_end; - } - else - { - fprintf(stderr, "clock_gettime not working, falling back to clock\n"); - time_start = clock_time_start; - time_end = clock_time_end; - } -#endif + time_init(); bench_sha1_compress(); bench_salsa20_core(); bench_sha3_permute(); diff --git a/examples/timing.c b/examples/timing.c new file mode 100644 index 0000000..108399a --- /dev/null +++ b/examples/timing.c @@ -0,0 +1,110 @@ +/* timing.c */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2013 Niels Möller + * + * The nettle library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The nettle library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the nettle library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02111-1301, USA. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "timing.h" + +#include <errno.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#if HAVE_CLOCK_GETTIME && defined CLOCK_PROCESS_CPUTIME_ID +#define TRY_CLOCK_GETTIME 1 +struct timespec cgt_start; + +static void NORETURN PRINTF_STYLE(1,2) +die(const char *format, ...) +{ + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + + exit(EXIT_FAILURE); +} + +static int +cgt_works_p(void) +{ + struct timespec now; + return clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &now) == 0; +} + +static void +cgt_time_start(void) +{ + if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &cgt_start) < 0) + die("clock_gettime failed: %s\n", strerror(errno)); +} + +static double +cgt_time_end(void) +{ + struct timespec end; + if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end) < 0) + die("clock_gettime failed: %s\n", strerror(errno)); + + return end.tv_sec - cgt_start.tv_sec + + 1e-9 * (end.tv_nsec - cgt_start.tv_nsec); +} +#endif /* !HAVE_CLOCK_GETTIME */ + +static clock_t clock_start; + +static void +clock_time_start(void) +{ + clock_start = clock(); +} + +static double +clock_time_end(void) +{ + return (double) (clock() - (clock_start)) / CLOCKS_PER_SEC; +} + +void (*time_start)(void) = clock_time_start; +double (*time_end)(void) = clock_time_end; + +void time_init(void) +{ + /* Choose timing function */ +#if TRY_CLOCK_GETTIME + if (cgt_works_p()) + { + time_start = cgt_time_start; + time_end = cgt_time_end; + } + else + { + fprintf(stderr, "clock_gettime not working, falling back to clock\n"); + time_start = clock_time_start; + time_end = clock_time_end; + } +#endif +} diff --git a/examples/timing.h b/examples/timing.h new file mode 100644 index 0000000..7307fa1 --- /dev/null +++ b/examples/timing.h @@ -0,0 +1,30 @@ +/* timing.c */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2013 Niels Möller + * + * The nettle library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The nettle library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the nettle library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02111-1301, USA. + */ + +#ifndef NETTLE_EXAMPLES_TIMING_H_INCLUDED +#define NETTLE_EXAMPLES_TIMING_H_INCLUDED + +void time_init(void); +extern void (*time_start)(void); +extern double (*time_end)(void); + +#endif /* NETTLE_EXAMPLES_TIMING_H_INCLUDED */
Martin Storsjö martin@martin.st writes:
This avoids unconditionally using clock_gettime in {ecc,hogweed}-benchmark, falling back to clock() in these as well.
Thanks a lot, checked in now.
I'm old fashioned enough to still value the ChangeLog file, so these well done patches would be even better if they included GNU-style ChangeLog entries. Maybe it would be easiest with ChangeLog separately from the patch, since ChangeLog patches are very likely to create conflicts, I could then apply the patch with git am (which I used for the first time today), insert entries in the ChangeLog, and commit --amend to get the ChangeLog together with the rest of the commit.
Regards, /Niels
nettle-bugs@lists.lysator.liu.se