gnunet-solver-eval.c 25 KB

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