2 This file is part of GNUnet.
3 (C) 2010-2013 Christian Grothoff (and other contributing authors)
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 3, or (at your
8 option) any later version.
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.
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.
21 * @file ats-tests/ats-testing-experiment.c
22 * @brief ats benchmark: controlled experiment execution
23 * @author Christian Grothoff
24 * @author Matthias Wachs
27 #include "gnunet_util_lib.h"
28 #include "gnunet-ats-solver-eval.h"
31 #define BIG_M_STRING "unlimited"
33 static struct Experiment *e;
35 static struct GNUNET_ATS_TESTING_SolverHandle *sh;
38 * cmd option -e: experiment file
40 static char *opt_exp_file;
42 static char *opt_solver;
45 * cmd option -l: enable logging
50 * cmd option -p: enable plots
55 * cmd option -v: verbose logs
57 static int opt_verbose;
66 * Preference Generators
69 static struct PreferenceGenerator *pg_head;
70 static struct PreferenceGenerator *pg_tail;
73 get_preference (struct PreferenceGenerator *pg)
75 struct GNUNET_TIME_Relative time_delta;
79 /* Calculate the current preference value */
81 case GNUNET_ATS_TEST_TG_CONSTANT:
82 pref_value = pg->base_value;
84 case GNUNET_ATS_TEST_TG_LINEAR:
85 time_delta = GNUNET_TIME_absolute_get_duration(pg->time_start);
86 /* Calculate point of time in the current period */
87 time_delta.rel_value_us = time_delta.rel_value_us %
88 pg->duration_period.rel_value_us;
89 delta_value = ((double) time_delta.rel_value_us /
90 pg->duration_period.rel_value_us) * (pg->max_value - pg->base_value);
91 if ((pg->max_value < pg->base_value) &&
92 ((pg->max_value - pg->base_value) > pg->base_value))
94 /* This will cause an underflow */
97 pref_value = pg->base_value + delta_value;
99 case GNUNET_ATS_TEST_TG_RANDOM:
100 delta_value = (double) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
101 10000 * (pg->max_value - pg->base_value)) / 10000;
102 pref_value = pg->base_value + delta_value;
104 case GNUNET_ATS_TEST_TG_SINUS:
105 time_delta = GNUNET_TIME_absolute_get_duration(pg->time_start);
106 /* Calculate point of time in the current period */
107 time_delta.rel_value_us = time_delta.rel_value_us %
108 pg->duration_period.rel_value_us;
109 if ((pg->max_value - pg->base_value) > pg->base_value)
111 /* This will cause an underflow for second half of sinus period,
112 * will be detected in general when experiments are loaded */
115 delta_value = (pg->max_value - pg->base_value) *
116 sin ( (2 * M_PI) / ((double) pg->duration_period.rel_value_us) *
117 time_delta.rel_value_us);
118 pref_value = pg->base_value + delta_value;
124 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Current preference value is %f\n",
131 set_pref_task (void *cls,
132 const struct GNUNET_SCHEDULER_TaskContext *tc)
134 struct PreferenceGenerator *pg = cls;
136 pg->set_task = GNUNET_SCHEDULER_NO_TASK;
138 pref_value = get_preference (pg);
140 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
141 "Setting preference for peer [%u] address [%u] for %s to %f\n",
142 pg->peer, pg->address_id,
143 GNUNET_ATS_print_preference_type (pg->kind), pref_value);
145 /* set performance here!
146 GNUNET_ATS_performance_change_preference(p->me->ats_perf_handle,
147 &p->dest->id, p->pg->kind, pref_value, GNUNET_ATS_PREFERENCE_END);
151 case GNUNET_ATS_PREFERENCE_BANDWIDTH:
152 //p->pref_bandwidth = pref_value;
154 case GNUNET_ATS_PREFERENCE_LATENCY:
155 //p->pref_delay = pref_value;
161 pg->set_task = GNUNET_SCHEDULER_add_delayed (pg->frequency,
166 static struct PreferenceGenerator *
167 find_pref_gen (unsigned int peer, unsigned int address,
168 enum GNUNET_ATS_PreferenceKind kind)
170 struct PreferenceGenerator *cur;
171 for (cur = pg_head; NULL != cur; cur = cur->next)
172 if ((cur->peer == peer) && (cur->address_id == address) && (cur->kind == kind))
178 GNUNET_ATS_solver_generate_preferences_stop (struct PreferenceGenerator *pg)
180 GNUNET_CONTAINER_DLL_remove (pg_head, pg_tail, pg);
182 if (GNUNET_SCHEDULER_NO_TASK != pg->set_task)
184 GNUNET_SCHEDULER_cancel (pg->set_task);
185 pg->set_task = GNUNET_SCHEDULER_NO_TASK;
187 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
188 "Removing old up preference generator peer [%u] address [%u] `%s'\n",
189 pg->peer, pg->address_id, GNUNET_ATS_print_preference_type(pg->kind));
196 * Generate between the source master and the partner and set preferences with a
197 * value depending on the generator.
200 * @param dest partner
201 * @param type type of preferences to generate
202 * @param base_rate traffic base rate to send data with
203 * @param max_rate traffic maximum rate to send data with
204 * @param period duration of a period of traffic generation (~ 1/frequency)
205 * @param duration how long to generate traffic
206 * @return the traffic generator
208 struct PreferenceGenerator *
209 GNUNET_ATS_solver_generate_preferences_start (unsigned int peer,
210 unsigned int address_id,
211 enum GeneratorType type,
214 struct GNUNET_TIME_Relative period,
215 struct GNUNET_TIME_Relative frequency,
216 enum GNUNET_ATS_PreferenceKind kind)
218 struct PreferenceGenerator *pg;
220 pg = GNUNET_new (struct PreferenceGenerator);
221 GNUNET_CONTAINER_DLL_insert (pg_head, pg_tail, pg);
224 pg->address_id = address_id;
226 pg->base_value = base_value;
227 pg->max_value = value_rate;
228 pg->duration_period = period;
229 pg->frequency = frequency;
230 pg->time_start = GNUNET_TIME_absolute_get();
233 case GNUNET_ATS_TEST_TG_CONSTANT:
234 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
235 "Setting up constant preference generator peer [%u] address [%u] `%s' max %u Bips\n",
236 pg->peer, pg->address_id, GNUNET_ATS_print_preference_type(kind),
239 case GNUNET_ATS_TEST_TG_LINEAR:
240 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
241 "Setting up linear preference generator peer [%u] address [%u] `%s' min %u Bips max %u Bips\n",
242 pg->peer, pg->address_id, GNUNET_ATS_print_preference_type(kind),
243 base_value, value_rate);
245 case GNUNET_ATS_TEST_TG_SINUS:
246 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
247 "Setting up sinus preference generator peer [%u] address [%u] `%s' baserate %u Bips, amplitude %u Bps\n",
248 pg->peer, pg->address_id, GNUNET_ATS_print_preference_type(kind),
249 base_value, value_rate);
252 case GNUNET_ATS_TEST_TG_RANDOM:
253 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
254 "Setting up random preference generator peer [%u] address [%u] `%s' min %u Bips max %u Bps\n",
255 pg->peer, pg->address_id, GNUNET_ATS_print_preference_type(kind),
256 base_value, value_rate);
262 pg->set_task = GNUNET_SCHEDULER_add_now (&set_pref_task, pg);
269 * Stop all preferences generators
272 GNUNET_ATS_solver_generate_preferences_stop_all ()
274 struct PreferenceGenerator *cur;
275 struct PreferenceGenerator *next;
277 for (cur = next; NULL != cur; cur = next)
280 GNUNET_ATS_solver_generate_preferences_stop(cur);
291 print_op (enum OperationType op)
294 case SOLVER_OP_ADD_ADDRESS:
295 return "ADD_ADDRESS";
296 case SOLVER_OP_DEL_ADDRESS:
297 return "DEL_ADDRESS";
298 case SOLVER_OP_START_SET_PREFERENCE:
299 return "START_SET_PREFERENCE";
300 case SOLVER_OP_STOP_SET_PREFERENCE:
301 return "STOP_STOP_PREFERENCE";
302 case SOLVER_OP_START_SET_PROPERTY:
303 return "START_SET_PROPERTY";
304 case SOLVER_OP_STOP_SET_PROPERTY:
305 return "STOP_SET_PROPERTY";
312 static struct Experiment *
315 struct Experiment *e;
316 e = GNUNET_new (struct Experiment);
321 e->total_duration = GNUNET_TIME_UNIT_ZERO;
326 free_experiment (struct Experiment *e)
329 struct Episode *next;
330 struct GNUNET_ATS_TEST_Operation *cur_o;
331 struct GNUNET_ATS_TEST_Operation *next_o;
334 for (cur = next; NULL != cur; cur = next)
339 for (cur_o = next_o; NULL != cur_o; cur_o = next_o)
341 next_o = cur_o->next;
342 GNUNET_free_non_null (cur_o->address);
343 GNUNET_free_non_null (cur_o->plugin);
349 GNUNET_free_non_null (e->name);
350 GNUNET_free_non_null (e->cfg_file);
356 load_op_add_address (struct GNUNET_ATS_TEST_Operation *o,
360 const struct GNUNET_CONFIGURATION_Handle *cfg)
365 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
366 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
367 sec_name, op_name, &o->peer_id))
369 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
370 op_counter, "ADD_ADDRESS", op_name);
371 GNUNET_free (op_name);
372 return GNUNET_SYSERR;
374 GNUNET_free (op_name);
377 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
378 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
379 sec_name, op_name, &o->address_id))
381 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
382 op_counter, "ADD_ADDRESS", op_name);
383 GNUNET_free (op_name);
384 return GNUNET_SYSERR;
386 GNUNET_free (op_name);
389 GNUNET_asprintf(&op_name, "op-%u-plugin", op_counter);
390 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
391 sec_name, op_name, &o->plugin))
393 fprintf (stderr, "Missing plugin in operation %u `%s' in episode `%s'\n",
394 op_counter, "ADD_ADDRESS", op_name);
395 GNUNET_free (op_name);
396 return GNUNET_SYSERR;
398 GNUNET_free (op_name);
401 GNUNET_asprintf(&op_name, "op-%u-address", op_counter);
402 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
403 sec_name, op_name, &o->address))
405 fprintf (stderr, "Missing address in operation %u `%s' in episode `%s'\n",
406 op_counter, "ADD_ADDRESS", op_name);
407 GNUNET_free (op_name);
408 return GNUNET_SYSERR;
410 GNUNET_free (op_name);
413 GNUNET_asprintf(&op_name, "op-%u-address-session", op_counter);
414 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
415 sec_name, op_name, &o->address_session))
417 fprintf (stderr, "Missing address-session in operation %u `%s' in episode `%s'\n",
418 op_counter, "ADD_ADDRESS", op_name);
419 GNUNET_free (op_name);
420 return GNUNET_SYSERR;
422 GNUNET_free (op_name);
425 GNUNET_asprintf(&op_name, "op-%u-address-network", op_counter);
426 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
427 sec_name, op_name, &o->address_network))
429 fprintf (stderr, "Missing address-network in operation %u `%s' in episode `%s'\n",
430 op_counter, "ADD_ADDRESS", op_name);
431 GNUNET_free (op_name);
432 return GNUNET_SYSERR;
434 GNUNET_free (op_name);
437 "Found operation %s: [%llu:%llu] address `%s' plugin `%s' \n",
438 "ADD_ADDRESS", o->peer_id, o->address_id, o->address, o->plugin);
444 load_op_del_address (struct GNUNET_ATS_TEST_Operation *o,
448 const struct GNUNET_CONFIGURATION_Handle *cfg)
453 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
454 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
455 sec_name, op_name, &o->peer_id))
457 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
458 op_counter, "DEL_ADDRESS", op_name);
459 GNUNET_free (op_name);
460 return GNUNET_SYSERR;
462 GNUNET_free (op_name);
465 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
466 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
467 sec_name, op_name, &o->address_id))
469 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
470 op_counter, "DEL_ADDRESS", op_name);
471 GNUNET_free (op_name);
472 return GNUNET_SYSERR;
474 GNUNET_free (op_name);
477 GNUNET_asprintf(&op_name, "op-%u-plugin", op_counter);
478 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
479 sec_name, op_name, &o->plugin))
481 fprintf (stderr, "Missing plugin in operation %u `%s' in episode `%s'\n",
482 op_counter, "DEL_ADDRESS", op_name);
483 GNUNET_free (op_name);
484 return GNUNET_SYSERR;
486 GNUNET_free (op_name);
489 GNUNET_asprintf(&op_name, "op-%u-address", op_counter);
490 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
491 sec_name, op_name, &o->address))
493 fprintf (stderr, "Missing address in operation %u `%s' in episode `%s'\n",
494 op_counter, "DEL_ADDRESS", op_name);
495 GNUNET_free (op_name);
496 return GNUNET_SYSERR;
498 GNUNET_free (op_name);
501 GNUNET_asprintf(&op_name, "op-%u-address-session", op_counter);
502 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
503 sec_name, op_name, &o->address_session))
505 fprintf (stderr, "Missing address-session in operation %u `%s' in episode `%s'\n",
506 op_counter, "DEL_ADDRESS", op_name);
507 GNUNET_free (op_name);
508 return GNUNET_SYSERR;
510 GNUNET_free (op_name);
513 GNUNET_asprintf(&op_name, "op-%u-address-network", op_counter);
514 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
515 sec_name, op_name, &o->address_network))
517 fprintf (stderr, "Missing address-network in operation %u `%s' in episode `%s'\n",
518 op_counter, "DEL_ADDRESS", op_name);
519 GNUNET_free (op_name);
520 return GNUNET_SYSERR;
522 GNUNET_free (op_name);
525 "Found operation %s: [%llu:%llu] address `%s' plugin `%s' \n",
526 "DEL_ADDRESS", o->peer_id, o->address_id, o->address, o->plugin);
531 static enum GNUNET_ATS_Property
532 parse_preference_string (const char * str)
535 char *props[GNUNET_ATS_PreferenceCount] = GNUNET_ATS_PreferenceTypeString;
537 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
538 if (0 == strcmp(str, props[c]))
544 load_op_start_set_preference (struct GNUNET_ATS_TEST_Operation *o,
548 const struct GNUNET_CONFIGURATION_Handle *cfg)
555 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
556 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
557 sec_name, op_name, &o->peer_id))
559 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
560 op_counter, "START_SET_PREFERENCE", op_name);
561 GNUNET_free (op_name);
562 return GNUNET_SYSERR;
564 GNUNET_free (op_name);
567 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
568 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
569 sec_name, op_name, &o->address_id))
571 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
572 op_counter, "START_SET_PREFERENCE", op_name);
573 GNUNET_free (op_name);
574 return GNUNET_SYSERR;
576 GNUNET_free (op_name);
579 GNUNET_asprintf(&op_name, "op-%u-gen-type", op_counter);
580 if ( (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
581 sec_name, op_name, &type)) )
583 fprintf (stderr, "Missing type in operation %u `%s' in episode `%s'\n",
584 op_counter, "START_SET_PREFERENCE", op_name);
585 GNUNET_free (op_name);
586 return GNUNET_SYSERR;
589 /* Load arguments for set_rate, start_send, set_preference */
590 if (0 == strcmp (type, "constant"))
592 o->tg_type = GNUNET_ATS_TEST_TG_CONSTANT;
594 else if (0 == strcmp (type, "linear"))
596 o->tg_type = GNUNET_ATS_TEST_TG_LINEAR;
598 else if (0 == strcmp (type, "sinus"))
600 o->tg_type = GNUNET_ATS_TEST_TG_SINUS;
602 else if (0 == strcmp (type, "random"))
604 o->tg_type = GNUNET_ATS_TEST_TG_RANDOM;
608 fprintf (stderr, "Invalid generator type %u `%s' in episode %u\n",
609 op_counter, op_name, e->id);
611 GNUNET_free (op_name);
612 return GNUNET_SYSERR;
615 GNUNET_free (op_name);
619 GNUNET_asprintf(&op_name, "op-%u-base-rate", op_counter);
620 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
621 sec_name, op_name, &o->base_rate))
623 fprintf (stderr, "Missing base rate in operation %u `%s' in episode %u\n",
624 op_counter, op_name, e->id);
625 GNUNET_free (op_name);
626 return GNUNET_SYSERR;
628 GNUNET_free (op_name);
632 GNUNET_asprintf(&op_name, "op-%u-max-rate", op_counter);
633 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
634 sec_name, op_name, &o->max_rate))
636 if ((GNUNET_ATS_TEST_TG_LINEAR == o->tg_type) ||
637 (GNUNET_ATS_TEST_TG_RANDOM == o->tg_type) ||
638 (GNUNET_ATS_TEST_TG_SINUS == o->tg_type))
640 fprintf (stderr, "Missing max rate in operation %u `%s' in episode %u\n",
641 op_counter, op_name, e->id);
642 GNUNET_free (op_name);
643 return GNUNET_SYSERR;
646 GNUNET_free (op_name);
649 GNUNET_asprintf(&op_name, "op-%u-period", op_counter);
650 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
651 sec_name, op_name, &o->period))
653 o->period = e->duration;
655 GNUNET_free (op_name);
658 GNUNET_asprintf(&op_name, "op-%u-frequency", op_counter);
659 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
660 sec_name, op_name, &o->frequency))
662 fprintf (stderr, "Missing frequency in operation %u `%s' in episode %u\n",
663 op_counter, op_name, e->id);
664 GNUNET_free (op_name);
665 return GNUNET_SYSERR;
667 GNUNET_free (op_name);
670 GNUNET_asprintf(&op_name, "op-%u-pref", op_counter);
671 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
672 sec_name, op_name, &pref))
674 fprintf (stderr, "Missing preference in operation %u `%s' in episode %u\n",
675 op_counter, op_name, e->id);
676 GNUNET_free (op_name);
677 return GNUNET_SYSERR;
680 if (0 == (o->pref_type = parse_preference_string(pref)))
682 fprintf (stderr, "Invalid preference in operation %u `%s' in episode %u\n",
683 op_counter, op_name, e->id);
684 GNUNET_free (op_name);
686 return GNUNET_SYSERR;
689 GNUNET_free (op_name);
692 "Found operation %s: [%llu:%llu]: %s = %llu\n",
693 "START_SET_PREFERENCE", o->peer_id, o->address_id,
694 GNUNET_ATS_print_preference_type(o->pref_type), o->base_rate);
700 load_op_stop_set_preference (struct GNUNET_ATS_TEST_Operation *o,
704 const struct GNUNET_CONFIGURATION_Handle *cfg)
710 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
711 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
712 sec_name, op_name, &o->peer_id))
714 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
715 op_counter, "STOP_SET_PREFERENCE", op_name);
716 GNUNET_free (op_name);
717 return GNUNET_SYSERR;
719 GNUNET_free (op_name);
722 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
723 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
724 sec_name, op_name, &o->address_id))
726 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
727 op_counter, "STOP_SET_PREFERENCE", op_name);
728 GNUNET_free (op_name);
729 return GNUNET_SYSERR;
731 GNUNET_free (op_name);
734 GNUNET_asprintf(&op_name, "op-%u-pref", op_counter);
735 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
736 sec_name, op_name, &pref))
738 fprintf (stderr, "Missing preference in operation %u `%s' in episode `%s'\n",
739 op_counter, "STOP_SET_PREFERENCE", op_name);
740 GNUNET_free (op_name);
741 return GNUNET_SYSERR;
744 if (0 == (o->pref_type = parse_preference_string(pref)))
746 fprintf (stderr, "Invalid preference in operation %u `%s' in episode %u\n",
747 op_counter, op_name, e->id);
748 GNUNET_free (op_name);
750 return GNUNET_SYSERR;
753 GNUNET_free (op_name);
756 "Found operation %s: [%llu:%llu]: %s\n",
757 "STOP_SET_PREFERENCE", o->peer_id, o->address_id,
758 GNUNET_ATS_print_preference_type(o->pref_type));
762 static enum GNUNET_ATS_Property
763 parse_property_string (const char * str)
766 char *props[GNUNET_ATS_PropertyCount] = GNUNET_ATS_PropertyStrings;
768 for (c = 0; c < GNUNET_ATS_PropertyCount; c++)
769 if (0 == strcmp(str, props[c]))
775 load_op_start_set_property(struct GNUNET_ATS_TEST_Operation *o,
779 const struct GNUNET_CONFIGURATION_Handle *cfg)
786 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
787 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
788 sec_name, op_name, &o->peer_id))
790 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
791 op_counter, "START_SET_PROPERTY", op_name);
792 GNUNET_free (op_name);
793 return GNUNET_SYSERR;
795 GNUNET_free (op_name);
798 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
799 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
800 sec_name, op_name, &o->address_id))
802 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
803 op_counter, "START_SET_PROPERTY", op_name);
804 GNUNET_free (op_name);
805 return GNUNET_SYSERR;
807 GNUNET_free (op_name);
810 GNUNET_asprintf(&op_name, "op-%u-gen-type", op_counter);
811 if ( (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
812 sec_name, op_name, &type)) )
814 fprintf (stderr, "Missing type in operation %u `%s' in episode `%s'\n",
815 op_counter, "START_SET_PROPERTY", op_name);
816 GNUNET_free (op_name);
817 return GNUNET_SYSERR;
820 /* Load arguments for set_rate, start_send, set_preference */
821 if (0 == strcmp (type, "constant"))
823 o->tg_type = GNUNET_ATS_TEST_TG_CONSTANT;
825 else if (0 == strcmp (type, "linear"))
827 o->tg_type = GNUNET_ATS_TEST_TG_LINEAR;
829 else if (0 == strcmp (type, "sinus"))
831 o->tg_type = GNUNET_ATS_TEST_TG_SINUS;
833 else if (0 == strcmp (type, "random"))
835 o->tg_type = GNUNET_ATS_TEST_TG_RANDOM;
839 fprintf (stderr, "Invalid generator type %u `%s' in episode %u\n",
840 op_counter, op_name, e->id);
842 GNUNET_free (op_name);
843 return GNUNET_SYSERR;
846 GNUNET_free (op_name);
850 GNUNET_asprintf(&op_name, "op-%u-base-rate", op_counter);
851 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
852 sec_name, op_name, &o->base_rate))
854 fprintf (stderr, "Missing base rate in operation %u `%s' in episode %u\n",
855 op_counter, op_name, e->id);
856 GNUNET_free (op_name);
857 return GNUNET_SYSERR;
859 GNUNET_free (op_name);
863 GNUNET_asprintf(&op_name, "op-%u-max-rate", op_counter);
864 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
865 sec_name, op_name, &o->max_rate))
867 if ((GNUNET_ATS_TEST_TG_LINEAR == o->tg_type) ||
868 (GNUNET_ATS_TEST_TG_RANDOM == o->tg_type) ||
869 (GNUNET_ATS_TEST_TG_SINUS == o->tg_type))
871 fprintf (stderr, "Missing max rate in operation %u `%s' in episode %u\n",
872 op_counter, op_name, e->id);
873 GNUNET_free (op_name);
874 return GNUNET_SYSERR;
877 GNUNET_free (op_name);
880 GNUNET_asprintf(&op_name, "op-%u-period", op_counter);
881 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
882 sec_name, op_name, &o->period))
884 o->period = e->duration;
886 GNUNET_free (op_name);
889 GNUNET_asprintf(&op_name, "op-%u-frequency", op_counter);
890 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
891 sec_name, op_name, &o->frequency))
893 fprintf (stderr, "Missing frequency in operation %u `%s' in episode %u\n",
894 op_counter, op_name, e->id);
895 GNUNET_free (op_name);
896 return GNUNET_SYSERR;
898 GNUNET_free (op_name);
901 GNUNET_asprintf(&op_name, "op-%u-property", op_counter);
902 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
903 sec_name, op_name, &prop))
905 fprintf (stderr, "Missing property in operation %u `%s' in episode %u\n",
906 op_counter, op_name, e->id);
907 GNUNET_free (op_name);
908 GNUNET_free_non_null (prop);
909 return GNUNET_SYSERR;
912 if (0 == (o->prop_type = parse_property_string(prop)))
914 fprintf (stderr, "Invalid property in operation %u `%s' in episode %u\n",
915 op_counter, op_name, e->id);
916 GNUNET_free (op_name);
918 return GNUNET_SYSERR;
922 GNUNET_free (op_name);
925 "Found operation %s: [%llu:%llu] %s = %llu\n",
926 "START_SET_PROPERTY", o->peer_id, o->address_id,
927 GNUNET_ATS_print_property_type (o->prop_type), o->base_rate);
933 load_op_stop_set_property (struct GNUNET_ATS_TEST_Operation *o,
937 const struct GNUNET_CONFIGURATION_Handle *cfg)
943 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
944 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
945 sec_name, op_name, &o->peer_id))
947 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
948 op_counter, "STOP_SET_PROPERTY", op_name);
949 GNUNET_free (op_name);
950 return GNUNET_SYSERR;
952 GNUNET_free (op_name);
955 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
956 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
957 sec_name, op_name, &o->address_id))
959 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
960 op_counter, "STOP_SET_PROPERTY", op_name);
961 GNUNET_free (op_name);
962 return GNUNET_SYSERR;
964 GNUNET_free (op_name);
967 GNUNET_asprintf(&op_name, "op-%u-property", op_counter);
968 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
969 sec_name, op_name, &pref))
971 fprintf (stderr, "Missing property in operation %u `%s' in episode `%s'\n",
972 op_counter, "STOP_SET_PROPERTY", op_name);
973 GNUNET_free (op_name);
974 GNUNET_free_non_null (pref);
975 return GNUNET_SYSERR;
978 if (0 == (o->prop_type = parse_property_string(pref)))
980 fprintf (stderr, "Invalid property in operation %u `%s' in episode %u\n",
981 op_counter, op_name, e->id);
982 GNUNET_free (op_name);
984 GNUNET_free_non_null (pref);
985 return GNUNET_SYSERR;
989 GNUNET_free (op_name);
992 "Found operation %s: [%llu:%llu] %s\n",
993 "STOP_SET_PROPERTY", o->peer_id, o->address_id,
994 GNUNET_ATS_print_property_type (o->prop_type));
1000 load_episode (struct Experiment *e, struct Episode *cur,
1001 struct GNUNET_CONFIGURATION_Handle *cfg)
1003 struct GNUNET_ATS_TEST_Operation *o;
1008 fprintf (stderr, "Parsing episode %u\n",cur->id);
1009 GNUNET_asprintf(&sec_name, "episode-%u", cur->id);
1013 /* Load operation */
1014 GNUNET_asprintf(&op_name, "op-%u-operation", op_counter);
1015 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
1016 sec_name, op_name, &op))
1018 GNUNET_free (op_name);
1021 o = GNUNET_new (struct GNUNET_ATS_TEST_Operation);
1022 /* operations = set_rate, start_send, stop_send, set_preference */
1023 if (0 == strcmp (op, "address_add"))
1025 o->type = SOLVER_OP_ADD_ADDRESS;
1026 if (GNUNET_SYSERR == load_op_add_address (o, cur,
1027 op_counter, sec_name, cfg))
1031 GNUNET_free (op_name);
1032 GNUNET_free (sec_name);
1033 return GNUNET_SYSERR;
1036 else if (0 == strcmp (op, "address_del"))
1038 o->type = SOLVER_OP_DEL_ADDRESS;
1039 if (GNUNET_SYSERR == load_op_del_address (o, cur,
1040 op_counter, sec_name, cfg))
1044 GNUNET_free (op_name);
1045 GNUNET_free (sec_name);
1046 return GNUNET_SYSERR;
1049 else if (0 == strcmp (op, "start_set_property"))
1051 o->type = SOLVER_OP_START_SET_PROPERTY;
1052 if (GNUNET_SYSERR == load_op_start_set_property (o, cur,
1053 op_counter, sec_name, cfg))
1057 GNUNET_free (op_name);
1058 GNUNET_free (sec_name);
1059 return GNUNET_SYSERR;
1062 else if (0 == strcmp (op, "stop_set_property"))
1064 o->type = SOLVER_OP_STOP_SET_PROPERTY;
1065 if (GNUNET_SYSERR == load_op_stop_set_property (o, cur,
1066 op_counter, sec_name, cfg))
1070 GNUNET_free (op_name);
1071 GNUNET_free (sec_name);
1072 return GNUNET_SYSERR;
1075 else if (0 == strcmp (op, "start_set_preference"))
1077 o->type = SOLVER_OP_START_SET_PREFERENCE;
1078 if (GNUNET_SYSERR == load_op_start_set_preference (o, cur,
1079 op_counter, sec_name, cfg))
1083 GNUNET_free (op_name);
1084 GNUNET_free (sec_name);
1085 return GNUNET_SYSERR;
1088 else if (0 == strcmp (op, "stop_set_preference"))
1090 o->type = SOLVER_OP_STOP_SET_PREFERENCE;
1091 if (GNUNET_SYSERR == load_op_stop_set_preference (o, cur,
1092 op_counter, sec_name, cfg))
1096 GNUNET_free (op_name);
1097 GNUNET_free (sec_name);
1098 return GNUNET_SYSERR;
1103 fprintf (stderr, "Invalid operation %u `%s' in episode %u\n",
1104 op_counter, op, cur->id);
1107 GNUNET_free (op_name);
1108 GNUNET_free (sec_name);
1109 return GNUNET_SYSERR;
1112 GNUNET_free (op_name);
1114 GNUNET_CONTAINER_DLL_insert (cur->head,cur->tail, o);
1117 GNUNET_free (sec_name);
1122 GNUNET_asprintf(&op_name, "op-%u-src", op_counter);
1123 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1124 sec_name, op_name, &o->src_id))
1126 fprintf (stderr, "Missing src in operation %u `%s' in episode %u\n",
1127 op_counter, op, cur->id);
1129 GNUNET_free (op_name);
1130 return GNUNET_SYSERR;
1132 if (o->src_id > (e->num_masters - 1))
1134 fprintf (stderr, "Invalid src %llu in operation %u `%s' in episode %u\n",
1135 o->src_id, op_counter, op, cur->id);
1137 GNUNET_free (op_name);
1138 return GNUNET_SYSERR;
1140 GNUNET_free (op_name);
1142 /* Get destination */
1143 GNUNET_asprintf(&op_name, "op-%u-dest", op_counter);
1144 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1145 sec_name, op_name, &o->dest_id))
1147 fprintf (stderr, "Missing src in operation %u `%s' in episode %u\n",
1148 op_counter, op, cur->id);
1150 GNUNET_free (op_name);
1151 return GNUNET_SYSERR;
1153 if (o->dest_id > (e->num_slaves - 1))
1155 fprintf (stderr, "Invalid destination %llu in operation %u `%s' in episode %u\n",
1156 o->dest_id, op_counter, op, cur->id);
1158 GNUNET_free (op_name);
1159 return GNUNET_SYSERR;
1161 GNUNET_free (op_name);
1163 GNUNET_asprintf(&op_name, "op-%u-type", op_counter);
1164 if ( (GNUNET_SYSERR != GNUNET_CONFIGURATION_get_value_string(cfg,
1165 sec_name, op_name, &type)) &&
1166 ((STOP_SEND != o->type) || (STOP_PREFERENCE != o->type)))
1168 /* Load arguments for set_rate, start_send, set_preference */
1169 if (0 == strcmp (type, "constant"))
1171 o->tg_type = GNUNET_ATS_TEST_TG_CONSTANT;
1173 else if (0 == strcmp (type, "linear"))
1175 o->tg_type = GNUNET_ATS_TEST_TG_LINEAR;
1177 else if (0 == strcmp (type, "sinus"))
1179 o->tg_type = GNUNET_ATS_TEST_TG_SINUS;
1181 else if (0 == strcmp (type, "random"))
1183 o->tg_type = GNUNET_ATS_TEST_TG_RANDOM;
1187 fprintf (stderr, "Invalid type %u `%s' in episode %u\n",
1188 op_counter, op, cur->id);
1191 GNUNET_free (op_name);
1192 return GNUNET_SYSERR;
1194 GNUNET_free (op_name);
1197 GNUNET_asprintf(&op_name, "op-%u-base-rate", op_counter);
1198 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1199 sec_name, op_name, &o->base_rate))
1201 fprintf (stderr, "Missing base rate in operation %u `%s' in episode %u\n",
1202 op_counter, op, cur->id);
1205 GNUNET_free (op_name);
1206 return GNUNET_SYSERR;
1208 GNUNET_free (op_name);
1211 GNUNET_asprintf(&op_name, "op-%u-max-rate", op_counter);
1212 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
1213 sec_name, op_name, &o->max_rate))
1215 if ((GNUNET_ATS_TEST_TG_LINEAR == o->tg_type) ||
1216 (GNUNET_ATS_TEST_TG_RANDOM == o->tg_type) ||
1217 (GNUNET_ATS_TEST_TG_SINUS == o->tg_type))
1219 fprintf (stderr, "Missing max rate in operation %u `%s' in episode %u\n",
1220 op_counter, op, cur->id);
1222 GNUNET_free (op_name);
1224 return GNUNET_SYSERR;
1227 GNUNET_free (op_name);
1230 GNUNET_asprintf(&op_name, "op-%u-period", op_counter);
1231 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1232 sec_name, op_name, &o->period))
1234 o->period = cur->duration;
1236 GNUNET_free (op_name);
1238 if (START_PREFERENCE == o->type)
1241 GNUNET_asprintf(&op_name, "op-%u-frequency", op_counter);
1242 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
1243 sec_name, op_name, &o->frequency))
1245 fprintf (stderr, "Missing frequency in operation %u `%s' in episode %u\n",
1246 op_counter, op, cur->id);
1248 GNUNET_free (op_name);
1250 return GNUNET_SYSERR;
1252 GNUNET_free (op_name);
1254 /* Get preference */
1255 GNUNET_asprintf(&op_name, "op-%u-pref", op_counter);
1256 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
1257 sec_name, op_name, &pref))
1259 fprintf (stderr, "Missing preference in operation %u `%s' in episode %u\n",
1260 op_counter, op, cur->id);
1262 GNUNET_free (op_name);
1264 GNUNET_free_non_null (pref);
1265 return GNUNET_SYSERR;
1268 if (0 == strcmp(pref, "bandwidth"))
1269 o->pref_type = GNUNET_ATS_PREFERENCE_BANDWIDTH;
1270 else if (0 == strcmp(pref, "latency"))
1271 o->pref_type = GNUNET_ATS_PREFERENCE_LATENCY;
1274 fprintf (stderr, "Invalid preference in operation %u `%s' in episode %u\n",
1275 op_counter, op, cur->id);
1277 GNUNET_free (op_name);
1280 GNUNET_free_non_null (pref);
1281 return GNUNET_SYSERR;
1284 GNUNET_free (op_name);
1289 if ((GNUNET_ATS_TEST_TG_LINEAR == o->tg_type) ||
1290 (GNUNET_ATS_TEST_TG_SINUS == o->tg_type))
1292 if ((o->max_rate - o->base_rate) > o->base_rate)
1294 /* This will cause an underflow */
1297 fprintf (stderr, "Selected max rate and base rate cannot be used for desired traffic form!\n");
1300 if ((START_SEND == o->type) || (START_PREFERENCE == o->type))
1301 fprintf (stderr, "Found operation %u in episode %u: %s [%llu]->[%llu] == %s, %llu -> %llu in %s\n",
1302 op_counter, cur->id, print_op (o->type), o->src_id,
1303 o->dest_id, (NULL != type) ? type : "",
1304 o->base_rate, o->max_rate,
1305 GNUNET_STRINGS_relative_time_to_string (o->period, GNUNET_YES));
1307 fprintf (stderr, "Found operation %u in episode %u: %s [%llu]->[%llu]\n",
1308 op_counter, cur->id, print_op (o->type), o->src_id, o->dest_id);
1310 GNUNET_free_non_null (type);
1318 load_episodes (struct Experiment *e, struct GNUNET_CONFIGURATION_Handle *cfg)
1322 struct GNUNET_TIME_Relative e_duration;
1323 struct Episode *cur;
1324 struct Episode *last;
1330 GNUNET_asprintf(&sec_name, "episode-%u", e_counter);
1331 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg,
1332 sec_name, "duration", &e_duration))
1334 GNUNET_free (sec_name);
1338 cur = GNUNET_new (struct Episode);
1339 cur->duration = e_duration;
1340 cur->id = e_counter;
1342 if (GNUNET_OK != load_episode (e, cur, cfg))
1344 GNUNET_free (sec_name);
1346 return GNUNET_SYSERR;
1349 fprintf (stderr, "Found episode %u with duration %s \n",
1351 GNUNET_STRINGS_relative_time_to_string(cur->duration, GNUNET_YES));
1353 /* Update experiment */
1355 e->total_duration = GNUNET_TIME_relative_add(e->total_duration, cur->duration);
1356 /* Put in linked list */
1362 GNUNET_free (sec_name);
1370 timeout_experiment (void *cls, const struct GNUNET_SCHEDULER_TaskContext* tc)
1372 struct Experiment *e = cls;
1373 e->experiment_timeout_task = GNUNET_SCHEDULER_NO_TASK;
1374 fprintf (stderr, "Experiment timeout!\n");
1376 if (GNUNET_SCHEDULER_NO_TASK != e->episode_timeout_task)
1378 GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
1379 e->episode_timeout_task = GNUNET_SCHEDULER_NO_TASK;
1382 e->e_done_cb (e, GNUNET_TIME_absolute_get_duration(e->start_time),
1387 enforce_add_address (struct GNUNET_ATS_TEST_Operation *op)
1390 struct BenchmarkPeer *peer;
1391 struct BenchmarkPartner *partner;
1393 peer = GNUNET_ATS_TEST_get_peer (op->src_id);
1400 partner = GNUNET_ATS_TEST_get_partner (op->src_id, op->dest_id);
1401 if (NULL == partner)
1407 fprintf (stderr, "Found master %llu slave %llu\n",op->src_id, op->dest_id);
1409 if (NULL != partner->tg)
1411 fprintf (stderr, "Stopping traffic between master %llu slave %llu\n",op->src_id, op->dest_id);
1412 GNUNET_ATS_TEST_generate_traffic_stop(partner->tg);
1416 partner->tg = GNUNET_ATS_TEST_generate_traffic_start(peer, partner,
1417 op->tg_type, op->base_rate, op->max_rate, op->period,
1418 GNUNET_TIME_UNIT_FOREVER_REL);
1423 enforce_del_address (struct GNUNET_ATS_TEST_Operation *op)
1426 struct BenchmarkPartner *p;
1427 p = GNUNET_ATS_TEST_get_partner (op->src_id, op->dest_id);
1434 fprintf (stderr, "Found master %llu slave %llu\n",op->src_id, op->dest_id);
1438 fprintf (stderr, "Stopping traffic between master %llu slave %llu\n",
1439 op->src_id, op->dest_id);
1440 GNUNET_ATS_TEST_generate_traffic_stop(p->tg);
1447 enforce_start_property (struct GNUNET_ATS_TEST_Operation *op)
1453 enforce_stop_property (struct GNUNET_ATS_TEST_Operation *op)
1459 enforce_start_preference (struct GNUNET_ATS_TEST_Operation *op)
1461 struct PreferenceGenerator *pg;
1462 if (NULL != (pg = find_pref_gen (op->peer_id, op->address_id, op->pref_type)))
1464 GNUNET_ATS_solver_generate_preferences_stop (pg);
1468 GNUNET_ATS_solver_generate_preferences_start (op->peer_id,
1479 enforce_stop_preference (struct GNUNET_ATS_TEST_Operation *op)
1481 struct PreferenceGenerator *pg = find_pref_gen(op->peer_id, op->address_id,
1484 GNUNET_ATS_solver_generate_preferences_stop (pg);
1487 static void enforce_episode (struct Episode *ep)
1489 struct GNUNET_ATS_TEST_Operation *cur;
1490 for (cur = ep->head; NULL != cur; cur = cur->next)
1492 switch (cur->type) {
1493 case SOLVER_OP_ADD_ADDRESS:
1494 fprintf (stderr, "Enforcing operation: %s [%llu:%llu]\n",
1495 print_op (cur->type), cur->peer_id, cur->address_id);
1496 enforce_add_address (cur);
1498 case SOLVER_OP_DEL_ADDRESS:
1499 fprintf (stderr, "Enforcing operation: %s [%llu:%llu]\n",
1500 print_op (cur->type), cur->peer_id, cur->address_id);
1501 enforce_del_address (cur);
1503 case SOLVER_OP_START_SET_PROPERTY:
1504 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
1505 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
1506 enforce_start_property (cur);
1508 case SOLVER_OP_STOP_SET_PROPERTY:
1509 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
1510 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
1511 enforce_stop_property (cur);
1513 case SOLVER_OP_START_SET_PREFERENCE:
1514 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
1515 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
1516 enforce_start_preference (cur);
1518 case SOLVER_OP_STOP_SET_PREFERENCE:
1519 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
1520 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
1521 enforce_stop_preference (cur);
1530 timeout_episode (void *cls, const struct GNUNET_SCHEDULER_TaskContext* tc)
1532 struct Experiment *e = cls;
1533 e->episode_timeout_task = GNUNET_SCHEDULER_NO_TASK;
1534 if (NULL != e->ep_done_cb)
1535 e->ep_done_cb (e->cur);
1537 /* Scheduling next */
1538 e->cur = e->cur->next;
1542 fprintf (stderr, "Last episode done!\n");
1543 if (GNUNET_SCHEDULER_NO_TASK != e->experiment_timeout_task)
1545 GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
1546 e->experiment_timeout_task = GNUNET_SCHEDULER_NO_TASK;
1548 e->e_done_cb (e, GNUNET_TIME_absolute_get_duration(e->start_time), GNUNET_OK);
1552 fprintf (stderr, "Running episode %u with timeout %s\n",
1554 GNUNET_STRINGS_relative_time_to_string(e->cur->duration, GNUNET_YES));
1555 e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
1556 &timeout_episode, e);
1557 enforce_episode(e->cur);
1564 GNUNET_ATS_solvers_experimentation_run (struct Experiment *e,
1565 GNUNET_ATS_TESTING_EpisodeDoneCallback ep_done_cb,
1566 GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb)
1568 fprintf (stderr, "Running experiment `%s' with timeout %s\n", e->name,
1569 GNUNET_STRINGS_relative_time_to_string(e->max_duration, GNUNET_YES));
1570 e->e_done_cb = e_done_cb;
1571 e->ep_done_cb = ep_done_cb;
1572 e->start_time = GNUNET_TIME_absolute_get();
1574 /* Start total time out */
1575 e->experiment_timeout_task = GNUNET_SCHEDULER_add_delayed (e->max_duration,
1576 &timeout_experiment, e);
1580 if (NULL == e->start)
1586 fprintf (stderr, "Running episode %u with timeout %s\n",
1588 GNUNET_STRINGS_relative_time_to_string(e->cur->duration, GNUNET_YES));
1589 e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
1590 &timeout_episode, e);
1591 enforce_episode(e->cur);
1596 GNUNET_ATS_solvers_experimentation_stop (struct Experiment *e)
1598 if (GNUNET_SCHEDULER_NO_TASK != e->experiment_timeout_task)
1600 GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
1601 e->experiment_timeout_task = GNUNET_SCHEDULER_NO_TASK;
1603 if (GNUNET_SCHEDULER_NO_TASK != e->episode_timeout_task)
1605 GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
1606 e->episode_timeout_task = GNUNET_SCHEDULER_NO_TASK;
1610 GNUNET_CONFIGURATION_destroy(e->cfg);
1613 free_experiment (e);
1618 GNUNET_ATS_solvers_experimentation_load (char *filename)
1620 struct Experiment *e;
1621 struct GNUNET_CONFIGURATION_Handle *cfg;
1624 cfg = GNUNET_CONFIGURATION_create();
1625 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, filename))
1627 fprintf (stderr, "Failed to load `%s'\n", filename);
1628 GNUNET_CONFIGURATION_destroy (cfg);
1632 e = create_experiment ();
1634 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "experiment",
1637 fprintf (stderr, "Invalid %s", "name");
1638 free_experiment (e);
1642 fprintf (stderr, "Experiment name: `%s'\n", e->name);
1644 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_filename (cfg, "experiment",
1645 "cfg_file", &e->cfg_file))
1647 fprintf (stderr, "Invalid %s", "cfg_file");
1648 free_experiment (e);
1653 fprintf (stderr, "Experiment name: `%s'\n", e->cfg_file);
1654 e->cfg = GNUNET_CONFIGURATION_create();
1655 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (e->cfg, e->cfg_file))
1657 fprintf (stderr, "Invalid configuration %s", "cfg_file");
1658 free_experiment (e);
1664 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number(cfg, "experiment",
1665 "masters", &e->num_masters))
1667 fprintf (stderr, "Invalid %s", "masters");
1668 free_experiment (e);
1672 fprintf (stderr, "Experiment masters: `%llu'\n",
1675 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number(cfg, "experiment",
1676 "slaves", &e->num_slaves))
1678 fprintf (stderr, "Invalid %s", "slaves");
1679 free_experiment (e);
1683 fprintf (stderr, "Experiment slaves: `%llu'\n",
1686 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment",
1687 "log_freq", &e->log_freq))
1689 fprintf (stderr, "Invalid %s", "log_freq");
1690 free_experiment (e);
1694 fprintf (stderr, "Experiment logging frequency: `%s'\n",
1695 GNUNET_STRINGS_relative_time_to_string (e->log_freq, GNUNET_YES));
1697 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment",
1698 "max_duration", &e->max_duration))
1700 fprintf (stderr, "Invalid %s", "max_duration");
1701 free_experiment (e);
1705 fprintf (stderr, "Experiment duration: `%s'\n",
1706 GNUNET_STRINGS_relative_time_to_string (e->max_duration, GNUNET_YES));
1708 if (GNUNET_SYSERR == load_episodes (e, cfg))
1710 GNUNET_ATS_solvers_experimentation_stop (e);
1711 GNUNET_CONFIGURATION_destroy (cfg);
1713 fprintf (stderr, "Failed to load experiment\n");
1716 fprintf (stderr, "Loaded %u episodes with total duration %s\n",
1718 GNUNET_STRINGS_relative_time_to_string (e->total_duration, GNUNET_YES));
1720 GNUNET_CONFIGURATION_destroy (cfg);
1733 struct GNUNET_ATS_TESTING_SolverHandle
1736 struct GNUNET_ATS_PluginEnvironment env;
1738 struct GNUNET_CONTAINER_MultiPeerMap *addresses;
1741 enum GNUNET_ATS_Solvers
1743 GNUNET_ATS_SOLVER_PROPORTIONAL,
1744 GNUNET_ATS_SOLVER_MLP,
1745 GNUNET_ATS_SOLVER_RIL,
1749 GNUNET_ATS_solvers_solver_stop (struct GNUNET_ATS_TESTING_SolverHandle *sh)
1751 GNUNET_STATISTICS_destroy ((struct GNUNET_STATISTICS_Handle *) sh->env.stats,
1753 GNUNET_CONTAINER_multipeermap_destroy(sh->env.addresses);
1754 GNUNET_PLUGIN_unload (sh->plugin, sh->solver);
1755 GNUNET_CONTAINER_multipeermap_destroy(sh->addresses);
1756 GNUNET_free (sh->plugin);
1761 * Load quotas for networks from configuration
1763 * @param cfg configuration handle
1764 * @param out_dest where to write outbound quotas
1765 * @param in_dest where to write inbound quotas
1766 * @param dest_length length of inbound and outbound arrays
1767 * @return number of networks loaded
1770 GNUNET_ATS_solvers_load_quotas (const struct GNUNET_CONFIGURATION_Handle *cfg,
1771 unsigned long long *out_dest,
1772 unsigned long long *in_dest,
1775 char *network_str[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkTypeString;
1776 char * entry_in = NULL;
1777 char * entry_out = NULL;
1778 char * quota_out_str;
1779 char * quota_in_str;
1783 for (c = 0; (c < GNUNET_ATS_NetworkTypeCount) && (c < dest_length); c++)
1787 GNUNET_asprintf (&entry_out, "%s_QUOTA_OUT", network_str[c]);
1788 GNUNET_asprintf (&entry_in, "%s_QUOTA_IN", network_str[c]);
1791 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_out, "a_out_str))
1794 if (0 == strcmp(quota_out_str, BIG_M_STRING))
1796 out_dest[c] = GNUNET_ATS_MaxBandwidth;
1799 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_STRINGS_fancy_size_to_bytes (quota_out_str, &out_dest[c])))
1801 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_out, &out_dest[c])))
1804 if (GNUNET_NO == res)
1806 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"),
1807 network_str[c], quota_out_str, GNUNET_ATS_DefaultBandwidth);
1808 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
1812 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Outbound quota configure for network `%s' is %llu\n"),
1813 network_str[c], out_dest[c]);
1815 GNUNET_free (quota_out_str);
1819 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("No outbound quota configured for network `%s', assigning default bandwidth %llu\n"),
1820 network_str[c], GNUNET_ATS_DefaultBandwidth);
1821 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
1825 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_in, "a_in_str))
1828 if (0 == strcmp(quota_in_str, BIG_M_STRING))
1830 in_dest[c] = GNUNET_ATS_MaxBandwidth;
1833 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_STRINGS_fancy_size_to_bytes (quota_in_str, &in_dest[c])))
1835 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_in, &in_dest[c])))
1838 if (GNUNET_NO == res)
1840 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"),
1841 network_str[c], quota_in_str, GNUNET_ATS_DefaultBandwidth);
1842 in_dest[c] = GNUNET_ATS_DefaultBandwidth;
1846 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Inbound quota configured for network `%s' is %llu\n"),
1847 network_str[c], in_dest[c]);
1849 GNUNET_free (quota_in_str);
1853 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("No outbound quota configure for network `%s', assigning default bandwidth %llu\n"),
1854 network_str[c], GNUNET_ATS_DefaultBandwidth);
1855 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
1857 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loaded quota for network `%s' (in/out): %llu %llu\n", network_str[c], in_dest[c], out_dest[c]);
1858 GNUNET_free (entry_out);
1859 GNUNET_free (entry_in);
1861 return GNUNET_ATS_NetworkTypeCount;
1865 * Information callback for the solver
1867 * @param op the solver operation
1868 * @param stat status of the solver operation
1869 * @param add additional solver information
1872 solver_info_cb (void *cls,
1873 enum GAS_Solver_Operation op,
1874 enum GAS_Solver_Status stat,
1875 enum GAS_Solver_Additional_Information add)
1880 add_info = "GAS_INFO_NONE";
1883 add_info = "GAS_INFO_MLP_FULL";
1885 case GAS_INFO_UPDATED:
1886 add_info = "GAS_INFO_MLP_UPDATED";
1888 case GAS_INFO_PROP_ALL:
1889 add_info = "GAS_INFO_PROP_ALL";
1891 case GAS_INFO_PROP_SINGLE:
1892 add_info = "GAS_INFO_PROP_SINGLE";
1895 add_info = "INVALID";
1901 case GAS_OP_SOLVE_START:
1902 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1903 "Solver notifies `%s' with result `%s' `%s'\n", "GAS_OP_SOLVE_START",
1904 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL", add_info);
1906 case GAS_OP_SOLVE_STOP:
1907 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1908 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_STOP",
1909 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL", add_info);
1912 case GAS_OP_SOLVE_SETUP_START:
1913 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1914 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_START",
1915 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
1918 case GAS_OP_SOLVE_SETUP_STOP:
1919 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1920 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_STOP",
1921 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
1924 case GAS_OP_SOLVE_MLP_LP_START:
1925 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1926 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_START",
1927 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
1929 case GAS_OP_SOLVE_MLP_LP_STOP:
1930 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1931 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_STOP",
1932 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
1935 case GAS_OP_SOLVE_MLP_MLP_START:
1936 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1937 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_START",
1938 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
1940 case GAS_OP_SOLVE_MLP_MLP_STOP:
1941 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1942 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_STOP",
1943 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
1945 case GAS_OP_SOLVE_UPDATE_NOTIFICATION_START:
1946 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1947 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_START",
1948 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
1950 case GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP:
1951 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1952 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP",
1953 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
1961 solver_bandwidth_changed_cb (void *cls, struct ATS_Address *address)
1963 if ( (0 == ntohl (address->assigned_bw_out.value__)) &&
1964 (0 == ntohl (address->assigned_bw_in.value__)) )
1967 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1968 "Bandwidth changed addresses %s %p to %u Bps out / %u Bps in\n",
1969 GNUNET_i2s (&address->peer),
1971 (unsigned int) ntohl (address->assigned_bw_out.value__),
1972 (unsigned int) ntohl (address->assigned_bw_in.value__));
1973 /*if (GNUNET_YES == ph.bulk_running)
1979 get_preferences_cb (void *cls, const struct GNUNET_PeerIdentity *id)
1981 return GAS_normalization_get_preferences_by_peer (id);
1986 get_property_cb (void *cls, const struct ATS_Address *address)
1988 return GAS_normalization_get_properties ((struct ATS_Address *) address);
1992 normalized_property_changed_cb (void *cls, struct ATS_Address *peer,
1993 uint32_t type, double prop_rel)
1999 struct GNUNET_ATS_TESTING_SolverHandle *
2000 GNUNET_ATS_solvers_solver_start (enum GNUNET_ATS_Solvers type)
2002 struct GNUNET_ATS_TESTING_SolverHandle *sh;
2004 unsigned long long quotas_in[GNUNET_ATS_NetworkTypeCount];
2005 unsigned long long quotas_out[GNUNET_ATS_NetworkTypeCount];
2008 case GNUNET_ATS_SOLVER_PROPORTIONAL:
2009 solver_str = "proportional";
2011 case GNUNET_ATS_SOLVER_MLP:
2014 case GNUNET_ATS_SOLVER_RIL:
2023 sh = GNUNET_new (struct GNUNET_ATS_TESTING_SolverHandle);
2024 GNUNET_asprintf (&sh->plugin, "libgnunet_plugin_ats_%s", solver_str);
2026 /* setup environment */
2027 sh->env.cfg = e->cfg;
2028 sh->env.stats = GNUNET_STATISTICS_create ("ats", e->cfg);
2029 sh->env.addresses = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO);
2030 sh->env.bandwidth_changed_cb = &solver_bandwidth_changed_cb;
2031 sh->env.get_preferences = &get_preferences_cb;
2032 sh->env.get_property = &get_property_cb;
2033 sh->env.network_count = GNUNET_ATS_NetworkTypeCount;
2034 sh->env.info_cb = &solver_info_cb;
2035 sh->env.info_cb_cls = NULL;
2037 /* start normalization */
2038 GAS_normalization_start (NULL, NULL, &normalized_property_changed_cb, NULL );
2041 if (GNUNET_ATS_NetworkTypeCount != GNUNET_ATS_solvers_load_quotas (e->cfg,
2042 quotas_out, quotas_in, GNUNET_ATS_NetworkTypeCount))
2045 GNUNET_free (sh->plugin);
2051 sh->solver = GNUNET_PLUGIN_load (sh->plugin, &sh->env);
2052 if (NULL == sh->solver)
2054 fprintf (stderr, "Failed to load solver `%s'\n", sh->plugin);
2056 GNUNET_free (sh->plugin);
2062 sh->addresses = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO);
2070 /* Clean up experiment */
2071 GNUNET_ATS_solver_generate_preferences_stop_all ();
2072 GNUNET_ATS_solvers_experimentation_stop (e);
2081 experiment_done_cb (struct Experiment *e, struct GNUNET_TIME_Relative duration,int success)
2083 if (GNUNET_OK == success)
2084 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment done successful in %s\n",
2085 GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_YES));
2087 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment failed \n");
2090 // GNUNET_ATS_TEST_logging_stop (l);
2092 /* Stop traffic generation */
2093 // GNUNET_ATS_TEST_generate_traffic_stop_all();
2095 /* Stop all preference generations */
2096 GNUNET_ATS_solver_generate_preferences_stop_all ();
2099 evaluate (duration);
2101 GNUNET_ATS_TEST_logging_write_to_file(l, opt_exp_file, opt_plot);
2105 GNUNET_ATS_TEST_logging_stop (l);
2106 GNUNET_ATS_TEST_logging_clean_up (l);
2110 GNUNET_SCHEDULER_add_now (&done, NULL);
2114 episode_done_cb (struct Episode *ep)
2116 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Episode %u done\n", ep->id);
2129 GNUNET_ATS_solvers_experimentation_stop (e);
2134 GNUNET_ATS_solvers_solver_stop (sh);
2140 run (void *cls, char * const *args, const char *cfgfile,
2141 const struct GNUNET_CONFIGURATION_Handle *cfg)
2143 enum GNUNET_ATS_Solvers solver;
2145 if (NULL == opt_exp_file)
2147 fprintf (stderr, "No experiment given ...\n");
2153 if (NULL == opt_solver)
2155 fprintf (stderr, "No solver given ...\n");
2161 if (0 == strcmp(opt_solver, "mlp"))
2163 solver = GNUNET_ATS_SOLVER_MLP;
2165 else if (0 == strcmp(opt_solver, "proportional"))
2167 solver = GNUNET_ATS_SOLVER_PROPORTIONAL;
2169 else if (0 == strcmp(opt_solver, "ril"))
2171 solver = GNUNET_ATS_SOLVER_RIL;
2175 fprintf (stderr, "No solver given ...");
2181 /* load experiment */
2182 e = GNUNET_ATS_solvers_experimentation_load (opt_exp_file);
2185 fprintf (stderr, "Failed to load experiment ...\n");
2193 sh = GNUNET_ATS_solvers_solver_start (solver);
2196 fprintf (stderr, "Failed to start solver ...\n");
2205 /* run experiment */
2206 GNUNET_ATS_solvers_experimentation_run (e, episode_done_cb,
2207 experiment_done_cb);
2214 * Main function of the benchmark
2216 * @param argc argument count
2217 * @param argv argument values
2220 main (int argc, char *argv[])
2222 opt_exp_file = NULL;
2224 opt_log = GNUNET_NO;
2225 opt_plot = GNUNET_NO;
2229 static struct GNUNET_GETOPT_CommandLineOption options[] =
2231 { 's', "solver", NULL,
2232 gettext_noop ("solver to use"),
2233 1, &GNUNET_GETOPT_set_string, &opt_solver},
2234 { 'e', "experiment", NULL,
2235 gettext_noop ("experiment to use"),
2236 1, &GNUNET_GETOPT_set_string, &opt_exp_file},
2237 { 'e', "experiment", NULL,
2238 gettext_noop ("experiment to use"),
2239 1, &GNUNET_GETOPT_set_one, &opt_verbose},
2240 GNUNET_GETOPT_OPTION_END
2243 GNUNET_PROGRAM_run (argc, argv, argv[0], NULL, options, &run, argv[0]);
2247 /* end of file ats-testing-experiment.c*/