gnunet-solver-eval.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2010-2013 Christian Grothoff (and other contributing authors)
  4. GNUnet is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published
  6. by the Free Software Foundation; either version 3, or (at your
  7. option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNUnet; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  15. Boston, MA 02111-1307, USA.
  16. */
  17. /**
  18. * @file ats-tests/ats-testing-experiment.c
  19. * @brief ats benchmark: controlled experiment execution
  20. * @author Christian Grothoff
  21. * @author Matthias Wachs
  22. */
  23. #include "platform.h"
  24. #include "gnunet_util_lib.h"
  25. #include "gnunet_ats_plugin.h"
  26. #include "gnunet_ats_service.h"
  27. #include "ats-testing.h"
  28. /**
  29. * Experiments
  30. */
  31. const char *
  32. print_op (enum OperationType op)
  33. {
  34. switch (op) {
  35. case START_SEND:
  36. return "START_SEND";
  37. case STOP_SEND:
  38. return "STOP_SEND";
  39. case START_PREFERENCE:
  40. return "START_PREFERENCE";
  41. case STOP_PREFERENCE:
  42. return "STOP_PREFERENCE";
  43. default:
  44. break;
  45. }
  46. return "";
  47. }
  48. static struct Experiment *
  49. create_experiment ()
  50. {
  51. struct Experiment *e;
  52. e = GNUNET_new (struct Experiment);
  53. e->name = NULL;
  54. e->num_masters = 0;
  55. e->num_slaves = 0;
  56. e->start = NULL;
  57. e->total_duration = GNUNET_TIME_UNIT_ZERO;
  58. return e;
  59. }
  60. static void
  61. free_experiment (struct Experiment *e)
  62. {
  63. struct Episode *cur;
  64. struct Episode *next;
  65. struct GNUNET_ATS_TEST_Operation *cur_o;
  66. struct GNUNET_ATS_TEST_Operation *next_o;
  67. next = e->start;
  68. for (cur = next; NULL != cur; cur = next)
  69. {
  70. next = cur->next;
  71. next_o = cur->head;
  72. for (cur_o = next_o; NULL != cur_o; cur_o = next_o)
  73. {
  74. next_o = cur_o->next;
  75. GNUNET_free (cur_o);
  76. }
  77. GNUNET_free (cur);
  78. }
  79. GNUNET_free_non_null (e->name);
  80. GNUNET_free_non_null (e->cfg_file);
  81. GNUNET_free (e);
  82. }
  83. static int
  84. load_episode (struct Experiment *e, struct Episode *cur,
  85. struct GNUNET_CONFIGURATION_Handle *cfg)
  86. {
  87. struct GNUNET_ATS_TEST_Operation *o;
  88. char *sec_name;
  89. char *op_name;
  90. char *op;
  91. char *type;
  92. char *pref;
  93. int op_counter = 0;
  94. fprintf (stderr, "Parsing episode %u\n",cur->id);
  95. GNUNET_asprintf(&sec_name, "episode-%u", cur->id);
  96. while (1)
  97. {
  98. /* Load operation */
  99. GNUNET_asprintf(&op_name, "op-%u-operation", op_counter);
  100. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
  101. sec_name, op_name, &op))
  102. {
  103. GNUNET_free (op_name);
  104. break;
  105. }
  106. o = GNUNET_new (struct GNUNET_ATS_TEST_Operation);
  107. /* operations = set_rate, start_send, stop_send, set_preference */
  108. if (0 == strcmp (op, "start_send"))
  109. {
  110. o->type = START_SEND;
  111. }
  112. else if (0 == strcmp (op, "stop_send"))
  113. {
  114. o->type = STOP_SEND;
  115. }
  116. else if (0 == strcmp (op, "start_preference"))
  117. {
  118. o->type = START_PREFERENCE;
  119. }
  120. else if (0 == strcmp (op, "stop_preference"))
  121. {
  122. o->type = STOP_PREFERENCE;
  123. }
  124. else
  125. {
  126. fprintf (stderr, "Invalid operation %u `%s' in episode %u\n",
  127. op_counter, op, cur->id);
  128. GNUNET_free (op);
  129. GNUNET_free (op_name);
  130. GNUNET_free (sec_name);
  131. GNUNET_free (o);
  132. return GNUNET_SYSERR;
  133. }
  134. GNUNET_free (op_name);
  135. /* Get source */
  136. GNUNET_asprintf(&op_name, "op-%u-src", op_counter);
  137. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
  138. sec_name, op_name, &o->src_id))
  139. {
  140. fprintf (stderr, "Missing src in operation %u `%s' in episode %u\n",
  141. op_counter, op, cur->id);
  142. GNUNET_free (op);
  143. GNUNET_free (op_name);
  144. GNUNET_free (sec_name);
  145. GNUNET_free (o);
  146. return GNUNET_SYSERR;
  147. }
  148. if (o->src_id > (e->num_masters - 1))
  149. {
  150. fprintf (stderr, "Invalid src %llu in operation %u `%s' in episode %u\n",
  151. o->src_id, op_counter, op, cur->id);
  152. GNUNET_free (op);
  153. GNUNET_free (op_name);
  154. GNUNET_free (sec_name);
  155. GNUNET_free (o);
  156. return GNUNET_SYSERR;
  157. }
  158. GNUNET_free (op_name);
  159. /* Get destination */
  160. GNUNET_asprintf(&op_name, "op-%u-dest", op_counter);
  161. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
  162. sec_name, op_name, &o->dest_id))
  163. {
  164. fprintf (stderr, "Missing src in operation %u `%s' in episode %u\n",
  165. op_counter, op, cur->id);
  166. GNUNET_free (op);
  167. GNUNET_free (op_name);
  168. GNUNET_free (sec_name);
  169. GNUNET_free (o);
  170. return GNUNET_SYSERR;
  171. }
  172. if (o->dest_id > (e->num_slaves - 1))
  173. {
  174. fprintf (stderr, "Invalid destination %llu in operation %u `%s' in episode %u\n",
  175. o->dest_id, op_counter, op, cur->id);
  176. GNUNET_free (op);
  177. GNUNET_free (op_name);
  178. GNUNET_free (sec_name);
  179. GNUNET_free (o);
  180. return GNUNET_SYSERR;
  181. }
  182. GNUNET_free (op_name);
  183. GNUNET_asprintf(&op_name, "op-%u-type", op_counter);
  184. if ( (GNUNET_SYSERR != GNUNET_CONFIGURATION_get_value_string(cfg,
  185. sec_name, op_name, &type)) &&
  186. ((STOP_SEND != o->type) || (STOP_PREFERENCE != o->type)))
  187. {
  188. /* Load arguments for set_rate, start_send, set_preference */
  189. if (0 == strcmp (type, "constant"))
  190. {
  191. o->gen_type = GNUNET_ATS_TEST_TG_CONSTANT;
  192. }
  193. else if (0 == strcmp (type, "linear"))
  194. {
  195. o->gen_type = GNUNET_ATS_TEST_TG_LINEAR;
  196. }
  197. else if (0 == strcmp (type, "sinus"))
  198. {
  199. o->gen_type = GNUNET_ATS_TEST_TG_SINUS;
  200. }
  201. else if (0 == strcmp (type, "random"))
  202. {
  203. o->gen_type = GNUNET_ATS_TEST_TG_RANDOM;
  204. }
  205. else
  206. {
  207. fprintf (stderr, "Invalid type %u `%s' in episode %u\n",
  208. op_counter, op, cur->id);
  209. GNUNET_free (type);
  210. GNUNET_free (op);
  211. GNUNET_free (op_name);
  212. GNUNET_free (sec_name);
  213. GNUNET_free (o);
  214. return GNUNET_SYSERR;
  215. }
  216. GNUNET_free (op_name);
  217. /* Get base rate */
  218. GNUNET_asprintf(&op_name, "op-%u-base-rate", op_counter);
  219. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
  220. sec_name, op_name, &o->base_rate))
  221. {
  222. fprintf (stderr, "Missing base rate in operation %u `%s' in episode %u\n",
  223. op_counter, op, cur->id);
  224. GNUNET_free (type);
  225. GNUNET_free (op);
  226. GNUNET_free (op_name);
  227. GNUNET_free (sec_name);
  228. GNUNET_free (o);
  229. return GNUNET_SYSERR;
  230. }
  231. GNUNET_free (op_name);
  232. /* Get max rate */
  233. GNUNET_asprintf(&op_name, "op-%u-max-rate", op_counter);
  234. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
  235. sec_name, op_name, &o->max_rate))
  236. {
  237. if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
  238. (GNUNET_ATS_TEST_TG_RANDOM == o->gen_type) ||
  239. (GNUNET_ATS_TEST_TG_SINUS == o->gen_type))
  240. {
  241. fprintf (stderr, "Missing max rate in operation %u `%s' in episode %u\n",
  242. op_counter, op, cur->id);
  243. GNUNET_free (type);
  244. GNUNET_free (op_name);
  245. GNUNET_free (op);
  246. GNUNET_free (sec_name);
  247. GNUNET_free (o);
  248. return GNUNET_SYSERR;
  249. }
  250. }
  251. GNUNET_free (op_name);
  252. /* Get period */
  253. GNUNET_asprintf(&op_name, "op-%u-period", op_counter);
  254. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
  255. sec_name, op_name, &o->period))
  256. {
  257. o->period = cur->duration;
  258. }
  259. GNUNET_free (op_name);
  260. if (START_PREFERENCE == o->type)
  261. {
  262. /* Get frequency */
  263. GNUNET_asprintf(&op_name, "op-%u-frequency", op_counter);
  264. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
  265. sec_name, op_name, &o->frequency))
  266. {
  267. fprintf (stderr, "Missing frequency in operation %u `%s' in episode %u\n",
  268. op_counter, op, cur->id);
  269. GNUNET_free (type);
  270. GNUNET_free (op_name);
  271. GNUNET_free (op);
  272. GNUNET_free (sec_name);
  273. GNUNET_free (o);
  274. return GNUNET_SYSERR;
  275. }
  276. GNUNET_free (op_name);
  277. /* Get preference */
  278. GNUNET_asprintf(&op_name, "op-%u-pref", op_counter);
  279. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
  280. sec_name, op_name, &pref))
  281. {
  282. fprintf (stderr, "Missing preference in operation %u `%s' in episode %u\n",
  283. op_counter, op, cur->id);
  284. GNUNET_free (type);
  285. GNUNET_free (op_name);
  286. GNUNET_free (op);
  287. GNUNET_free (sec_name);
  288. GNUNET_free_non_null (pref);
  289. GNUNET_free (o);
  290. return GNUNET_SYSERR;
  291. }
  292. if (0 == strcmp(pref, "bandwidth"))
  293. o->pref_type = GNUNET_ATS_PREFERENCE_BANDWIDTH;
  294. else if (0 == strcmp(pref, "latency"))
  295. o->pref_type = GNUNET_ATS_PREFERENCE_LATENCY;
  296. else
  297. {
  298. fprintf (stderr, "Invalid preference in operation %u `%s' in episode %u\n",
  299. op_counter, op, cur->id);
  300. GNUNET_free (type);
  301. GNUNET_free (op_name);
  302. GNUNET_free (op);
  303. GNUNET_free (pref);
  304. GNUNET_free (sec_name);
  305. GNUNET_free_non_null (pref);
  306. GNUNET_free (o);
  307. return GNUNET_SYSERR;
  308. }
  309. GNUNET_free (pref);
  310. GNUNET_free (op_name);
  311. }
  312. }
  313. /* Safety checks */
  314. if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
  315. (GNUNET_ATS_TEST_TG_SINUS == o->gen_type))
  316. {
  317. if ((o->max_rate - o->base_rate) > o->base_rate)
  318. {
  319. /* This will cause an underflow */
  320. GNUNET_break (0);
  321. }
  322. fprintf (stderr, "Selected max rate and base rate cannot be used for desired traffic form!\n");
  323. }
  324. if ((START_SEND == o->type) || (START_PREFERENCE == o->type))
  325. fprintf (stderr, "Found operation %u in episode %u: %s [%llu]->[%llu] == %s, %llu -> %llu in %s\n",
  326. op_counter, cur->id, print_op (o->type), o->src_id,
  327. o->dest_id, (NULL != type) ? type : "",
  328. o->base_rate, o->max_rate,
  329. GNUNET_STRINGS_relative_time_to_string (o->period, GNUNET_YES));
  330. else
  331. fprintf (stderr, "Found operation %u in episode %u: %s [%llu]->[%llu]\n",
  332. op_counter, cur->id, print_op (o->type), o->src_id, o->dest_id);
  333. GNUNET_free_non_null (type);
  334. GNUNET_free (op);
  335. GNUNET_CONTAINER_DLL_insert (cur->head,cur->tail, o);
  336. op_counter++;
  337. }
  338. GNUNET_free (sec_name);
  339. return GNUNET_OK;
  340. }
  341. static int
  342. load_episodes (struct Experiment *e, struct GNUNET_CONFIGURATION_Handle *cfg)
  343. {
  344. int e_counter = 0;
  345. char *sec_name;
  346. struct GNUNET_TIME_Relative e_duration;
  347. struct Episode *cur;
  348. struct Episode *last;
  349. e_counter = 0;
  350. last = NULL;
  351. while (1)
  352. {
  353. GNUNET_asprintf(&sec_name, "episode-%u", e_counter);
  354. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg,
  355. sec_name, "duration", &e_duration))
  356. {
  357. GNUNET_free (sec_name);
  358. break;
  359. }
  360. cur = GNUNET_new (struct Episode);
  361. cur->duration = e_duration;
  362. cur->id = e_counter;
  363. if (GNUNET_OK != load_episode (e, cur, cfg))
  364. {
  365. GNUNET_free (sec_name);
  366. GNUNET_free (cur);
  367. return GNUNET_SYSERR;
  368. }
  369. fprintf (stderr, "Found episode %u with duration %s \n",
  370. e_counter,
  371. GNUNET_STRINGS_relative_time_to_string(cur->duration, GNUNET_YES));
  372. /* Update experiment */
  373. e->num_episodes ++;
  374. e->total_duration = GNUNET_TIME_relative_add(e->total_duration, cur->duration);
  375. /* Put in linked list */
  376. if (NULL == last)
  377. e->start = cur;
  378. else
  379. last->next = cur;
  380. GNUNET_free (sec_name);
  381. e_counter ++;
  382. last = cur;
  383. }
  384. return e_counter;
  385. }
  386. static void
  387. timeout_experiment (void *cls, const struct GNUNET_SCHEDULER_TaskContext* tc)
  388. {
  389. struct Experiment *e = cls;
  390. e->experiment_timeout_task = NULL;
  391. fprintf (stderr, "Experiment timeout!\n");
  392. if (NULL != e->episode_timeout_task)
  393. {
  394. GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
  395. e->episode_timeout_task = NULL;
  396. }
  397. e->e_done_cb (e, GNUNET_TIME_absolute_get_duration(e->start_time),
  398. GNUNET_SYSERR);
  399. }
  400. static void
  401. enforce_start_send (struct GNUNET_ATS_TEST_Operation *op)
  402. {
  403. /*
  404. struct BenchmarkPeer *peer;
  405. struct BenchmarkPartner *partner;
  406. peer = GNUNET_ATS_TEST_get_peer (op->src_id);
  407. if (NULL == peer)
  408. {
  409. GNUNET_break (0);
  410. return;
  411. }
  412. partner = GNUNET_ATS_TEST_get_partner (op->src_id, op->dest_id);
  413. if (NULL == partner)
  414. {
  415. GNUNET_break (0);
  416. return;
  417. }
  418. fprintf (stderr, "Found master %llu slave %llu\n",op->src_id, op->dest_id);
  419. if (NULL != partner->tg)
  420. {
  421. fprintf (stderr, "Stopping traffic between master %llu slave %llu\n",op->src_id, op->dest_id);
  422. GNUNET_ATS_TEST_generate_traffic_stop(partner->tg);
  423. partner->tg = NULL;
  424. }
  425. partner->tg = GNUNET_ATS_TEST_generate_traffic_start(peer, partner,
  426. op->tg_type, op->base_rate, op->max_rate, op->period,
  427. GNUNET_TIME_UNIT_FOREVER_REL);
  428. */
  429. }
  430. static void
  431. enforce_stop_send (struct GNUNET_ATS_TEST_Operation *op)
  432. {
  433. /*
  434. struct BenchmarkPartner *p;
  435. p = GNUNET_ATS_TEST_get_partner (op->src_id, op->dest_id);
  436. if (NULL == p)
  437. {
  438. GNUNET_break (0);
  439. return;
  440. }
  441. fprintf (stderr, "Found master %llu slave %llu\n",op->src_id, op->dest_id);
  442. if (NULL != p->tg)
  443. {
  444. fprintf (stderr, "Stopping traffic between master %llu slave %llu\n",
  445. op->src_id, op->dest_id);
  446. GNUNET_ATS_TEST_generate_traffic_stop(p->tg);
  447. p->tg = NULL;
  448. }
  449. */
  450. }
  451. static void
  452. enforce_start_preference (struct GNUNET_ATS_TEST_Operation *op)
  453. {
  454. /*
  455. struct BenchmarkPeer *peer;
  456. struct BenchmarkPartner *partner;
  457. peer = GNUNET_ATS_TEST_get_peer (op->src_id);
  458. if (NULL == peer)
  459. {
  460. GNUNET_break (0);
  461. return;
  462. }
  463. partner = GNUNET_ATS_TEST_get_partner (op->src_id, op->dest_id);
  464. if (NULL == partner)
  465. {
  466. GNUNET_break (0);
  467. return;
  468. }
  469. fprintf (stderr, "Found master %llu slave %llu\n",op->src_id, op->dest_id);
  470. if (NULL != partner->pg)
  471. {
  472. fprintf (stderr, "Stopping traffic between master %llu slave %llu\n",
  473. op->src_id, op->dest_id);
  474. GNUNET_ATS_TEST_generate_preferences_stop(partner->pg);
  475. partner->pg = NULL;
  476. }
  477. partner->pg = GNUNET_ATS_TEST_generate_preferences_start(peer, partner,
  478. op->tg_type, op->base_rate, op->max_rate, op->period, op->frequency,
  479. op->pref_type);
  480. */
  481. }
  482. static void
  483. enforce_stop_preference (struct GNUNET_ATS_TEST_Operation *op)
  484. {
  485. /*
  486. struct BenchmarkPartner *p;
  487. p = GNUNET_ATS_TEST_get_partner (op->src_id, op->dest_id);
  488. if (NULL == p)
  489. {
  490. GNUNET_break (0);
  491. return;
  492. }
  493. fprintf (stderr, "Found master %llu slave %llu\n",op->src_id, op->dest_id);
  494. if (NULL != p->pg)
  495. {
  496. fprintf (stderr, "Stopping preference between master %llu slave %llu\n",
  497. op->src_id, op->dest_id);
  498. GNUNET_ATS_TEST_generate_preferences_stop (p->pg);
  499. p->pg = NULL;
  500. }
  501. */
  502. }
  503. static void enforce_episode (struct Episode *ep)
  504. {
  505. struct GNUNET_ATS_TEST_Operation *cur;
  506. for (cur = ep->head; NULL != cur; cur = cur->next)
  507. {
  508. fprintf (stderr, "Enforcing operation: %s [%llu]->[%llu] == %llu\n",
  509. print_op (cur->type), cur->src_id, cur->dest_id, cur->base_rate);
  510. switch (cur->type) {
  511. case START_SEND:
  512. enforce_start_send (cur);
  513. break;
  514. case STOP_SEND:
  515. enforce_stop_send (cur);
  516. break;
  517. case START_PREFERENCE:
  518. enforce_start_preference (cur);
  519. break;
  520. case STOP_PREFERENCE:
  521. enforce_stop_preference (cur);
  522. break;
  523. default:
  524. break;
  525. }
  526. }
  527. }
  528. static void
  529. timeout_episode (void *cls, const struct GNUNET_SCHEDULER_TaskContext* tc)
  530. {
  531. struct Experiment *e = cls;
  532. e->episode_timeout_task = NULL;
  533. if (NULL != e->ep_done_cb)
  534. e->ep_done_cb (e->cur);
  535. /* Scheduling next */
  536. e->cur = e->cur->next;
  537. if (NULL == e->cur)
  538. {
  539. /* done */
  540. fprintf (stderr, "Last episode done!\n");
  541. if (NULL != e->experiment_timeout_task)
  542. {
  543. GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
  544. e->experiment_timeout_task = NULL;
  545. }
  546. e->e_done_cb (e, GNUNET_TIME_absolute_get_duration(e->start_time), GNUNET_OK);
  547. return;
  548. }
  549. fprintf (stderr, "Running episode %u with timeout %s\n",
  550. e->cur->id,
  551. GNUNET_STRINGS_relative_time_to_string(e->cur->duration, GNUNET_YES));
  552. enforce_episode(e->cur);
  553. e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
  554. &timeout_episode, e);
  555. }
  556. void
  557. GNUNET_ATS_solvers_experimentation_run (struct Experiment *e,
  558. GNUNET_ATS_TESTING_EpisodeDoneCallback ep_done_cb,
  559. GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb)
  560. {
  561. fprintf (stderr, "Running experiment `%s' with timeout %s\n", e->name,
  562. GNUNET_STRINGS_relative_time_to_string(e->max_duration, GNUNET_YES));
  563. e->e_done_cb = e_done_cb;
  564. e->ep_done_cb = ep_done_cb;
  565. e->start_time = GNUNET_TIME_absolute_get();
  566. /* Start total time out */
  567. e->experiment_timeout_task = GNUNET_SCHEDULER_add_delayed (e->max_duration,
  568. &timeout_experiment, e);
  569. /* Start */
  570. e->cur = e->start;
  571. fprintf (stderr, "Running episode %u with timeout %s\n",
  572. e->cur->id,
  573. GNUNET_STRINGS_relative_time_to_string(e->cur->duration, GNUNET_YES));
  574. enforce_episode(e->cur);
  575. e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
  576. &timeout_episode, e);
  577. }
  578. struct Experiment *
  579. GNUNET_ATS_solvers_experimentation_load (char *filename)
  580. {
  581. struct Experiment *e;
  582. struct GNUNET_CONFIGURATION_Handle *cfg;
  583. e = NULL;
  584. cfg = GNUNET_CONFIGURATION_create();
  585. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, filename))
  586. {
  587. fprintf (stderr, "Failed to load `%s'\n", filename);
  588. GNUNET_CONFIGURATION_destroy (cfg);
  589. return NULL;
  590. }
  591. e = create_experiment ();
  592. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "experiment",
  593. "name", &e->name))
  594. {
  595. fprintf (stderr, "Invalid %s", "name");
  596. free_experiment (e);
  597. return NULL;
  598. }
  599. else
  600. fprintf (stderr, "Experiment name: `%s'\n", e->name);
  601. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_filename (cfg, "experiment",
  602. "cfg_file", &e->cfg_file))
  603. {
  604. fprintf (stderr, "Invalid %s", "cfg_file");
  605. free_experiment (e);
  606. return NULL;
  607. }
  608. else
  609. fprintf (stderr, "Experiment name: `%s'\n", e->cfg_file);
  610. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number(cfg, "experiment",
  611. "masters", &e->num_masters))
  612. {
  613. fprintf (stderr, "Invalid %s", "masters");
  614. free_experiment (e);
  615. return NULL;
  616. }
  617. else
  618. fprintf (stderr, "Experiment masters: `%llu'\n",
  619. e->num_masters);
  620. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number(cfg, "experiment",
  621. "slaves", &e->num_slaves))
  622. {
  623. fprintf (stderr, "Invalid %s", "slaves");
  624. free_experiment (e);
  625. return NULL;
  626. }
  627. else
  628. fprintf (stderr, "Experiment slaves: `%llu'\n",
  629. e->num_slaves);
  630. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment",
  631. "log_freq", &e->log_freq))
  632. {
  633. fprintf (stderr, "Invalid %s", "log_freq");
  634. free_experiment (e);
  635. return NULL;
  636. }
  637. else
  638. fprintf (stderr, "Experiment logging frequency: `%s'\n",
  639. GNUNET_STRINGS_relative_time_to_string (e->log_freq, GNUNET_YES));
  640. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment",
  641. "max_duration", &e->max_duration))
  642. {
  643. fprintf (stderr, "Invalid %s", "max_duration");
  644. free_experiment (e);
  645. return NULL;
  646. }
  647. else
  648. fprintf (stderr, "Experiment duration: `%s'\n",
  649. GNUNET_STRINGS_relative_time_to_string (e->max_duration, GNUNET_YES));
  650. load_episodes (e, cfg);
  651. fprintf (stderr, "Loaded %u episodes with total duration %s\n",
  652. e->num_episodes,
  653. GNUNET_STRINGS_relative_time_to_string (e->total_duration, GNUNET_YES));
  654. GNUNET_CONFIGURATION_destroy (cfg);
  655. return e;
  656. }
  657. void
  658. GNUNET_ATS_solvers_experimentation_stop (struct Experiment *e)
  659. {
  660. if (NULL != e->experiment_timeout_task)
  661. {
  662. GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
  663. e->experiment_timeout_task = NULL;
  664. }
  665. if (NULL != e->episode_timeout_task)
  666. {
  667. GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
  668. e->episode_timeout_task = NULL;
  669. }
  670. free_experiment (e);
  671. }
  672. /**
  673. * Solver
  674. */
  675. struct GNUNET_ATS_TESTING_SolverHandle
  676. {
  677. char * plugin;
  678. struct GNUNET_ATS_PluginEnvironment env;
  679. void *solver;
  680. };
  681. enum GNUNET_ATS_Solvers
  682. {
  683. GNUNET_ATS_SOLVER_PROPORTIONAL,
  684. GNUNET_ATS_SOLVER_MLP,
  685. GNUNET_ATS_SOLVER_RIL,
  686. };
  687. void
  688. GNUNET_ATS_solvers_solver_stop (struct GNUNET_ATS_TESTING_SolverHandle *sh)
  689. {
  690. GNUNET_PLUGIN_unload (sh->plugin, sh->solver);
  691. GNUNET_free (sh->plugin);
  692. GNUNET_free (sh);
  693. }
  694. struct GNUNET_ATS_TESTING_SolverHandle *
  695. GNUNET_ATS_solvers_solver_start (enum GNUNET_ATS_Solvers type)
  696. {
  697. struct GNUNET_ATS_TESTING_SolverHandle *sh;
  698. char * solver_str;
  699. switch (type) {
  700. case GNUNET_ATS_SOLVER_PROPORTIONAL:
  701. solver_str = "proportional";
  702. break;
  703. case GNUNET_ATS_SOLVER_MLP:
  704. solver_str = "mlp";
  705. break;
  706. case GNUNET_ATS_SOLVER_RIL:
  707. solver_str = "ril";
  708. break;
  709. default:
  710. GNUNET_break (0);
  711. return NULL;
  712. break;
  713. }
  714. sh = GNUNET_new (struct GNUNET_ATS_TESTING_SolverHandle);
  715. GNUNET_asprintf (&sh->plugin, "libgnunet_plugin_ats_%s", solver_str);
  716. //sh->solver = GNUNET_PLUGIN_load (sh->plugin, &sh->env);
  717. if (NULL == sh->solver)
  718. {
  719. fprintf (stderr, "Failed to load solver `%s'\n", sh->plugin);
  720. exit (1);
  721. }
  722. return sh;
  723. }
  724. static struct Experiment *e;
  725. static struct GNUNET_ATS_TESTING_SolverHandle *sh;
  726. /**
  727. * cmd option -e: experiment file
  728. */
  729. static char *opt_exp_file;
  730. static char *opt_solver;
  731. /**
  732. * cmd option -l: enable logging
  733. */
  734. static int opt_log;
  735. /**
  736. * cmd option -p: enable plots
  737. */
  738. static int opt_plot;
  739. /**
  740. * cmd option -v: verbose logs
  741. */
  742. static int opt_verbose;
  743. static void
  744. run (void *cls, char * const *args, const char *cfgfile,
  745. const struct GNUNET_CONFIGURATION_Handle *cfg)
  746. {
  747. enum GNUNET_ATS_Solvers solver;
  748. if (NULL == opt_exp_file)
  749. {
  750. fprintf (stderr, "No experiment given ...\n");
  751. exit (1);
  752. }
  753. if (NULL == opt_solver)
  754. {
  755. fprintf (stderr, "No solver given ...\n");
  756. exit (1);
  757. }
  758. if (0 == strcmp(opt_solver, "mlp"))
  759. {
  760. solver = GNUNET_ATS_SOLVER_MLP;
  761. }
  762. else if (0 == strcmp(opt_solver, "proportional"))
  763. {
  764. solver = GNUNET_ATS_SOLVER_PROPORTIONAL;
  765. }
  766. else if (0 == strcmp(opt_solver, "ril"))
  767. {
  768. solver = GNUNET_ATS_SOLVER_RIL;
  769. }
  770. else
  771. {
  772. fprintf (stderr, "No solver given ...");
  773. return;
  774. }
  775. /* load experiment */
  776. e = GNUNET_ATS_solvers_experimentation_load (opt_exp_file);
  777. if (NULL == e)
  778. {
  779. fprintf (stderr, "Failed to load experiment ...\n");
  780. return;
  781. }
  782. /* load solver */
  783. sh = GNUNET_ATS_solvers_solver_start (solver);
  784. if (NULL == sh)
  785. {
  786. fprintf (stderr, "Failed to start solver ...\n");
  787. return;
  788. }
  789. /* start logging */
  790. /* run experiment */
  791. /* WAIT */
  792. }
  793. /**
  794. * Main function of the benchmark
  795. *
  796. * @param argc argument count
  797. * @param argv argument values
  798. */
  799. int
  800. main (int argc, char *argv[])
  801. {
  802. opt_exp_file = NULL;
  803. opt_solver = NULL;
  804. opt_log = GNUNET_NO;
  805. opt_plot = GNUNET_NO;
  806. static struct GNUNET_GETOPT_CommandLineOption options[] =
  807. {
  808. { 's', "solver", NULL,
  809. gettext_noop ("solver to use"),
  810. 1, &GNUNET_GETOPT_set_string, &opt_solver},
  811. { 'e', "experiment", NULL,
  812. gettext_noop ("experiment to use"),
  813. 1, &GNUNET_GETOPT_set_string, &opt_exp_file},
  814. { 'e', "experiment", NULL,
  815. gettext_noop ("experiment to use"),
  816. 1, &GNUNET_GETOPT_set_one, &opt_verbose},
  817. GNUNET_GETOPT_OPTION_END
  818. };
  819. GNUNET_PROGRAM_run (argc, argv, argv[0], NULL, options, &run, argv[0]);
  820. return 0;
  821. }
  822. /* end of file ats-testing-experiment.c*/