Added boilerplate.
[gnutls.git] / src / benchmark.c
blob8ab3f8c2b11de11c30c82ba3fe0351c3ceed3f51
1 /*
2 * Copyright (C) 2011-2012 Free Software Foundation, Inc.
4 * This file is part of GnuTLS.
6 * GnuTLS is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GnuTLS is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <config.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <signal.h>
24 #include <sys/time.h>
25 #include <time.h>
26 #include <unistd.h>
27 #include "benchmark.h"
29 int benchmark_must_finish = 0;
31 #if defined(_WIN32)
32 #include <windows.h>
33 DWORD WINAPI
34 alarm_handler (LPVOID lpParameter)
36 HANDLE wtimer = *((HANDLE *) lpParameter);
37 WaitForSingleObject (wtimer, INFINITE);
38 benchmark_must_finish = 1;
39 return 0;
41 #else
42 static void
43 alarm_handler (int signo)
45 benchmark_must_finish = 1;
47 #endif
49 static void
50 value2human (unsigned long bytes, double time, double *data, double *speed,
51 char *metric)
53 if (bytes > 1000 && bytes < 1000 * 1000)
55 *data = ((double) bytes) / 1000;
56 *speed = *data / time;
57 strcpy (metric, "KB");
58 return;
60 else if (bytes >= 1000 * 1000 && bytes < 1000 * 1000 * 1000)
62 *data = ((double) bytes) / (1000 * 1000);
63 *speed = *data / time;
64 strcpy (metric, "MB");
65 return;
67 else if (bytes >= 1000 * 1000 * 1000)
69 *data = ((double) bytes) / (1000 * 1000 * 1000);
70 *speed = *data / time;
71 strcpy (metric, "GB");
72 return;
74 else
76 *data = (double) bytes;
77 *speed = *data / time;
78 strcpy (metric, "bytes");
79 return;
83 void start_benchmark(struct benchmark_st * st)
85 memset(st, 0, sizeof(*st));
86 #ifndef _WIN32
87 st->old_handler = signal (SIGALRM, alarm_handler);
88 #endif
89 gettime (&st->start);
90 benchmark_must_finish = 0;
92 #if defined(_WIN32)
93 st->wtimer = CreateWaitableTimer (NULL, TRUE, NULL);
94 if (st->wtimer == NULL)
96 fprintf (stderr, "error: CreateWaitableTimer %u\n", GetLastError ());
97 exit(1);
99 st->wthread = CreateThread (NULL, 0, alarm_handler, &st->wtimer, 0, NULL);
100 if (st->wthread == NULL)
102 fprintf (stderr, "error: CreateThread %u\n", GetLastError ());
103 exit(1);
105 st->alarm_timeout.QuadPart = (2) * 10000000;
106 if (SetWaitableTimer (st->wtimer, &st->alarm_timeout, 0, NULL, NULL, FALSE) == 0)
108 fprintf (stderr, "error: SetWaitableTimer %u\n", GetLastError ());
109 exit(1);
111 #else
112 alarm (2);
113 #endif
117 /* returns the elapsed time */
118 double stop_benchmark(struct benchmark_st * st, const char* metric)
120 double secs;
121 unsigned long lsecs;
122 struct timespec stop;
123 double dspeed, ddata;
124 char imetric[16];
126 #if defined(_WIN32)
127 if (st->wtimer != NULL)
128 CloseHandle (st->wtimer);
129 if (st->wthread != NULL)
130 CloseHandle (st->wthread);
131 #else
132 signal(SIGALRM, st->old_handler);
133 #endif
135 gettime (&stop);
137 lsecs = (stop.tv_sec * 1000 + stop.tv_nsec / (1000 * 1000) -
138 (st->start.tv_sec * 1000 + st->start.tv_nsec / (1000 * 1000)));
139 secs = lsecs;
140 secs /= 1000;
142 if (metric == NULL)
143 { /* assume bytes/sec */
144 value2human (st->size, secs, &ddata, &dspeed, imetric);
145 printf (" Processed %.2f %s in %.2f secs: ", ddata, imetric, secs);
146 printf ("%.2f %s/sec\n", dspeed, imetric);
148 else
150 ddata = (double) st->size;
151 dspeed = ddata / secs;
152 printf (" Processed %.2f %s in %.2f secs: ", ddata, metric, secs);
153 printf ("%.2f %s/sec\n", dspeed, metric);
156 return secs;