diff options
author | Florian Dold <florian.dold@gmail.com> | 2013-08-12 23:13:13 +0000 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2013-08-12 23:13:13 +0000 |
commit | c1c986c8827d66cd20923b17ba1f5103d673e5ea (patch) | |
tree | 61a702a7732307d97cebe3926a1f8dfaa0f57267 /src/consensus/gnunet-consensus-profiler.c | |
parent | f4e5fc766bbabe63f68f82d1907e7f7ac5125b0d (diff) | |
download | gnunet-c1c986c8827d66cd20923b17ba1f5103d673e5ea.tar.gz gnunet-c1c986c8827d66cd20923b17ba1f5103d673e5ea.zip |
- rename gnunet-consensus to gnunet-consensus-profiler
---This line, and those below, will be ignored--
D consensus/gnunet-consensus.c
A + consensus/gnunet-consensus-profiler.c
M consensus/Makefile.am
Diffstat (limited to 'src/consensus/gnunet-consensus-profiler.c')
-rw-r--r-- | src/consensus/gnunet-consensus-profiler.c | 400 |
1 files changed, 400 insertions, 0 deletions
diff --git a/src/consensus/gnunet-consensus-profiler.c b/src/consensus/gnunet-consensus-profiler.c new file mode 100644 index 000000000..42040527f --- /dev/null +++ b/src/consensus/gnunet-consensus-profiler.c | |||
@@ -0,0 +1,400 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | (C) 2012 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 2, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file consensus/gnunet-consensus.c | ||
23 | * @brief profiling tool for gnunet-consensus | ||
24 | * @author Florian Dold | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_common.h" | ||
28 | #include "gnunet_util_lib.h" | ||
29 | #include "gnunet_consensus_service.h" | ||
30 | #include "gnunet_testbed_service.h" | ||
31 | |||
32 | static unsigned int num_peers = 2; | ||
33 | |||
34 | static unsigned int replication = 1; | ||
35 | |||
36 | static unsigned int num_values = 5; | ||
37 | |||
38 | static struct GNUNET_TIME_Relative conclude_timeout; | ||
39 | |||
40 | static struct GNUNET_CONSENSUS_Handle **consensus_handles; | ||
41 | |||
42 | static struct GNUNET_TESTBED_Operation **testbed_operations; | ||
43 | |||
44 | static unsigned int num_connected_handles; | ||
45 | |||
46 | static struct GNUNET_TESTBED_Peer **peers; | ||
47 | |||
48 | static struct GNUNET_PeerIdentity *peer_ids; | ||
49 | |||
50 | static unsigned int num_retrieved_peer_ids; | ||
51 | |||
52 | static struct GNUNET_HashCode session_id; | ||
53 | |||
54 | static unsigned int peers_done = 0; | ||
55 | |||
56 | static unsigned *results_for_peer; | ||
57 | |||
58 | |||
59 | /** | ||
60 | * Signature of the event handler function called by the | ||
61 | * respective event controller. | ||
62 | * | ||
63 | * @param cls closure | ||
64 | * @param event information about the event | ||
65 | */ | ||
66 | static void | ||
67 | controller_cb(void *cls, | ||
68 | const struct GNUNET_TESTBED_EventInformation *event) | ||
69 | { | ||
70 | GNUNET_assert (0); | ||
71 | } | ||
72 | |||
73 | static void | ||
74 | destroy (void *cls, const struct GNUNET_SCHEDULER_TaskContext *ctx) | ||
75 | { | ||
76 | struct GNUNET_CONSENSUS_Handle *consensus; | ||
77 | consensus = cls; | ||
78 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "destroying consensus\n"); | ||
79 | GNUNET_CONSENSUS_destroy (consensus); | ||
80 | peers_done++; | ||
81 | if (peers_done == num_peers) | ||
82 | { | ||
83 | unsigned int i; | ||
84 | for (i = 0; i < num_peers; i++) | ||
85 | GNUNET_TESTBED_operation_done (testbed_operations[i]); | ||
86 | for (i = 0; i < num_peers; i++) | ||
87 | printf ("P%u got %u of %u elements\n", i, results_for_peer[i], num_values); | ||
88 | GNUNET_SCHEDULER_shutdown (); | ||
89 | } | ||
90 | } | ||
91 | |||
92 | |||
93 | /** | ||
94 | * Called when a conclusion was successful. | ||
95 | * | ||
96 | * @param cls closure, the consensus handle | ||
97 | * @return GNUNET_YES if more consensus groups should be offered, GNUNET_NO if not | ||
98 | */ | ||
99 | static void | ||
100 | conclude_cb (void *cls) | ||
101 | { | ||
102 | struct GNUNET_CONSENSUS_Handle **chp = cls; | ||
103 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "consensus %d done\n", chp - consensus_handles); | ||
104 | GNUNET_SCHEDULER_add_now (destroy, *chp); | ||
105 | } | ||
106 | |||
107 | |||
108 | static void | ||
109 | generate_indices (int *indices) | ||
110 | { | ||
111 | int j; | ||
112 | j = 0; | ||
113 | while (j < replication) | ||
114 | { | ||
115 | int n; | ||
116 | int k; | ||
117 | int repeat; | ||
118 | n = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, num_peers); | ||
119 | repeat = GNUNET_NO; | ||
120 | for (k = 0; k < j; k++) | ||
121 | if (indices[k] == n) | ||
122 | { | ||
123 | repeat = GNUNET_YES; | ||
124 | break; | ||
125 | } | ||
126 | if (GNUNET_NO == repeat) | ||
127 | indices[j++] = n; | ||
128 | } | ||
129 | } | ||
130 | |||
131 | |||
132 | static void | ||
133 | do_consensus () | ||
134 | { | ||
135 | int unique_indices[replication]; | ||
136 | int i; | ||
137 | |||
138 | for (i = 0; i < num_values; i++) | ||
139 | { | ||
140 | int j; | ||
141 | struct GNUNET_HashCode *val; | ||
142 | struct GNUNET_SET_Element *element; | ||
143 | generate_indices(unique_indices); | ||
144 | |||
145 | val = GNUNET_malloc (sizeof *val); | ||
146 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, val); | ||
147 | |||
148 | element = GNUNET_malloc (sizeof *element); | ||
149 | element->data = val; | ||
150 | element->size = sizeof *val; | ||
151 | |||
152 | for (j = 0; j < replication; j++) | ||
153 | { | ||
154 | int cid; | ||
155 | cid = unique_indices[j]; | ||
156 | GNUNET_CONSENSUS_insert (consensus_handles[cid], element, NULL, NULL); | ||
157 | } | ||
158 | } | ||
159 | |||
160 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "all elements inserted, calling conclude\n"); | ||
161 | |||
162 | for (i = 0; i < num_peers; i++) | ||
163 | GNUNET_CONSENSUS_conclude (consensus_handles[i], conclude_timeout, conclude_cb, &consensus_handles[i]); | ||
164 | } | ||
165 | |||
166 | |||
167 | /** | ||
168 | * Callback to be called when a service connect operation is completed | ||
169 | * | ||
170 | * @param cls the callback closure from functions generating an operation | ||
171 | * @param op the operation that has been finished | ||
172 | * @param ca_result the service handle returned from GNUNET_TESTBED_ConnectAdapter() | ||
173 | * @param emsg error message in case the operation has failed; will be NULL if | ||
174 | * operation has executed successfully. | ||
175 | */ | ||
176 | static void | ||
177 | connect_complete (void *cls, | ||
178 | struct GNUNET_TESTBED_Operation *op, | ||
179 | void *ca_result, | ||
180 | const char *emsg) | ||
181 | { | ||
182 | |||
183 | if (NULL != emsg) | ||
184 | { | ||
185 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "testbed connect emsg: %s\n", emsg); | ||
186 | GNUNET_assert (0); | ||
187 | } | ||
188 | |||
189 | num_connected_handles++; | ||
190 | |||
191 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "connect complete\n"); | ||
192 | |||
193 | if (num_connected_handles == num_peers) | ||
194 | { | ||
195 | do_consensus (); | ||
196 | } | ||
197 | } | ||
198 | |||
199 | |||
200 | static void | ||
201 | new_element_cb (void *cls, | ||
202 | const struct GNUNET_SET_Element *element) | ||
203 | { | ||
204 | struct GNUNET_CONSENSUS_Handle **chp = cls; | ||
205 | |||
206 | GNUNET_assert (NULL != cls); | ||
207 | |||
208 | results_for_peer[chp - consensus_handles]++; | ||
209 | } | ||
210 | |||
211 | |||
212 | /** | ||
213 | * Adapter function called to establish a connection to | ||
214 | * a service. | ||
215 | * | ||
216 | * @param cls closure | ||
217 | * @param cfg configuration of the peer to connect to; will be available until | ||
218 | * GNUNET_TESTBED_operation_done() is called on the operation returned | ||
219 | * from GNUNET_TESTBED_service_connect() | ||
220 | * @return service handle to return in 'op_result', NULL on error | ||
221 | */ | ||
222 | static void * | ||
223 | connect_adapter (void *cls, | ||
224 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
225 | { | ||
226 | struct GNUNET_CONSENSUS_Handle **chp = cls; | ||
227 | struct GNUNET_CONSENSUS_Handle *consensus; | ||
228 | chp = (struct GNUNET_CONSENSUS_Handle **) cls; | ||
229 | |||
230 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "connect adapter, %d peers\n", num_peers); | ||
231 | consensus = GNUNET_CONSENSUS_create (cfg, num_peers, peer_ids, &session_id, new_element_cb, chp); | ||
232 | *chp = (struct GNUNET_CONSENSUS_Handle *) consensus; | ||
233 | return consensus; | ||
234 | } | ||
235 | |||
236 | |||
237 | /** | ||
238 | * Adapter function called to destroy a connection to | ||
239 | * a service. | ||
240 | * | ||
241 | * @param cls closure | ||
242 | * @param op_result service handle returned from the connect adapter | ||
243 | */ | ||
244 | static void | ||
245 | disconnect_adapter(void *cls, void *op_result) | ||
246 | { | ||
247 | /* FIXME: what to do here? */ | ||
248 | } | ||
249 | |||
250 | |||
251 | /** | ||
252 | * Callback to be called when the requested peer information is available | ||
253 | * | ||
254 | * @param cb_cls the closure from GNUNET_TETSBED_peer_get_information() | ||
255 | * @param op the operation this callback corresponds to | ||
256 | * @param pinfo the result; will be NULL if the operation has failed | ||
257 | * @param emsg error message if the operation has failed; will be NULL if the | ||
258 | * operation is successfull | ||
259 | */ | ||
260 | static void | ||
261 | peer_info_cb (void *cb_cls, | ||
262 | struct GNUNET_TESTBED_Operation *op, | ||
263 | const struct GNUNET_TESTBED_PeerInformation *pinfo, | ||
264 | const char *emsg) | ||
265 | { | ||
266 | struct GNUNET_PeerIdentity *p; | ||
267 | int i; | ||
268 | |||
269 | GNUNET_assert (NULL == emsg); | ||
270 | |||
271 | p = (struct GNUNET_PeerIdentity *) cb_cls; | ||
272 | |||
273 | if (pinfo->pit == GNUNET_TESTBED_PIT_IDENTITY) | ||
274 | { | ||
275 | *p = *pinfo->result.id; | ||
276 | num_retrieved_peer_ids++; | ||
277 | if (num_retrieved_peer_ids == num_peers) | ||
278 | for (i = 0; i < num_peers; i++) | ||
279 | testbed_operations[i] = | ||
280 | GNUNET_TESTBED_service_connect (NULL, peers[i], "consensus", connect_complete, NULL, | ||
281 | connect_adapter, disconnect_adapter, &consensus_handles[i]); | ||
282 | } | ||
283 | else | ||
284 | { | ||
285 | GNUNET_assert (0); | ||
286 | } | ||
287 | |||
288 | GNUNET_TESTBED_operation_done (op); | ||
289 | } | ||
290 | |||
291 | |||
292 | /** | ||
293 | * Signature of a main function for a testcase. | ||
294 | * | ||
295 | * @param cls closure | ||
296 | * @param num_peers number of peers in 'peers' | ||
297 | * @param started_peers handle to peers run in the testbed. NULL upon timeout (see | ||
298 | * GNUNET_TESTBED_test_run()). | ||
299 | * @param links_succeeded the number of overlay link connection attempts that | ||
300 | * succeeded | ||
301 | * @param links_failed the number of overlay link connection attempts that | ||
302 | * failed | ||
303 | */ | ||
304 | static void | ||
305 | test_master (void *cls, | ||
306 | unsigned int num_peers, | ||
307 | struct GNUNET_TESTBED_Peer **started_peers, | ||
308 | unsigned int links_succeeded, | ||
309 | unsigned int links_failed) | ||
310 | { | ||
311 | int i; | ||
312 | |||
313 | GNUNET_log_setup ("gnunet-consensus", "INFO", NULL); | ||
314 | |||
315 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "test master\n"); | ||
316 | |||
317 | peers = started_peers; | ||
318 | |||
319 | peer_ids = GNUNET_malloc (num_peers * sizeof (struct GNUNET_PeerIdentity)); | ||
320 | |||
321 | results_for_peer = GNUNET_malloc (num_peers * sizeof (unsigned int)); | ||
322 | consensus_handles = GNUNET_malloc (num_peers * sizeof (struct ConsensusHandle *)); | ||
323 | testbed_operations = GNUNET_malloc (num_peers * sizeof (struct ConsensusHandle *)); | ||
324 | |||
325 | for (i = 0; i < num_peers; i++) | ||
326 | GNUNET_TESTBED_peer_get_information (peers[i], | ||
327 | GNUNET_TESTBED_PIT_IDENTITY, | ||
328 | peer_info_cb, | ||
329 | &peer_ids[i]); | ||
330 | } | ||
331 | |||
332 | static void | ||
333 | run (void *cls, char *const *args, const char *cfgfile, | ||
334 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
335 | { | ||
336 | static char *session_str = "gnunet-consensus/test"; | ||
337 | char *topology; | ||
338 | |||
339 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "testbed", "OVERLAY_TOPOLOGY", &topology)) | ||
340 | { | ||
341 | fprintf (stderr, "'OVERLAY_TOPOLOGY' not found in 'testbed' config section, " | ||
342 | "seems like you passed the wrong configuration file\n"); | ||
343 | return; | ||
344 | } | ||
345 | |||
346 | if (0 == strcasecmp (topology, "NONE")) | ||
347 | { | ||
348 | fprintf (stderr, "'OVERLAY_TOPOLOGY' set to 'NONE', " | ||
349 | "seems like you passed the wrong configuration file\n"); | ||
350 | return; | ||
351 | } | ||
352 | |||
353 | GNUNET_free (topology); | ||
354 | |||
355 | if (num_peers < replication) | ||
356 | { | ||
357 | fprintf (stderr, "k must be <=n\n"); | ||
358 | return; | ||
359 | } | ||
360 | |||
361 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "running gnunet-consensus\n"); | ||
362 | |||
363 | GNUNET_CRYPTO_hash (session_str, strlen(session_str), &session_id); | ||
364 | |||
365 | (void) GNUNET_TESTBED_test_run ("gnunet-consensus", | ||
366 | cfgfile, | ||
367 | num_peers, | ||
368 | 0, | ||
369 | controller_cb, | ||
370 | NULL, | ||
371 | test_master, | ||
372 | NULL); | ||
373 | } | ||
374 | |||
375 | |||
376 | int | ||
377 | main (int argc, char **argv) | ||
378 | { | ||
379 | static const struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
380 | { 'n', "num-peers", NULL, | ||
381 | gettext_noop ("number of peers in consensus"), | ||
382 | GNUNET_YES, &GNUNET_GETOPT_set_uint, &num_peers }, | ||
383 | { 'k', "value-replication", NULL, | ||
384 | gettext_noop ("how many peers receive one value?"), | ||
385 | GNUNET_YES, &GNUNET_GETOPT_set_uint, &replication }, | ||
386 | { 'x', "num-values", NULL, | ||
387 | gettext_noop ("number of values"), | ||
388 | GNUNET_YES, &GNUNET_GETOPT_set_uint, &num_values }, | ||
389 | { 't', "timeout", NULL, | ||
390 | gettext_noop ("consensus timeout"), | ||
391 | GNUNET_YES, &GNUNET_GETOPT_set_relative_time, &conclude_timeout }, | ||
392 | GNUNET_GETOPT_OPTION_END | ||
393 | }; | ||
394 | conclude_timeout = GNUNET_TIME_UNIT_SECONDS; | ||
395 | GNUNET_PROGRAM_run2 (argc, argv, "gnunet-consensus", | ||
396 | "help", | ||
397 | options, &run, NULL, GNUNET_YES); | ||
398 | return 0; | ||
399 | } | ||
400 | |||