aboutsummaryrefslogtreecommitdiff
path: root/src/util/benchmark.c
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2018-08-18 01:36:37 +0200
committerFlorian Dold <florian.dold@gmail.com>2018-08-18 01:36:37 +0200
commitf9c7588373cb3a047345e68377158965d8e8d08a (patch)
treec6d9792953cb6ac703250601084201dfa13554c2 /src/util/benchmark.c
parentb51d78907d2e16e38c8d95d69827d99bc0a9612d (diff)
downloadgnunet-f9c7588373cb3a047345e68377158965d8e8d08a.tar.gz
gnunet-f9c7588373cb3a047345e68377158965d8e8d08a.zip
missing files
Diffstat (limited to 'src/util/benchmark.c')
-rw-r--r--src/util/benchmark.c144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/util/benchmark.c b/src/util/benchmark.c
new file mode 100644
index 000000000..4a0c9b7c8
--- /dev/null
+++ b/src/util/benchmark.c
@@ -0,0 +1,144 @@
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.c
21 * @brief benchmarking for various operations
22 * @author Florian Dold <flo@dold.me>
23 */
24
25#include "platform.h"
26#include "gnunet_util_lib.h"
27#include "benchmark.h"
28#include <pthread.h>
29#include <sys/syscall.h>
30
31/**
32 * Thread-local storage key for the benchmark data.
33 */
34static pthread_key_t key;
35
36/**
37 * One-time initialization marker for key.
38 */
39static pthread_once_t key_once = PTHREAD_ONCE_INIT;
40
41
42/**
43 * Write benchmark data to a file.
44 *
45 * @param bd the benchmark data
46 */
47static void
48write_benchmark_data (struct BenchmarkData *bd)
49{
50 struct GNUNET_DISK_FileHandle *fh;
51 pid_t pid = getpid ();
52 pid_t tid = syscall (SYS_gettid);
53 char *s;
54
55 GNUNET_asprintf (&s, "gnunet-benchmark-%llu-%llu.txt",
56 (unsigned long long) pid,
57 (unsigned long long) tid);
58
59 fh = GNUNET_DISK_file_open (s,
60 (GNUNET_DISK_OPEN_WRITE |
61 GNUNET_DISK_OPEN_TRUNCATE |
62 GNUNET_DISK_OPEN_CREATE),
63 (GNUNET_DISK_PERM_USER_READ |
64 GNUNET_DISK_PERM_USER_WRITE));
65 GNUNET_assert (NULL != fh);
66 GNUNET_free (s);
67
68 GNUNET_asprintf (&s, "eddsa_sign_count %llu",
69 (unsigned long long) bd->eddsa_sign_count);
70 GNUNET_assert (GNUNET_SYSERR != GNUNET_DISK_file_write_blocking (fh, s, strlen (s)));
71 GNUNET_free (s);
72
73 GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh));
74}
75
76
77/**
78 * Called when the main thread exits and benchmark data for it was created.
79 */
80static void
81main_thread_destructor ()
82{
83 struct BenchmarkData *bd;
84
85 bd = pthread_getspecific (key);
86 if (NULL != bd)
87 write_benchmark_data (bd);
88}
89
90
91/**
92 * Called when a thread exits and benchmark data for it was created.
93 *
94 * @param cls closure
95 */
96static void
97thread_destructor (void *cls)
98{
99 struct BenchmarkData *bd = cls;
100
101 // main thread will be handled by atexit
102 if (getpid () == (pid_t) syscall (SYS_gettid))
103 return;
104
105 GNUNET_assert (NULL != bd);
106
107}
108
109
110/**
111 * Initialize the thread-local variable key for benchmark data.
112 */
113static void
114make_key()
115{
116 (void) pthread_key_create (&key, &thread_destructor);
117}
118
119
120/**
121 * Acquire the benchmark data for the current thread, allocate if necessary.
122 * Installs handler to collect the benchmark data on thread termination.
123 *
124 * @return benchmark data for the current thread
125 */
126struct BenchmarkData *
127get_benchmark_data (void)
128{
129 struct BenchmarkData *bd;
130
131 (void) pthread_once (&key_once, &make_key);
132
133 if (NULL == (bd = pthread_getspecific (key)))
134 {
135 bd = GNUNET_new (struct BenchmarkData);
136 (void) pthread_setspecific (key, bd);
137 if (getpid () == (pid_t) syscall (SYS_gettid))
138 {
139 // We're the main thread!
140 atexit (main_thread_destructor);
141 }
142 }
143 return bd;
144}