Commit 44317e4e authored by Joanne Hugé's avatar Joanne Hugé

WIP: rewrite and clean up code

parent c7b294cd
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#define _GNU_SOURCE #define _GNU_SOURCE
#include <errno.h> #include <errno.h>
#include <error.h> #include <error.h>
#include <limits.h>
#include <pthread.h> #include <pthread.h>
#include <sched.h> #include <sched.h>
#include <signal.h> #include <signal.h>
...@@ -18,9 +19,9 @@ ...@@ -18,9 +19,9 @@
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include "common.h"
#include "recv_packet.h" #include "recv_packet.h"
#include "send_packet.h" #include "send_packet.h"
#include "common.h"
// Structs // Structs
...@@ -48,14 +49,14 @@ typedef struct main_param { ...@@ -48,14 +49,14 @@ typedef struct main_param {
// Static functions // Static functions
static void process_options(int argc, char *argv[]); static void process_options(int argc, char *argv[]);
static void do_tsn_task(struct thread_param *param, char *data, uint64_t next_txtime); static void do_tsn_task(char *data, uint64_t next_txtime);
static void print_histograms(); static void print_histograms();
static void sighand(int sig_num); static void sighand(int sig_num);
// Static variables // Static variables
static int64_t kernel_latency_hist[MAX_KERNEL_LATENCY]++; static int64_t kernel_latency_hist[MAX_KERNEL_LATENCY];
static int64_t rtt_hist[MAX_RTT_LATENCY]++; static int64_t rtt_hist[MAX_RTT];
static int nb_cycles; static int nb_cycles;
...@@ -64,6 +65,8 @@ static thread_param_t thread_params; ...@@ -64,6 +65,8 @@ static thread_param_t thread_params;
static rtt_stat_t rtt_stats; static rtt_stat_t rtt_stats;
static egress_stat_t egress_stats; static egress_stat_t egress_stats;
static egress_param_t egress_params; static egress_param_t egress_params;
static ingress_stat_t ingress_stats;
static ingress_param_t ingress_params;
static int enable_histograms; static int enable_histograms;
static int enable_affinity; static int enable_affinity;
...@@ -114,7 +117,7 @@ static void *packet_sending_thread(void *p) { ...@@ -114,7 +117,7 @@ static void *packet_sending_thread(void *p) {
} }
// Set thread priority // Set thread priority
priority.sched_priority = param->priority; priority.sched_priority = thread_params.priority;
if (sched_setscheduler(0, SCHED_FIFO, &priority)) if (sched_setscheduler(0, SCHED_FIFO, &priority))
error(EXIT_FAILURE, errno, "Couldn't set priority"); error(EXIT_FAILURE, errno, "Couldn't set priority");
...@@ -122,7 +125,7 @@ static void *packet_sending_thread(void *p) { ...@@ -122,7 +125,7 @@ static void *packet_sending_thread(void *p) {
// Measure from CLOCK_TAI to generate timestamp // Measure from CLOCK_TAI to generate timestamp
clock_gettime(CLOCK_TAI, &next); clock_gettime(CLOCK_TAI, &next);
next_txtime = next.tv_sec * NSEC_PER_SEC + next.tv_nsec; next_txtime = next.tv_sec * NSEC_PER_SEC + next.tv_nsec;
next_txtime += param->etf_offset; next_txtime += thread_params.etf_offset;
} else { } else {
next_txtime = 0; next_txtime = 0;
} }
...@@ -183,8 +186,8 @@ int main(int argc, char *argv[]) { ...@@ -183,8 +186,8 @@ int main(int argc, char *argv[]) {
if (enable_histograms) { if (enable_histograms) {
// Init histograms // Init histograms
memset(kernel_latency, 0, MAX_KERNEL_LATENCY); memset(kernel_latency_hist, 0, MAX_KERNEL_LATENCY);
memset(rtt_latency, 0, MAX_RTT_LATENCY); memset(rtt_hist, 0, MAX_RTT);
} }
// Catch breaks with sighand to print the histograms // Catch breaks with sighand to print the histograms
...@@ -193,17 +196,20 @@ int main(int argc, char *argv[]) { ...@@ -193,17 +196,20 @@ int main(int argc, char *argv[]) {
// Initialize the UDP packet sending socket // Initialize the UDP packet sending socket
init_udp_send(&egress_params, init_udp_send(&egress_params,
&egress_stats, &egress_stats,
&thread_params,
enable_histograms, enable_histograms,
kernel_latency_hist); kernel_latency_hist);
// Initialize the UDP packet receiving socket if RTT is measured // Initialize the UDP packet receiving socket if RTT is measured
if (tsn_task == RTT_TASK) if (tsn_task == RTT_TASK)
init_udp_recv(0, network_config.network_if); init_udp_recv(&ingress_params,
&ingress_stats,
enable_histograms,
kernel_latency_hist);
// Create the real time thread // Create the real time thread
if (pthread_create(&thread, NULL, packet_sending_thread, NULL)); if (pthread_create(&thread, NULL, packet_sending_thread, NULL))
error(EXIT_FAILURE, errno, "Couldn't create thread"); ;
error(EXIT_FAILURE, errno, "Couldn't create thread");
// Verbose loop // Verbose loop
for (;;) { for (;;) {
...@@ -213,15 +219,15 @@ int main(int argc, char *argv[]) { ...@@ -213,15 +219,15 @@ int main(int argc, char *argv[]) {
if (tsn_task == RTT_TASK) { if (tsn_task == RTT_TASK) {
printf("%10d: RTT: %4d %4d %4d\n", nb_cycles, rtt_stats.min_rtt, printf("%10d: RTT: %4d %4d %4d\n", nb_cycles, rtt_stats.min_rtt,
rtt_stats.avg_rtt, rtt_stats.avg_rtt,
rtt_stats.max_rtt); rtt_stats.max_rtt);
printf("\033[%dA", 1); printf("\033[%dA", 1);
} else if (enable_timestamps) { } else if (enable_timestamps) {
printf("%10d: K: %4d %4d %4d\n", printf("%10d: K: %4d %4d %4d\n",
nb_cycles, egress_stats.min_kernel_latency, nb_cycles, egress_stats.min_kernel_latency,
egress_stats.avg_kernel_latency, egress_stats.avg_kernel_latency,
egress_stats.max_kernel_latency); egress_stats.max_kernel_latency);
printf("\033[%dA", 1); printf("\033[%dA", 1);
} }
} }
...@@ -259,13 +265,12 @@ static void do_tsn_task(char *data, uint64_t next_txtime) { ...@@ -259,13 +265,12 @@ static void do_tsn_task(char *data, uint64_t next_txtime) {
rtt_stats.min_rtt = min(rtt_us, rtt_stats.min_rtt); rtt_stats.min_rtt = min(rtt_us, rtt_stats.min_rtt);
rtt_stats.max_rtt = max(rtt_us, rtt_stats.max_rtt); rtt_stats.max_rtt = max(rtt_us, rtt_stats.max_rtt);
rtt_stats.avg_rtt = (((uint64_t)rtt_stats.avg_rtt) * (nb_cycles-1) + rtt_us) / nb_cycles; rtt_stats.avg_rtt = (((uint64_t)rtt_stats.avg_rtt) * (nb_cycles - 1) + rtt_us) / nb_cycles;
if (rtt_us > MAX_RTT_VAL) if (rtt_us > MAX_RTT)
fprintf(stderr, "RTT value higher than MAX_RTT_VAL : %d ( > %d)\n", rtt_us, MAX_RTT_VAL); fprintf(stderr, "RTT value higher than MAX_RTT : %d ( > %d)\n", rtt_us, MAX_RTT);
else else
rtt_hist[rtt_us]++; rtt_hist[rtt_us]++;
}
} }
} }
...@@ -275,7 +280,7 @@ static void print_histograms() { ...@@ -275,7 +280,7 @@ static void print_histograms() {
uint64_t duration; uint64_t duration;
int duration_hour, duration_minutes, interval; int duration_hour, duration_minutes, interval;
int max_hist_val, nb_hists; int max_hist_val, nb_hists;
uint64_t * histogram; uint64_t *histogram;
clock_gettime(CLOCK_MONOTONIC, &measures_end); clock_gettime(CLOCK_MONOTONIC, &measures_end);
...@@ -283,7 +288,7 @@ static void print_histograms() { ...@@ -283,7 +288,7 @@ static void print_histograms() {
duration_hour = duration / NSEC_PER_SEC / 3600; duration_hour = duration / NSEC_PER_SEC / 3600;
duration_minutes = duration / NSEC_PER_SEC / 60 - duration_hour * 60; duration_minutes = duration / NSEC_PER_SEC / 60 - duration_hour * 60;
interval = param->interval / 1000; interval = thread_params.interval / 1000;
if (tsn_task == SEND_PACKET_TASK) { if (tsn_task == SEND_PACKET_TASK) {
printf("{\"measure_sets\": [{" printf("{\"measure_sets\": [{"
...@@ -296,7 +301,12 @@ static void print_histograms() { ...@@ -296,7 +301,12 @@ static void print_histograms() {
"}," "},"
"\"props\": [", "\"props\": [",
interval, duration_hour, duration_minutes, thread_params.etf_offset); interval, duration_hour, duration_minutes, thread_params.etf_offset);
histogram = kernel_latency_hist; histogram = kernel_latency_hist;
max_hist_val = 0;
for (int j = 0; j < MAX_KERNEL_LATENCY; j++)
if (histogram[j])
max_hist_val = j > max_hist_val ? j : max_hist_val;
} else if (tsn_task == RTT_TASK) { } else if (tsn_task == RTT_TASK) {
printf("{\"measure_sets\": [{" printf("{\"measure_sets\": [{"
...@@ -309,15 +319,14 @@ static void print_histograms() { ...@@ -309,15 +319,14 @@ static void print_histograms() {
"}," "},"
"\"props\": [", "\"props\": [",
interval, duration_hour, duration_minutes, thread_params.etf_offset); interval, duration_hour, duration_minutes, thread_params.etf_offset);
histogram = rtt_hist; histogram = rtt_hist;
max_hist_val = 0;
for (int j = 0; j < MAX_RTT; j++)
if (histogram[j])
max_hist_val = j > max_hist_val ? j : max_hist_val;
} }
max_hist_val = 0;
for (int j = 0; j < MAX_HIST_VAL; j++)
if (histogram[j])
max_hist_val = j > max_hist_val ? j : max_hist_val;
printf("["); printf("[");
for (int j = 0; j < max_hist_val; j++) for (int j = 0; j < max_hist_val; j++)
printf("%" PRIi64 "%s", histogram[j], (j + 1 < max_hist_val ? ", " : "")); printf("%" PRIi64 "%s", histogram[j], (j + 1 < max_hist_val ? ", " : ""));
...@@ -410,5 +419,5 @@ static void process_options(int argc, char *argv[]) { ...@@ -410,5 +419,5 @@ static void process_options(int argc, char *argv[]) {
help(argv); help(argv);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
strcpy(egress_params.ip_address, argv[optind]); strcpy(egress_params.server_ip, argv[optind]);
} }
...@@ -32,8 +32,8 @@ uint64_t calcdiff_ns(struct timespec t1, struct timespec t2) { ...@@ -32,8 +32,8 @@ uint64_t calcdiff_ns(struct timespec t1, struct timespec t2) {
return diff; return diff;
} }
uint64_t max(uint64_t a, uint64_t b) { return a > b ? a : b; } int max(int a, int b) { return a > b ? a : b; }
uint64_t min(uint64_t a, uint64_t b) { return a < b ? a : b; } int min(int a, int b) { return a < b ? a : b; }
static void sighand_wrapper(int sig) { static void sighand_wrapper(int sig) {
......
...@@ -13,26 +13,20 @@ ...@@ -13,26 +13,20 @@
#define SERVER_PORT_INT 50000 #define SERVER_PORT_INT 50000
#define MAX_KERNEL_LATENCY 1000 #define MAX_KERNEL_LATENCY 1000
#define MAX_RTT_LATENCY 1000 #define MAX_RTT 1000
#define MAX_JITTER 1000 #define MAX_JITTER 1000
#define MAX_BUFFER_SIZE 1024 #define MAX_BUFFER_SIZE 1024
typedef struct packet_info {
uint64_t userspace_enter_ts;
uint64_t userspace_exit_ts;
uint64_t kernelspace_ts;
char data[MAX_BUFFER_SIZE];
} packet_info_t;
uint64_t ts_to_uint(struct timespec t); uint64_t ts_to_uint(struct timespec t);
void add_ns(struct timespec *t, uint64_t ns); void add_ns(struct timespec *t, uint64_t ns);
uint64_t calcdiff_ns(struct timespec t1, struct timespec t2); uint64_t calcdiff_ns(struct timespec t1, struct timespec t2);
uint64_t max(uint64_t a, uint64_t b);
uint64_t min(uint64_t a, uint64_t b);
void init_signals(void (*_sighand)(int), int enable_histograms); void init_signals(void (*_sighand)(int), int enable_histograms);
int min(int a, int b);
int max(int a, int b);
extern void (*previous_handlers[NSIG])(int); extern void (*previous_handlers[NSIG])(int);
#endif #endif
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#include <unistd.h> #include <unistd.h>
#include "common.h" #include "common.h"
#include "send_packet.h" #include "recv_packet.h"
static char rx_buffer[MAX_BUFFER_SIZE]; static char rx_buffer[MAX_BUFFER_SIZE];
static int sock_fd; static int sock_fd;
...@@ -34,6 +34,11 @@ static int sock_fd; ...@@ -34,6 +34,11 @@ static int sock_fd;
static int so_timestamping_flags = static int so_timestamping_flags =
SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_SOFTWARE; SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_SOFTWARE;
static ingress_param_t *params;
static ingress_stat_t *stats;
static uint64_t *kernel_latency_hist;
static int use_histogram;
static uint64_t timestamps_buffer[64]; static uint64_t timestamps_buffer[64];
static int ts_buf_read_index = 0; static int ts_buf_read_index = 0;
static int ts_buf_write_index = 0; static int ts_buf_write_index = 0;
...@@ -43,7 +48,7 @@ static int set_if() { ...@@ -43,7 +48,7 @@ static int set_if() {
struct ifreq ifreq; struct ifreq ifreq;
memset(&ifreq, 0, sizeof(ifreq)); memset(&ifreq, 0, sizeof(ifreq));
strncpy(ifreq.ifr_name, ingress_params->network_if, sizeof(ifreq.ifr_name) - 1); strncpy(ifreq.ifr_name, params->network_if, sizeof(ifreq.ifr_name) - 1);
if (ioctl(sock_fd, SIOCGIFINDEX, &ifreq)) if (ioctl(sock_fd, SIOCGIFINDEX, &ifreq))
error(EXIT_FAILURE, errno, "ioctl SIOCGIFINDEX failed\n"); error(EXIT_FAILURE, errno, "ioctl SIOCGIFINDEX failed\n");
...@@ -53,7 +58,7 @@ static int set_if() { ...@@ -53,7 +58,7 @@ static int set_if() {
void init_udp_recv(ingress_param_t *_params, void init_udp_recv(ingress_param_t *_params,
ingress_stat_t *_stats, ingress_stat_t *_stats,
int use_histogram, int _use_histogram,
uint64_t *_kernel_latency_hist) { uint64_t *_kernel_latency_hist) {
int getaddrinfo_err; int getaddrinfo_err;
int set_if_err; int set_if_err;
...@@ -125,7 +130,7 @@ void recv_udp_packet() { ...@@ -125,7 +130,7 @@ void recv_udp_packet() {
struct timespec ts; struct timespec ts;
if (use_timestamps) { if (params->use_timestamps) {
clock_gettime(CLOCK_REALTIME, &ts); clock_gettime(CLOCK_REALTIME, &ts);
timestamps_buffer[ts_buf_write_index++] = ts_to_uint(ts); timestamps_buffer[ts_buf_write_index++] = ts_to_uint(ts);
} }
...@@ -171,25 +176,6 @@ void recv_udp_packet() { ...@@ -171,25 +176,6 @@ void recv_udp_packet() {
strcpy(stats->data, rx_buffer); strcpy(stats->data, rx_buffer);
} }
static void fill_histograms(packet_info_t *packet_info, int64_t histograms[NB_HISTOGRAMS][MAX_HIST_VAL]) {
uint64_t user_space_time = packet_info->userspace_exit_ts - packet_info->userspace_enter_ts;
uint64_t kernel_space_time = packet_info->userspace_enter_ts - packet_info->kernelspace_ts;
user_space_time /= 1000u;
kernel_space_time /= 1000u;
if (user_space_time > MAX_HIST_VAL)
fprintf(stderr, "user_space_time value too high: %" PRIu64 "us\n", user_space_time);
else
histograms[0][user_space_time]++;
if (kernel_space_time > MAX_HIST_VAL)
fprintf(stderr, "kernel_space_time value too high: %" PRIu64 "us\n", kernel_space_time);
else
histograms[1][kernel_space_time]++;
}
#ifdef DEBUG #ifdef DEBUG
/* /*
......
#ifndef RECV_PACKET #ifndef RECV_PACKET
#define RECV_PACKET #define RECV_PACKET
#include "utilities.h" #include "common.h"
void init_udp_recv(ingress_param_t *_params,
ingress_stat_t *stats,
int use_histogram,
uint64_t *_kernel_latency_hist);
void recv_udp_packet();
void init_udp_recv(ingress_param_t *params,
uint64_t *kernel_latency_hist);
void recv_udp_packet(int nb_cycles);
typedef struct ingress_param { typedef struct ingress_param {
char network_if[16]; char network_if[16];
int use_timestamps; int use_timestamps;
size_t tx_buffer_len;
} ingress_param_t; } ingress_param_t;
typedef struct ingress_stat { typedef struct ingress_stat {
uint64_t high_kernel_latency;
int min_kernel_latency; int min_kernel_latency;
int avg_kernel_latency; int avg_kernel_latency;
int max_kernel_latency; int max_kernel_latency;
...@@ -33,6 +22,18 @@ typedef struct ingress_stat { ...@@ -33,6 +22,18 @@ typedef struct ingress_stat {
int avg_interval; int avg_interval;
int max_interval; int max_interval;
} egress_stat_t; uint64_t high_kernel_latency;
uint64_t packets_received;
int lost_packets;
char data[MAX_BUFFER_SIZE];
} ingress_stat_t;
void init_udp_recv(ingress_param_t *_params,
ingress_stat_t *stats,
int use_histogram,
uint64_t *_kernel_latency_hist);
void recv_udp_packet();
#endif #endif
...@@ -34,10 +34,10 @@ ...@@ -34,10 +34,10 @@
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include "send_packet.h"
#include "common.h" #include "common.h"
#include "send_packet.h"
static void * poll_thread(void *p); static void *poll_thread(void *p);
static void process_error_queue(); static void process_error_queue();
static void init_tx_buffer(); static void init_tx_buffer();
...@@ -46,10 +46,11 @@ static int set_if(); ...@@ -46,10 +46,11 @@ static int set_if();
static int so_timestamping_flags = static int so_timestamping_flags =
SOF_TIMESTAMPING_TX_SOFTWARE | SOF_TIMESTAMPING_SOFTWARE; SOF_TIMESTAMPING_TX_SOFTWARE | SOF_TIMESTAMPING_SOFTWARE;
egress_param_t * params; static egress_param_t *params;
egress_stat_t * stats; static egress_stat_t *stats;
uint64_t * kernel_latency_hist; static uint64_t *kernel_latency_hist;
int use_histogram; static int use_histogram;
static uint64_t packets_sent = 0;
static struct sock_txtime sk_txtime; static struct sock_txtime sk_txtime;
static char *tx_buffer; static char *tx_buffer;
...@@ -62,10 +63,10 @@ static int ts_buf_write_index = 0; ...@@ -62,10 +63,10 @@ static int ts_buf_write_index = 0;
/* /*
* Init UDP socket * Init UDP socket
*/ */
void init_udp_send(egress_param_t * _params, void init_udp_send(egress_param_t *_params,
egress_stat_t * _stats, egress_stat_t *_stats,
int _use_histogram, int _use_histogram,
uint64_t * _kernel_latency_hist) { uint64_t *_kernel_latency_hist) {
int set_if_err; int set_if_err;
pthread_t thread; pthread_t thread;
...@@ -73,7 +74,7 @@ void init_udp_send(egress_param_t * _params, ...@@ -73,7 +74,7 @@ void init_udp_send(egress_param_t * _params,
params = _params; params = _params;
stats = _stats; stats = _stats;
kernel_latency_hist = _kernel_latency_hist; kernel_latency_hist = _kernel_latency_hist;
use_histogram = _use_histogram use_histogram = _use_histogram;
init_tx_buffer(); init_tx_buffer();
...@@ -116,7 +117,7 @@ void init_udp_send(egress_param_t * _params, ...@@ -116,7 +117,7 @@ void init_udp_send(egress_param_t * _params,
* Sends udp packets * Sends udp packets
*/ */
void send_udp_packet(char *data, void send_udp_packet(char *data,
uint64_t txtime, int nb_cycles) { uint64_t txtime) {
struct msghdr msg; // Message hardware, sent to the socket struct msghdr msg; // Message hardware, sent to the socket
struct cmsghdr *cmsg; // Control message hardware, for txtime struct cmsghdr *cmsg; // Control message hardware, for txtime
...@@ -131,11 +132,13 @@ void send_udp_packet(char *data, ...@@ -131,11 +132,13 @@ void send_udp_packet(char *data,
timestamps_buffer[ts_buf_write_index++] = ts_to_uint(ts); timestamps_buffer[ts_buf_write_index++] = ts_to_uint(ts);
} }
packets_sent++;
strcpy(tx_buffer, data); strcpy(tx_buffer, data);
memset(&sin, 0, sizeof(sin)); memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET; sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr(server_ip); sin.sin_addr.s_addr = inet_addr(params->server_ip);
sin.sin_port = htons(SERVER_PORT_INT); sin.sin_port = htons(SERVER_PORT_INT);
iov.iov_base = tx_buffer; iov.iov_base = tx_buffer;
...@@ -165,7 +168,7 @@ void send_udp_packet(char *data, ...@@ -165,7 +168,7 @@ void send_udp_packet(char *data,
error(EXIT_FAILURE, errno, "sendmsg failed, ret value: %d\n", sendmsgerr); error(EXIT_FAILURE, errno, "sendmsg failed, ret value: %d\n", sendmsgerr);
} }
static void * poll_thread(void *p) { static void *poll_thread(void *p) {
(void)p; (void)p;
// Poll file descriptor // Poll file descriptor
...@@ -175,13 +178,15 @@ static void * poll_thread(void *p) { ...@@ -175,13 +178,15 @@ static void * poll_thread(void *p) {
int ret; int ret;
ret = poll(&poll_fd, 1, -1); ret = poll(&poll_fd, 1, -1);
if (ret == 1 && p_fd.revents & POLLERR) { if (ret == 1 && poll_fd.revents & POLLERR) {
process_error_queue(nb_cycles); process_error_queue();
} }
} }
} }
static void process_error_queue(int nb_cycles) { static void process_error_queue() {
int recv_ret;
// IO vector // IO vector
unsigned char data_buffer[256]; // Buffer in io vector unsigned char data_buffer[256]; // Buffer in io vector
struct iovec iov = { struct iovec iov = {
...@@ -201,8 +206,8 @@ static void process_error_queue(int nb_cycles) { ...@@ -201,8 +206,8 @@ static void process_error_queue(int nb_cycles) {
struct cmsghdr *cmsg; struct cmsghdr *cmsg;
// Timestamps and errors are received in the error queue // Timestamps and errors are received in the error queue
res = recvmsg(sock_fd, &msg, MSG_ERRQUEUE | MSG_DONTWAIT); recv_ret = recvmsg(sock_fd, &msg, MSG_ERRQUEUE | MSG_DONTWAIT);
if (res == -1) { if (recv_ret == -1) {
fprintf(stderr, "recvmsg() failed\n"); fprintf(stderr, "recvmsg() failed\n");
return; return;
} }
...@@ -213,12 +218,11 @@ static void process_error_queue(int nb_cycles) { ...@@ -213,12 +218,11 @@ static void process_error_queue(int nb_cycles) {
struct timespec *stamp = (struct timespec *)CMSG_DATA(cmsg); struct timespec *stamp = (struct timespec *)CMSG_DATA(cmsg);
uint64_t kernel_latency = ts_to_uint(stamp) - timestamps_buffer[ts_buf_read_index++]; int kernel_latency = (ts_to_uint(*stamp) - timestamps_buffer[ts_buf_read_index++]) / 1000;
kernel_latency /= 1000u;
stats->min_kernel_latency = min(kernel_latency, stats->min_kernel_latency); stats->min_kernel_latency = min(kernel_latency, stats->min_kernel_latency);
stats->max_kernel_latency = max(kernel_latency, stats->max_kernel_latency); stats->max_kernel_latency = max(kernel_latency, stats->max_kernel_latency);
stats->avg_kernel_latency = (stats->max_kernel_latency * (nb_cycles-1) + kernel_latency) / nb_cycles; stats->avg_kernel_latency = (stats->max_kernel_latency * (packets_sent - 1) + kernel_latency) / packets_sent;
if (use_histogram) { if (use_histogram) {
if (kernel_latency > MAX_KERNEL_LATENCY) if (kernel_latency > MAX_KERNEL_LATENCY)
...@@ -248,7 +252,6 @@ static void process_error_queue(int nb_cycles) { ...@@ -248,7 +252,6 @@ static void process_error_queue(int nb_cycles) {
} }
} }
} }
} }
// Sets the interface // Sets the interface
......
...@@ -3,13 +3,6 @@ ...@@ -3,13 +3,6 @@
#include "common.h" #include "common.h"
void init_udp_send(egress_param_t *_params,
egress_stat_t *_stats,
int _use_histogram,
uint64_t *_kernel_latency_hist);
void send_udp_packet(char *data, uint64_t txtime, int nb_cycles);
typedef struct egress_param { typedef struct egress_param {
int packet_priority; int packet_priority;
size_t tx_buffer_len; size_t tx_buffer_len;
...@@ -33,4 +26,11 @@ typedef struct egress_stat { ...@@ -33,4 +26,11 @@ typedef struct egress_stat {
} egress_stat_t; } egress_stat_t;
void init_udp_send(egress_param_t *_params,
egress_stat_t *_stats,
int _use_histogram,
uint64_t *_kernel_latency_hist);
void send_udp_packet(char *data, uint64_t txtime);
#endif #endif
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <errno.h> #include <errno.h>
#include <error.h> #include <error.h>
#include <inttypes.h> #include <inttypes.h>
#include <limits.h>
#include <netdb.h> #include <netdb.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <pthread.h> #include <pthread.h>
...@@ -30,18 +31,6 @@ ...@@ -30,18 +31,6 @@
// Structs // Structs
typedef struct thread_stat {
int min_interval;
int avg_interval;
int max_interval;
int packets_received;
int lost_packets;
char *data[MAX_BUFFER_SIZE];
} thread_stat_t;
typedef struct thread_param { typedef struct thread_param {
int interval; int interval;
int priority; int priority;
...@@ -51,7 +40,6 @@ typedef struct thread_param { ...@@ -51,7 +40,6 @@ typedef struct thread_param {
typedef struct main_params { typedef struct main_params {
int refresh_rate; int refresh_rate;
int verbose; int verbose;
size_t tx_buffer_len;
} main_param_t; } main_param_t;
static void process_options(int argc, char *argv[]); static void process_options(int argc, char *argv[]);
...@@ -67,13 +55,14 @@ static main_param_t main_params; ...@@ -67,13 +55,14 @@ static main_param_t main_params;
static thread_param_t thread_params; static thread_param_t thread_params;
static ingress_stat_t ingress_stats; static ingress_stat_t ingress_stats;
static ingress_param_t ingress_params; static ingress_param_t ingress_params;
static egress_stat_t egress_stats;
static egress_param_t egress_params;
static int enable_histograms; static int enable_histograms;
static int enable_affinity; static int enable_affinity;
static int enable_timestamps; static int enable_timestamps;
enum TSNTask { RECV_PACKET_TASK, enum TSNTask { RECV_PACKET_TASK, RTT_TASK };
RTT_TASK };
static enum TSNTask tsn_task; static enum TSNTask tsn_task;
struct timespec measures_start; struct timespec measures_start;
...@@ -126,7 +115,7 @@ static void *packet_receiving_thread(void *p) { ...@@ -126,7 +115,7 @@ static void *packet_receiving_thread(void *p) {
clock_gettime(CLOCK_MONOTONIC, &measures_start); clock_gettime(CLOCK_MONOTONIC, &measures_start);
// Packet receiving loop // Packet receiving loop
for (stats->packets_received = 0;; stats->packets_received++) { for (ingress_stats.packets_received = 0;; ingress_stats.packets_received++) {
if (tsn_task == RTT_TASK) { if (tsn_task == RTT_TASK) {
...@@ -139,10 +128,11 @@ static void *packet_receiving_thread(void *p) { ...@@ -139,10 +128,11 @@ static void *packet_receiving_thread(void *p) {
clock_gettime(CLOCK_MONOTONIC, &current); clock_gettime(CLOCK_MONOTONIC, &current);
current_packet_id = recv_udp_packet(); recv_udp_packet();
current_packet_id = atoi(ingress_stats.data);
// If this is not the first received packet // If this is not the first received packet
if (stats->packets_received) { if (ingress_stats.packets_received) {
int interval_us = calcdiff_ns(current, previous) / 1000; int interval_us = calcdiff_ns(current, previous) / 1000;
ingress_stats.min_interval = min(interval_us, ingress_stats.min_interval); ingress_stats.min_interval = min(interval_us, ingress_stats.min_interval);
...@@ -192,13 +182,12 @@ int main(int argc, char *argv[]) { ...@@ -192,13 +182,12 @@ int main(int argc, char *argv[]) {
// Process bash options // Process bash options
process_options(argc, argv); process_options(argc, argv);
ingress_params.use_histograms = enable_histograms;
ingress_params.use_timestamps = enable_timestamps; ingress_params.use_timestamps = enable_timestamps;
if (enable_histograms) { if (enable_histograms) {
// Init histograms // Init histograms
memset(kernel_latency_hist, 0, MAX_LATENCY_VAL); memset(kernel_latency_hist, 0, MAX_KERNEL_LATENCY);
memset(jitter_hist, 0, MAX_JITTER_VAL); memset(jitter_hist, 0, MAX_JITTER);
} }
// Catch breaks with sighand to print the histograms // Catch breaks with sighand to print the histograms
...@@ -213,6 +202,7 @@ int main(int argc, char *argv[]) { ...@@ -213,6 +202,7 @@ int main(int argc, char *argv[]) {
// Initialize the UDP packet sending socket if RTT is measured // Initialize the UDP packet sending socket if RTT is measured
if (tsn_task == RTT_TASK) if (tsn_task == RTT_TASK)
init_udp_send(&egress_params, init_udp_send(&egress_params,
&egress_stats,
0, 0,
NULL); NULL);
...@@ -228,7 +218,7 @@ int main(int argc, char *argv[]) { ...@@ -228,7 +218,7 @@ int main(int argc, char *argv[]) {
if (tsn_task == RECV_PACKET_TASK) { if (tsn_task == RECV_PACKET_TASK) {
int jitter = ingress_stats->max_interval - ingress_stats->min_interval; int jitter = ingress_stats.max_interval - ingress_stats.min_interval;
printf("%10d: J: %4d, I: %4d %4d %4d", printf("%10d: J: %4d, I: %4d %4d %4d",
ingress_stats.packets_received, ingress_stats.packets_received,
...@@ -240,9 +230,11 @@ int main(int argc, char *argv[]) { ...@@ -240,9 +230,11 @@ int main(int argc, char *argv[]) {
if (enable_timestamps) { if (enable_timestamps) {
printf(", K: %4d %4d %4d, D: %5s, L: %4d\n", printf(", K: %4d %4d %4d, D: %5s, L: %4d\n",
kernel_space_time, ingress_stats.min_kernel_latency,
stats->packet_info.data, ingress_stats.avg_kernel_latency,
stats->lost_packets); ingress_stats.max_kernel_latency,
ingress_stats.data,
ingress_stats.lost_packets);
} else { } else {
printf("\n"); printf("\n");
} }
...@@ -258,7 +250,7 @@ static void print_histograms() { ...@@ -258,7 +250,7 @@ static void print_histograms() {
uint64_t duration; uint64_t duration;
int duration_hour, duration_minutes, interval; int duration_hour, duration_minutes, interval;
int max_hist_val, min_hist_val; int max_latency, min_latency, max_jitter, min_jitter;
clock_gettime(CLOCK_MONOTONIC, &measures_end); clock_gettime(CLOCK_MONOTONIC, &measures_end);
...@@ -331,8 +323,8 @@ static void sighand(int sig_num) { ...@@ -331,8 +323,8 @@ static void sighand(int sig_num) {
print_histograms(); print_histograms();
if (stats.lost_packets) if (ingress_stats.lost_packets)
fprintf(stderr, "%d packets were lost\n", stats.lost_packets); fprintf(stderr, "%d packets were lost\n", ingress_stats.lost_packets);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
...@@ -354,7 +346,7 @@ static void process_options(int argc, char *argv[]) { ...@@ -354,7 +346,7 @@ static void process_options(int argc, char *argv[]) {
break; break;
case 'b': case 'b':
tsn_task = RTT_TASK; tsn_task = RTT_TASK;
strcpy(ingress_params.ip_address, optarg); strcpy(egress_params.server_ip, optarg);
break; break;
case 'd': case 'd':
ingress_params.tx_buffer_len = atoi(optarg); ingress_params.tx_buffer_len = atoi(optarg);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment