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

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357
  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...",
  453. (unsigned int)pthread_self());
  454. pthread_create(&thread, NULL, start_routine, (void *) nopt);
  455. fprintf(stderr, " %u\n", (unsigned int)thread);
  456. pthread_join(thread, NULL);
  457. } else {
  458. pthread_create(&thread, NULL, start_routine, (void *) nopt);
  459. pthread_detach(thread);
  460. }
  461. }
  462. /* wait_threads: it waits until the total number of threads doesn't change anymore*/
  463. void
  464. wait_threads(void)
  465. {
  466. int tt = 0;
  467. while (total_threads != tt) {
  468. tt = total_threads;
  469. sleep(5);
  470. }
  471. }
  472. /* gen_rnd_map: Generate Random Map.
  473. * It creates the start_node in the map.
  474. * (If back_link >= 0) It then adds the back_link node (with rtt equal to back_link_rtt)
  475. * in the start_node's rnodes and adds other random rnodes (with random rtt).
  476. * If the added new rnode doesn't exist yet in the map it calls recusively itself giving
  477. * the rnode as the "start_node" argument, the start_node as back_link and the rnode's rtt
  478. * as back_link_rtt. Else if the new rnode exists, it adds the start_node in the rnode's rnodes.
  479. * Automagically it terminates.
  480. */
  481. void
  482. gen_rnd_map(int start_node, int back_link, int back_link_rtt)
  483. {
  484. int i = start_node, r = 0, e, b = 0, rnode_rnd, ms_rnd;
  485. map_rnode rtmp;
  486. if (i > MAXGROUPNODE)
  487. i = rand_range(0, MAXGROUPNODE - 1);
  488. if (back_link >= 0 && back_link < MAXGROUPNODE)
  489. b = 1;
  490. if (int_map[i].flags & MAP_HNODE)
  491. return;
  492. r = rand_range(0, MAXLINKS);
  493. int_map[i].flags |= MAP_HNODE;
  494. int_map[i].flags &= ~MAP_VOID;
  495. if (b) {
  496. r++;
  497. setzero(&rtmp, sizeof(map_rnode));
  498. rtmp.r_node = (int *) & int_map[back_link];
  499. rtmp.rtt.tv_usec = back_link_rtt;
  500. //printf("Node %d -> Adding rnode %d (back link)\n", i, back_link);
  501. rnode_add(&int_map[i], &rtmp);
  502. b = 0;
  503. }
  504. /*printf("Creating %d links for the node %d\n", r, i); */
  505. 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 */
  506. setzero(&rtmp, sizeof(map_rnode));
  507. random_node:
  508. /*Are we adding ourself or an already addded node in our rnodes? */
  509. while ((rnode_rnd = (rand_range(0, MAXGROUPNODE - 1))) == i);
  510. for (b = 0; b < int_map[i].links; b++)
  511. if ((map_node *) & int_map[rnode_rnd] ==
  512. (map_node *) int_map[i].r_node[b].r_node) {
  513. //printf("goto random_node;\n");
  514. goto random_node;
  515. }
  516. /*the building of the new rnode is here */
  517. rtmp.r_node = (int *) & int_map[rnode_rnd];
  518. ms_rnd = rand_range(0, (MAXRTT * 1000));
  519. rtmp.rtt.tv_usec = ms_rnd * 1000;
  520. //printf("Node %d -> Adding rnode %d\n", i, rnode_rnd);
  521. rnode_add(&int_map[i], &rtmp);
  522. /*Does exist the node "rnode_rnd" added as rnode? */
  523. if (int_map[rnode_rnd].flags & MAP_VOID) {
  524. /*No, let's create it */
  525. gen_rnd_map(rnode_rnd, i, rtmp.rtt.tv_usec);
  526. } else {
  527. /*It does, let's check if it has a link to me */
  528. int c = 0;
  529. for (b = 0; b < int_map[rnode_rnd].links; b++)
  530. if ((map_node *) int_map[rnode_rnd].r_node[b].r_node ==
  531. &int_map[i]) {
  532. c = 1;
  533. break;
  534. }
  535. if (!c) {
  536. /*We create the back link from rnode_rnd to me (i) */
  537. setzero(&rtmp, sizeof(map_rnode));
  538. rtmp.r_node = (int *) & int_map[i];
  539. rtmp.rtt.tv_usec = ms_rnd * 1000;
  540. //printf("Node %d -> Adding rnode %d (front link)\n", rnode_rnd,i);
  541. rnode_add(&int_map[rnode_rnd], &rtmp);
  542. }
  543. }
  544. }
  545. }
  546. /*init the qspn queue*/
  547. void
  548. init_q_queue(map_node * map)
  549. {
  550. int i;
  551. for (i = 0; i < MAXGROUPNODE; i++) {
  552. if (map[i].links) {
  553. qspn_q[i] = xmalloc(sizeof(struct qspn_queue) * map[i].links);
  554. setzero(qspn_q[i], sizeof(struct qspn_queue));
  555. }
  556. }
  557. }
  558. void
  559. free_q_queue(map_node * map)
  560. {
  561. int i;
  562. for (i = 0; i < MAXGROUPNODE; i++) {
  563. xfree(qspn_q[i]);
  564. }
  565. }
  566. /* store_tracer_pkt: It stores the tracer_pkt received in the
  567. * packets' db (used to collect stats after) and it adds our
  568. * entry in the new tracer_pkt that will be sent
  569. */
  570. int
  571. store_tracer_pkt(struct q_opt *qopt)
  572. {
  573. int x, pkt, to = qopt->q.to;
  574. pthread_mutex_lock(&mutex[to]);
  575. pkt = pkt_dbc[to];
  576. pkt_dbc[to]++;
  577. pthread_mutex_unlock(&mutex[to]);
  578. if (!pkt)
  579. pkt_db[to] = xmalloc(sizeof(struct q_opt *));
  580. else
  581. pkt_db[to] =
  582. xrealloc(pkt_db[to], sizeof(struct q_opt *) * pkt_dbc[to]);
  583. pkt_db[to][pkt] = xmalloc(sizeof(struct q_pkt));
  584. setzero(pkt_db[to][pkt], sizeof(struct q_pkt));
  585. pkt_db[to][pkt]->q_id = qopt->q.q_id;
  586. pkt_db[to][pkt]->q_sub_id = qopt->q.q_sub_id;
  587. pkt_db[to][pkt]->from = qopt->q.from;
  588. pkt_db[to][pkt]->routes = qopt->q.routes + 1;
  589. if (pkt_db[to][pkt]->routes) {
  590. pkt_db[to][pkt]->tracer =
  591. xmalloc(sizeof(short) * pkt_db[to][pkt]->routes);
  592. for (x = 0; x < qopt->q.routes; x++)
  593. pkt_db[to][pkt]->tracer[x] = qopt->q.tracer[x];
  594. /*Let's add our entry in the tracer pkt */
  595. pkt_db[to][pkt]->tracer[pkt_db[to][pkt]->routes - 1] = to;
  596. }
  597. pkt_db[to][pkt]->op = qopt->q.op;
  598. pkt_db[to][pkt]->broadcast = qopt->q.broadcast;
  599. return pkt;
  600. }
  601. /*Ok, I see... The qspn_backpro is a completely lame thing!*/
  602. void *
  603. send_qspn_backpro(void *argv)
  604. {
  605. struct q_opt *qopt = (struct q_opt *) argv, *nopt;
  606. int x, dst, pkt, to = qopt->q.to;
  607. usleep(qopt->sleep);
  608. fprintf(stderr, "%u: qspn_backpro from %d to %d\n",
  609. (unsigned int)pthread_self(), qopt->q.from, to);
  610. /*Now we store the received pkt in our pkt_db */
  611. pkt = store_tracer_pkt(qopt);
  612. /*We've arrived... finally */
  613. if (int_map[to].flags & QSPN_STARTER) {
  614. fprintf(stderr, "%u: qspn_backpro: We've arrived... finally\n",
  615. (unsigned int)pthread_self());
  616. return NULL;
  617. }
  618. for (x = 0; x < int_map[to].links; x++) {
  619. if ((map_node *) int_map[to].r_node[x].r_node ==
  620. &int_map[qopt->q.from])
  621. continue;
  622. if (int_map[to].r_node[x].flags & QSPN_CLOSED) {
  623. dst =
  624. ((void *) int_map[to].r_node[x].r_node -
  625. (void *) int_map) / sizeof(map_node);
  626. gbl_stat.total_pkts++;
  627. node_stat[to].total_pkts++;
  628. nopt = xmalloc(sizeof(struct q_opt));
  629. setzero(nopt, sizeof(struct q_opt));
  630. nopt->sleep = int_map[to].r_node[x].rtt.tv_usec;
  631. nopt->q.to = dst;
  632. nopt->q.from = to;
  633. nopt->q.routes = pkt_db[to][pkt]->routes;
  634. nopt->q.tracer = pkt_db[to][pkt]->tracer;
  635. nopt->q.broadcast = pkt_db[to][pkt]->broadcast;
  636. nopt->join = qopt->join;
  637. gbl_stat.qspn_backpro++;
  638. node_stat[to].qspn_backpro++;
  639. nopt->q.op = OP_BACKPRO;
  640. thread_joint(qopt->join, send_qspn_backpro, (void *) nopt);
  641. }
  642. }
  643. xfree(qopt);
  644. total_threads--;
  645. pthread_exit(NULL);
  646. }
  647. void *
  648. send_qspn_reply(void *argv)
  649. {
  650. struct q_opt *qopt = (struct q_opt *) argv, *nopt;
  651. int x, dst, pkt, to = qopt->q.to;
  652. usleep(qopt->sleep);
  653. fprintf(stderr, "%u: qspn_reply from %d to %d\n",
  654. (unsigned int)pthread_self(), qopt->q.from, to);
  655. /*Let's store the tracer_pkt first */
  656. pkt = store_tracer_pkt(qopt);
  657. /*Bad old broadcast pkt */
  658. if (qopt->q.broadcast <= int_map[to].brdcast[qopt->q.from]) {
  659. fprintf(stderr,
  660. "%u: DROPPED old brdcast: q.broadcast: %d, qopt->q.from broadcast: %d\n",
  661. (unsigned int)pthread_self(),
  662. qopt->q.broadcast,
  663. int_map[to].brdcast[qopt->q.from]);
  664. return NULL;
  665. } else
  666. int_map[to].brdcast[qopt->q.from] = qopt->q.broadcast;
  667. /*Let's keep broadcasting */
  668. for (x = 0; x < int_map[to].links; x++) {
  669. if ((map_node *) int_map[to].r_node[x].r_node ==
  670. &int_map[qopt->q.from])
  671. continue;
  672. dst =
  673. ((void *) int_map[to].r_node[x].r_node -
  674. (void *) int_map) / sizeof(map_node);
  675. gbl_stat.total_pkts++;
  676. node_stat[to].total_pkts++;
  677. nopt = xmalloc(sizeof(struct q_opt));
  678. setzero(nopt, sizeof(struct q_opt));
  679. nopt->sleep = int_map[to].r_node[x].rtt.tv_usec;
  680. nopt->q.to = dst;
  681. nopt->q.from = to;
  682. nopt->q.routes = pkt_db[to][pkt]->routes;
  683. nopt->q.tracer = pkt_db[to][pkt]->tracer;
  684. nopt->q.broadcast = pkt_db[to][pkt]->broadcast;
  685. nopt->join = qopt->join;
  686. gbl_stat.qspn_replies++;
  687. node_stat[to].qspn_replies++;
  688. nopt->q.op = OP_REPLY;
  689. thread_joint(qopt->join, send_qspn_reply, (void *) nopt);
  690. }
  691. xfree(qopt);
  692. total_threads--;
  693. pthread_exit(NULL);
  694. }
  695. /*Holy Disagio, I wrote this piece of code without seeing actually it, I don't
  696. * know what it will generate... where am I?
  697. */
  698. void *
  699. send_qspn_open(void *argv)
  700. {
  701. struct q_opt *qopt = (struct q_opt *) argv, *nopt;
  702. int x, i = 0, dst, pkt, to = qopt->q.to;
  703. int sub_id = qopt->q.q_sub_id;
  704. usleep(qopt->sleep);
  705. fprintf(stderr, "%u: qspn_open from %d to %d [subid: %d]\n",
  706. (unsigned int)pthread_self(), qopt->q.from, to, sub_id);
  707. pkt = store_tracer_pkt(qopt);
  708. if (to == sub_id) {
  709. fprintf(stderr,
  710. "%u: qspn_open: We received a qspn_open, but we are the OPENER!!\n",
  711. (unsigned int)pthread_self());
  712. return NULL;
  713. }
  714. for (x = 0; x < int_map[to].links; x++) {
  715. if ((map_node *) int_map[to].r_node[x].r_node ==
  716. &int_map[qopt->q.from]) {
  717. qspn_q[to][x].flags[sub_id] |= QSPN_OPENED;
  718. fprintf(stderr, "%u: node:%d->rnode %d opened\n",
  719. (unsigned int)pthread_self(), to, x);
  720. }
  721. if (!(qspn_q[to][x].flags[sub_id] & QSPN_OPENED))
  722. i++;
  723. }
  724. /*Shall we stop our insane run? */
  725. if (!i) {
  726. /*Yai! We've finished the reopening of heaven */
  727. fprintf(stderr,
  728. "%u: Yai! We've finished the reopening of heaven\n",
  729. (unsigned int)pthread_self());
  730. return NULL;
  731. }
  732. for (x = 0; x < int_map[to].links; x++) {
  733. if ((map_node *) int_map[to].r_node[x].r_node ==
  734. &int_map[qopt->q.from])
  735. continue;
  736. if (qspn_q[to][x].flags[sub_id] & QSPN_OPENED)
  737. continue;
  738. dst =
  739. ((void *) int_map[to].r_node[x].r_node -
  740. (void *) int_map) / sizeof(map_node);
  741. gbl_stat.total_pkts++;
  742. node_stat[to].total_pkts++;
  743. nopt = xmalloc(sizeof(struct q_opt));
  744. setzero(nopt, sizeof(struct q_opt));
  745. nopt->q.q_id = qopt->q.q_id;
  746. nopt->q.q_sub_id = sub_id;
  747. nopt->q.from = to;
  748. nopt->q.to = dst;
  749. nopt->q.routes = pkt_db[to][pkt]->routes;
  750. nopt->q.tracer = pkt_db[to][pkt]->tracer;
  751. nopt->sleep = int_map[to].r_node[x].rtt.tv_usec;
  752. nopt->q.broadcast = pkt_db[to][pkt]->broadcast;
  753. if (x == int_map[to].links - 1)
  754. qopt->join = 1;
  755. nopt->join = qopt->join;
  756. gbl_stat.qspn_replies++;
  757. node_stat[to].qspn_replies++;
  758. nopt->q.op = OP_OPEN;
  759. thread_joint(qopt->join, send_qspn_open, (void *) nopt);
  760. }
  761. xfree(qopt);
  762. total_threads--;
  763. pthread_exit(NULL);
  764. }
  765. void *
  766. send_qspn_pkt(void *argv)
  767. {
  768. struct q_opt *qopt = (struct q_opt *) argv, *nopt;
  769. int x, i = 0, dst, pkt, to = qopt->q.to;
  770. usleep(qopt->sleep);
  771. fprintf(stderr, "%u: qspn_pkt from %d to %d\n",
  772. (unsigned int)pthread_self(), qopt->q.from, to);
  773. pkt = store_tracer_pkt(qopt);
  774. if (qopt->q.routes > 1 && (int_map[to].flags & QSPN_STARTER)) {
  775. fprintf(stderr,
  776. "%u: qspn_pkt: We received a qspn_pkt, but we are the QSPN_STARTER!!\n",
  777. (unsigned int)pthread_self());
  778. return NULL;
  779. }
  780. for (x = 0; x < int_map[to].links; x++) {
  781. if ((map_node *) int_map[to].r_node[x].r_node ==
  782. &int_map[qopt->q.from]) {
  783. int_map[to].r_node[x].flags |= QSPN_CLOSED;
  784. /*fprintf(stderr, "%u: node:%d->rnode %d closed\n", pthread_self(), to, x); */
  785. }
  786. if (!(int_map[to].r_node[x].flags & QSPN_CLOSED))
  787. i++;
  788. }
  789. #ifdef Q_OPEN
  790. if (!i && !(int_map[to].flags & QSPN_OPENER)
  791. && !(int_map[to].flags & QSPN_STARTER)) {
  792. /*W00t I'm an extreme node! */
  793. fprintf(stderr, "%u: W00t I'm an extreme node!\n", (unsigned int)pthread_self());
  794. int_map[to].flags |= QSPN_OPENER;
  795. for (x = 0; x < int_map[to].links; x++) {
  796. /*if(int_map[to].r_node[x].flags & QSPN_SENT)
  797. continue;
  798. */
  799. dst =
  800. ((void *) int_map[to].r_node[x].r_node -
  801. (void *) int_map) / sizeof(map_node);
  802. gbl_stat.total_pkts++;
  803. node_stat[to].total_pkts++;
  804. nopt = xmalloc(sizeof(struct q_opt));
  805. setzero(nopt, sizeof(struct q_opt));
  806. nopt->sleep = int_map[to].r_node[x].rtt.tv_usec;
  807. nopt->q.q_id = pkt_db[to][pkt]->q_id;
  808. nopt->q.q_sub_id = to;
  809. nopt->q.to = dst;
  810. nopt->q.from = to;
  811. if ((map_node *) int_map[to].r_node[x].r_node ==
  812. &int_map[qopt->q.from]) {
  813. nopt->q.tracer = xmalloc(sizeof(short));
  814. nopt->q.tracer[0] = nopt->q.from;
  815. nopt->q.routes = 1;
  816. } else {
  817. nopt->q.routes = pkt_db[to][pkt]->routes;
  818. nopt->q.tracer = pkt_db[to][pkt]->tracer;
  819. }
  820. nopt->q.op = OP_OPEN;
  821. nopt->q.broadcast = pkt_db[to][pkt]->broadcast;
  822. nopt->join = qopt->join;
  823. gbl_stat.qspn_replies++;
  824. node_stat[to].qspn_replies++;
  825. fprintf(stderr, "%u: Sending a qspn_open to %d\n",
  826. (unsigned int)pthread_self(), dst);
  827. thread_joint(qopt->join, send_qspn_open, (void *) nopt);
  828. xfree(qopt);
  829. return NULL;
  830. }
  831. }
  832. #else /*Q_OPEN not defined */
  833. /*Shall we send a QSPN_REPLY? */
  834. if (!i && !(int_map[to].flags & QSPN_OPENER)
  835. && !(int_map[to].flags & QSPN_STARTER)) {
  836. /*W00t I'm an extreme node! */
  837. fprintf(stderr, "%u: W00t I'm an extreme node!\n", pthread_self());
  838. int_map[to].flags |= QSPN_OPENER;
  839. for (x = 0; x < int_map[to].links; x++) {
  840. if ((map_node *) int_map[to].r_node[x].r_node ==
  841. &int_map[qopt->q.from])
  842. continue;
  843. /*We've to clear the closed link
  844. int_map[to].r_node[x].flags&=~QSPN_CLOSED;
  845. */
  846. dst =
  847. ((void *) int_map[to].r_node[x].r_node -
  848. (void *) int_map) / sizeof(map_node);
  849. gbl_stat.total_pkts++;
  850. node_stat[to].total_pkts++;
  851. nopt = xmalloc(sizeof(struct q_opt));
  852. setzero(nopt, sizeof(struct q_opt));
  853. nopt->sleep = int_map[to].r_node[x].rtt.tv_usec;
  854. nopt->q.to = dst;
  855. nopt->q.from = to;
  856. nopt->q.routes = pkt_db[to][pkt]->routes;
  857. nopt->q.tracer = pkt_db[to][pkt]->tracer;
  858. nopt->q.op = OP_REPLY;
  859. int_map[to].broadcast[to]++;
  860. nopt->q.broadcast = int_map[to].broadcast[to];
  861. nopt->join = qopt->join;
  862. gbl_stat.qspn_replies++;
  863. node_stat[to].qspn_replies++;
  864. fprintf(stderr, "%u: Sending a qspn_reply to %d\n",
  865. pthread_self(), dst);
  866. thread_joint(qopt->join, send_qspn_reply, (void *) nopt);
  867. xfree(qopt);
  868. return NULL;
  869. }
  870. }
  871. #endif /*Q_OPEN */
  872. for (x = 0; x < int_map[to].links; x++) {
  873. if ((map_node *) int_map[to].r_node[x].r_node ==
  874. &int_map[qopt->q.from])
  875. continue;
  876. #ifndef Q_BACKPRO
  877. if (int_map[to].r_node[x].flags & QSPN_CLOSED)
  878. continue;
  879. #endif
  880. dst =
  881. ((void *) int_map[to].r_node[x].r_node -
  882. (void *) int_map) / sizeof(map_node);
  883. gbl_stat.total_pkts++;
  884. node_stat[to].total_pkts++;
  885. nopt = xmalloc(sizeof(struct q_opt));
  886. setzero(nopt, sizeof(struct q_opt));
  887. nopt->q.from = to;
  888. nopt->q.to = dst;
  889. nopt->q.routes = pkt_db[to][pkt]->routes;
  890. nopt->q.tracer = pkt_db[to][pkt]->tracer;
  891. nopt->sleep = int_map[to].r_node[x].rtt.tv_usec;
  892. nopt->q.broadcast = pkt_db[to][pkt]->broadcast;
  893. nopt->join = qopt->join;
  894. if (int_map[to].r_node[x].flags & QSPN_CLOSED
  895. && !(int_map[to].r_node[x].flags & QSPN_BACKPRO)) {
  896. #ifdef Q_BACKPRO
  897. gbl_stat.qspn_backpro++;
  898. node_stat[to].qspn_backpro++;
  899. nopt->q.op = OP_BACKPRO;
  900. int_map[to].r_node[x].flags |= QSPN_BACKPRO;
  901. thread_joint(qopt->join, send_qspn_backpro, (void *) nopt);
  902. #else
  903. #endif /*Q_BACKPRO */
  904. } else if (!(int_map[to].r_node[x].flags & QSPN_CLOSED)) {
  905. gbl_stat.qspn_requests++;
  906. node_stat[to].qspn_requests++;
  907. nopt->q.op = OP_REQUEST;
  908. //int_map[to].r_node[x].flags|=QSPN_SENT;
  909. thread_joint(qopt->join, send_qspn_pkt, (void *) nopt);
  910. }
  911. }
  912. xfree(qopt);
  913. total_threads--;
  914. pthread_exit(NULL);
  915. }
  916. /*collect_data: it calculates how many routes we have for each node*/
  917. void
  918. collect_data(void)
  919. {
  920. int i, x, e;
  921. fprintf(stderr, "Collecting the data!\n");
  922. for (i = 0; i < MAXGROUPNODE; i++)
  923. for (e = 0; e < pkt_dbc[i]; e++)
  924. for (x = 0; x < pkt_db[i][e]->routes; x++) {
  925. rt_stat[i][pkt_db[i][e]->tracer[x]]++;
  926. if (rt_stat[i][pkt_db[i][e]->tracer[x]]++ == 1)
  927. rt_total[i]++;
  928. }
  929. }
  930. /*show_temp_stat: Every 5 seconds it shows how is it going*/
  931. void *
  932. show_temp_stat(void *null)
  933. {
  934. FILE *fd = stdout;
  935. while (1) {
  936. sleep(5);
  937. fprintf(fd, "Total_threads: %d\n", total_threads);
  938. fprintf(fd, "Gbl_stat{\n\ttotal_pkts: %d\n\tqspn_requests: %d"
  939. "\n\tqspn_replies: %d\n\tqspn_backpro: %d }\n\n",
  940. gbl_stat.total_pkts, gbl_stat.qspn_requests,
  941. gbl_stat.qspn_replies, gbl_stat.qspn_backpro);
  942. }
  943. }
  944. /*print_map: Print the map in human readable form in the "map_file"*/
  945. int
  946. print_map(map_node * map, char *map_file)
  947. {
  948. int x, e, node;
  949. FILE *fd;
  950. fd = fopen(map_file, "w");
  951. fprintf(fd, "--- map ---\n");
  952. for (x = 0; x < MAXGROUPNODE; x++) {
  953. fprintf(fd, "Node %d\n", x);
  954. for (e = 0; e < map[x].links; e++) {
  955. node =
  956. ((void *) map[x].r_node[e].r_node -
  957. (void *) map) / sizeof(map_node);
  958. fprintf(fd, " -> %d\n", node);
  959. }
  960. fprintf(fd, "--\n");
  961. }
  962. fclose(fd);
  963. return 0;
  964. }
  965. /*lgl_print_map saves the map in the lgl format.
  966. * (LGL is a nice program to generate images of graphs)*/
  967. int
  968. lgl_print_map(map_node * map, char *lgl_mapfile)
  969. {
  970. int x, e, i, c = 0, d, node;
  971. FILE *lgl;
  972. lgl = fopen(lgl_mapfile, "w");
  973. for (x = 0; x < MAXGROUPNODE; x++) {
  974. fprintf(lgl, "# %d\n", x);
  975. for (e = 0; e < map[x].links; e++) {
  976. c = 0;
  977. for (i = 0; i < x; i++)
  978. if (&map[i] == (map_node *) map[x].r_node[e].r_node) {
  979. for (d = 0; d < map[i].links; d++)
  980. if ((map_node *) map[i].r_node[d].r_node ==
  981. &map[x]) {
  982. c = 1;
  983. break;
  984. }
  985. if (c)
  986. break;
  987. }
  988. if (!c) {
  989. node =
  990. ((void *) map[x].r_node[e].r_node -
  991. (void *) map) / sizeof(map_node);
  992. fprintf(lgl, "%d %d\n", node,
  993. (int)map[x].r_node[e].rtt.tv_usec);
  994. }
  995. }
  996. }
  997. fclose(lgl);
  998. return 0;
  999. }
  1000. /*print_data: Prints the accumulated data and statistics in "file"*/
  1001. void
  1002. print_data(char *file)
  1003. {
  1004. int i, x, e, null, maxgroupnode;
  1005. FILE *fd;
  1006. fprintf(stderr, "Saving the d4ta\n");
  1007. fd = fopen((file), "w");
  1008. fprintf(fd, "---- Test dump n. 6 ----\n");
  1009. for (i = 0, null = 0; i < MAXGROUPNODE; i++)
  1010. if (!int_map[i].links)
  1011. null++;
  1012. maxgroupnode = MAXGROUPNODE - null;
  1013. for (i = 0; i < MAXGROUPNODE; i++)
  1014. if (rt_total[i] < maxgroupnode && int_map[i].links)
  1015. fprintf(fd,
  1016. "*WARNING* The node %d has only %d/%d routes *WARNING*\n",
  1017. i, rt_total[i], maxgroupnode);
  1018. fprintf(fd, "- Gbl_stat{\n\ttotal_pkts: %d\n\tqspn_requests: %d"
  1019. "\n\tqspn_replies: %d\n\tqspn_backpro: %d }, QSPN finished in :%d seconds\n",
  1020. gbl_stat.total_pkts, gbl_stat.qspn_requests,
  1021. gbl_stat.qspn_replies, gbl_stat.qspn_backpro, time_stat);
  1022. fprintf(fd, "- Total routes: \n");
  1023. for (i = 0; i < MAXGROUPNODE; i++) {
  1024. fprintf(fd, "Node: %d { ", i);
  1025. for (x = 0; x < MAXGROUPNODE; x++) {
  1026. if (!int_map[x].links)
  1027. fprintf(fd, "(%d)NULL ", x);
  1028. else
  1029. fprintf(fd, "(%d)%d ", x, rt_stat[i][x]);
  1030. if (!x % 20 && x)
  1031. fprintf(fd, "\n ");
  1032. }
  1033. fprintf(fd, "}\n");
  1034. }
  1035. fprintf(fd, "\n--\n\n");
  1036. fprintf(fd, "- Node single stats: \n");
  1037. for (i = 0; i < MAXGROUPNODE; i++)
  1038. fprintf(fd, "%d_stat{\n\ttotal_pkts: %d\n\tqspn_requests: %d\n\t"
  1039. "qspn_replies: %d\n\tqspn_backpro: %d }\n", i,
  1040. node_stat[i].total_pkts, node_stat[i].qspn_requests,
  1041. node_stat[i].qspn_replies, node_stat[i].qspn_backpro);
  1042. fprintf(fd, "- Pkts dump: \n");
  1043. for (i = 0; i < MAXGROUPNODE; i++) {
  1044. for (x = 0; x < pkt_dbc[i]; x++) {
  1045. fprintf(fd, "(%d) { op: %d, from: %d, broadcast: %d, ",
  1046. i, pkt_db[i][x]->op, pkt_db[i][x]->from,
  1047. pkt_db[i][x]->broadcast);
  1048. fprintf(fd, "tracer: ");
  1049. for (e = 0; e < pkt_db[i][x]->routes; e++) {
  1050. fprintf(fd, "%d -> ", pkt_db[i][x]->tracer[e]);
  1051. if (!x % 16 && x)
  1052. fprintf(fd, "\n");
  1053. }
  1054. fprintf(fd, "}\n");
  1055. }
  1056. }
  1057. fclose(fd);
  1058. }
  1059. void
  1060. clear_all(void)
  1061. {
  1062. fprintf(stderr, "Clearing all the dirty\n");
  1063. setzero(&gbl_stat, sizeof(struct qstat));
  1064. setzero(&node_stat, sizeof(struct qstat) * MAXGROUPNODE);
  1065. setzero(&pkt_db, sizeof(struct q_pkt) * MAXGROUPNODE);
  1066. setzero(&pkt_dbc, sizeof(int) * MAXGROUPNODE);
  1067. setzero(&rt_stat, sizeof(short) * MAXGROUPNODE * MAXGROUPNODE);
  1068. setzero(&rt_total, sizeof(short) * MAXGROUPNODE);
  1069. }
  1070. int
  1071. main(int argc, char **argv)
  1072. {
  1073. struct q_opt *nopt;
  1074. int i, r, e, x, qspn_id;
  1075. time_t start, end;
  1076. log_init(argv[0], 1, 1);
  1077. clear_all();
  1078. for (i = 0; i < MAXGROUPNODE; i++)
  1079. pthread_mutex_init(&mutex[i], NULL);
  1080. if (argc > 1) {
  1081. if (!(int_map = load_map(argv[1], 0))) {
  1082. printf("Error! Cannot load the map\n");
  1083. exit(1);
  1084. }
  1085. printf("Map loaded. Printing it... \n");
  1086. print_map(int_map, "QSPN-map.load");
  1087. lgl_print_map(int_map, "QSPN-map.lgl.load");
  1088. } else {
  1089. int_map = init_map(sizeof(map_node) * MAXGROUPNODE);
  1090. printf("Generating a random map...\n");
  1091. srandom(time(0));
  1092. i = rand_range(0, MAXGROUPNODE - 1);
  1093. gen_rnd_map(i, -1, 0);
  1094. for (x = 0; x < MAXGROUPNODE; x++)
  1095. rnode_rtt_order(&int_map[x]);
  1096. printf("Map generated. Printing it... \n");
  1097. print_map(int_map, "QSPN-map");
  1098. lgl_print_map(int_map, "QSPN-map.lgl");
  1099. int_map[i].flags |= MAP_ME;
  1100. printf("Saving the map to QSPN-map.raw\n");
  1101. save_map(int_map, &int_map[i], "QSPN-map.raw");
  1102. }
  1103. printf("Initialization of qspn_queue\n");
  1104. init_q_queue(int_map);
  1105. printf("Running the first test...\n");
  1106. thread_joint(0, show_temp_stat, NULL);
  1107. #ifdef NO_JOINT
  1108. disable_joint = 1;
  1109. #endif
  1110. if (argc > 2)
  1111. r = atoi(argv[2]);
  1112. else
  1113. r = rand_range(0, MAXGROUPNODE - 1);
  1114. printf("Starting the QSPN spreading from node %d\n", r);
  1115. int_map[r].flags |= QSPN_STARTER;
  1116. qspn_id = random();
  1117. start = time(0);
  1118. for (x = 0; x < int_map[r].links; x++) {
  1119. gbl_stat.total_pkts++;
  1120. node_stat[r].total_pkts++;
  1121. nopt = xmalloc(sizeof(struct q_opt));
  1122. setzero(nopt, sizeof(struct q_opt));
  1123. nopt->q.q_id = qspn_id;
  1124. nopt->q.from = r;
  1125. nopt->q.to =
  1126. ((void *) int_map[r].r_node[x].r_node -
  1127. (void *) int_map) / sizeof(map_node);
  1128. nopt->q.tracer = xmalloc(sizeof(short));
  1129. nopt->q.tracer[0] = nopt->q.from;
  1130. nopt->q.routes = 1;
  1131. nopt->sleep = int_map[r].r_node[x].rtt.tv_usec;
  1132. nopt->q.broadcast = 0;
  1133. nopt->join = 0;
  1134. gbl_stat.qspn_requests++;
  1135. node_stat[r].qspn_requests++;
  1136. nopt->q.op = OP_REQUEST;
  1137. if (x == int_map[r].links - 1)
  1138. nopt->join = 1;
  1139. thread_joint(nopt->join, send_qspn_pkt, (void *) nopt);
  1140. }
  1141. #ifdef NO_JOINT
  1142. wait_threads();
  1143. #endif
  1144. end = time(0);
  1145. time_stat = end - start;
  1146. int_map[r].flags &= ~QSPN_STARTER;
  1147. printf("Saving the data to QSPN1...\n");
  1148. collect_data();
  1149. print_data("QSPN1");
  1150. for (x = 0; x < MAXGROUPNODE; x++) {
  1151. for (e = 0; e < pkt_dbc[x]; e++) {
  1152. xfree(pkt_db[x][e]->tracer);
  1153. xfree(pkt_db[x][e]);
  1154. }
  1155. xfree(pkt_db[x]);
  1156. }
  1157. free_q_queue(int_map); /*WARNING* To be used when the int_map it's of no more use */
  1158. clear_all();
  1159. printf("All done yeah\n");
  1160. fprintf(stderr, "All done yeah\n");
  1161. exit(0);
  1162. }