optimized _asn1_find_up().
[platform/upstream/libtasn1.git] / src / benchmark.c
1 /*
2  * Copyright (C) 2011-2014 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuTLS.
5  *
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.
10  *
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.
15  *
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/>.
18  */
19
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"
28
29 int benchmark_must_finish = 0;
30
31 #if defined _WIN32
32 #include <windows.h>
33 DWORD WINAPI
34 alarm_handler (LPVOID lpParameter)
35 {
36   HANDLE wtimer = *((HANDLE *) lpParameter);
37   WaitForSingleObject (wtimer, INFINITE);
38   benchmark_must_finish = 1;
39   return 0;
40 }
41 #else
42 static void
43 alarm_handler (int signo)
44 {
45   benchmark_must_finish = 1;
46 }
47 #endif
48
49 static void
50 value2human (unsigned long bytes, double secs, double *data, double *speed,
51              char *metric)
52 {
53   if (bytes > 1000 && bytes < 1000 * 1000)
54     {
55       *data = ((double) bytes) / 1000;
56       *speed = *data / secs;
57       strcpy (metric, "KB");
58       return;
59     }
60   else if (bytes >= 1000 * 1000 && bytes < 1000 * 1000 * 1000)
61     {
62       *data = ((double) bytes) / (1000 * 1000);
63       *speed = *data / secs;
64       strcpy (metric, "MB");
65       return;
66     }
67   else if (bytes >= 1000 * 1000 * 1000)
68     {
69       *data = ((double) bytes) / (1000 * 1000 * 1000);
70       *speed = *data / secs;
71       strcpy (metric, "GB");
72       return;
73     }
74   else
75     {
76       *data = (double) bytes;
77       *speed = *data / secs;
78       strcpy (metric, "bytes");
79       return;
80     }
81 }
82
83 void
84 start_benchmark (struct benchmark_st *st)
85 {
86   memset (st, 0, sizeof (*st));
87 #ifndef _WIN32
88   st->old_handler = signal (SIGALRM, alarm_handler);
89 #endif
90   gettime (&st->start);
91   benchmark_must_finish = 0;
92
93 #if defined _WIN32
94   st->wtimer = CreateWaitableTimer (NULL, TRUE, NULL);
95   if (st->wtimer == NULL)
96     {
97       fprintf (stderr, "error: CreateWaitableTimer %u\n", GetLastError ());
98       exit (1);
99     }
100   st->wthread = CreateThread (NULL, 0, alarm_handler, &st->wtimer, 0, NULL);
101   if (st->wthread == NULL)
102     {
103       fprintf (stderr, "error: CreateThread %u\n", GetLastError ());
104       exit (1);
105     }
106   st->alarm_timeout.QuadPart = (5) * 10000000;
107   if (SetWaitableTimer (st->wtimer, &st->alarm_timeout, 0, NULL, NULL, FALSE)
108       == 0)
109     {
110       fprintf (stderr, "error: SetWaitableTimer %u\n", GetLastError ());
111       exit (1);
112     }
113 #else
114   alarm (5);
115 #endif
116
117 }
118
119 /* returns the elapsed time */
120 double
121 stop_benchmark (struct benchmark_st *st, const char *metric)
122 {
123   double secs;
124   unsigned long lsecs;
125   struct timespec stop;
126   double dspeed, ddata;
127   char imetric[16];
128
129 #if defined _WIN32
130   if (st->wtimer != NULL)
131     CloseHandle (st->wtimer);
132   if (st->wthread != NULL)
133     CloseHandle (st->wthread);
134 #else
135   signal (SIGALRM, st->old_handler);
136 #endif
137
138   gettime (&stop);
139
140   lsecs = (stop.tv_sec * 1000 + stop.tv_nsec / (1000 * 1000) -
141            (st->start.tv_sec * 1000 + st->start.tv_nsec / (1000 * 1000)));
142   secs = lsecs;
143   secs /= 1000;
144
145   if (metric == NULL)
146     {                           /* assume bytes/sec */
147       value2human (st->size, secs, &ddata, &dspeed, imetric);
148       printf ("  Processed %.2f %s in %.2f secs: ", ddata, imetric, secs);
149       printf ("%.2f %s/sec\n", dspeed, imetric);
150     }
151   else
152     {
153       ddata = (double) st->size;
154       dspeed = ddata / secs;
155       printf ("  Processed %.2f %s in %.2f secs: ", ddata, metric, secs);
156       printf ("%.2f %s/sec\n", dspeed, metric);
157     }
158
159   return secs;
160 }