145d7cee7c76bc57976406852f50cbb681e6efba
[oweals/gnunet.git] / src / util / benchmark.h
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2018 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Affero General Public License for more details.
14     
15      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 /**
20  * @file util/benchmark.h
21  * @brief benchmarking for various operations
22  * @author Florian Dold <flo@dold.me>
23  */
24
25 #ifndef BENCHMARK_H_
26 #define BENCHMARK_H_
27
28 #include "gnunet_time_lib.h"
29
30 /**
31  * Maximum length of URLs considered for benchmarking.
32  * Shorter URLs are simply truncated.
33  */
34 #define MAX_BENCHMARK_URL_LEN 128
35
36 #if ENABLE_BENCHMARK
37 #define BENCHMARK_START(opname) \
38     struct GNUNET_TIME_Absolute _benchmark_##opname##_start = GNUNET_TIME_absolute_get ()
39 #define BENCHMARK_END(opname) do { \
40   { \
41     struct GNUNET_TIME_Absolute _benchmark_##opname##_end = GNUNET_TIME_absolute_get (); \
42     struct BenchmarkData *bd = get_benchmark_data (); \
43     bd->opname##_count++; \
44     bd->opname##_time = \
45         GNUNET_TIME_relative_add (bd->opname##_time, \
46                                   GNUNET_TIME_absolute_get_difference (_benchmark_##opname##_start, \
47                                                                        _benchmark_##opname##_end)); \
48   } \
49 } while (0)
50 #else
51 #define BENCHMARK_START(opname) do { } while (0)
52 #define BENCHMARK_END(opname) do { } while (0)
53 #endif
54
55
56 /**
57  * Struct for benchmark data for one URL.
58  */
59 struct UrlRequestData
60 {
61   /**
62    * Request URL, truncated (but 0-terminated).
63    */
64   char request_url[MAX_BENCHMARK_URL_LEN];
65
66   /**
67    * HTTP status code.
68    */
69   unsigned int status;
70   
71   /**
72    * How often was the URL requested?
73    */
74   uint64_t count;
75
76   /**
77    * Total time spent requesting this URL.
78    */
79   struct GNUNET_TIME_Relative time;
80
81   /**
82    * Slowest time to response.
83    */
84   struct GNUNET_TIME_Relative time_max;
85
86   /**
87    * Fastest time to response.
88    */
89   struct GNUNET_TIME_Relative time_min;
90 };
91
92 #define GNUNET_DECLARE_BENCHMARK_OP(opname) \
93     uint64_t opname##_count; \
94     struct GNUNET_TIME_Relative opname##_time
95
96 /**
97  * Thread-local struct for benchmarking data.
98  */
99 struct BenchmarkData
100 {
101   GNUNET_DECLARE_BENCHMARK_OP (ecc_ecdh);
102   GNUNET_DECLARE_BENCHMARK_OP (ecdh_eddsa);
103   GNUNET_DECLARE_BENCHMARK_OP (ecdhe_key_create);
104   GNUNET_DECLARE_BENCHMARK_OP (ecdhe_key_get_public);
105   GNUNET_DECLARE_BENCHMARK_OP (ecdsa_ecdh);
106   GNUNET_DECLARE_BENCHMARK_OP (ecdsa_key_create);
107   GNUNET_DECLARE_BENCHMARK_OP (ecdsa_key_get_public);
108   GNUNET_DECLARE_BENCHMARK_OP (ecdsa_sign);
109   GNUNET_DECLARE_BENCHMARK_OP (ecdsa_verify);
110   GNUNET_DECLARE_BENCHMARK_OP (eddsa_ecdh);
111   GNUNET_DECLARE_BENCHMARK_OP (eddsa_key_create);
112   GNUNET_DECLARE_BENCHMARK_OP (eddsa_key_get_public);
113   GNUNET_DECLARE_BENCHMARK_OP (eddsa_sign);
114   GNUNET_DECLARE_BENCHMARK_OP (eddsa_verify);
115   GNUNET_DECLARE_BENCHMARK_OP (hash);
116   GNUNET_DECLARE_BENCHMARK_OP (hash_context_finish);
117   GNUNET_DECLARE_BENCHMARK_OP (hash_context_read);
118   GNUNET_DECLARE_BENCHMARK_OP (hash_context_start);
119   GNUNET_DECLARE_BENCHMARK_OP (hkdf);
120   GNUNET_DECLARE_BENCHMARK_OP (rsa_blind);
121   GNUNET_DECLARE_BENCHMARK_OP (rsa_private_key_create);
122   GNUNET_DECLARE_BENCHMARK_OP (rsa_private_key_get_public);
123   GNUNET_DECLARE_BENCHMARK_OP (rsa_sign_blinded);
124   GNUNET_DECLARE_BENCHMARK_OP (rsa_unblind);
125   GNUNET_DECLARE_BENCHMARK_OP (rsa_verify);
126
127   struct UrlRequestData *urd;
128
129   unsigned int urd_len;
130
131   unsigned int urd_capacity;
132 };
133
134 #undef GNUNET_DECLARE_BENCHMARK_OP
135
136
137 /**
138  * Acquire the benchmark data for the current thread, allocate if necessary.
139  * Installs handler to collect the benchmark data on thread termination.
140  *
141  * @return benchmark data for the current thread
142  */
143 struct BenchmarkData *
144 get_benchmark_data (void);
145
146 /**
147  * Get benchmark data for a URL.  If the URL is too long, it's truncated
148  * before looking up the correspoding benchmark data.
149  *
150  * Statistics are bucketed by URL and status code.
151  *
152  * @param url url to get request data for
153  * @param status http status code
154  */
155 struct UrlRequestData *
156 get_url_benchmark_data (char *url, unsigned int status);
157
158 #endif  /* BENCHMARK_H_ */