Commit c7b294cd authored by Joanne Hugé's avatar Joanne Hugé

WIP: rewrite and clean up code

parent 52742c4d
...@@ -154,6 +154,10 @@ static void *packet_sending_thread(void *p) { ...@@ -154,6 +154,10 @@ static void *packet_sending_thread(void *p) {
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
pthread_t thread; pthread_t thread;
egress_stats.min_kernel_latency = INT_MAX;
egress_stats.avg_kernel_latency = 0;
egress_stats.max_kernel_latency = 0;
// Default configuration values // Default configuration values
thread_params.interval = 100000 * 1000; thread_params.interval = 100000 * 1000;
thread_params.max_cycles = 0; thread_params.max_cycles = 0;
......
...@@ -25,8 +25,8 @@ ...@@ -25,8 +25,8 @@
#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 char rx_buffer[MAX_BUFFER_SIZE]; static char rx_buffer[MAX_BUFFER_SIZE];
static int sock_fd; static int sock_fd;
...@@ -51,16 +51,18 @@ static int set_if() { ...@@ -51,16 +51,18 @@ static int set_if() {
return ifreq.ifr_ifindex; return ifreq.ifr_ifindex;
} }
void init_udp_recv(struct ingress_param * _params, void init_udp_recv(ingress_param_t *_params,
int use_histogram, ingress_stat_t *_stats,
uint64_t * _kernel_latency_hist) { int use_histogram,
uint64_t *_kernel_latency_hist) {
int getaddrinfo_err; int getaddrinfo_err;
int set_if_err; int set_if_err;
struct addrinfo hints, *servinfo, *servinfo_it; struct addrinfo hints, *servinfo, *servinfo_it;
params = _params; params = _params;
use_histogram = _use_histogram; stats = _stats;
kernel_latency_hist = _kernel_latency_hist; use_histogram = _use_histogram;
kernel_latency_hist = _kernel_latency_hist;
memset(&hints, 0, sizeof hints); memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; hints.ai_family = AF_UNSPEC;
...@@ -108,7 +110,7 @@ void init_udp_recv(struct ingress_param * _params, ...@@ -108,7 +110,7 @@ void init_udp_recv(struct ingress_param * _params,
/* /*
* Receives udp packets * Receives udp packets
*/ */
void recv_udp_packet(int nb_cycles) { void recv_udp_packet() {
struct cmsghdr *cmsg; struct cmsghdr *cmsg;
struct msghdr msg; // Message hardware, sent to the socket struct msghdr msg; // Message hardware, sent to the socket
...@@ -152,13 +154,13 @@ void recv_udp_packet(int nb_cycles) { ...@@ -152,13 +154,13 @@ void recv_udp_packet(int nb_cycles) {
uint64_t kernel_latency = timestamps_buffer[ts_buf_read_index++] - ts_to_uint(*stamp); uint64_t kernel_latency = timestamps_buffer[ts_buf_read_index++] - ts_to_uint(*stamp);
kernel_latency /= 1000u; kernel_latency /= 1000u;
ingress_stats->min_kernel_latency = min(kernel_latency, ingress_stats->min_kernel_latency); stats->min_kernel_latency = min(kernel_latency, stats->min_kernel_latency);
ingress_stats->max_kernel_latency = max(kernel_latency, ingress_stats->max_kernel_latency); stats->max_kernel_latency = max(kernel_latency, stats->max_kernel_latency);
ingress_stats->avg_kernel_latency = (ingress_stats->max_kernel_latency * (nb_cycles-1) + kernel_latency) / nb_cycles; stats->avg_kernel_latency = (stats->max_kernel_latency * (stats->packets_received - 1) + kernel_latency) / stats->packets_received;
if (use_histogram) { if (use_histogram) {
if (kernel_latency > MAX_KERNEL_LATENCY) if (kernel_latency > MAX_KERNEL_LATENCY)
stats.high_kernel_latency++; stats->high_kernel_latency++;
else else
kernel_latency_hist[kernel_latency]++; kernel_latency_hist[kernel_latency]++;
} }
......
...@@ -3,17 +3,17 @@ ...@@ -3,17 +3,17 @@
#include "utilities.h" #include "utilities.h"
void init_udp_recv(struct ingress_param * _params, void init_udp_recv(ingress_param_t *_params,
int use_histogram, ingress_stat_t *stats,
uint64_t * _kernel_latency_hist); int use_histogram,
uint64_t *_kernel_latency_hist);
void recv_udp_packet(int nb_cycles); void recv_udp_packet();
void init_udp_recv(ingress_param_t * params, void init_udp_recv(ingress_param_t *params,
uint64_t * kernel_latency_hist); uint64_t *kernel_latency_hist);
void recv_udp_packet(int nb_cycles); void recv_udp_packet(int nb_cycles);
typedef struct ingress_param { typedef struct ingress_param {
char network_if[16]; char network_if[16];
...@@ -21,4 +21,18 @@ typedef struct ingress_param { ...@@ -21,4 +21,18 @@ typedef struct ingress_param {
} ingress_param_t; } ingress_param_t;
typedef struct ingress_stat {
uint64_t high_kernel_latency;
int min_kernel_latency;
int avg_kernel_latency;
int max_kernel_latency;
int min_interval;
int avg_interval;
int max_interval;
} egress_stat_t;
#endif #endif
...@@ -3,9 +3,11 @@ ...@@ -3,9 +3,11 @@
#include "common.h" #include "common.h"
void init_udp_send(egress_param_t * _params, void init_udp_send(egress_param_t *_params,
int _use_histogram, egress_stat_t *_stats,
uint64_t * _kernel_latency_hist); int _use_histogram,
uint64_t *_kernel_latency_hist);
void send_udp_packet(char *data, uint64_t txtime, int nb_cycles); void send_udp_packet(char *data, uint64_t txtime, int nb_cycles);
typedef struct egress_param { typedef struct egress_param {
...@@ -29,6 +31,6 @@ typedef struct egress_stat { ...@@ -29,6 +31,6 @@ typedef struct egress_stat {
int avg_kernel_latency; int avg_kernel_latency;
int max_kernel_latency; int max_kernel_latency;
} thread_stat_t; } egress_stat_t;
#endif #endif
...@@ -24,20 +24,22 @@ ...@@ -24,20 +24,22 @@
#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
typedef struct thread_stat { typedef struct thread_stat {
uint64_t min_interval; int min_interval;
uint64_t avg_interval; int avg_interval;
uint64_t max_interval; int max_interval;
int packets_received; int packets_received;
int lost_packets; int lost_packets;
char *data[MAX_BUFFER_SIZE];
} thread_stat_t; } thread_stat_t;
typedef struct thread_param { typedef struct thread_param {
...@@ -63,14 +65,15 @@ static int64_t jitter_hist[MAX_JITTER]; ...@@ -63,14 +65,15 @@ static int64_t jitter_hist[MAX_JITTER];
static main_param_t main_params; 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 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, RTT_TASK }; enum TSNTask { RECV_PACKET_TASK,
RTT_TASK };
static enum TSNTask tsn_task; static enum TSNTask tsn_task;
struct timespec measures_start; struct timespec measures_start;
...@@ -97,13 +100,16 @@ static void help(char *argv[]) { ...@@ -97,13 +100,16 @@ static void help(char *argv[]) {
static void *packet_receiving_thread(void *p) { static void *packet_receiving_thread(void *p) {
struct timespec current, previous; struct timespec current, previous;
struct sched_param priority; struct sched_param priority;
uint64_t diff = 0;
cpu_set_t mask; cpu_set_t mask;
int64_t dist_to_interval;
int prev_packet_id = 0; int prev_packet_id = 0;
stats->min_interval = UINT64_MAX; ingress_stats.min_interval = INT_MAX;
stats->max_interval = 0; ingress_stats.avg_interval = 0;
ingress_stats.max_interval = 0;
ingress_stats.min_kernel_latency = INT_MAX;
ingress_stats.avg_kernel_latency = 0;
ingress_stats.max_kernel_latency = 0;
if (enable_affinity) { if (enable_affinity) {
// Set thread CPU affinity // Set thread CPU affinity
...@@ -124,37 +130,36 @@ static void *packet_receiving_thread(void *p) { ...@@ -124,37 +130,36 @@ static void *packet_receiving_thread(void *p) {
if (tsn_task == RTT_TASK) { if (tsn_task == RTT_TASK) {
recv_udp_packet(0, 0, NULL); recv_udp_packet();
send_udp_packet("", 0); send_udp_packet("", 0);
} else if (tsn_task == RECV_PACKET_TASK) { } else if (tsn_task == RECV_PACKET_TASK) {
int current_packet_id; int current_packet_id;
thread_params.stats.packet_info = recv_udp_packet(enable_timestamps, enable_histograms, histograms);
clock_gettime(CLOCK_MONOTONIC, &current); clock_gettime(CLOCK_MONOTONIC, &current);
current_packet_id = atoi(thread_params.stats.packet_info.data); current_packet_id = recv_udp_packet();
// If this is not the first received packet // If this is not the first received packet
if (stats->packets_received) { if (stats->packets_received) {
int interval_us = calcdiff_ns(current, previous) / 1000;
diff = calcdiff_ns(current, previous); ingress_stats.min_interval = min(interval_us, ingress_stats.min_interval);
stats->min_interval = diff < stats->min_interval ? diff : stats->min_interval; ingress_stats.max_interval = max(interval_us, ingress_stats.max_interval);
stats->max_interval = diff > stats->max_interval ? diff : stats->max_interval; ingress_stats.avg_interval = (ingress_stats.avg_interval * (ingress_stats.packets_received - 1) + interval_us) / ingress_stats.packets_received;
// Check if packets were lost // Check if packets were lost
thread_params.stats.lost_packets += (current_packet_id - prev_packet_id - 1) % 1000; ingress_stats.lost_packets += (current_packet_id - prev_packet_id - 1) % 1000;
if (enable_histograms) { if (enable_histograms) {
dist_to_interval = (((int64_t)diff) - thread_params.interval) / 1000; int dist_to_interval = interval_us - (thread_params.interval / 1000);
dist_to_interval += MAX_HIST_VAL / 2; dist_to_interval += MAX_JITTER / 2;
if (dist_to_interval > ((int)MAX_HIST_VAL) || dist_to_interval < 0) if (dist_to_interval > ((int)MAX_JITTER) || dist_to_interval < 0)
fprintf(stderr, "jitter higher than MAX_HIST_VAL: %" PRIi64 "\n", dist_to_interval); fprintf(stderr, "jitter higher than MAX_JITTER: %d\n", dist_to_interval);
else else
histograms[2][dist_to_interval]++; jitter_hist[dist_to_interval]++;
} }
} }
...@@ -182,14 +187,18 @@ int main(int argc, char *argv[]) { ...@@ -182,14 +187,18 @@ int main(int argc, char *argv[]) {
enable_histograms = 0; enable_histograms = 0;
tsn_task = RECV_PACKET_TASK; tsn_task = RECV_PACKET_TASK;
network_config.tx_buffer_len = 1024; ingress_params.tx_buffer_len = 1024;
// 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;
if (enable_histograms) { if (enable_histograms) {
// Init histograms // Init histograms
memset((int64_t *)histograms, 0, NB_HISTOGRAMS * MAX_HIST_VAL); memset(kernel_latency_hist, 0, MAX_LATENCY_VAL);
memset(jitter_hist, 0, MAX_JITTER_VAL);
} }
// Catch breaks with sighand to print the histograms // Catch breaks with sighand to print the histograms
...@@ -204,7 +213,6 @@ int main(int argc, char *argv[]) { ...@@ -204,7 +213,6 @@ 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);
...@@ -220,28 +228,26 @@ int main(int argc, char *argv[]) { ...@@ -220,28 +228,26 @@ int main(int argc, char *argv[]) {
if (tsn_task == RECV_PACKET_TASK) { if (tsn_task == RECV_PACKET_TASK) {
uint64_t jitter = ((int64_t)stats->max_interval) - stats->min_interval; int jitter = ingress_stats->max_interval - ingress_stats->min_interval;
printf("%*d: J: %*" PRIi64, printf("%10d: J: %4d, I: %4d %4d %4d",
10, stats->packets_received, ingress_stats.packets_received,
10, jitter); jitter,
ingress_stats.min_interval,
ingress_stats.avg_interval,
ingress_stats.max_interval);
if (enable_timestamps) { if (enable_timestamps) {
int64_t user_space_time = stats->packet_info.userspace_exit_ts - stats->packet_info.userspace_enter_ts; printf(", K: %4d %4d %4d, D: %5s, L: %4d\n",
int64_t kernel_space_time = stats->packet_info.userspace_enter_ts - stats->packet_info.kernelspace_ts; kernel_space_time,
stats->packet_info.data,
printf(", U: %*" PRIi64 ", K: %*" PRIi64 ", D: %*s, L: %*d\n", stats->lost_packets);
10, user_space_time, } else {
10, kernel_space_time,
4, stats->packet_info.data,
4, stats->lost_packets);
}
else {
printf("\n"); printf("\n");
} }
printf("\033[%dA", 1); printf("\033[%dA", 1);
} }
} }
} }
...@@ -274,28 +280,26 @@ static void print_histograms() { ...@@ -274,28 +280,26 @@ static void print_histograms() {
"\"props\": [", "\"props\": [",
interval, duration_hour, duration_minutes); interval, duration_hour, duration_minutes);
max_hist_val = 0; max_latency = 0;
for (int i = 0; i < 2; i++) for (int j = 0; j < MAX_KERNEL_LATENCY; j++)
for (int j = 0; j < MAX_HIST_VAL; j++) if (kernel_latency_hist[j])
if (histograms[i][j]) max_latency = j;
max_hist_val = j > max_hist_val ? j : max_hist_val;
printf("[");
for (int i = 0; i < 2; i++) { for (int j = 0; j < max_latency; j++)
printf("["); printf("%" PRIi64 "%s", kernel_latency_hist[j], (j + 1 < max_latency ? ", " : ""));
for (int j = 0; j < max_hist_val; j++) printf("%s]");
printf("%" PRIi64 "%s", histograms[i][j], (j + 1 < max_hist_val ? ", " : ""));
printf("%s", (i + 1 < 2 ? "], " : "]"));
}
} }
max_hist_val = 0; max_jitter = 0;
for (int j = 0; j < MAX_HIST_VAL; j++) for (int j = 0; j < MAX_JITTER; j++)
if (histograms[2][j]) if (jitter_hist[j])
max_hist_val = j; max_jitter = j;
min_hist_val = MAX_HIST_VAL - 1;
for (int j = MAX_HIST_VAL - 1; j >= 0; j--) min_jitter = MAX_JITTER - 1;
if (histograms[2][j]) for (int j = MAX_JITTER - 1; j >= 0; j--)
min_hist_val = j; if (jitter_hist[j])
min_jitter = j;
if (!enable_timestamps) if (!enable_timestamps)
printf("{\"measure_sets\": [{"); printf("{\"measure_sets\": [{");
...@@ -311,13 +315,13 @@ static void print_histograms() { ...@@ -311,13 +315,13 @@ static void print_histograms() {
"\"i\": \"%dus\", \"duration\": \"%dh%d\"" "\"i\": \"%dus\", \"duration\": \"%dh%d\""
"}," "},"
"\"props\": [[", "\"props\": [[",
MAX_HIST_VAL / 2 - min_hist_val, MAX_JITTER / 2 - min_jitter,
interval, interval,
duration_hour, duration_hour,
duration_minutes); duration_minutes);
for (int j = min_hist_val; j < max_hist_val; j++) for (int j = min_jitter; j < max_jitter; j++)
printf("%" PRIi64 "%s", histograms[2][j], (j + 1 < max_hist_val ? ", " : "")); printf("%" PRIi64 "%s", jitter_hist[j], (j + 1 < max_jitter ? ", " : ""));
printf("]]}]}\n"); printf("]]}]}\n");
} }
...@@ -327,8 +331,8 @@ static void sighand(int sig_num) { ...@@ -327,8 +331,8 @@ static void sighand(int sig_num) {
print_histograms(); print_histograms();
if (thread_params.stats.lost_packets) if (stats.lost_packets)
fprintf(stderr, "%d packets were lost\n", thread_params.stats.lost_packets); fprintf(stderr, "%d packets were lost\n", stats.lost_packets);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
...@@ -350,18 +354,18 @@ static void process_options(int argc, char *argv[]) { ...@@ -350,18 +354,18 @@ static void process_options(int argc, char *argv[]) {
break; break;
case 'b': case 'b':
tsn_task = RTT_TASK; tsn_task = RTT_TASK;
strcpy(network_config.ip_address, optarg); strcpy(ingress_params.ip_address, optarg);
break; break;
case 'd': case 'd':
network_config.tx_buffer_len = atoi(optarg); ingress_params.tx_buffer_len = atoi(optarg);
if (network_config.tx_buffer_len < 1) { if (ingress_params.tx_buffer_len < 1) {
fprintf(stderr, "BUF_LEN should be greater than 1\n"); fprintf(stderr, "BUF_LEN should be greater than 1\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
break; break;
case 'f': case 'f':
network_if_specified = 1; network_if_specified = 1;
strcpy(network_config.network_if, optarg); strcpy(ingress_params.network_if, optarg);
break; break;
case 'h': case 'h':
help(argv); help(argv);
......
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