Commit 3bbec828 authored by Joanne Hugé's avatar Joanne Hugé

Merge branch 'packet-exchange'

parents 147e41be 4c33499c
......@@ -54,9 +54,9 @@ typedef struct network_config {
// Static functions
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(struct thread_param *param, char *data, uint64_t next_txtime);
static void print_histograms();
static void sigint_handler(int sig_num);
static void sighand(int sig_num);
// Static variables
......@@ -122,13 +122,12 @@ static void *packet_sending_thread(void *p) {
if (sched_setscheduler(0, SCHED_FIFO, &priority))
error(EXIT_FAILURE, errno, "Couldn't set priority");
if(enable_etf) {
if (enable_etf) {
// Measure from CLOCK_TAI to generate timestamp
clock_gettime(CLOCK_TAI, &next);
next_txtime = next.tv_sec * NSEC_PER_SEC + next.tv_nsec;
next_txtime += param->etf_offset;
}
else {
} else {
next_txtime = 0;
}
......@@ -145,7 +144,7 @@ static void *packet_sending_thread(void *p) {
add_ns(&next, param->interval);
if(enable_etf)
if (enable_etf)
next_txtime += param->interval;
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next, NULL);
......@@ -160,9 +159,6 @@ int main(int argc, char *argv[]) {
pthread_t thread;
thread_stat_t *stats;
// Catch breaks with sigint_handler
signal(SIGINT, sigint_handler);
param = malloc(sizeof(thread_param_t));
stats = &param->stats;
......@@ -191,6 +187,9 @@ int main(int argc, char *argv[]) {
memset((int64_t *)histograms, 0, NB_HISTOGRAMS * MAX_HIST_VAL);
}
// Catch breaks with sighand to print the histograms
init_signals(sighand, enable_histograms);
// Initialize the UDP packet sending socket
init_udp_send(enable_etf, enable_timestamps,
network_config.packet_priority,
......@@ -240,7 +239,7 @@ int main(int argc, char *argv[]) {
}
// Critical TSN task
static void do_tsn_task(struct thread_param *param, char * data, uint64_t next_txtime) {
static void do_tsn_task(struct thread_param *param, char *data, uint64_t next_txtime) {
struct timespec t1, t2;
int rtt_us;
......@@ -262,9 +261,9 @@ static void do_tsn_task(struct thread_param *param, char * data, uint64_t next_t
param->stats.rtt = calcdiff_ns(t2, t1);
if(enable_histograms) {
if (enable_histograms) {
rtt_us = param->stats.rtt / 1000;
if(rtt_us > MAX_HIST_VAL) {
if (rtt_us > MAX_HIST_VAL) {
fprintf(stderr, "RTT value higher than MAX_HIST_VAL : %d ( > %d)\n", rtt_us, MAX_HIST_VAL);
exit(EXIT_FAILURE);
}
......@@ -288,26 +287,28 @@ static void print_histograms() {
interval = param->interval / 1000;
if(tsn_task == SEND_PACKET_TASK) {
if (tsn_task == SEND_PACKET_TASK) {
printf("{\"measure_sets\": [{"
"\"measure_type\": \"packet_send_timestamps\","
"\"props_names\": [\"user_space\", \"kernel_space\"],"
"\"units\": [\"us\", \"us\"],"
"\"props_type\": \"histogram\","
"\"metadata\": {"
"\"i\": \"%dus\", \"duration\": \"%dh%d\""
"},"
"\"props\": [", interval, duration_hour, duration_minutes);
} else if(tsn_task == RTT_TASK) {
"\"measure_type\": \"packet_send_timestamps\","
"\"props_names\": [\"user_space\", \"kernel_space\"],"
"\"units\": [\"us\", \"us\"],"
"\"props_type\": \"histogram\","
"\"metadata\": {"
"\"i\": \"%dus\", \"duration\": \"%dh%d\", \"etf_offset\": \"%dus\","
"},"
"\"props\": [",
interval, duration_hour, duration_minutes, param->etf_offset);
} else if (tsn_task == RTT_TASK) {
printf("{\"measure_sets\": [{"
"\"measure_type\": \"packet_rtt\","
"\"props_names\": [\"rtt\"],"
"\"units\": [\"us\"],"
"\"props_type\": \"histogram\","
"\"metadata\": {"
"\"i\": \"%dus\", \"duration\": \"%dh%d\""
"},"
"\"props\": [", interval, duration_hour, duration_minutes);
"\"measure_type\": \"packet_rtt\","
"\"props_names\": [\"rtt\"],"
"\"units\": [\"us\"],"
"\"props_type\": \"histogram\","
"\"metadata\": {"
"\"i\": \"%dus\", \"duration\": \"%dh%d\", \"etf_offset\": \"%dus\","
"},"
"\"props\": [",
interval, duration_hour, duration_minutes, param->etf_offset);
}
nb_hists = tsn_task == SEND_PACKET_TASK ? 2 : 1;
......@@ -325,13 +326,12 @@ static void print_histograms() {
printf("%s", (i + 1 < nb_hists ? "], " : "]"));
}
printf( "]}]}\n");
printf("]}]}\n");
}
static void sigint_handler(int sig_num) {
static void sighand(int sig_num) {
(void)sig_num;
if (enable_histograms)
print_histograms();
print_histograms();
exit(EXIT_SUCCESS);
}
......
......@@ -107,11 +107,11 @@ packet_info_t recv_udp_packet(int use_timestamps, int use_histograms, int64_t hi
struct cmsghdr *cmsg;
struct msghdr msg; // Message hardware, sent to the socket
struct iovec iov; // The iovec structures stores the RX buffer
struct iovec iov; // The iovec structures stores the RX buffer
struct sockaddr_in sin;
struct {
struct cmsghdr cm;
char control[512];
struct cmsghdr cm;
char control[512];
} control;
int recvmsgerr;
......@@ -144,7 +144,7 @@ packet_info_t recv_udp_packet(int use_timestamps, int use_histograms, int64_t hi
packet_info.userspace_enter_ts = ts_to_uint(ts);
}
if(use_timestamps) {
if (use_timestamps) {
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMPING) {
......@@ -154,7 +154,7 @@ packet_info_t recv_udp_packet(int use_timestamps, int use_histograms, int64_t hi
clock_gettime(CLOCK_REALTIME, &ts);
packet_info.userspace_exit_ts = ts_to_uint(ts);
if(use_histograms)
if (use_histograms)
fill_histograms(&packet_info, histograms);
}
}
......
......@@ -42,7 +42,7 @@ static void init_tx_buffer(size_t _tx_buffer_len);
static int so_priority = 3;
static struct sock_txtime sk_txtime;
static unsigned char *tx_buffer;
static char *tx_buffer;
static size_t tx_buffer_len;
static int sock_fd;
......@@ -128,15 +128,15 @@ void init_udp_send(int use_etf, int use_timestamps, int packet_priority,
* Sends udp packets
*/
packet_info_t send_udp_packet(int use_etf, int use_timestamps,
char * data,
uint64_t txtime,
const char *server_ip,
int64_t histograms[NB_HISTOGRAMS][MAX_HIST_VAL]) {
char *data,
uint64_t txtime,
const char *server_ip,
int64_t histograms[NB_HISTOGRAMS][MAX_HIST_VAL]) {
struct msghdr msg; // Message hardware, sent to the socket
struct cmsghdr *cmsg; // Control message hardware, for txtime
struct msghdr msg; // Message hardware, sent to the socket
struct cmsghdr *cmsg; // Control message hardware, for txtime
char control[CMSG_SPACE(sizeof(txtime))] = {}; // Stores txtime
struct iovec iov; // The iovec structures stores the TX buffer
struct iovec iov; // The iovec structures stores the TX buffer
// Poll file descriptor, used to poll for timestamp messages
struct pollfd poll_fd = {sock_fd, POLLPRI, 0};
int sendmsgerr, pollerr;
......@@ -260,7 +260,6 @@ static void process_timestamps(packet_info_t *packet_info, int64_t histograms[NB
fprintf(stderr, "process_timestamps: level %d type %d", cmsg->cmsg_level,
cmsg->cmsg_type);
#endif
}
}
}
......
......@@ -4,6 +4,6 @@
#include "utilities.h"
void init_udp_send(int use_etf, int use_timestamps, int so_priority, char *network_if, size_t tx_buffer_len);
packet_info_t send_udp_packet(int use_etf, int use_timestamps, char * data, uint64_t txtime, const char *server_ip, int64_t histograms[NB_HISTOGRAMS][MAX_HIST_VAL]);
packet_info_t send_udp_packet(int use_etf, int use_timestamps, char *data, uint64_t txtime, const char *server_ip, int64_t histograms[NB_HISTOGRAMS][MAX_HIST_VAL]);
#endif
......@@ -60,7 +60,7 @@ typedef struct main_param {
static void process_options(int argc, char *argv[]);
static void print_histograms();
static void sigint_handler(int sig_num);
static void sighand(int sig_num);
// Static variables
......@@ -136,7 +136,7 @@ static void *packet_receiving_thread(void *p) {
} else if (tsn_task == RECV_PACKET_TASK) {
int current_packet_id;
int current_packet_id;
param->stats.packet_info = recv_udp_packet(enable_timestamps, enable_histograms, histograms);
......@@ -154,14 +154,13 @@ static void *packet_receiving_thread(void *p) {
// Check if packets were lost
param->stats.lost_packets += (current_packet_id - prev_packet_id - 1) % 1000;
if(enable_histograms) {
if (enable_histograms) {
dist_to_interval = (((int64_t)diff) - param->interval) / 1000;
dist_to_interval += MAX_HIST_VAL / 2;
if( dist_to_interval > ((int)MAX_HIST_VAL) || dist_to_interval < 0 ) {
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);
exit(EXIT_FAILURE);
}
else {
} else {
histograms[2][dist_to_interval]++;
}
}
......@@ -182,9 +181,6 @@ int main(int argc, char *argv[]) {
thread_stat_t *stats;
int64_t diff;
// Catch breaks with sigint_handler
signal(SIGINT, sigint_handler);
param = malloc(sizeof(thread_param_t));
stats = &param->stats;
......@@ -210,6 +206,9 @@ int main(int argc, char *argv[]) {
memset((int64_t *)histograms, 0, NB_HISTOGRAMS * MAX_HIST_VAL);
}
// Catch breaks with sighand to print the histograms
init_signals(sighand, enable_histograms);
// Initialize the UDP packet receiving socket
init_udp_recv(enable_timestamps, network_config.network_if);
......@@ -225,17 +224,17 @@ int main(int argc, char *argv[]) {
for (;;) {
usleep(main_param.refresh_rate);
if(main_param.verbose) {
if (main_param.verbose) {
if(tsn_task == RECV_PACKET_TASK) {
if (tsn_task == RECV_PACKET_TASK) {
diff = ((int64_t)stats->max_interval) - stats->min_interval;
printf( "(%d) Jitter : %" PRIi64 " [Packet data: %s] [Lost packets: %d]\n",
stats->packets_received,
diff,
stats->packet_info.data,
stats->lost_packets);
printf("(%d) Jitter : %" PRIi64 " [Packet data: %s] [Lost packets: %d]\n",
stats->packets_received,
diff,
stats->packet_info.data,
stats->lost_packets);
if(enable_timestamps) {
if (enable_timestamps) {
printf("(%d) Enter send_udp_packet timestamp: %" PRIu64 "\n",
stats->packets_received,
stats->packet_info.userspace_enter_ts);
......@@ -266,16 +265,17 @@ static void print_histograms() {
interval = param->interval / 1000;
if(enable_timestamps) {
if (enable_timestamps) {
printf("{\"measure_sets\": [{"
"\"measure_type\": \"packet_recv_timestamps\","
"\"props_names\": [\"user_space\", \"kernel_space\"],"
"\"units\": [\"us\", \"us\"],"
"\"props_type\": \"histogram\","
"\"metadata\": {"
"\"i\": \"%dus\", \"duration\": \"%dh%d\""
"},"
"\"props\": [", interval, duration_hour, duration_minutes);
"\"measure_type\": \"packet_recv_timestamps\","
"\"props_names\": [\"user_space\", \"kernel_space\"],"
"\"units\": [\"us\", \"us\"],"
"\"props_type\": \"histogram\","
"\"metadata\": {"
"\"i\": \"%dus\", \"duration\": \"%dh%d\""
"},"
"\"props\": [",
interval, duration_hour, duration_minutes);
max_hist_val = 0;
for (int i = 0; i < 2; i++)
......@@ -293,42 +293,46 @@ static void print_histograms() {
max_hist_val = 0;
for (int j = 0; j < MAX_HIST_VAL; j++)
if(histograms[2][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])
if (histograms[2][j])
min_hist_val = j;
if(!enable_timestamps)
if (!enable_timestamps)
printf("{\"measure_sets\": [{");
else
printf( "]}, {");
printf( "\"measure_type\": \"packet_jitter\","
"\"props_names\": [\"jitter\"],"
"\"units\": [\"us\"],"
"\"props_type\": \"histogram\","
"\"middle\": \"%d\","
"\"metadata\": {"
"\"i\": \"%dus\", \"duration\": \"%dh%d\""
"},"
"\"props\": [[", MAX_HIST_VAL / 2 - min_hist_val,
interval,
duration_hour,
duration_minutes);
printf("]}, {");
printf("\"measure_type\": \"packet_jitter\","
"\"props_names\": [\"jitter\"],"
"\"units\": [\"us\"],"
"\"props_type\": \"histogram\","
"\"middle\": \"%d\","
"\"metadata\": {"
"\"i\": \"%dus\", \"duration\": \"%dh%d\""
"},"
"\"props\": [[",
MAX_HIST_VAL / 2 - min_hist_val,
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 ? ", " : ""));
printf( "]]}]}\n");
printf("]]}]}\n");
}
static void sigint_handler(int sig_num) {
static void sighand(int sig_num) {
(void)sig_num;
if (enable_histograms)
print_histograms();
print_histograms();
if (param->stats.lost_packets)
fprintf(stderr, "%d packets were lost\n", param->stats.lost_packets);
exit(EXIT_SUCCESS);
}
......
#define _GNU_SOURCE
#include <inttypes.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "utilities.h"
void (*previous_handlers[NSIG])(int);
static void (*sighand)(int);
uint64_t ts_to_uint(struct timespec t) {
return t.tv_sec * NSEC_PER_SEC + t.tv_nsec;
}
......@@ -28,3 +34,32 @@ uint64_t calcdiff_ns(struct timespec t1, struct timespec t2) {
uint64_t max(uint64_t a, uint64_t b) { return a > b ? a : b; }
uint64_t min(uint64_t a, uint64_t b) { return a < b ? a : b; }
static void sighand_wrapper(int sig) {
// If we get un unexpected signal, report it, if not print the histogram
if (sig == SIGINT || sig == SIGTERM)
(*sighand)(sig); // Will print the histogram
else
printf("Uknown signal interrupt: %s (%d)\n", strsignal(sig), sig);
// Execute the default handler
if (previous_handlers[sig] == SIG_DFL) {
signal(sig, SIG_DFL);
raise(sig);
} else if (previous_handlers[sig] == SIG_IGN) {
return;
} else {
(*previous_handlers[sig])(sig);
}
}
void init_signals(void (*_sighand)(int), int enable_histograms) {
sighand = _sighand;
if (enable_histograms)
for (int i = 0; i < NSIG; i++)
signal(i, sighand_wrapper);
}
......@@ -3,6 +3,7 @@
#define _GNU_SOURCE
#include <inttypes.h>
#include <signal.h>
#include <stdint.h>
#include <time.h>
#include <unistd.h>
......@@ -27,4 +28,8 @@ 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);
extern void (*previous_handlers[NSIG])(int);
#endif
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