You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

qspn-empiric.c 35KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356
  1. /* This file is part of Netsukuku
  2. * (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
  3. *
  4. * This source code is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as published
  6. * by the Free Software Foundation; either version 2 of the License,
  7. * or (at your option) any later version.
  8. *
  9. * This source code is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. * Please refer to the GNU Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Public License along with
  15. * this source code; if not, write to:
  16. * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. *
  18. * qspn-empiric:
  19. * This is the living proof of the QSPN algorithm.
  20. * The qspn-empiric simulates an entire network and runs on it the QSPN,
  21. * but it doesn't simulate the qspn with levels.
  22. * Then when all is done it collects the generated data and makes some
  23. * statistics, in this way it's possible to watch the effect of a QSPN
  24. * explosion in a network.
  25. * The qspn-empiric can be also used to solve graph without using djkstra
  26. * hehehe.
  27. * ah,.. yes it uses threads... a lot of them... ^_^ I want a cluster!
  28. * -
  29. * time to explain how this thing happens to work:
  30. * If a map filename to load is not given as argv[1] gen_rnd_map is used
  31. * to create a new random map of MAXGROUPNODE nodes.
  32. * Then we choose a random node to be the QSPN_STARTER.
  33. * Now, instead of simulating the nodes we simulate the packets! Each pkt
  34. * is a thread. When a new thread/pkt is created it sleeps for the rtt there
  35. * is between the "from" node and the "to" node.
  36. * Now we have only to wait.
  37. * enjoy the trip.
  38. */
  39. #include "includes.h"
  40. #include "common.h"
  41. #include "inet.h"
  42. #include "endianness.h"
  43. #include "qspn-empiric.h"
  44. /*
  45. * * * Map functions * * *
  46. */
  47. /*
  48. * pos_from_node: Position from node: It returns the position of the `node'
  49. * in the `map'.
  50. */
  51. int
  52. pos_from_node(map_node * node, map_node * map)
  53. {
  54. return ((char *) node - (char *) map) / sizeof(map_node);
  55. }
  56. map_node *
  57. init_map(size_t len)
  58. {
  59. int i;
  60. map_node *map;
  61. if (!len)
  62. len = sizeof(map_node) * MAXGROUPNODE;
  63. map = (map_node *) xmalloc(len);
  64. setzero(map, len);
  65. for (i = 0; i < MAXGROUPNODE; i++)
  66. map[i].flags |= MAP_VOID;
  67. return map;
  68. }
  69. void
  70. free_map(map_node * map, size_t count)
  71. {
  72. int i, len;
  73. if (!count)
  74. count = MAXGROUPNODE;
  75. len = sizeof(map_node) * count;
  76. for (i = 0; i < count; i++) {
  77. if (map[i].links) {
  78. if (map[i].r_node)
  79. xfree(map[i].r_node);
  80. }
  81. }
  82. setzero(map, len);
  83. xfree(map);
  84. }
  85. map_rnode *
  86. rnode_insert(map_rnode * buf, size_t pos, map_rnode * new)
  87. {
  88. map_rnode *ptr = buf + pos;
  89. memcpy(ptr, new, sizeof(map_rnode));
  90. return ptr;
  91. }
  92. map_rnode *
  93. map_rnode_insert(map_node * node, size_t pos, map_rnode * new)
  94. {
  95. if (pos >= node->links)
  96. fatal("Error in %s: %d: Cannot insert map_rnode in %u position."
  97. " It goes beyond the buffer\n", ERROR_POS, pos);
  98. return rnode_insert(node->r_node, pos, new);
  99. }
  100. map_rnode *
  101. rnode_add(map_node * node, map_rnode * new)
  102. {
  103. node->links++;
  104. if (node->links == 1)
  105. node->r_node = xmalloc(sizeof(map_rnode));
  106. else
  107. node->r_node =
  108. xrealloc(node->r_node, node->links * sizeof(map_rnode));
  109. return map_rnode_insert(node, node->links - 1, new);
  110. }
  111. /*rnode_rtt_compar: It's used by rnode_rtt_order*/
  112. int
  113. rnode_rtt_compar(const void *a, const void *b)
  114. {
  115. map_rnode *rnode_a = (map_rnode *) a, *rnode_b = (map_rnode *) b;
  116. if (MILLISEC(rnode_a->rtt) > MILLISEC(rnode_b->rtt))
  117. return 1;
  118. else if (MILLISEC(rnode_a->rtt) == MILLISEC(rnode_b->rtt))
  119. return 0;
  120. else
  121. return -1;
  122. }
  123. /*rnode_rtt_order: It qsort the rnodes of a map_node comparing their rtt
  124. */
  125. void
  126. rnode_rtt_order(map_node * node)
  127. {
  128. qsort(node->r_node, node->links, sizeof(map_rnode), rnode_rtt_compar);
  129. }
  130. /*
  131. * mod_rnode_addr: Modify_rnode_address
  132. */
  133. int
  134. mod_rnode_addr(map_rnode * rnode, int *map_start, int *new_start)
  135. {
  136. rnode->r_node =
  137. (int *) (((char *) rnode->r_node - (char *) map_start) +
  138. (char *) new_start);
  139. return 0;
  140. }
  141. /*
  142. * get_rnode_block: It packs all the rnode structs of a node. The node->r_node
  143. * pointer of the map_rnode struct is changed to point to the position of the
  144. * node in the map, instead of the address. get_rnode_block returns the number
  145. * of rnode structs packed.
  146. * Note that the packed structs will be in network order.
  147. */
  148. int
  149. get_rnode_block(int *map, map_node * node, map_rnode * rblock, int rstart)
  150. {
  151. int e;
  152. char *p;
  153. for (e = 0; e < node->links; e++) {
  154. p = (char *) &rblock[e + rstart];
  155. memcpy(p, &node->r_node[e].flags, sizeof(u_short));
  156. p += sizeof(u_short);
  157. memcpy(p, &node->r_node[e].r_node, sizeof(int *));
  158. p += sizeof(int *);
  159. memcpy(p, &node->r_node[e].rtt, sizeof(struct timeval));
  160. p += sizeof(struct timeval);
  161. memcpy(p, &node->r_node[e].trtt, sizeof(struct timeval));
  162. p += sizeof(struct timeval);
  163. mod_rnode_addr(&rblock[e + rstart], map, 0);
  164. ints_host_to_network(&rblock[e + rstart], map_rnode_iinfo);
  165. }
  166. return e;
  167. }
  168. /*
  169. * map_get_rblock: It uses get_rnode_block to pack all the int_map's rnode.
  170. * `maxgroupnode' is the number of nodes present in the map.
  171. * `map' is the actual int_map, while `addr_map' is the address used by get_rnode_block
  172. * to change the rnodes' pointers (read get_rnode_block).
  173. * It returns a pointer to the start of the rnode block and stores in `count'
  174. * the number of rnode structs packed.
  175. * On error NULL is returned.
  176. */
  177. map_rnode *
  178. map_get_rblock(map_node * map, int *addr_map, int maxgroupnode, int *count)
  179. {
  180. int i, c = 0, tot = 0;
  181. map_rnode *rblock;
  182. *count = 0;
  183. for (i = 0; i < maxgroupnode; i++)
  184. tot += map[i].links;
  185. if (!tot)
  186. return 0;
  187. rblock = (map_rnode *) xmalloc(MAP_RNODE_PACK_SZ * tot);
  188. for (i = 0; i < maxgroupnode; i++)
  189. c += get_rnode_block((int *) addr_map, &map[i], rblock, c);
  190. *count = c;
  191. return rblock;
  192. }
  193. /*
  194. * store_rnode_block: Given a correct `node' it restores in it all the r_node structs
  195. * contained in the rnode_block. It returns the number of rnode structs restored.
  196. * Note that `rblock' will be modified during the restoration.
  197. */
  198. int
  199. store_rnode_block(int *map, map_node * node, map_rnode * rblock,
  200. int rstart)
  201. {
  202. int i;
  203. char *p;
  204. if (!node->links)
  205. return 0;
  206. node->r_node = xmalloc(MAP_RNODE_PACK_SZ * node->links);
  207. for (i = 0; i < node->links; i++) {
  208. p = (char *) &rblock[i + rstart];
  209. ints_network_to_host(p, map_rnode_iinfo);
  210. memcpy(&node->r_node[i].flags, p, sizeof(u_short));
  211. p += sizeof(u_short);
  212. memcpy(&node->r_node[i].r_node, p, sizeof(int *));
  213. p += sizeof(int *);
  214. memcpy(&node->r_node[i].rtt, p, sizeof(struct timeval));
  215. p += sizeof(struct timeval);
  216. memcpy(&node->r_node[i].trtt, p, sizeof(struct timeval));
  217. p += sizeof(struct timeval);
  218. mod_rnode_addr(&node->r_node[i], 0, map);
  219. }
  220. return i;
  221. }
  222. /*
  223. * map_store_rblock: Given a correct int_map with `maxgroupnode' nodes,
  224. * it restores all the r_node structs in the `map' from the `rblock'
  225. * using store_rnode_block. `addr_map' is the address used to change
  226. * the rnodes' pointers (read store_rnode_block).
  227. */
  228. int
  229. map_store_rblock(map_node * map, int *addr_map, int maxgroupnode,
  230. map_rnode * rblock)
  231. {
  232. int i, c = 0;
  233. for (i = 0; i < maxgroupnode; i++)
  234. c += store_rnode_block(addr_map, &map[i], rblock, c);
  235. return c;
  236. }
  237. int
  238. verify_int_map_hdr(struct int_map_hdr *imap_hdr, int maxgroupnode,
  239. int maxrnodeblock)
  240. {
  241. return 0;
  242. }
  243. /*
  244. * pack_map_node: it packs the `node' struct and stores it in `pack'.
  245. * The packed struct will be in network order
  246. */
  247. void
  248. pack_map_node(map_node * node, char *pack)
  249. {
  250. char *buf;
  251. buf = pack;
  252. memcpy(buf, &node->flags, sizeof(u_int));
  253. buf += sizeof(u_int);
  254. memcpy(buf, &node->brdcast, sizeof(u_int) * MAXGROUPNODE);
  255. buf += sizeof(u_int) * MAXGROUPNODE;
  256. memcpy(buf, &node->links, sizeof(u_short));
  257. buf += sizeof(u_short);
  258. ints_host_to_network(pack, map_node_iinfo);
  259. }
  260. /*
  261. * unpack_map_node: it unpacks `pack', which contains a packed map_node struct.
  262. * The restored map_node struct will be written in `node'.
  263. * Note that `pack' will be modified during the restoration.
  264. */
  265. void
  266. unpack_map_node(map_node * node, char *pack)
  267. {
  268. char *buf;
  269. ints_network_to_host(pack, map_node_iinfo);
  270. buf = pack;
  271. memcpy(&node->flags, buf, sizeof(u_int));
  272. buf += sizeof(u_int);
  273. memcpy(&node->brdcast, buf, sizeof(u_int) * MAXGROUPNODE);
  274. buf += sizeof(u_int) * MAXGROUPNODE;
  275. memcpy(&node->links, buf, sizeof(u_short));
  276. buf += sizeof(u_short);
  277. node->r_node = 0;
  278. }
  279. /*
  280. * pack_map: It returns a pack of the int/bmap_map `map', which has
  281. * `maxgroupnode' nodes ready to be saved or sent. In `pack_sz' it
  282. * stores the size of the package. For info on `addr_map' please
  283. * read get_map_rblock().
  284. * The pack will be in network order.
  285. */
  286. char *
  287. pack_map(map_node * map, int *addr_map, int maxgroupnode,
  288. map_node * root_node, size_t * pack_sz)
  289. {
  290. struct int_map_hdr imap_hdr;
  291. map_rnode *rblock = 0;
  292. int count, i;
  293. char *package, *p;
  294. if (!addr_map)
  295. addr_map = (int *) map;
  296. setzero(&imap_hdr, sizeof(struct int_map_hdr));
  297. if (map) {
  298. /*rblock packing */
  299. rblock = map_get_rblock(map, addr_map, maxgroupnode, &count);
  300. /*Header creation */
  301. imap_hdr.root_node = root_node ? pos_from_node(root_node, map) : 0;
  302. imap_hdr.rblock_sz = count * MAP_RNODE_PACK_SZ;
  303. imap_hdr.int_map_sz = maxgroupnode * MAP_NODE_PACK_SZ;
  304. }
  305. /*Package creation */
  306. *pack_sz = INT_MAP_BLOCK_SZ(imap_hdr.int_map_sz, imap_hdr.rblock_sz);
  307. package = xmalloc(*pack_sz);
  308. memcpy(package, &imap_hdr, sizeof(struct int_map_hdr));
  309. ints_host_to_network(package, int_map_hdr_iinfo);
  310. p = package;
  311. if (imap_hdr.int_map_sz) {
  312. /* Pack the map_node strucs of the `map' */
  313. p += sizeof(struct int_map_hdr);
  314. for (i = 0; i < maxgroupnode; i++) {
  315. pack_map_node(&map[i], p);
  316. p += MAP_NODE_PACK_SZ;
  317. }
  318. }
  319. if (imap_hdr.rblock_sz) {
  320. memcpy(p, rblock, imap_hdr.rblock_sz);
  321. xfree(rblock);
  322. }
  323. return package;
  324. }
  325. /*
  326. * unpack_map: Given a valid int/bmap_map package (packed with pack_intmap), it
  327. * allocates a brand new int_map and restores in it the map and the rnodes.
  328. * It puts in `*new_root' the pointer to the root_node in the loaded map.
  329. * For info on `addr_map' please read map_store_rblock().
  330. * On success the a pointer to the new int_map is retuned, otherwise 0 will be
  331. * the fatal value.
  332. * Note: `pack' will be modified during the unpacking.
  333. */
  334. map_node *
  335. unpack_map(char *pack, int *addr_map, map_node ** new_root,
  336. int maxgroupnode, int maxrnodeblock)
  337. {
  338. map_node *map;
  339. struct int_map_hdr *imap_hdr = (struct int_map_hdr *) pack;
  340. map_rnode *rblock;
  341. int err, nodes, i;
  342. char *p;
  343. ints_network_to_host(imap_hdr, int_map_hdr_iinfo);
  344. if (verify_int_map_hdr(imap_hdr, maxgroupnode, maxrnodeblock)) {
  345. error("Malformed int/bmap_map_hdr. Aborting unpack_map().");
  346. return 0;
  347. }
  348. /*Extracting the map... */
  349. p = pack + sizeof(struct int_map_hdr);
  350. map = init_map(0);
  351. if (!imap_hdr->int_map_sz)
  352. return map;
  353. /* Restore in `map' the packed map_node struct */
  354. nodes = imap_hdr->int_map_sz / MAP_NODE_PACK_SZ;
  355. for (i = 0; i < nodes; i++) {
  356. unpack_map_node(&map[i], p);
  357. p += MAP_NODE_PACK_SZ;
  358. }
  359. /*Restoring the rnodes... */
  360. if (imap_hdr->rblock_sz) {
  361. /*Extracting the rnodes block and merging it to the map */
  362. rblock = (map_rnode *) p;
  363. if (!addr_map)
  364. addr_map = (int *) map;
  365. err = map_store_rblock(map, addr_map, nodes, rblock);
  366. if (err != imap_hdr->rblock_sz / MAP_RNODE_PACK_SZ) {
  367. error
  368. ("An error occurred while storing the rnodes block in the int/bnode_map");
  369. free_map(map, 0);
  370. return 0;
  371. }
  372. }
  373. if (new_root) {
  374. map[imap_hdr->root_node].flags |= MAP_ME;
  375. *new_root = &map[imap_hdr->root_node];
  376. }
  377. return map;
  378. }
  379. /*
  380. * * * save/load int_map * * *
  381. */
  382. int
  383. save_map(map_node * map, map_node * root_node, char *file)
  384. {
  385. FILE *fd;
  386. size_t pack_sz;
  387. char *pack;
  388. /*Pack! */
  389. pack = pack_map(map, 0, MAXGROUPNODE, root_node, &pack_sz);
  390. if (!pack_sz || !pack)
  391. return 0;
  392. if ((fd = fopen(file, "w")) == NULL) {
  393. error("Cannot save the int_map in %s: %s", file, strerror(errno));
  394. return -1;
  395. }
  396. /*Write! */
  397. fwrite(pack, pack_sz, 1, fd);
  398. xfree(pack);
  399. fclose(fd);
  400. return 0;
  401. }
  402. /*
  403. * load_map: It loads the internal_map from `file'.
  404. * It returns the start of the map and if `new_root' is not NULL, it
  405. * puts in `*new_root' the pointer to the root_node in the loaded map.
  406. * On error it returns NULL.
  407. */
  408. map_node *
  409. load_map(char *file, map_node ** new_root)
  410. {
  411. map_node *map = 0;
  412. FILE *fd;
  413. struct int_map_hdr imap_hdr;
  414. char *pack = 0;
  415. size_t pack_sz;
  416. if ((fd = fopen(file, "r")) == NULL) {
  417. error("Cannot load the map from %s: %s", file, strerror(errno));
  418. return 0;
  419. }
  420. if (!fread(&imap_hdr, sizeof(struct int_map_hdr), 1, fd))
  421. goto finish;
  422. ints_network_to_host(&imap_hdr, int_map_hdr_iinfo);
  423. if (!imap_hdr.int_map_sz)
  424. goto finish;
  425. if (verify_int_map_hdr(&imap_hdr, MAXGROUPNODE, MAXRNODEBLOCK_PACK_SZ))
  426. goto finish;
  427. rewind(fd);
  428. pack_sz = INT_MAP_BLOCK_SZ(imap_hdr.int_map_sz, imap_hdr.rblock_sz);
  429. pack = xmalloc(pack_sz);
  430. if (!fread(pack, pack_sz, 1, fd))
  431. goto finish;
  432. map =
  433. unpack_map(pack, 0, new_root, MAXGROUPNODE, MAXRNODEBLOCK_PACK_SZ);
  434. finish:
  435. if (pack)
  436. xfree(pack);
  437. fclose(fd);
  438. if (!map)
  439. error("Malformed map file. Aborting load_map().");
  440. return map;
  441. }
  442. /*
  443. * ******* End of map functions *********
  444. */
  445. /* thread_joint creates a thread in JOINED STATE or in DETACHED STATE*/
  446. void
  447. thread_joint(int joint, void *(*start_routine) (void *), void *nopt)
  448. {
  449. pthread_t thread;
  450. total_threads++;
  451. if (joint && !disable_joint) {
  452. fprintf(stderr, "%u: Joining the thread...", pthread_self());
  453. pthread_create(&thread, NULL, start_routine, (void *) nopt);
  454. fprintf(stderr, " %u\n", thread);
  455. pthread_join(thread, NULL);
  456. } else {
  457. pthread_create(&thread, NULL, start_routine, (void *) nopt);
  458. pthread_detach(thread);
  459. }
  460. }
  461. /* wait_threads: it waits until the total number of threads doesn't change anymore*/
  462. void
  463. wait_threads(void)
  464. {
  465. int tt = 0;
  466. while (total_threads != tt) {
  467. tt = total_threads;
  468. sleep(5);
  469. }
  470. }
  471. /* gen_rnd_map: Generate Random Map.
  472. * It creates the start_node in the map.
  473. * (If back_link >= 0) It then adds the back_link node (with rtt equal to back_link_rtt)
  474. * in the start_node's rnodes and adds other random rnodes (with random rtt).
  475. * If the added new rnode doesn't exist yet in the map it calls recusively itself giving
  476. * the rnode as the "start_node" argument, the start_node as back_link and the rnode's rtt
  477. * as back_link_rtt. Else if the new rnode exists, it adds the start_node in the rnode's rnodes.
  478. * Automagically it terminates.
  479. */
  480. void
  481. gen_rnd_map(int start_node, int back_link, int back_link_rtt)
  482. {
  483. int i = start_node, r = 0, e, b = 0, rnode_rnd, ms_rnd;
  484. map_rnode rtmp;
  485. if (i > MAXGROUPNODE)
  486. i = rand_range(0, MAXGROUPNODE - 1);
  487. if (back_link >= 0 && back_link < MAXGROUPNODE)
  488. b = 1;
  489. if (int_map[i].flags & MAP_HNODE)
  490. return;
  491. r = rand_range(0, MAXLINKS);
  492. int_map[i].flags |= MAP_HNODE;
  493. int_map[i].flags &= ~MAP_VOID;
  494. if (b) {
  495. r++;
  496. setzero(&rtmp, sizeof(map_rnode));
  497. rtmp.r_node = (u_int *) & int_map[back_link];
  498. rtmp.rtt.tv_usec = back_link_rtt;
  499. //printf("Node %d -> Adding rnode %d (back link)\n", i, back_link);
  500. rnode_add(&int_map[i], &rtmp);
  501. b = 0;
  502. }
  503. /*printf("Creating %d links for the node %d\n", r, i); */
  504. for (e = 0; e < r; e++) { /*It's e<r and not e<=r because we've already added the back_link rnode at r position */
  505. setzero(&rtmp, sizeof(map_rnode));
  506. random_node:
  507. /*Are we adding ourself or an already addded node in our rnodes? */
  508. while ((rnode_rnd = (rand_range(0, MAXGROUPNODE - 1))) == i);
  509. for (b = 0; b < int_map[i].links; b++)
  510. if ((map_node *) & int_map[rnode_rnd] ==
  511. (map_node *) int_map[i].r_node[b].r_node) {
  512. //printf("goto random_node;\n");
  513. goto random_node;
  514. }
  515. /*the building of the new rnode is here */
  516. rtmp.r_node = (u_int *) & int_map[rnode_rnd];
  517. ms_rnd = rand_range(0, (MAXRTT * 1000));
  518. rtmp.rtt.tv_usec = ms_rnd * 1000;
  519. //printf("Node %d -> Adding rnode %d\n", i, rnode_rnd);
  520. rnode_add(&int_map[i], &rtmp);
  521. /*Does exist the node "rnode_rnd" added as rnode? */
  522. if (int_map[rnode_rnd].flags & MAP_VOID) {
  523. /*No, let's create it */
  524. gen_rnd_map(rnode_rnd, i, rtmp.rtt.tv_usec);
  525. } else {
  526. /*It does, let's check if it has a link to me */
  527. int c = 0;
  528. for (b = 0; b < int_map[rnode_rnd].links; b++)
  529. if ((map_node *) int_map[rnode_rnd].r_node[b].r_node ==
  530. &int_map[i]) {
  531. c = 1;
  532. break;
  533. }
  534. if (!c) {
  535. /*We create the back link from rnode_rnd to me (i) */
  536. setzero(&rtmp, sizeof(map_rnode));
  537. rtmp.r_node = (u_int *) & int_map[i];
  538. rtmp.rtt.tv_usec = ms_rnd * 1000;
  539. //printf("Node %d -> Adding rnode %d (front link)\n", rnode_rnd,i);
  540. rnode_add(&int_map[rnode_rnd], &rtmp);
  541. }
  542. }
  543. }
  544. }
  545. /*init the qspn queue*/
  546. void
  547. init_q_queue(map_node * map)
  548. {
  549. int i;
  550. for (i = 0; i < MAXGROUPNODE; i++) {
  551. if (map[i].links) {
  552. qspn_q[i] = xmalloc(sizeof(struct qspn_queue) * map[i].links);
  553. setzero(qspn_q[i], sizeof(struct qspn_queue));
  554. }
  555. }
  556. }
  557. void
  558. free_q_queue(map_node * map)
  559. {
  560. int i, e, x;
  561. for (i = 0; i < MAXGROUPNODE; i++) {
  562. xfree(qspn_q[i]);
  563. }
  564. }
  565. /* store_tracer_pkt: It stores the tracer_pkt received in the
  566. * packets' db (used to collect stats after) and it adds our
  567. * entry in the new tracer_pkt that will be sent
  568. */
  569. int
  570. store_tracer_pkt(struct q_opt *qopt)
  571. {
  572. int x, pkt, to = qopt->q.to;
  573. pthread_mutex_lock(&mutex[to]);
  574. pkt = pkt_dbc[to];
  575. pkt_dbc[to]++;
  576. pthread_mutex_unlock(&mutex[to]);
  577. if (!pkt)
  578. pkt_db[to] = xmalloc(sizeof(struct q_opt *));
  579. else
  580. pkt_db[to] =
  581. xrealloc(pkt_db[to], sizeof(struct q_opt *) * pkt_dbc[to]);
  582. pkt_db[to][pkt] = xmalloc(sizeof(struct q_pkt));
  583. setzero(pkt_db[to][pkt], sizeof(struct q_pkt));
  584. pkt_db[to][pkt]->q_id = qopt->q.q_id;
  585. pkt_db[to][pkt]->q_sub_id = qopt->q.q_sub_id;
  586. pkt_db[to][pkt]->from = qopt->q.from;
  587. pkt_db[to][pkt]->routes = qopt->q.routes + 1;
  588. if (pkt_db[to][pkt]->routes) {
  589. pkt_db[to][pkt]->tracer =
  590. xmalloc(sizeof(short) * pkt_db[to][pkt]->routes);
  591. for (x = 0; x < qopt->q.routes; x++)
  592. pkt_db[to][pkt]->tracer[x] = qopt->q.tracer[x];
  593. /*Let's add our entry in the tracer pkt */
  594. pkt_db[to][pkt]->tracer[pkt_db[to][pkt]->routes - 1] = to;
  595. }
  596. pkt_db[to][pkt]->op = qopt->q.op;
  597. pkt_db[to][pkt]->broadcast = qopt->q.broadcast;
  598. return pkt;
  599. }
  600. /*Ok, I see... The qspn_backpro is a completely lame thing!*/
  601. void *
  602. send_qspn_backpro(void *argv)
  603. {
  604. struct q_opt *qopt = (struct q_opt *) argv, *nopt;
  605. int x, dst, pkt, to = qopt->q.to;
  606. usleep(qopt->sleep);
  607. fprintf(stderr, "%u: qspn_backpro from %d to %d\n", pthread_self(),
  608. qopt->q.from, to);
  609. /*Now we store the received pkt in our pkt_db */
  610. pkt = store_tracer_pkt(qopt);
  611. /*We've arrived... finally */
  612. if (int_map[to].flags & QSPN_STARTER) {
  613. fprintf(stderr, "%u: qspn_backpro: We've arrived... finally\n",
  614. pthread_self());
  615. return NULL;
  616. }
  617. for (x = 0; x < int_map[to].links; x++) {
  618. if ((map_node *) int_map[to].r_node[x].r_node ==
  619. &int_map[qopt->q.from])
  620. continue;
  621. if (int_map[to].r_node[x].flags & QSPN_CLOSED) {
  622. dst =
  623. ((void *) int_map[to].r_node[x].r_node -
  624. (void *) int_map) / sizeof(map_node);
  625. gbl_stat.total_pkts++;
  626. node_stat[to].total_pkts++;
  627. nopt = xmalloc(sizeof(struct q_opt));
  628. setzero(nopt, sizeof(struct q_opt));
  629. nopt->sleep = int_map[to].r_node[x].rtt.tv_usec;
  630. nopt->q.to = dst;
  631. nopt->q.from = to;
  632. nopt->q.routes = pkt_db[to][pkt]->routes;
  633. nopt->q.tracer = pkt_db[to][pkt]->tracer;
  634. nopt->q.broadcast = pkt_db[to][pkt]->broadcast;
  635. nopt->join = qopt->join;
  636. gbl_stat.qspn_backpro++;
  637. node_stat[to].qspn_backpro++;
  638. nopt->q.op = OP_BACKPRO;
  639. thread_joint(qopt->join, send_qspn_backpro, (void *) nopt);
  640. }
  641. }
  642. xfree(qopt);
  643. total_threads--;
  644. pthread_exit(NULL);
  645. }
  646. void *
  647. send_qspn_reply(void *argv)
  648. {
  649. struct q_opt *qopt = (struct q_opt *) argv, *nopt;
  650. int x, dst, pkt, to = qopt->q.to;
  651. usleep(qopt->sleep);
  652. fprintf(stderr, "%u: qspn_reply from %d to %d\n", pthread_self(),
  653. qopt->q.from, to);
  654. /*Let's store the tracer_pkt first */
  655. pkt = store_tracer_pkt(qopt);
  656. /*Bad old broadcast pkt */
  657. if (qopt->q.broadcast <= int_map[to].brdcast[qopt->q.from]) {
  658. fprintf(stderr,
  659. "%u: DROPPED old brdcast: q.broadcast: %d, qopt->q.from broadcast: %d\n",
  660. pthread_self(), qopt->q.broadcast,
  661. int_map[to].brdcast[qopt->q.from]);
  662. return NULL;
  663. } else
  664. int_map[to].brdcast[qopt->q.from] = qopt->q.broadcast;
  665. /*Let's keep broadcasting */
  666. for (x = 0; x < int_map[to].links; x++) {
  667. if ((map_node *) int_map[to].r_node[x].r_node ==
  668. &int_map[qopt->q.from])
  669. continue;
  670. dst =
  671. ((void *) int_map[to].r_node[x].r_node -
  672. (void *) int_map) / sizeof(map_node);
  673. gbl_stat.total_pkts++;
  674. node_stat[to].total_pkts++;
  675. nopt = xmalloc(sizeof(struct q_opt));
  676. setzero(nopt, sizeof(struct q_opt));
  677. nopt->sleep = int_map[to].r_node[x].rtt.tv_usec;
  678. nopt->q.to = dst;
  679. nopt->q.from = to;
  680. nopt->q.routes = pkt_db[to][pkt]->routes;
  681. nopt->q.tracer = pkt_db[to][pkt]->tracer;
  682. nopt->q.broadcast = pkt_db[to][pkt]->broadcast;
  683. nopt->join = qopt->join;
  684. gbl_stat.qspn_replies++;
  685. node_stat[to].qspn_replies++;
  686. nopt->q.op = OP_REPLY;
  687. thread_joint(qopt->join, send_qspn_reply, (void *) nopt);
  688. }
  689. xfree(qopt);
  690. total_threads--;
  691. pthread_exit(NULL);
  692. }
  693. /*Holy Disagio, I wrote this piece of code without seeing actually it, I don't
  694. * know what it will generate... where am I?
  695. */
  696. void *
  697. send_qspn_open(void *argv)
  698. {
  699. struct q_opt *qopt = (struct q_opt *) argv, *nopt;
  700. int x, i = 0, dst, pkt, to = qopt->q.to;
  701. int re, sub_id = qopt->q.q_sub_id;
  702. usleep(qopt->sleep);
  703. fprintf(stderr, "%u: qspn_open from %d to %d [subid: %d]\n",
  704. pthread_self(), qopt->q.from, to, sub_id);
  705. pkt = store_tracer_pkt(qopt);
  706. if (to == sub_id) {
  707. fprintf(stderr,
  708. "%u: qspn_open: We received a qspn_open, but we are the OPENER!!\n",
  709. pthread_self());
  710. return NULL;
  711. }
  712. for (x = 0; x < int_map[to].links; x++) {
  713. if ((map_node *) int_map[to].r_node[x].r_node ==
  714. &int_map[qopt->q.from]) {
  715. qspn_q[to][x].flags[sub_id] |= QSPN_OPENED;
  716. fprintf(stderr, "%u: node:%d->rnode %d opened\n",
  717. pthread_self(), to, x);
  718. }
  719. if (!(qspn_q[to][x].flags[sub_id] & QSPN_OPENED))
  720. i++;
  721. }
  722. /*Shall we stop our insane run? */
  723. if (!i) {
  724. /*Yai! We've finished the reopening of heaven */
  725. fprintf(stderr,
  726. "%u: Yai! We've finished the reopening of heaven\n",
  727. pthread_self());
  728. return NULL;
  729. }
  730. for (x = 0; x < int_map[to].links; x++) {
  731. if ((map_node *) int_map[to].r_node[x].r_node ==
  732. &int_map[qopt->q.from])
  733. continue;
  734. if (qspn_q[to][x].flags[sub_id] & QSPN_OPENED)
  735. continue;
  736. dst =
  737. ((void *) int_map[to].r_node[x].r_node -
  738. (void *) int_map) / sizeof(map_node);
  739. gbl_stat.total_pkts++;
  740. node_stat[to].total_pkts++;
  741. nopt = xmalloc(sizeof(struct q_opt));
  742. setzero(nopt, sizeof(struct q_opt));
  743. nopt->q.q_id = qopt->q.q_id;
  744. nopt->q.q_sub_id = sub_id;
  745. nopt->q.from = to;
  746. nopt->q.to = dst;
  747. nopt->q.routes = pkt_db[to][pkt]->routes;
  748. nopt->q.tracer = pkt_db[to][pkt]->tracer;
  749. nopt->sleep = int_map[to].r_node[x].rtt.tv_usec;
  750. nopt->q.broadcast = pkt_db[to][pkt]->broadcast;
  751. if (x == int_map[to].links - 1)
  752. qopt->join = 1;
  753. nopt->join = qopt->join;
  754. gbl_stat.qspn_replies++;
  755. node_stat[to].qspn_replies++;
  756. nopt->q.op = OP_OPEN;
  757. thread_joint(qopt->join, send_qspn_open, (void *) nopt);
  758. }
  759. xfree(qopt);
  760. total_threads--;
  761. pthread_exit(NULL);
  762. }
  763. void *
  764. send_qspn_pkt(void *argv)
  765. {
  766. struct q_opt *qopt = (struct q_opt *) argv, *nopt;
  767. int x, i = 0, dst, pkt, to = qopt->q.to;
  768. usleep(qopt->sleep);
  769. fprintf(stderr, "%u: qspn_pkt from %d to %d\n", pthread_self(),
  770. qopt->q.from, to);
  771. pkt = store_tracer_pkt(qopt);
  772. if (qopt->q.routes > 1 && (int_map[to].flags & QSPN_STARTER)) {
  773. fprintf(stderr,
  774. "%u: qspn_pkt: We received a qspn_pkt, but we are the QSPN_STARTER!!\n",
  775. pthread_self());
  776. return NULL;
  777. }
  778. for (x = 0; x < int_map[to].links; x++) {
  779. if ((map_node *) int_map[to].r_node[x].r_node ==
  780. &int_map[qopt->q.from]) {
  781. int_map[to].r_node[x].flags |= QSPN_CLOSED;
  782. /*fprintf(stderr, "%u: node:%d->rnode %d closed\n", pthread_self(), to, x); */
  783. }
  784. if (!(int_map[to].r_node[x].flags & QSPN_CLOSED))
  785. i++;
  786. }
  787. #ifdef Q_OPEN
  788. if (!i && !(int_map[to].flags & QSPN_OPENER)
  789. && !(int_map[to].flags & QSPN_STARTER)) {
  790. /*W00t I'm an extreme node! */
  791. fprintf(stderr, "%u: W00t I'm an extreme node!\n", pthread_self());
  792. int_map[to].flags |= QSPN_OPENER;
  793. for (x = 0; x < int_map[to].links; x++) {
  794. /*if(int_map[to].r_node[x].flags & QSPN_SENT)
  795. continue;
  796. */
  797. dst =
  798. ((void *) int_map[to].r_node[x].r_node -
  799. (void *) int_map) / sizeof(map_node);
  800. gbl_stat.total_pkts++;
  801. node_stat[to].total_pkts++;
  802. nopt = xmalloc(sizeof(struct q_opt));
  803. setzero(nopt, sizeof(struct q_opt));
  804. nopt->sleep = int_map[to].r_node[x].rtt.tv_usec;
  805. nopt->q.q_id = pkt_db[to][pkt]->q_id;
  806. nopt->q.q_sub_id = to;
  807. nopt->q.to = dst;
  808. nopt->q.from = to;
  809. if ((map_node *) int_map[to].r_node[x].r_node ==
  810. &int_map[qopt->q.from]) {
  811. nopt->q.tracer = xmalloc(sizeof(short));
  812. nopt->q.tracer[0] = nopt->q.from;
  813. nopt->q.routes = 1;
  814. } else {
  815. nopt->q.routes = pkt_db[to][pkt]->routes;
  816. nopt->q.tracer = pkt_db[to][pkt]->tracer;
  817. }
  818. nopt->q.op = OP_OPEN;
  819. nopt->q.broadcast = pkt_db[to][pkt]->broadcast;
  820. nopt->join = qopt->join;
  821. gbl_stat.qspn_replies++;
  822. node_stat[to].qspn_replies++;
  823. fprintf(stderr, "%u: Sending a qspn_open to %d\n",
  824. pthread_self(), dst);
  825. thread_joint(qopt->join, send_qspn_open, (void *) nopt);
  826. xfree(qopt);
  827. return NULL;
  828. }
  829. }
  830. #else /*Q_OPEN not defined */
  831. /*Shall we send a QSPN_REPLY? */
  832. if (!i && !(int_map[to].flags & QSPN_OPENER)
  833. && !(int_map[to].flags & QSPN_STARTER)) {
  834. /*W00t I'm an extreme node! */
  835. fprintf(stderr, "%u: W00t I'm an extreme node!\n", pthread_self());
  836. int_map[to].flags |= QSPN_OPENER;
  837. for (x = 0; x < int_map[to].links; x++) {
  838. if ((map_node *) int_map[to].r_node[x].r_node ==
  839. &int_map[qopt->q.from])
  840. continue;
  841. /*We've to clear the closed link
  842. int_map[to].r_node[x].flags&=~QSPN_CLOSED;
  843. */
  844. dst =
  845. ((void *) int_map[to].r_node[x].r_node -
  846. (void *) int_map) / sizeof(map_node);
  847. gbl_stat.total_pkts++;
  848. node_stat[to].total_pkts++;
  849. nopt = xmalloc(sizeof(struct q_opt));
  850. setzero(nopt, sizeof(struct q_opt));
  851. nopt->sleep = int_map[to].r_node[x].rtt.tv_usec;
  852. nopt->q.to = dst;
  853. nopt->q.from = to;
  854. nopt->q.routes = pkt_db[to][pkt]->routes;
  855. nopt->q.tracer = pkt_db[to][pkt]->tracer;
  856. nopt->q.op = OP_REPLY;
  857. int_map[to].broadcast[to]++;
  858. nopt->q.broadcast = int_map[to].broadcast[to];
  859. nopt->join = qopt->join;
  860. gbl_stat.qspn_replies++;
  861. node_stat[to].qspn_replies++;
  862. fprintf(stderr, "%u: Sending a qspn_reply to %d\n",
  863. pthread_self(), dst);
  864. thread_joint(qopt->join, send_qspn_reply, (void *) nopt);
  865. xfree(qopt);
  866. return NULL;
  867. }
  868. }
  869. #endif /*Q_OPEN */
  870. for (x = 0; x < int_map[to].links; x++) {
  871. if ((map_node *) int_map[to].r_node[x].r_node ==
  872. &int_map[qopt->q.from])
  873. continue;
  874. #ifndef Q_BACKPRO
  875. if (int_map[to].r_node[x].flags & QSPN_CLOSED)
  876. continue;
  877. #endif
  878. dst =
  879. ((void *) int_map[to].r_node[x].r_node -
  880. (void *) int_map) / sizeof(map_node);
  881. gbl_stat.total_pkts++;
  882. node_stat[to].total_pkts++;
  883. nopt = xmalloc(sizeof(struct q_opt));
  884. setzero(nopt, sizeof(struct q_opt));
  885. nopt->q.from = to;
  886. nopt->q.to = dst;
  887. nopt->q.routes = pkt_db[to][pkt]->routes;
  888. nopt->q.tracer = pkt_db[to][pkt]->tracer;
  889. nopt->sleep = int_map[to].r_node[x].rtt.tv_usec;
  890. nopt->q.broadcast = pkt_db[to][pkt]->broadcast;
  891. nopt->join = qopt->join;
  892. if (int_map[to].r_node[x].flags & QSPN_CLOSED
  893. && !(int_map[to].r_node[x].flags & QSPN_BACKPRO)) {
  894. #ifdef Q_BACKPRO
  895. gbl_stat.qspn_backpro++;
  896. node_stat[to].qspn_backpro++;
  897. nopt->q.op = OP_BACKPRO;
  898. int_map[to].r_node[x].flags |= QSPN_BACKPRO;
  899. thread_joint(qopt->join, send_qspn_backpro, (void *) nopt);
  900. #else
  901. 0;
  902. #endif /*Q_BACKPRO */
  903. } else if (!(int_map[to].r_node[x].flags & QSPN_CLOSED)) {
  904. gbl_stat.qspn_requests++;
  905. node_stat[to].qspn_requests++;
  906. nopt->q.op = OP_REQUEST;
  907. //int_map[to].r_node[x].flags|=QSPN_SENT;
  908. thread_joint(qopt->join, send_qspn_pkt, (void *) nopt);
  909. }
  910. }
  911. xfree(qopt);
  912. total_threads--;
  913. pthread_exit(NULL);
  914. }
  915. /*collect_data: it calculates how many routes we have for each node*/
  916. void
  917. collect_data(void)
  918. {
  919. int i, x, e;
  920. fprintf(stderr, "Collecting the data!\n");
  921. for (i = 0; i < MAXGROUPNODE; i++)
  922. for (e = 0; e < pkt_dbc[i]; e++)
  923. for (x = 0; x < pkt_db[i][e]->routes; x++) {
  924. rt_stat[i][pkt_db[i][e]->tracer[x]]++;
  925. if (rt_stat[i][pkt_db[i][e]->tracer[x]]++ == 1)
  926. rt_total[i]++;
  927. }
  928. }
  929. /*show_temp_stat: Every 5 seconds it shows how is it going*/
  930. void *
  931. show_temp_stat(void *null)
  932. {
  933. FILE *fd = stdout;
  934. while (1) {
  935. sleep(5);
  936. fprintf(fd, "Total_threads: %d\n", total_threads);
  937. fprintf(fd, "Gbl_stat{\n\ttotal_pkts: %d\n\tqspn_requests: %d"
  938. "\n\tqspn_replies: %d\n\tqspn_backpro: %d }\n\n",
  939. gbl_stat.total_pkts, gbl_stat.qspn_requests,
  940. gbl_stat.qspn_replies, gbl_stat.qspn_backpro);
  941. }
  942. }
  943. /*print_map: Print the map in human readable form in the "map_file"*/
  944. int
  945. print_map(map_node * map, char *map_file)
  946. {
  947. int x, e, node;
  948. FILE *fd;
  949. fd = fopen(map_file, "w");
  950. fprintf(fd, "--- map ---\n");
  951. for (x = 0; x < MAXGROUPNODE; x++) {
  952. fprintf(fd, "Node %d\n", x);
  953. for (e = 0; e < map[x].links; e++) {
  954. node =
  955. ((void *) map[x].r_node[e].r_node -
  956. (void *) map) / sizeof(map_node);
  957. fprintf(fd, " -> %d\n", node);
  958. }
  959. fprintf(fd, "--\n");
  960. }
  961. fclose(fd);
  962. return 0;
  963. }
  964. /*lgl_print_map saves the map in the lgl format.
  965. * (LGL is a nice program to generate images of graphs)*/
  966. int
  967. lgl_print_map(map_node * map, char *lgl_mapfile)
  968. {
  969. int x, e, i, c = 0, d, node;
  970. FILE *lgl;
  971. lgl = fopen(lgl_mapfile, "w");
  972. for (x = 0; x < MAXGROUPNODE; x++) {
  973. fprintf(lgl, "# %d\n", x);
  974. for (e = 0; e < map[x].links; e++) {
  975. c = 0;
  976. for (i = 0; i < x; i++)
  977. if (&map[i] == (map_node *) map[x].r_node[e].r_node) {
  978. for (d = 0; d < map[i].links; d++)
  979. if ((map_node *) map[i].r_node[d].r_node ==
  980. &map[x]) {
  981. c = 1;
  982. break;
  983. }
  984. if (c)
  985. break;
  986. }
  987. if (!c) {
  988. node =
  989. ((void *) map[x].r_node[e].r_node -
  990. (void *) map) / sizeof(map_node);
  991. fprintf(lgl, "%d %d\n", node,
  992. map[x].r_node[e].rtt.tv_usec);
  993. }
  994. }
  995. }
  996. fclose(lgl);
  997. return 0;
  998. }
  999. /*print_data: Prints the accumulated data and statistics in "file"*/
  1000. void
  1001. print_data(char *file)
  1002. {
  1003. int i, x, e, null, maxgroupnode;
  1004. FILE *fd;
  1005. fprintf(stderr, "Saving the d4ta\n");
  1006. fd = fopen((file), "w");
  1007. fprintf(fd, "---- Test dump n. 6 ----\n");
  1008. for (i = 0, null = 0; i < MAXGROUPNODE; i++)
  1009. if (!int_map[i].links)
  1010. null++;
  1011. maxgroupnode = MAXGROUPNODE - null;
  1012. for (i = 0; i < MAXGROUPNODE; i++)
  1013. if (rt_total[i] < maxgroupnode && int_map[i].links)
  1014. fprintf(fd,
  1015. "*WARNING* The node %d has only %d/%d routes *WARNING*\n",
  1016. i, rt_total[i], maxgroupnode);
  1017. fprintf(fd, "- Gbl_stat{\n\ttotal_pkts: %d\n\tqspn_requests: %d"
  1018. "\n\tqspn_replies: %d\n\tqspn_backpro: %d }, QSPN finished in :%d seconds\n",
  1019. gbl_stat.total_pkts, gbl_stat.qspn_requests,
  1020. gbl_stat.qspn_replies, gbl_stat.qspn_backpro, time_stat);
  1021. fprintf(fd, "- Total routes: \n");
  1022. for (i = 0; i < MAXGROUPNODE; i++) {
  1023. fprintf(fd, "Node: %d { ", i);
  1024. for (x = 0; x < MAXGROUPNODE; x++) {
  1025. if (!int_map[x].links)
  1026. fprintf(fd, "(%d)NULL ", x);
  1027. else
  1028. fprintf(fd, "(%d)%d ", x, rt_stat[i][x]);
  1029. if (!x % 20 && x)
  1030. fprintf(fd, "\n ");
  1031. }
  1032. fprintf(fd, "}\n");
  1033. }
  1034. fprintf(fd, "\n--\n\n");
  1035. fprintf(fd, "- Node single stats: \n");
  1036. for (i = 0; i < MAXGROUPNODE; i++)
  1037. fprintf(fd, "%d_stat{\n\ttotal_pkts: %d\n\tqspn_requests: %d\n\t"
  1038. "qspn_replies: %d\n\tqspn_backpro: %d }\n", i,
  1039. node_stat[i].total_pkts, node_stat[i].qspn_requests,
  1040. node_stat[i].qspn_replies, node_stat[i].qspn_backpro);
  1041. fprintf(fd, "- Pkts dump: \n");
  1042. for (i = 0; i < MAXGROUPNODE; i++) {
  1043. for (x = 0; x < pkt_dbc[i]; x++) {
  1044. fprintf(fd, "(%d) { op: %d, from: %d, broadcast: %d, ",
  1045. i, pkt_db[i][x]->op, pkt_db[i][x]->from,
  1046. pkt_db[i][x]->broadcast);
  1047. fprintf(fd, "tracer: ");
  1048. for (e = 0; e < pkt_db[i][x]->routes; e++) {
  1049. fprintf(fd, "%d -> ", pkt_db[i][x]->tracer[e]);
  1050. if (!x % 16 && x)
  1051. fprintf(fd, "\n");
  1052. }
  1053. fprintf(fd, "}\n");
  1054. }
  1055. }
  1056. fclose(fd);
  1057. }
  1058. void
  1059. clear_all(void)
  1060. {
  1061. fprintf(stderr, "Clearing all the dirty\n");
  1062. setzero(&gbl_stat, sizeof(struct qstat));
  1063. setzero(&node_stat, sizeof(struct qstat) * MAXGROUPNODE);
  1064. setzero(&pkt_db, sizeof(struct q_pkt) * MAXGROUPNODE);
  1065. setzero(&pkt_dbc, sizeof(int) * MAXGROUPNODE);
  1066. setzero(&rt_stat, sizeof(short) * MAXGROUPNODE * MAXGROUPNODE);
  1067. setzero(&rt_total, sizeof(short) * MAXGROUPNODE);
  1068. }
  1069. int
  1070. main(int argc, char **argv)
  1071. {
  1072. struct q_opt *nopt;
  1073. int i, r, e, x, qspn_id;
  1074. time_t start, end;
  1075. log_init(argv[0], 1, 1);
  1076. clear_all();
  1077. for (i = 0; i < MAXGROUPNODE; i++)
  1078. pthread_mutex_init(&mutex[i], NULL);
  1079. if (argc > 1) {
  1080. if (!(int_map = load_map(argv[1], 0))) {
  1081. printf("Error! Cannot load the map\n");
  1082. exit(1);
  1083. }
  1084. printf("Map loaded. Printing it... \n");
  1085. print_map(int_map, "QSPN-map.load");
  1086. lgl_print_map(int_map, "QSPN-map.lgl.load");
  1087. } else {
  1088. int_map = init_map(sizeof(map_node) * MAXGROUPNODE);
  1089. printf("Generating a random map...\n");
  1090. srandom(time(0));
  1091. i = rand_range(0, MAXGROUPNODE - 1);
  1092. gen_rnd_map(i, -1, 0);
  1093. for (x = 0; x < MAXGROUPNODE; x++)
  1094. rnode_rtt_order(&int_map[x]);
  1095. printf("Map generated. Printing it... \n");
  1096. print_map(int_map, "QSPN-map");
  1097. lgl_print_map(int_map, "QSPN-map.lgl");
  1098. int_map[i].flags |= MAP_ME;
  1099. printf("Saving the map to QSPN-map.raw\n");
  1100. save_map(int_map, &int_map[i], "QSPN-map.raw");
  1101. }
  1102. printf("Initialization of qspn_queue\n");
  1103. init_q_queue(int_map);
  1104. printf("Running the first test...\n");
  1105. thread_joint(0, show_temp_stat, NULL);
  1106. #ifdef NO_JOINT
  1107. disable_joint = 1;
  1108. #endif
  1109. if (argc > 2)
  1110. r = atoi(argv[2]);
  1111. else
  1112. r = rand_range(0, MAXGROUPNODE - 1);
  1113. printf("Starting the QSPN spreading from node %d\n", r);
  1114. int_map[r].flags |= QSPN_STARTER;
  1115. qspn_id = random();
  1116. start = time(0);
  1117. for (x = 0; x < int_map[r].links; x++) {
  1118. gbl_stat.total_pkts++;
  1119. node_stat[r].total_pkts++;
  1120. nopt = xmalloc(sizeof(struct q_opt));
  1121. setzero(nopt, sizeof(struct q_opt));
  1122. nopt->q.q_id = qspn_id;
  1123. nopt->q.from = r;
  1124. nopt->q.to =
  1125. ((void *) int_map[r].r_node[x].r_node -
  1126. (void *) int_map) / sizeof(map_node);
  1127. nopt->q.tracer = xmalloc(sizeof(short));
  1128. nopt->q.tracer[0] = nopt->q.from;
  1129. nopt->q.routes = 1;
  1130. nopt->sleep = int_map[r].r_node[x].rtt.tv_usec;
  1131. nopt->q.broadcast = 0;
  1132. nopt->join = 0;
  1133. gbl_stat.qspn_requests++;
  1134. node_stat[r].qspn_requests++;
  1135. nopt->q.op = OP_REQUEST;
  1136. if (x == int_map[r].links - 1)
  1137. nopt->join = 1;
  1138. thread_joint(nopt->join, send_qspn_pkt, (void *) nopt);
  1139. }
  1140. #ifdef NO_JOINT
  1141. wait_threads();
  1142. #endif
  1143. end = time(0);
  1144. time_stat = end - start;
  1145. int_map[r].flags &= ~QSPN_STARTER;
  1146. printf("Saving the data to QSPN1...\n");
  1147. collect_data();
  1148. print_data("QSPN1");
  1149. for (x = 0; x < MAXGROUPNODE; x++) {
  1150. for (e = 0; e < pkt_dbc[x]; e++) {
  1151. xfree(pkt_db[x][e]->tracer);
  1152. xfree(pkt_db[x][e]);
  1153. }
  1154. xfree(pkt_db[x]);
  1155. }
  1156. free_q_queue(int_map); /*WARNING* To be used when the int_map it's of no more use */
  1157. clear_all();
  1158. printf("All done yeah\n");
  1159. fprintf(stderr, "All done yeah\n");
  1160. exit(0);
  1161. }