1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357 |
- /* This file is part of Netsukuku
- * (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
- *
- * This source code is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License,
- * or (at your option) any later version.
- *
- * This source code is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * Please refer to the GNU Public License for more details.
- *
- * You should have received a copy of the GNU Public License along with
- * this source code; if not, write to:
- * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * qspn-empiric:
- * This is the living proof of the QSPN algorithm.
- * The qspn-empiric simulates an entire network and runs on it the QSPN,
- * but it doesn't simulate the qspn with levels.
- * Then when all is done it collects the generated data and makes some
- * statistics, in this way it's possible to watch the effect of a QSPN
- * explosion in a network.
- * The qspn-empiric can be also used to solve graph without using djkstra
- * hehehe.
- * ah,.. yes it uses threads... a lot of them... ^_^ I want a cluster!
- * -
- * time to explain how this thing happens to work:
- * If a map filename to load is not given as argv[1] gen_rnd_map is used
- * to create a new random map of MAXGROUPNODE nodes.
- * Then we choose a random node to be the QSPN_STARTER.
- * Now, instead of simulating the nodes we simulate the packets! Each pkt
- * is a thread. When a new thread/pkt is created it sleeps for the rtt there
- * is between the "from" node and the "to" node.
- * Now we have only to wait.
- * enjoy the trip.
- */
-
-
- #include "includes.h"
-
- #include "common.h"
- #include "inet.h"
- #include "endianness.h"
- #include "qspn-empiric.h"
-
-
- /*
- * * * Map functions * * *
- */
- /*
- * pos_from_node: Position from node: It returns the position of the `node'
- * in the `map'.
- */
- int
- pos_from_node(map_node * node, map_node * map)
- {
- return ((char *) node - (char *) map) / sizeof(map_node);
- }
-
-
- map_node *
- init_map(size_t len)
- {
- int i;
- map_node *map;
- if (!len)
- len = sizeof(map_node) * MAXGROUPNODE;
-
- map = (map_node *) xmalloc(len);
- setzero(map, len);
- for (i = 0; i < MAXGROUPNODE; i++)
- map[i].flags |= MAP_VOID;
-
- return map;
- }
-
- void
- free_map(map_node * map, size_t count)
- {
- int i, len;
-
- if (!count)
- count = MAXGROUPNODE;
- len = sizeof(map_node) * count;
-
- for (i = 0; i < count; i++) {
- if (map[i].links) {
- if (map[i].r_node)
- xfree(map[i].r_node);
- }
- }
-
- setzero(map, len);
- xfree(map);
- }
-
- map_rnode *
- rnode_insert(map_rnode * buf, size_t pos, map_rnode * new)
- {
- map_rnode *ptr = buf + pos;
-
- memcpy(ptr, new, sizeof(map_rnode));
- return ptr;
- }
-
- map_rnode *
- map_rnode_insert(map_node * node, size_t pos, map_rnode * new)
- {
- if (pos >= node->links)
- fatal("Error in %s: %d: Cannot insert map_rnode in %u position."
- " It goes beyond the buffer\n", ERROR_POS, pos);
-
- return rnode_insert(node->r_node, pos, new);
- }
-
- map_rnode *
- rnode_add(map_node * node, map_rnode * new)
- {
- node->links++;
- if (node->links == 1)
- node->r_node = xmalloc(sizeof(map_rnode));
- else
- node->r_node =
- xrealloc(node->r_node, node->links * sizeof(map_rnode));
- return map_rnode_insert(node, node->links - 1, new);
- }
-
- /*rnode_rtt_compar: It's used by rnode_rtt_order*/
- int
- rnode_rtt_compar(const void *a, const void *b)
- {
- map_rnode *rnode_a = (map_rnode *) a, *rnode_b = (map_rnode *) b;
-
- if (MILLISEC(rnode_a->rtt) > MILLISEC(rnode_b->rtt))
- return 1;
- else if (MILLISEC(rnode_a->rtt) == MILLISEC(rnode_b->rtt))
- return 0;
- else
- return -1;
- }
-
- /*rnode_rtt_order: It qsort the rnodes of a map_node comparing their rtt
- */
- void
- rnode_rtt_order(map_node * node)
- {
- qsort(node->r_node, node->links, sizeof(map_rnode), rnode_rtt_compar);
- }
-
-
- /*
- * mod_rnode_addr: Modify_rnode_address
- */
- int
- mod_rnode_addr(map_rnode * rnode, int *map_start, int *new_start)
- {
- rnode->r_node =
- (int *) (((char *) rnode->r_node - (char *) map_start) +
- (char *) new_start);
- return 0;
- }
-
- /*
- * get_rnode_block: It packs all the rnode structs of a node. The node->r_node
- * pointer of the map_rnode struct is changed to point to the position of the
- * node in the map, instead of the address. get_rnode_block returns the number
- * of rnode structs packed.
- * Note that the packed structs will be in network order.
- */
- int
- get_rnode_block(int *map, map_node * node, map_rnode * rblock, int rstart)
- {
- int e;
- char *p;
-
- for (e = 0; e < node->links; e++) {
- p = (char *) &rblock[e + rstart];
-
- memcpy(p, &node->r_node[e].flags, sizeof(u_short));
- p += sizeof(u_short);
-
- memcpy(p, &node->r_node[e].r_node, sizeof(int *));
- p += sizeof(int *);
-
- memcpy(p, &node->r_node[e].rtt, sizeof(struct timeval));
- p += sizeof(struct timeval);
-
- memcpy(p, &node->r_node[e].trtt, sizeof(struct timeval));
- p += sizeof(struct timeval);
-
- mod_rnode_addr(&rblock[e + rstart], map, 0);
-
- ints_host_to_network(&rblock[e + rstart], map_rnode_iinfo);
- }
-
- return e;
- }
-
- /*
- * map_get_rblock: It uses get_rnode_block to pack all the int_map's rnode.
- * `maxgroupnode' is the number of nodes present in the map.
- * `map' is the actual int_map, while `addr_map' is the address used by get_rnode_block
- * to change the rnodes' pointers (read get_rnode_block).
- * It returns a pointer to the start of the rnode block and stores in `count'
- * the number of rnode structs packed.
- * On error NULL is returned.
- */
- map_rnode *
- map_get_rblock(map_node * map, int *addr_map, int maxgroupnode, int *count)
- {
- int i, c = 0, tot = 0;
- map_rnode *rblock;
- *count = 0;
-
- for (i = 0; i < maxgroupnode; i++)
- tot += map[i].links;
- if (!tot)
- return 0;
- rblock = (map_rnode *) xmalloc(MAP_RNODE_PACK_SZ * tot);
-
- for (i = 0; i < maxgroupnode; i++)
- c += get_rnode_block((int *) addr_map, &map[i], rblock, c);
-
- *count = c;
- return rblock;
- }
-
-
- /*
- * store_rnode_block: Given a correct `node' it restores in it all the r_node structs
- * contained in the rnode_block. It returns the number of rnode structs restored.
- * Note that `rblock' will be modified during the restoration.
- */
- int
- store_rnode_block(int *map, map_node * node, map_rnode * rblock,
- int rstart)
- {
- int i;
- char *p;
-
- if (!node->links)
- return 0;
-
- node->r_node = xmalloc(MAP_RNODE_PACK_SZ * node->links);
- for (i = 0; i < node->links; i++) {
- p = (char *) &rblock[i + rstart];
-
- ints_network_to_host(p, map_rnode_iinfo);
-
- memcpy(&node->r_node[i].flags, p, sizeof(u_short));
- p += sizeof(u_short);
-
- memcpy(&node->r_node[i].r_node, p, sizeof(int *));
- p += sizeof(int *);
-
- memcpy(&node->r_node[i].rtt, p, sizeof(struct timeval));
- p += sizeof(struct timeval);
-
- memcpy(&node->r_node[i].trtt, p, sizeof(struct timeval));
- p += sizeof(struct timeval);
-
- mod_rnode_addr(&node->r_node[i], 0, map);
- }
-
- return i;
- }
-
- /*
- * map_store_rblock: Given a correct int_map with `maxgroupnode' nodes,
- * it restores all the r_node structs in the `map' from the `rblock'
- * using store_rnode_block. `addr_map' is the address used to change
- * the rnodes' pointers (read store_rnode_block).
- */
- int
- map_store_rblock(map_node * map, int *addr_map, int maxgroupnode,
- map_rnode * rblock)
- {
- int i, c = 0;
-
- for (i = 0; i < maxgroupnode; i++)
- c += store_rnode_block(addr_map, &map[i], rblock, c);
- return c;
- }
-
- int
- verify_int_map_hdr(struct int_map_hdr *imap_hdr, int maxgroupnode,
- int maxrnodeblock)
- {
- return 0;
- }
-
- /*
- * pack_map_node: it packs the `node' struct and stores it in `pack'.
- * The packed struct will be in network order
- */
- void
- pack_map_node(map_node * node, char *pack)
- {
- char *buf;
-
- buf = pack;
-
- memcpy(buf, &node->flags, sizeof(u_int));
- buf += sizeof(u_int);
-
- memcpy(buf, &node->brdcast, sizeof(u_int) * MAXGROUPNODE);
- buf += sizeof(u_int) * MAXGROUPNODE;
-
- memcpy(buf, &node->links, sizeof(u_short));
- buf += sizeof(u_short);
-
- ints_host_to_network(pack, map_node_iinfo);
- }
-
- /*
- * unpack_map_node: it unpacks `pack', which contains a packed map_node struct.
- * The restored map_node struct will be written in `node'.
- * Note that `pack' will be modified during the restoration.
- */
- void
- unpack_map_node(map_node * node, char *pack)
- {
- char *buf;
-
- ints_network_to_host(pack, map_node_iinfo);
-
- buf = pack;
-
- memcpy(&node->flags, buf, sizeof(u_int));
- buf += sizeof(u_int);
-
- memcpy(&node->brdcast, buf, sizeof(u_int) * MAXGROUPNODE);
- buf += sizeof(u_int) * MAXGROUPNODE;
-
- memcpy(&node->links, buf, sizeof(u_short));
- buf += sizeof(u_short);
-
- node->r_node = 0;
- }
-
- /*
- * pack_map: It returns a pack of the int/bmap_map `map', which has
- * `maxgroupnode' nodes ready to be saved or sent. In `pack_sz' it
- * stores the size of the package. For info on `addr_map' please
- * read get_map_rblock().
- * The pack will be in network order.
- */
- char *
- pack_map(map_node * map, int *addr_map, int maxgroupnode,
- map_node * root_node, size_t * pack_sz)
- {
- struct int_map_hdr imap_hdr;
- map_rnode *rblock = 0;
- int count, i;
- char *package, *p;
-
- if (!addr_map)
- addr_map = (int *) map;
-
- setzero(&imap_hdr, sizeof(struct int_map_hdr));
- if (map) {
- /*rblock packing */
- rblock = map_get_rblock(map, addr_map, maxgroupnode, &count);
- /*Header creation */
- imap_hdr.root_node = root_node ? pos_from_node(root_node, map) : 0;
- imap_hdr.rblock_sz = count * MAP_RNODE_PACK_SZ;
- imap_hdr.int_map_sz = maxgroupnode * MAP_NODE_PACK_SZ;
- }
-
- /*Package creation */
- *pack_sz = INT_MAP_BLOCK_SZ(imap_hdr.int_map_sz, imap_hdr.rblock_sz);
- package = xmalloc(*pack_sz);
- memcpy(package, &imap_hdr, sizeof(struct int_map_hdr));
- ints_host_to_network(package, int_map_hdr_iinfo);
-
- p = package;
- if (imap_hdr.int_map_sz) {
- /* Pack the map_node strucs of the `map' */
-
- p += sizeof(struct int_map_hdr);
-
- for (i = 0; i < maxgroupnode; i++) {
- pack_map_node(&map[i], p);
- p += MAP_NODE_PACK_SZ;
- }
- }
-
- if (imap_hdr.rblock_sz) {
- memcpy(p, rblock, imap_hdr.rblock_sz);
- xfree(rblock);
- }
-
- return package;
- }
-
- /*
- * unpack_map: Given a valid int/bmap_map package (packed with pack_intmap), it
- * allocates a brand new int_map and restores in it the map and the rnodes.
- * It puts in `*new_root' the pointer to the root_node in the loaded map.
- * For info on `addr_map' please read map_store_rblock().
- * On success the a pointer to the new int_map is retuned, otherwise 0 will be
- * the fatal value.
- * Note: `pack' will be modified during the unpacking.
- */
- map_node *
- unpack_map(char *pack, int *addr_map, map_node ** new_root,
- int maxgroupnode, int maxrnodeblock)
- {
- map_node *map;
- struct int_map_hdr *imap_hdr = (struct int_map_hdr *) pack;
- map_rnode *rblock;
- int err, nodes, i;
- char *p;
-
- ints_network_to_host(imap_hdr, int_map_hdr_iinfo);
-
- if (verify_int_map_hdr(imap_hdr, maxgroupnode, maxrnodeblock)) {
- error("Malformed int/bmap_map_hdr. Aborting unpack_map().");
- return 0;
- }
-
- /*Extracting the map... */
- p = pack + sizeof(struct int_map_hdr);
- map = init_map(0);
-
- if (!imap_hdr->int_map_sz)
- return map;
-
- /* Restore in `map' the packed map_node struct */
- nodes = imap_hdr->int_map_sz / MAP_NODE_PACK_SZ;
- for (i = 0; i < nodes; i++) {
- unpack_map_node(&map[i], p);
- p += MAP_NODE_PACK_SZ;
- }
-
- /*Restoring the rnodes... */
- if (imap_hdr->rblock_sz) {
- /*Extracting the rnodes block and merging it to the map */
- rblock = (map_rnode *) p;
- if (!addr_map)
- addr_map = (int *) map;
- err = map_store_rblock(map, addr_map, nodes, rblock);
- if (err != imap_hdr->rblock_sz / MAP_RNODE_PACK_SZ) {
- error
- ("An error occurred while storing the rnodes block in the int/bnode_map");
- free_map(map, 0);
- return 0;
- }
- }
-
- if (new_root) {
- map[imap_hdr->root_node].flags |= MAP_ME;
- *new_root = &map[imap_hdr->root_node];
- }
-
- return map;
- }
-
-
- /*
- * * * save/load int_map * * *
- */
-
- int
- save_map(map_node * map, map_node * root_node, char *file)
- {
- FILE *fd;
- size_t pack_sz;
- char *pack;
-
- /*Pack! */
- pack = pack_map(map, 0, MAXGROUPNODE, root_node, &pack_sz);
- if (!pack_sz || !pack)
- return 0;
-
- if ((fd = fopen(file, "w")) == NULL) {
- error("Cannot save the int_map in %s: %s", file, strerror(errno));
- return -1;
- }
-
- /*Write! */
- fwrite(pack, pack_sz, 1, fd);
-
- xfree(pack);
- fclose(fd);
- return 0;
- }
-
- /*
- * load_map: It loads the internal_map from `file'.
- * It returns the start of the map and if `new_root' is not NULL, it
- * puts in `*new_root' the pointer to the root_node in the loaded map.
- * On error it returns NULL.
- */
- map_node *
- load_map(char *file, map_node ** new_root)
- {
- map_node *map = 0;
- FILE *fd;
- struct int_map_hdr imap_hdr;
- char *pack = 0;
- size_t pack_sz;
-
- if ((fd = fopen(file, "r")) == NULL) {
- error("Cannot load the map from %s: %s", file, strerror(errno));
- return 0;
- }
-
- if (!fread(&imap_hdr, sizeof(struct int_map_hdr), 1, fd))
- goto finish;
-
- ints_network_to_host(&imap_hdr, int_map_hdr_iinfo);
-
- if (!imap_hdr.int_map_sz)
- goto finish;
-
- if (verify_int_map_hdr(&imap_hdr, MAXGROUPNODE, MAXRNODEBLOCK_PACK_SZ))
- goto finish;
-
- rewind(fd);
- pack_sz = INT_MAP_BLOCK_SZ(imap_hdr.int_map_sz, imap_hdr.rblock_sz);
- pack = xmalloc(pack_sz);
- if (!fread(pack, pack_sz, 1, fd))
- goto finish;
-
- map =
- unpack_map(pack, 0, new_root, MAXGROUPNODE, MAXRNODEBLOCK_PACK_SZ);
-
- finish:
- if (pack)
- xfree(pack);
- fclose(fd);
- if (!map)
- error("Malformed map file. Aborting load_map().");
- return map;
- }
-
-
- /*
- * ******* End of map functions *********
- */
-
-
- /* thread_joint creates a thread in JOINED STATE or in DETACHED STATE*/
- void
- thread_joint(int joint, void *(*start_routine) (void *), void *nopt)
- {
- pthread_t thread;
- total_threads++;
- if (joint && !disable_joint) {
- fprintf(stderr, "%u: Joining the thread...",
- (unsigned int)pthread_self());
- pthread_create(&thread, NULL, start_routine, (void *) nopt);
- fprintf(stderr, " %u\n", (unsigned int)thread);
- pthread_join(thread, NULL);
- } else {
- pthread_create(&thread, NULL, start_routine, (void *) nopt);
- pthread_detach(thread);
- }
- }
-
- /* wait_threads: it waits until the total number of threads doesn't change anymore*/
- void
- wait_threads(void)
- {
- int tt = 0;
- while (total_threads != tt) {
- tt = total_threads;
- sleep(5);
- }
- }
-
- /* gen_rnd_map: Generate Random Map.
- * It creates the start_node in the map.
- * (If back_link >= 0) It then adds the back_link node (with rtt equal to back_link_rtt)
- * in the start_node's rnodes and adds other random rnodes (with random rtt).
- * If the added new rnode doesn't exist yet in the map it calls recusively itself giving
- * the rnode as the "start_node" argument, the start_node as back_link and the rnode's rtt
- * as back_link_rtt. Else if the new rnode exists, it adds the start_node in the rnode's rnodes.
- * Automagically it terminates.
- */
- void
- gen_rnd_map(int start_node, int back_link, int back_link_rtt)
- {
- int i = start_node, r = 0, e, b = 0, rnode_rnd, ms_rnd;
- map_rnode rtmp;
-
- if (i > MAXGROUPNODE)
- i = rand_range(0, MAXGROUPNODE - 1);
-
- if (back_link >= 0 && back_link < MAXGROUPNODE)
- b = 1;
-
- if (int_map[i].flags & MAP_HNODE)
- return;
-
- r = rand_range(0, MAXLINKS);
- int_map[i].flags |= MAP_HNODE;
- int_map[i].flags &= ~MAP_VOID;
- if (b) {
- r++;
- setzero(&rtmp, sizeof(map_rnode));
- rtmp.r_node = (int *) & int_map[back_link];
- rtmp.rtt.tv_usec = back_link_rtt;
- //printf("Node %d -> Adding rnode %d (back link)\n", i, back_link);
- rnode_add(&int_map[i], &rtmp);
- b = 0;
- }
- /*printf("Creating %d links for the node %d\n", r, i); */
- 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 */
- setzero(&rtmp, sizeof(map_rnode));
- random_node:
- /*Are we adding ourself or an already addded node in our rnodes? */
- while ((rnode_rnd = (rand_range(0, MAXGROUPNODE - 1))) == i);
- for (b = 0; b < int_map[i].links; b++)
- if ((map_node *) & int_map[rnode_rnd] ==
- (map_node *) int_map[i].r_node[b].r_node) {
- //printf("goto random_node;\n");
- goto random_node;
- }
-
- /*the building of the new rnode is here */
- rtmp.r_node = (int *) & int_map[rnode_rnd];
- ms_rnd = rand_range(0, (MAXRTT * 1000));
- rtmp.rtt.tv_usec = ms_rnd * 1000;
- //printf("Node %d -> Adding rnode %d\n", i, rnode_rnd);
- rnode_add(&int_map[i], &rtmp);
-
- /*Does exist the node "rnode_rnd" added as rnode? */
- if (int_map[rnode_rnd].flags & MAP_VOID) {
- /*No, let's create it */
- gen_rnd_map(rnode_rnd, i, rtmp.rtt.tv_usec);
- } else {
- /*It does, let's check if it has a link to me */
- int c = 0;
- for (b = 0; b < int_map[rnode_rnd].links; b++)
- if ((map_node *) int_map[rnode_rnd].r_node[b].r_node ==
- &int_map[i]) {
- c = 1;
- break;
- }
- if (!c) {
- /*We create the back link from rnode_rnd to me (i) */
- setzero(&rtmp, sizeof(map_rnode));
- rtmp.r_node = (int *) & int_map[i];
- rtmp.rtt.tv_usec = ms_rnd * 1000;
- //printf("Node %d -> Adding rnode %d (front link)\n", rnode_rnd,i);
- rnode_add(&int_map[rnode_rnd], &rtmp);
- }
- }
- }
- }
-
- /*init the qspn queue*/
- void
- init_q_queue(map_node * map)
- {
- int i;
-
- for (i = 0; i < MAXGROUPNODE; i++) {
- if (map[i].links) {
- qspn_q[i] = xmalloc(sizeof(struct qspn_queue) * map[i].links);
- setzero(qspn_q[i], sizeof(struct qspn_queue));
- }
- }
- }
-
- void
- free_q_queue(map_node * map)
- {
- int i;
- for (i = 0; i < MAXGROUPNODE; i++) {
- xfree(qspn_q[i]);
- }
- }
-
- /* store_tracer_pkt: It stores the tracer_pkt received in the
- * packets' db (used to collect stats after) and it adds our
- * entry in the new tracer_pkt that will be sent
- */
- int
- store_tracer_pkt(struct q_opt *qopt)
- {
- int x, pkt, to = qopt->q.to;
-
- pthread_mutex_lock(&mutex[to]);
- pkt = pkt_dbc[to];
- pkt_dbc[to]++;
- pthread_mutex_unlock(&mutex[to]);
-
- if (!pkt)
- pkt_db[to] = xmalloc(sizeof(struct q_opt *));
- else
- pkt_db[to] =
- xrealloc(pkt_db[to], sizeof(struct q_opt *) * pkt_dbc[to]);
-
- pkt_db[to][pkt] = xmalloc(sizeof(struct q_pkt));
- setzero(pkt_db[to][pkt], sizeof(struct q_pkt));
- pkt_db[to][pkt]->q_id = qopt->q.q_id;
- pkt_db[to][pkt]->q_sub_id = qopt->q.q_sub_id;
- pkt_db[to][pkt]->from = qopt->q.from;
- pkt_db[to][pkt]->routes = qopt->q.routes + 1;
- if (pkt_db[to][pkt]->routes) {
- pkt_db[to][pkt]->tracer =
- xmalloc(sizeof(short) * pkt_db[to][pkt]->routes);
- for (x = 0; x < qopt->q.routes; x++)
- pkt_db[to][pkt]->tracer[x] = qopt->q.tracer[x];
- /*Let's add our entry in the tracer pkt */
- pkt_db[to][pkt]->tracer[pkt_db[to][pkt]->routes - 1] = to;
- }
- pkt_db[to][pkt]->op = qopt->q.op;
- pkt_db[to][pkt]->broadcast = qopt->q.broadcast;
-
- return pkt;
- }
-
- /*Ok, I see... The qspn_backpro is a completely lame thing!*/
- void *
- send_qspn_backpro(void *argv)
- {
- struct q_opt *qopt = (struct q_opt *) argv, *nopt;
- int x, dst, pkt, to = qopt->q.to;
-
- usleep(qopt->sleep);
- fprintf(stderr, "%u: qspn_backpro from %d to %d\n",
- (unsigned int)pthread_self(), qopt->q.from, to);
-
- /*Now we store the received pkt in our pkt_db */
- pkt = store_tracer_pkt(qopt);
-
- /*We've arrived... finally */
- if (int_map[to].flags & QSPN_STARTER) {
- fprintf(stderr, "%u: qspn_backpro: We've arrived... finally\n",
- (unsigned int)pthread_self());
- return NULL;
- }
-
- for (x = 0; x < int_map[to].links; x++) {
- if ((map_node *) int_map[to].r_node[x].r_node ==
- &int_map[qopt->q.from])
- continue;
-
- if (int_map[to].r_node[x].flags & QSPN_CLOSED) {
- dst =
- ((void *) int_map[to].r_node[x].r_node -
- (void *) int_map) / sizeof(map_node);
-
- gbl_stat.total_pkts++;
- node_stat[to].total_pkts++;
-
- nopt = xmalloc(sizeof(struct q_opt));
- setzero(nopt, sizeof(struct q_opt));
- nopt->sleep = int_map[to].r_node[x].rtt.tv_usec;
- nopt->q.to = dst;
- nopt->q.from = to;
- nopt->q.routes = pkt_db[to][pkt]->routes;
- nopt->q.tracer = pkt_db[to][pkt]->tracer;
- nopt->q.broadcast = pkt_db[to][pkt]->broadcast;
- nopt->join = qopt->join;
-
- gbl_stat.qspn_backpro++;
- node_stat[to].qspn_backpro++;
- nopt->q.op = OP_BACKPRO;
- thread_joint(qopt->join, send_qspn_backpro, (void *) nopt);
- }
- }
- xfree(qopt);
- total_threads--;
- pthread_exit(NULL);
- }
-
- void *
- send_qspn_reply(void *argv)
- {
- struct q_opt *qopt = (struct q_opt *) argv, *nopt;
- int x, dst, pkt, to = qopt->q.to;
-
- usleep(qopt->sleep);
- fprintf(stderr, "%u: qspn_reply from %d to %d\n",
- (unsigned int)pthread_self(), qopt->q.from, to);
-
- /*Let's store the tracer_pkt first */
- pkt = store_tracer_pkt(qopt);
-
- /*Bad old broadcast pkt */
- if (qopt->q.broadcast <= int_map[to].brdcast[qopt->q.from]) {
- fprintf(stderr,
- "%u: DROPPED old brdcast: q.broadcast: %d, qopt->q.from broadcast: %d\n",
- (unsigned int)pthread_self(),
- qopt->q.broadcast,
- int_map[to].brdcast[qopt->q.from]);
- return NULL;
- } else
- int_map[to].brdcast[qopt->q.from] = qopt->q.broadcast;
-
- /*Let's keep broadcasting */
- for (x = 0; x < int_map[to].links; x++) {
- if ((map_node *) int_map[to].r_node[x].r_node ==
- &int_map[qopt->q.from])
- continue;
-
- dst =
- ((void *) int_map[to].r_node[x].r_node -
- (void *) int_map) / sizeof(map_node);
-
- gbl_stat.total_pkts++;
- node_stat[to].total_pkts++;
-
- nopt = xmalloc(sizeof(struct q_opt));
- setzero(nopt, sizeof(struct q_opt));
- nopt->sleep = int_map[to].r_node[x].rtt.tv_usec;
- nopt->q.to = dst;
- nopt->q.from = to;
- nopt->q.routes = pkt_db[to][pkt]->routes;
- nopt->q.tracer = pkt_db[to][pkt]->tracer;
- nopt->q.broadcast = pkt_db[to][pkt]->broadcast;
- nopt->join = qopt->join;
-
-
- gbl_stat.qspn_replies++;
- node_stat[to].qspn_replies++;
- nopt->q.op = OP_REPLY;
- thread_joint(qopt->join, send_qspn_reply, (void *) nopt);
- }
- xfree(qopt);
- total_threads--;
- pthread_exit(NULL);
- }
-
- /*Holy Disagio, I wrote this piece of code without seeing actually it, I don't
- * know what it will generate... where am I?
- */
- void *
- send_qspn_open(void *argv)
- {
- struct q_opt *qopt = (struct q_opt *) argv, *nopt;
- int x, i = 0, dst, pkt, to = qopt->q.to;
- int sub_id = qopt->q.q_sub_id;
-
- usleep(qopt->sleep);
- fprintf(stderr, "%u: qspn_open from %d to %d [subid: %d]\n",
- (unsigned int)pthread_self(), qopt->q.from, to, sub_id);
-
- pkt = store_tracer_pkt(qopt);
-
- if (to == sub_id) {
- fprintf(stderr,
- "%u: qspn_open: We received a qspn_open, but we are the OPENER!!\n",
- (unsigned int)pthread_self());
- return NULL;
- }
-
- for (x = 0; x < int_map[to].links; x++) {
- if ((map_node *) int_map[to].r_node[x].r_node ==
- &int_map[qopt->q.from]) {
- qspn_q[to][x].flags[sub_id] |= QSPN_OPENED;
- fprintf(stderr, "%u: node:%d->rnode %d opened\n",
- (unsigned int)pthread_self(), to, x);
- }
-
- if (!(qspn_q[to][x].flags[sub_id] & QSPN_OPENED))
- i++;
- }
- /*Shall we stop our insane run? */
- if (!i) {
- /*Yai! We've finished the reopening of heaven */
- fprintf(stderr,
- "%u: Yai! We've finished the reopening of heaven\n",
- (unsigned int)pthread_self());
- return NULL;
- }
-
- for (x = 0; x < int_map[to].links; x++) {
- if ((map_node *) int_map[to].r_node[x].r_node ==
- &int_map[qopt->q.from])
- continue;
-
- if (qspn_q[to][x].flags[sub_id] & QSPN_OPENED)
- continue;
-
- dst =
- ((void *) int_map[to].r_node[x].r_node -
- (void *) int_map) / sizeof(map_node);
- gbl_stat.total_pkts++;
- node_stat[to].total_pkts++;
-
- nopt = xmalloc(sizeof(struct q_opt));
- setzero(nopt, sizeof(struct q_opt));
- nopt->q.q_id = qopt->q.q_id;
- nopt->q.q_sub_id = sub_id;
- nopt->q.from = to;
- nopt->q.to = dst;
- nopt->q.routes = pkt_db[to][pkt]->routes;
- nopt->q.tracer = pkt_db[to][pkt]->tracer;
- nopt->sleep = int_map[to].r_node[x].rtt.tv_usec;
- nopt->q.broadcast = pkt_db[to][pkt]->broadcast;
- if (x == int_map[to].links - 1)
- qopt->join = 1;
- nopt->join = qopt->join;
-
- gbl_stat.qspn_replies++;
- node_stat[to].qspn_replies++;
- nopt->q.op = OP_OPEN;
- thread_joint(qopt->join, send_qspn_open, (void *) nopt);
- }
- xfree(qopt);
- total_threads--;
- pthread_exit(NULL);
- }
-
- void *
- send_qspn_pkt(void *argv)
- {
- struct q_opt *qopt = (struct q_opt *) argv, *nopt;
- int x, i = 0, dst, pkt, to = qopt->q.to;
-
- usleep(qopt->sleep);
- fprintf(stderr, "%u: qspn_pkt from %d to %d\n",
- (unsigned int)pthread_self(), qopt->q.from, to);
-
- pkt = store_tracer_pkt(qopt);
-
- if (qopt->q.routes > 1 && (int_map[to].flags & QSPN_STARTER)) {
- fprintf(stderr,
- "%u: qspn_pkt: We received a qspn_pkt, but we are the QSPN_STARTER!!\n",
- (unsigned int)pthread_self());
- return NULL;
- }
-
- for (x = 0; x < int_map[to].links; x++) {
- if ((map_node *) int_map[to].r_node[x].r_node ==
- &int_map[qopt->q.from]) {
- int_map[to].r_node[x].flags |= QSPN_CLOSED;
- /*fprintf(stderr, "%u: node:%d->rnode %d closed\n", pthread_self(), to, x); */
- }
- if (!(int_map[to].r_node[x].flags & QSPN_CLOSED))
- i++;
- }
-
- #ifdef Q_OPEN
- if (!i && !(int_map[to].flags & QSPN_OPENER)
- && !(int_map[to].flags & QSPN_STARTER)) {
- /*W00t I'm an extreme node! */
- fprintf(stderr, "%u: W00t I'm an extreme node!\n", (unsigned int)pthread_self());
- int_map[to].flags |= QSPN_OPENER;
- for (x = 0; x < int_map[to].links; x++) {
- /*if(int_map[to].r_node[x].flags & QSPN_SENT)
- continue;
- */
-
- dst =
- ((void *) int_map[to].r_node[x].r_node -
- (void *) int_map) / sizeof(map_node);
- gbl_stat.total_pkts++;
- node_stat[to].total_pkts++;
-
- nopt = xmalloc(sizeof(struct q_opt));
- setzero(nopt, sizeof(struct q_opt));
- nopt->sleep = int_map[to].r_node[x].rtt.tv_usec;
- nopt->q.q_id = pkt_db[to][pkt]->q_id;
- nopt->q.q_sub_id = to;
- nopt->q.to = dst;
- nopt->q.from = to;
- if ((map_node *) int_map[to].r_node[x].r_node ==
- &int_map[qopt->q.from]) {
- nopt->q.tracer = xmalloc(sizeof(short));
- nopt->q.tracer[0] = nopt->q.from;
- nopt->q.routes = 1;
- } else {
- nopt->q.routes = pkt_db[to][pkt]->routes;
- nopt->q.tracer = pkt_db[to][pkt]->tracer;
- }
- nopt->q.op = OP_OPEN;
- nopt->q.broadcast = pkt_db[to][pkt]->broadcast;
- nopt->join = qopt->join;
-
- gbl_stat.qspn_replies++;
- node_stat[to].qspn_replies++;
- fprintf(stderr, "%u: Sending a qspn_open to %d\n",
- (unsigned int)pthread_self(), dst);
- thread_joint(qopt->join, send_qspn_open, (void *) nopt);
- xfree(qopt);
- return NULL;
- }
- }
- #else /*Q_OPEN not defined */
- /*Shall we send a QSPN_REPLY? */
- if (!i && !(int_map[to].flags & QSPN_OPENER)
- && !(int_map[to].flags & QSPN_STARTER)) {
- /*W00t I'm an extreme node! */
- fprintf(stderr, "%u: W00t I'm an extreme node!\n", pthread_self());
-
- int_map[to].flags |= QSPN_OPENER;
- for (x = 0; x < int_map[to].links; x++) {
- if ((map_node *) int_map[to].r_node[x].r_node ==
- &int_map[qopt->q.from])
- continue;
-
- /*We've to clear the closed link
- int_map[to].r_node[x].flags&=~QSPN_CLOSED;
- */
-
- dst =
- ((void *) int_map[to].r_node[x].r_node -
- (void *) int_map) / sizeof(map_node);
- gbl_stat.total_pkts++;
- node_stat[to].total_pkts++;
-
- nopt = xmalloc(sizeof(struct q_opt));
- setzero(nopt, sizeof(struct q_opt));
- nopt->sleep = int_map[to].r_node[x].rtt.tv_usec;
- nopt->q.to = dst;
- nopt->q.from = to;
- nopt->q.routes = pkt_db[to][pkt]->routes;
- nopt->q.tracer = pkt_db[to][pkt]->tracer;
- nopt->q.op = OP_REPLY;
- int_map[to].broadcast[to]++;
- nopt->q.broadcast = int_map[to].broadcast[to];
- nopt->join = qopt->join;
-
- gbl_stat.qspn_replies++;
- node_stat[to].qspn_replies++;
- fprintf(stderr, "%u: Sending a qspn_reply to %d\n",
- pthread_self(), dst);
- thread_joint(qopt->join, send_qspn_reply, (void *) nopt);
- xfree(qopt);
- return NULL;
- }
- }
- #endif /*Q_OPEN */
-
- for (x = 0; x < int_map[to].links; x++) {
- if ((map_node *) int_map[to].r_node[x].r_node ==
- &int_map[qopt->q.from])
- continue;
- #ifndef Q_BACKPRO
- if (int_map[to].r_node[x].flags & QSPN_CLOSED)
- continue;
- #endif
-
- dst =
- ((void *) int_map[to].r_node[x].r_node -
- (void *) int_map) / sizeof(map_node);
- gbl_stat.total_pkts++;
- node_stat[to].total_pkts++;
-
- nopt = xmalloc(sizeof(struct q_opt));
- setzero(nopt, sizeof(struct q_opt));
- nopt->q.from = to;
- nopt->q.to = dst;
- nopt->q.routes = pkt_db[to][pkt]->routes;
- nopt->q.tracer = pkt_db[to][pkt]->tracer;
- nopt->sleep = int_map[to].r_node[x].rtt.tv_usec;
- nopt->q.broadcast = pkt_db[to][pkt]->broadcast;
- nopt->join = qopt->join;
-
- if (int_map[to].r_node[x].flags & QSPN_CLOSED
- && !(int_map[to].r_node[x].flags & QSPN_BACKPRO)) {
- #ifdef Q_BACKPRO
- gbl_stat.qspn_backpro++;
- node_stat[to].qspn_backpro++;
- nopt->q.op = OP_BACKPRO;
- int_map[to].r_node[x].flags |= QSPN_BACKPRO;
- thread_joint(qopt->join, send_qspn_backpro, (void *) nopt);
- #else
- #endif /*Q_BACKPRO */
- } else if (!(int_map[to].r_node[x].flags & QSPN_CLOSED)) {
- gbl_stat.qspn_requests++;
- node_stat[to].qspn_requests++;
- nopt->q.op = OP_REQUEST;
- //int_map[to].r_node[x].flags|=QSPN_SENT;
- thread_joint(qopt->join, send_qspn_pkt, (void *) nopt);
- }
- }
- xfree(qopt);
- total_threads--;
- pthread_exit(NULL);
- }
-
- /*collect_data: it calculates how many routes we have for each node*/
- void
- collect_data(void)
- {
- int i, x, e;
-
- fprintf(stderr, "Collecting the data!\n");
- for (i = 0; i < MAXGROUPNODE; i++)
- for (e = 0; e < pkt_dbc[i]; e++)
- for (x = 0; x < pkt_db[i][e]->routes; x++) {
- rt_stat[i][pkt_db[i][e]->tracer[x]]++;
- if (rt_stat[i][pkt_db[i][e]->tracer[x]]++ == 1)
- rt_total[i]++;
- }
- }
-
- /*show_temp_stat: Every 5 seconds it shows how is it going*/
- void *
- show_temp_stat(void *null)
- {
- FILE *fd = stdout;
- while (1) {
- sleep(5);
- fprintf(fd, "Total_threads: %d\n", total_threads);
- fprintf(fd, "Gbl_stat{\n\ttotal_pkts: %d\n\tqspn_requests: %d"
- "\n\tqspn_replies: %d\n\tqspn_backpro: %d }\n\n",
- gbl_stat.total_pkts, gbl_stat.qspn_requests,
- gbl_stat.qspn_replies, gbl_stat.qspn_backpro);
- }
- }
-
- /*print_map: Print the map in human readable form in the "map_file"*/
- int
- print_map(map_node * map, char *map_file)
- {
- int x, e, node;
- FILE *fd;
-
- fd = fopen(map_file, "w");
- fprintf(fd, "--- map ---\n");
- for (x = 0; x < MAXGROUPNODE; x++) {
- fprintf(fd, "Node %d\n", x);
- for (e = 0; e < map[x].links; e++) {
- node =
- ((void *) map[x].r_node[e].r_node -
- (void *) map) / sizeof(map_node);
- fprintf(fd, " -> %d\n", node);
- }
-
- fprintf(fd, "--\n");
- }
- fclose(fd);
- return 0;
- }
-
- /*lgl_print_map saves the map in the lgl format.
- * (LGL is a nice program to generate images of graphs)*/
- int
- lgl_print_map(map_node * map, char *lgl_mapfile)
- {
- int x, e, i, c = 0, d, node;
- FILE *lgl;
-
- lgl = fopen(lgl_mapfile, "w");
-
- for (x = 0; x < MAXGROUPNODE; x++) {
- fprintf(lgl, "# %d\n", x);
- for (e = 0; e < map[x].links; e++) {
- c = 0;
- for (i = 0; i < x; i++)
- if (&map[i] == (map_node *) map[x].r_node[e].r_node) {
- for (d = 0; d < map[i].links; d++)
- if ((map_node *) map[i].r_node[d].r_node ==
- &map[x]) {
- c = 1;
- break;
- }
- if (c)
- break;
- }
- if (!c) {
- node =
- ((void *) map[x].r_node[e].r_node -
- (void *) map) / sizeof(map_node);
- fprintf(lgl, "%d %d\n", node,
- (int)map[x].r_node[e].rtt.tv_usec);
- }
- }
- }
- fclose(lgl);
- return 0;
- }
-
- /*print_data: Prints the accumulated data and statistics in "file"*/
- void
- print_data(char *file)
- {
- int i, x, e, null, maxgroupnode;
- FILE *fd;
-
- fprintf(stderr, "Saving the d4ta\n");
- fd = fopen((file), "w");
-
- fprintf(fd, "---- Test dump n. 6 ----\n");
-
- for (i = 0, null = 0; i < MAXGROUPNODE; i++)
- if (!int_map[i].links)
- null++;
- maxgroupnode = MAXGROUPNODE - null;
- for (i = 0; i < MAXGROUPNODE; i++)
- if (rt_total[i] < maxgroupnode && int_map[i].links)
- fprintf(fd,
- "*WARNING* The node %d has only %d/%d routes *WARNING*\n",
- i, rt_total[i], maxgroupnode);
-
- fprintf(fd, "- Gbl_stat{\n\ttotal_pkts: %d\n\tqspn_requests: %d"
- "\n\tqspn_replies: %d\n\tqspn_backpro: %d }, QSPN finished in :%d seconds\n",
- gbl_stat.total_pkts, gbl_stat.qspn_requests,
- gbl_stat.qspn_replies, gbl_stat.qspn_backpro, time_stat);
-
- fprintf(fd, "- Total routes: \n");
- for (i = 0; i < MAXGROUPNODE; i++) {
- fprintf(fd, "Node: %d { ", i);
- for (x = 0; x < MAXGROUPNODE; x++) {
- if (!int_map[x].links)
- fprintf(fd, "(%d)NULL ", x);
- else
- fprintf(fd, "(%d)%d ", x, rt_stat[i][x]);
-
- if (!x % 20 && x)
- fprintf(fd, "\n ");
- }
- fprintf(fd, "}\n");
- }
-
- fprintf(fd, "\n--\n\n");
- fprintf(fd, "- Node single stats: \n");
-
- for (i = 0; i < MAXGROUPNODE; i++)
- fprintf(fd, "%d_stat{\n\ttotal_pkts: %d\n\tqspn_requests: %d\n\t"
- "qspn_replies: %d\n\tqspn_backpro: %d }\n", i,
- node_stat[i].total_pkts, node_stat[i].qspn_requests,
- node_stat[i].qspn_replies, node_stat[i].qspn_backpro);
-
- fprintf(fd, "- Pkts dump: \n");
- for (i = 0; i < MAXGROUPNODE; i++) {
- for (x = 0; x < pkt_dbc[i]; x++) {
- fprintf(fd, "(%d) { op: %d, from: %d, broadcast: %d, ",
- i, pkt_db[i][x]->op, pkt_db[i][x]->from,
- pkt_db[i][x]->broadcast);
- fprintf(fd, "tracer: ");
- for (e = 0; e < pkt_db[i][x]->routes; e++) {
- fprintf(fd, "%d -> ", pkt_db[i][x]->tracer[e]);
- if (!x % 16 && x)
- fprintf(fd, "\n");
- }
- fprintf(fd, "}\n");
- }
- }
- fclose(fd);
- }
-
- void
- clear_all(void)
- {
- fprintf(stderr, "Clearing all the dirty\n");
- setzero(&gbl_stat, sizeof(struct qstat));
- setzero(&node_stat, sizeof(struct qstat) * MAXGROUPNODE);
- setzero(&pkt_db, sizeof(struct q_pkt) * MAXGROUPNODE);
- setzero(&pkt_dbc, sizeof(int) * MAXGROUPNODE);
- setzero(&rt_stat, sizeof(short) * MAXGROUPNODE * MAXGROUPNODE);
- setzero(&rt_total, sizeof(short) * MAXGROUPNODE);
- }
-
- int
- main(int argc, char **argv)
- {
- struct q_opt *nopt;
- int i, r, e, x, qspn_id;
- time_t start, end;
-
- log_init(argv[0], 1, 1);
- clear_all();
-
- for (i = 0; i < MAXGROUPNODE; i++)
- pthread_mutex_init(&mutex[i], NULL);
-
- if (argc > 1) {
- if (!(int_map = load_map(argv[1], 0))) {
- printf("Error! Cannot load the map\n");
- exit(1);
- }
- printf("Map loaded. Printing it... \n");
- print_map(int_map, "QSPN-map.load");
- lgl_print_map(int_map, "QSPN-map.lgl.load");
- } else {
- int_map = init_map(sizeof(map_node) * MAXGROUPNODE);
- printf("Generating a random map...\n");
- srandom(time(0));
- i = rand_range(0, MAXGROUPNODE - 1);
- gen_rnd_map(i, -1, 0);
- for (x = 0; x < MAXGROUPNODE; x++)
- rnode_rtt_order(&int_map[x]);
- printf("Map generated. Printing it... \n");
- print_map(int_map, "QSPN-map");
- lgl_print_map(int_map, "QSPN-map.lgl");
- int_map[i].flags |= MAP_ME;
- printf("Saving the map to QSPN-map.raw\n");
- save_map(int_map, &int_map[i], "QSPN-map.raw");
- }
- printf("Initialization of qspn_queue\n");
- init_q_queue(int_map);
-
- printf("Running the first test...\n");
- thread_joint(0, show_temp_stat, NULL);
- #ifdef NO_JOINT
- disable_joint = 1;
- #endif
- if (argc > 2)
- r = atoi(argv[2]);
- else
- r = rand_range(0, MAXGROUPNODE - 1);
- printf("Starting the QSPN spreading from node %d\n", r);
- int_map[r].flags |= QSPN_STARTER;
- qspn_id = random();
- start = time(0);
- for (x = 0; x < int_map[r].links; x++) {
- gbl_stat.total_pkts++;
- node_stat[r].total_pkts++;
-
- nopt = xmalloc(sizeof(struct q_opt));
- setzero(nopt, sizeof(struct q_opt));
- nopt->q.q_id = qspn_id;
- nopt->q.from = r;
- nopt->q.to =
- ((void *) int_map[r].r_node[x].r_node -
- (void *) int_map) / sizeof(map_node);
- nopt->q.tracer = xmalloc(sizeof(short));
- nopt->q.tracer[0] = nopt->q.from;
- nopt->q.routes = 1;
- nopt->sleep = int_map[r].r_node[x].rtt.tv_usec;
- nopt->q.broadcast = 0;
- nopt->join = 0;
-
- gbl_stat.qspn_requests++;
- node_stat[r].qspn_requests++;
- nopt->q.op = OP_REQUEST;
- if (x == int_map[r].links - 1)
- nopt->join = 1;
-
- thread_joint(nopt->join, send_qspn_pkt, (void *) nopt);
- }
- #ifdef NO_JOINT
- wait_threads();
- #endif
- end = time(0);
- time_stat = end - start;
- int_map[r].flags &= ~QSPN_STARTER;
-
- printf("Saving the data to QSPN1...\n");
- collect_data();
- print_data("QSPN1");
- for (x = 0; x < MAXGROUPNODE; x++) {
- for (e = 0; e < pkt_dbc[x]; e++) {
- xfree(pkt_db[x][e]->tracer);
- xfree(pkt_db[x][e]);
- }
- xfree(pkt_db[x]);
- }
- free_q_queue(int_map); /*WARNING* To be used when the int_map it's of no more use */
- clear_all();
-
- printf("All done yeah\n");
- fprintf(stderr, "All done yeah\n");
- exit(0);
- }
|