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