Show scaled_net.c syntax highlighted
/*
*
* Copyright (c) 2003 The Regents of the University of California. All
* rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of the University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* scaled_net.c: Functions that generate data packets to probe the
* network.
*
* $Id: scaled_net.c,v 1.4 2005/10/31 09:25:51 cerpa Exp $
*/
char scaled_net_c_id[] = "$Id: scaled_net.c,v 1.4 2005/10/31 09:25:51 cerpa Exp $";
#include "scaled_i.h"
/*
* Construct a scale packet, which contains our outgoing sequence
* number.
*/
static void packet_send(neighbor_list_t *nl)
{
/* Allocate a small buffer for the packet */
buf_t *buf = buf_new();
uint16_t mtu=0;
int space_left;
int pkt_len;
int i;
link_pkt_t link_pkt = {
dst: {
id: LINK_BROADCAST,
},
type: PKT_TYPE_SCALE,
};
scale_pkt_t sc_pkt = {
src_id: my_node_id,
};
if (buf == NULL) {
elog(LOG_CRIT, "out of memory!");
return;
}
/* get the mtu */
if (lu_get_mtu(nl->link, &mtu) < 0) {
elog(LOG_WARNING, "Can't get the mtu for link %s: %m",
lu_name(nl->link, NULL));
}
/* construct the packet: the outer (link) header and sc pkt */
bufcpy(buf, &link_pkt, sizeof(link_pkt));
bufcpy(buf, &sc_pkt, sizeof(sc_pkt));
/* we have this much room left */
space_left = mtu - buf->len;
/* truncate pkt size limit if larger than available space */
if (nl->pkt_size > space_left)
pkt_len = space_left;
else
pkt_len = nl->pkt_size;
/* send random characters as payload */
for (i = buf->len; i < pkt_len; i++)
bufprintf(buf, "%c", (rand() % 26) + 'a');
/* increase tx counter */
nl->seqno++;
elog(LOG_DEBUG(10), "Sending test packet: %llu", nl->seqno);
/* launch the packet! */
if (lu_send(nl->link, (link_pkt_t *) buf->buf,
buf->len - sizeof(link_pkt_t)) < 0) {
elog(LOG_ERR, "can't send on %s: %m", lu_name(nl->link, NULL));
elog(LOG_ERR, "our MTU was %d", mtu);
}
else
elog(LOG_DEBUG(1), "sending probe packet seqno %lld, len %d", nl->seqno,
buf->len - sizeof(link_pkt_t));
/* and free it */
buf_free(buf);
}
int scaled_gps_to_cpu_time(struct timeval *src_tv, struct timeval *dest_tv)
{
sync_id_t src = {
node: my_node_id,
comp: GPS
};
sync_id_t dest = {
node: my_node_id,
comp: CPU
};
if (sync_convert_tv(&src, src_tv, &dest, dest_tv) < 0) {
elog(LOG_ERR, "couldn't convert from GPS to CPU time: %m\n");
return -1;
}
return 0;
}
int scaled_cpu_to_gps_time(struct timeval *src_tv, struct timeval *dest_tv)
{
sync_id_t src = {
node: my_node_id,
comp: CPU
};
sync_id_t dest = {
node: my_node_id,
comp: GPS
};
if (sync_convert_tv(&src, src_tv, &dest, dest_tv) < 0) {
elog(LOG_DEBUG(0), "couldn't convert from CPU to GPS time: %m\n");
return -1;
}
return 0;
}
void scaled_net_start(neighbor_list_t *nl)
{
struct timeval gtime;
struct timeval ctime;
struct timeval log_gtime;
struct timeval log_ctime;
int i,j, start;
/* convert (gpstime + safe guard band + timeshift (depends on each
* node) to CPU time.
*/
gtime = nl->gps_time;
start = (1000*TIME_GUARD_BAND) +
(nl->tx_window*(my_node_id - nl->root_node_id));
misc_tv_addms(>ime, start);
elog(LOG_DEBUG(5), "My node id is: %d, my start time is: %d",
my_node_id, start);
if(scaled_gps_to_cpu_time(>ime, &ctime) < 0) {
elog(LOG_CRIT, "Time conversion failed, cannot continue!!\n");
exit(1);
}
elog(LOG_DEBUG(10), "Busy waiting until: %s", misc_print_date(&ctime));
/* busy wait until ctime */
misc_busy_wait_until(&ctime);
/* loop forever */
for (i=0; ; i++) {
/* convert current CPU time to GPS for logging purposes */
gettimeofday(&log_ctime, NULL);
scaled_cpu_to_gps_time(&log_ctime, &log_gtime);
/* send n packets */
for (j=0; j < nl->total_pkts; j++)
packet_send(nl);
elog (LOG_NOTICE, "%s - %s - [%d] SENT %d packets of size: %d, with"
" cycle period of %d ms, and tx window of %d ms",
misc_print_date(&log_gtime), misc_tv_to_str(&log_gtime), i,
nl->total_pkts, nl->pkt_size, nl->period, nl->tx_window);
if (nl->use_logging) {
fprintf (nl->fp, "%s - %s - [%d] SENT %d packets of size: %d, "
"with cycle period of %d ms, and tx window of %d ms\n",
misc_print_date(&log_gtime), misc_tv_to_str(&log_gtime), i,
nl->total_pkts, nl->pkt_size, nl->period, nl->tx_window);
fflush(nl->fp);
}
/* convert (gpstime + i*period) to CPU time */
misc_tv_addms(>ime, nl->period);
if(scaled_gps_to_cpu_time(>ime, &ctime) < 0) {
elog(LOG_CRIT, "Time conversion failed, cannot continue!!\n");
exit(1);
}
elog(LOG_DEBUG(10), "Busy waiting until: %s", misc_print_date(&ctime));
/* busy wait until ctime */
misc_busy_wait_until(&ctime);
elog(LOG_DEBUG(5), "Completed cycle: %d\n", i);
}
}
void scaled_net_init(neighbor_list_t *nl)
{
lu_opts_t link_opts = {
opts: {
pkt_type: PKT_TYPE_SCALE,
data: nl,
name: nl->link_name
},
blocking_writes: 1, /* block on back to back writes and full queue */
};
/* Open the link to the underlying network interface */
if (lu_open(&link_opts, &nl->link) < 0) {
elog(LOG_CRIT, "can't open %s: %m", link_name(&link_opts.opts, NULL));
exit(1);
}
/* Get link status to get our if id, if available */
if (lu_status(nl->link, &nl->link_status) < 0) {
elog(LOG_WARNING, "couldn't get status from %s: %m",
lu_name(nl->link, NULL));
}
}
See more files for this project here