int timeval_delta2(const struct timeval *t1, const struct timeval *t2, struct timeval *delta) { int rc = timeval_delta(t1, t2, delta); if (rc) rc = timeval_delta(t2, t1, delta); return rc; }
/** * latency for receiving packets from the network * * return int sleeptime in usec */ int32_t recv_latency(int sock_udp, int port) { struct sockaddr_in rcv; char *random_data; float min_OSdelta[50], ord_min_OSdelta[50]; int j; struct timeval current_time, first_time; if ((random_data = malloc(max_packet_size * sizeof(char))) == NULL) { return -1; } srandom(getpid()); /* Create random payload; does it matter? */ for (j = 0; j < max_packet_size - 1; j++) random_data[j] = (char) (random() & 0x000000ff); bzero((char *) &rcv, sizeof(rcv)); rcv.sin_family = AF_INET; rcv.sin_addr.s_addr = INADDR_ANY; rcv.sin_port = htons(port); for (j = 0; j < 50; j++) { if (sendto(sock_udp, random_data, max_packet_size, 0, (struct sockaddr*) &rcv, sizeof(rcv)) == -1) { return -1; } gettimeofday(&first_time, NULL); recvfrom(sock_udp, random_data, max_packet_size, 0, NULL, NULL); gettimeofday(¤t_time, NULL); min_OSdelta[j] = timeval_delta(first_time, current_time); } /* Use median of measured latencies to avoid outliers */ order_float(min_OSdelta, ord_min_OSdelta, 50); free(random_data); return ((int32_t)(ord_min_OSdelta[24] + ord_min_OSdelta[25]) / 2); }
const gchar *get_exec_time(void) { static gchar timestr[30]; static struct timeval start_tv = {0, 0}; static struct timeval previous = {0, 0}; static gint started = 0; struct timeval tv = {0, 0}; static struct timeval delta = {0, 0}; gettimeofday(&tv, NULL); if (start_tv.tv_sec == 0) start_tv = tv; tv.tv_sec -= start_tv.tv_sec; if (tv.tv_usec >= start_tv.tv_usec) tv.tv_usec -= start_tv.tv_usec; else { tv.tv_usec += 1000000 - start_tv.tv_usec; tv.tv_sec -= 1; } if (started) timeval_delta(&delta, &tv, &previous); previous = tv; started = 1; g_snprintf(timestr, sizeof(timestr), "%5d.%06d (+%05d.%06d)", (gint)tv.tv_sec, (gint)tv.tv_usec, (gint)delta.tv_sec, (gint)delta.tv_usec); return timestr; }
double timeval_delta_d(const struct timeval *start, const struct timeval *end) { struct timeval delta; if (timeval_delta(start, end, &delta)) return INFINITY; return (double)delta.tv_usec / 1000000 + (double)delta.tv_sec; }
static void dccp_insert_option_timestamp_echo(struct sock *sk, struct sk_buff *skb) { struct dccp_sock *dp = dccp_sk(sk); #ifdef CONFIG_IP_DCCP_DEBUG const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ? "CLIENT TX opt: " : "server TX opt: "; #endif struct timeval now; u32 tstamp_echo; u32 elapsed_time; int len, elapsed_time_len; unsigned char *to; dccp_timestamp(sk, &now); elapsed_time = timeval_delta(&now, &dp->dccps_timestamp_time) / 10; elapsed_time_len = dccp_elapsed_time_len(elapsed_time); len = 6 + elapsed_time_len; if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) { LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small to insert " "timestamp echo!\n"); return; } DCCP_SKB_CB(skb)->dccpd_opt_len += len; to = skb_push(skb, len); *to++ = DCCPO_TIMESTAMP_ECHO; *to++ = len; tstamp_echo = htonl(dp->dccps_timestamp_echo); memcpy(to, &tstamp_echo, 4); to += 4; if (elapsed_time_len == 2) { const u16 var16 = htons((u16)elapsed_time); memcpy(to, &var16, 2); } else if (elapsed_time_len == 4) { const u32 var32 = htonl(elapsed_time); memcpy(to, &var32, 4); } dccp_pr_debug("%sTIMESTAMP_ECHO=%u, len=%d, seqno=%llu\n", debug_prefix, dp->dccps_timestamp_echo, len, (unsigned long long) DCCP_SKB_CB(skb)->dccpd_seq); dp->dccps_timestamp_echo = 0; dp->dccps_timestamp_time.tv_sec = 0; dp->dccps_timestamp_time.tv_usec = 0; }
/** * latency for sending packets from the network * * return int sleeptime in usec */ int32_t send_latency() { char *pack_buf; float min_OSdelta[50], ord_min_OSdelta[50]; int i, len; int sock_udp; struct timeval first_time, current_time; struct sockaddr_in snd_udp_addr, rcv_udp_addr; if (max_packet_size == 0 || (pack_buf = malloc(max_packet_size * sizeof(char))) == NULL) { return (-1); } if ((sock_udp = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { return (-1); } bzero((char*) &snd_udp_addr, sizeof(snd_udp_addr)); snd_udp_addr.sin_family = AF_INET; snd_udp_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); snd_udp_addr.sin_port = 0; if (bind(sock_udp, (struct sockaddr*) &snd_udp_addr, sizeof(snd_udp_addr)) < 0) { return (-1); } len = sizeof(rcv_udp_addr); if (getsockname(sock_udp, (struct sockaddr *) &rcv_udp_addr, (socklen_t *) &len) < 0) { return (-1); } if (connect(sock_udp, (struct sockaddr *) &rcv_udp_addr, sizeof(rcv_udp_addr)) < 0) { return (-1); } srandom(getpid()); /* Create random payload; does it matter? */ for (i = 0; i < max_packet_size - 1; i++) pack_buf[i] = (char) (random() & 0x000000ff); for (i = 0; i < 50; i++) { gettimeofday(&first_time, NULL); if (send(sock_udp, pack_buf, max_packet_size, 0) == -1) return -1; gettimeofday(¤t_time, NULL); recv(sock_udp, pack_buf, max_packet_size, 0); min_OSdelta[i] = timeval_delta(first_time, current_time); } /* Use median of measured latencies to avoid outliers */ order_float(min_OSdelta, ord_min_OSdelta, 50); if (pack_buf != NULL) free(pack_buf); return (ord_min_OSdelta[25]); }