Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
T
tsn-measures
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
tsn-measures
Commits
31441586
Commit
31441586
authored
Jun 02, 2020
by
Joanne Hugé
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add option to print histograms to stdout on exit
parent
f696b55f
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
218 additions
and
118 deletions
+218
-118
packet-exchange/src/client.c
packet-exchange/src/client.c
+186
-112
packet-exchange/src/send_packet.c
packet-exchange/src/send_packet.c
+26
-4
packet-exchange/src/send_packet.h
packet-exchange/src/send_packet.h
+3
-1
packet-exchange/src/server.c
packet-exchange/src/server.c
+1
-1
packet-exchange/src/utilities.h
packet-exchange/src/utilities.h
+2
-0
No files found.
packet-exchange/src/client.c
View file @
31441586
/*
/*
* Real time packet sending thread
* Real time packet sending thread
*
*
* Bash options:
*
* -a Run the real time thread on CPU1
* -b Measure RTT
* -d BUF_LEN Set the length of tx buffer
* -e Set a txtime (to be used in an ETF qdisc)
* -f IF Set the network interface to be used
* -i USEC Wake up the real time thread every USEC microseconds (Default: 10ms)
* -l N Wake up the real time thread N times (Default: 0)
* -p PRIO Run the real time thread at priority PRIO
* -r USEC Refresh the non real time main thread every USEC microseconds (Default: 50ms)
* -t Enable timestamps
*
* Large portions taken from cyclictest
* Large portions taken from cyclictest
*
*
*/
*/
...
@@ -23,6 +10,7 @@
...
@@ -23,6 +10,7 @@
#include <error.h>
#include <error.h>
#include <pthread.h>
#include <pthread.h>
#include <sched.h>
#include <sched.h>
#include <signal.h>
#include <stdint.h>
#include <stdint.h>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
...
@@ -30,11 +18,14 @@
...
@@ -30,11 +18,14 @@
#include <time.h>
#include <time.h>
#include <unistd.h>
#include <unistd.h>
#include "send_packet.h"
#include "recv_packet.h"
#include "recv_packet.h"
#include "send_packet.h"
#include "utilities.h"
#include "utilities.h"
enum
TSNTask
{
SEND_PACKET_TASK
,
RTT_TASK
};
// Enum and structs
enum
TSNTask
{
SEND_PACKET_TASK
,
RTT_TASK
};
typedef
struct
thread_stat
{
typedef
struct
thread_stat
{
int
nb_cycles
;
int
nb_cycles
;
...
@@ -50,7 +41,8 @@ typedef struct thread_param {
...
@@ -50,7 +41,8 @@ typedef struct thread_param {
int
enable_affinity
;
int
enable_affinity
;
int
enable_etf
;
int
enable_etf
;
int
enable_timestamps
;
int
enable_timestamps
;
enum
TSNTask
tsn_task
;
int
enable_histograms
;
enum
TSNTask
tsn_task
;
int
sockfd
;
int
sockfd
;
const
char
*
ip_address
;
const
char
*
ip_address
;
...
@@ -62,12 +54,41 @@ typedef struct thread_param {
...
@@ -62,12 +54,41 @@ typedef struct thread_param {
typedef
struct
main_param
{
typedef
struct
main_param
{
int
refresh_rate
;
int
refresh_rate
;
int
packet_priority
;
int
packet_priority
;
int
verbose
;
size_t
tx_buffer_len
;
size_t
tx_buffer_len
;
}
main_param_t
;
}
main_param_t
;
// Static functions
static
void
process_options
(
int
argc
,
char
*
argv
[],
thread_param_t
*
param
,
static
void
process_options
(
int
argc
,
char
*
argv
[],
thread_param_t
*
param
,
main_param_t
*
main_param
);
main_param_t
*
main_param
);
static
void
do_tsn_task
(
struct
thread_param
*
param
,
uint64_t
next_txtime
);
static
void
do_tsn_task
(
struct
thread_param
*
param
,
uint64_t
next_txtime
);
static
void
print_histograms
();
static
void
sigint_handler
(
int
sig_num
);
// Static variables
static
int64_t
histograms
[
NB_HISTOGRAMS
][
MAX_HIST_VAL
];
static
main_param_t
main_param
;
static
thread_param_t
*
param
;
static
void
help
(
char
*
argv
[])
{
printf
(
"Usage: %s [-abethgv] [-d BUF_LEN] [-f IF] [-i USEC] [-l N] [-p PRIO] [-r USEC]
\n\n
"
,
argv
[
0
]);
printf
(
" -a Run the real time thread on CPU1
\n
"
);
printf
(
" -b Measure RTT
\n
"
);
printf
(
" -d BUF_LEN Set the length of tx buffer
\n
"
);
printf
(
" -e Set a txtime (to be used in an ETF qdisc)
\n
"
);
printf
(
" -f IF Set the network interface to be used
\n
"
);
printf
(
" -g Print histograms to sdtout on exit
\n
"
);
printf
(
" -h Show help
\n
"
);
printf
(
" -i USEC Wake up the real time thread every USEC microseconds (Default: 10ms)
\n
"
);
printf
(
" -l N Wake up the real time thread N times (Default: 0)
\n
"
);
printf
(
" -p PRIO Run the real time thread at priority PRIO
\n
"
);
printf
(
" -r USEC Refresh the non real time main thread every USEC microseconds (Default: 50ms)
\n
"
);
printf
(
" -t Enable timestamps
\n
"
);
printf
(
" -v Verbose
\n
"
);
printf
(
"
\n
"
);
}
// Real-time thread
// Real-time thread
// Sends packets at a regular intervall
// Sends packets at a regular intervall
...
@@ -101,7 +122,8 @@ static void *packet_sending_thread(void *p) {
...
@@ -101,7 +122,8 @@ static void *packet_sending_thread(void *p) {
// Packet sending loop
// Packet sending loop
for
(
param
->
stats
.
nb_cycles
=
0
;;
param
->
stats
.
nb_cycles
++
)
{
for
(
param
->
stats
.
nb_cycles
=
0
;;
param
->
stats
.
nb_cycles
++
)
{
if
(
param
->
max_cycles
)
if
(
param
->
max_cycles
)
if
(
param
->
stats
.
nb_cycles
>=
param
->
max_cycles
)
break
;
if
(
param
->
stats
.
nb_cycles
>=
param
->
max_cycles
)
break
;
do_tsn_task
(
param
,
next_txtime
);
do_tsn_task
(
param
,
next_txtime
);
...
@@ -118,140 +140,192 @@ static void *packet_sending_thread(void *p) {
...
@@ -118,140 +140,192 @@ static void *packet_sending_thread(void *p) {
// Handles the IO and creates real time threads
// Handles the IO and creates real time threads
int
main
(
int
argc
,
char
*
argv
[])
{
int
main
(
int
argc
,
char
*
argv
[])
{
pthread_t
thread
;
pthread_t
thread
;
thread_param_t
param
;
main_param_t
main_param
;
signal
(
SIGINT
,
sigint_handler
);
param
=
malloc
(
sizeof
(
thread_param_t
));
// Default values
// Default values
param
.
interval
=
100000
*
1000
;
param
->
interval
=
100000
*
1000
;
param
.
max_cycles
=
0
;
param
->
max_cycles
=
0
;
param
.
priority
=
99
;
param
->
priority
=
99
;
param
.
enable_affinity
=
0
;
param
->
enable_affinity
=
0
;
param
.
enable_etf
=
0
;
param
->
enable_etf
=
0
;
param
.
enable_timestamps
=
0
;
param
->
enable_timestamps
=
0
;
param
.
tsn_task
=
SEND_PACKET_TASK
;
param
->
enable_histograms
=
0
;
param
->
tsn_task
=
SEND_PACKET_TASK
;
main_param
.
refresh_rate
=
50000
;
main_param
.
refresh_rate
=
50000
;
main_param
.
packet_priority
=
3
;
main_param
.
packet_priority
=
3
;
main_param
.
tx_buffer_len
=
1024
;
main_param
.
tx_buffer_len
=
1024
;
main_param
.
verbose
=
0
;
// Process bash options
// Process bash options
process_options
(
argc
,
argv
,
&
param
,
&
main_param
);
process_options
(
argc
,
argv
,
param
,
&
main_param
);
if
(
param
->
enable_histograms
)
{
// Init histograms
memset
((
int64_t
*
)
histograms
,
0
,
NB_HISTOGRAMS
*
MAX_HIST_VAL
);
}
init_udp_send
(
param
.
enable_etf
,
param
.
enable_timestamps
,
main_param
.
packet_priority
,
param
.
network_if
,
main_param
.
tx_buffer_len
);
init_udp_send
(
param
->
enable_etf
,
param
->
enable_timestamps
,
main_param
.
packet_priority
,
param
->
network_if
,
main_param
.
tx_buffer_len
);
if
(
param
.
tsn_task
==
RTT_TASK
)
if
(
param
->
tsn_task
==
RTT_TASK
)
param
.
sockfd
=
init_udp_recv
();
param
->
sockfd
=
init_udp_recv
();
usleep
(
10000
);
usleep
(
10000
);
if
(
pthread_create
(
&
thread
,
NULL
,
packet_sending_thread
,
(
void
*
)
&
param
))
if
(
pthread_create
(
&
thread
,
NULL
,
packet_sending_thread
,
(
void
*
)
param
))
error
(
EXIT_FAILURE
,
errno
,
"Couldn't create thread"
);
error
(
EXIT_FAILURE
,
errno
,
"Couldn't create thread"
);
for
(;;)
{
for
(;;)
{
usleep
(
main_param
.
refresh_rate
);
usleep
(
main_param
.
refresh_rate
);
if
(
param
.
tsn_task
==
RTT_TASK
)
{
if
(
main_param
.
verbose
)
{
printf
(
"RTT: %"
PRIu64
" (%d)
\n
"
,
param
.
stats
.
rtt
,
param
.
stats
.
nb_cycles
);
if
(
param
->
tsn_task
==
RTT_TASK
)
{
}
printf
(
"RTT: %"
PRIu64
" (%d)
\n
"
,
param
->
stats
.
rtt
,
else
if
(
param
.
enable_timestamps
)
{
param
->
stats
.
nb_cycles
);
printf
(
"(%d)
\n
"
,
param
.
stats
.
nb_cycles
);
}
else
if
(
param
->
enable_timestamps
)
{
printf
(
" Enter send_udp_packet timestamp: %"
PRIu64
"
\n
"
,
param
.
stats
.
packet_ts
.
user_enter_send
);
printf
(
"(%d)
\n
"
,
param
->
stats
.
nb_cycles
);
printf
(
" Call sendmsg timestamp : %"
PRIu64
"
\n
"
,
param
.
stats
.
packet_ts
.
user_call_sendmsg
);
printf
(
" Enter send_udp_packet timestamp: %"
PRIu64
"
\n
"
,
printf
(
" Leave kernel timestamp : %"
PRIu64
"
\n
"
,
param
.
stats
.
packet_ts
.
kernel_leave
);
param
->
stats
.
packet_ts
.
user_enter_send
);
printf
(
" Call sendmsg timestamp : %"
PRIu64
"
\n
"
,
param
->
stats
.
packet_ts
.
user_call_sendmsg
);
printf
(
" Leave kernel timestamp : %"
PRIu64
"
\n
"
,
param
->
stats
.
packet_ts
.
kernel_leave
);
}
}
}
if
(
param
.
max_cycles
)
if
(
param
->
max_cycles
)
if
(
param
.
max_cycles
==
param
.
stats
.
nb_cycles
)
break
;
if
(
param
->
max_cycles
==
param
->
stats
.
nb_cycles
)
break
;
}
}
if
(
param
->
enable_histograms
)
print_histograms
();
exit
(
EXIT_SUCCESS
);
exit
(
EXIT_SUCCESS
);
}
}
static
void
do_tsn_task
(
struct
thread_param
*
param
,
uint64_t
next_txtime
)
{
static
void
do_tsn_task
(
struct
thread_param
*
param
,
uint64_t
next_txtime
)
{
struct
timespec
t1
,
t2
;
struct
timespec
t1
,
t2
;
if
(
param
->
tsn_task
==
SEND_PACKET_TASK
)
{
param
->
stats
.
packet_ts
=
send_udp_packet
(
param
->
enable_etf
,
param
->
enable_timestamps
,
next_txtime
,
param
->
ip_address
,
histograms
);
}
else
if
(
param
->
tsn_task
==
RTT_TASK
)
{
clock_gettime
(
CLOCK_MONOTONIC
,
&
t1
);
send_udp_packet
(
param
->
enable_etf
,
param
->
enable_timestamps
,
next_txtime
,
param
->
ip_address
,
histograms
);
recv_udp_packet
(
param
->
sockfd
);
clock_gettime
(
CLOCK_MONOTONIC
,
&
t2
);
param
->
stats
.
rtt
=
calcdiff_ns
(
t2
,
t1
);
}
}
if
(
param
->
tsn_task
==
SEND_PACKET_TASK
)
{
static
void
print_histograms
()
{
param
->
stats
.
packet_ts
=
send_udp_packet
(
param
->
enable_etf
,
param
->
enable_timestamps
,
next_txtime
,
param
->
ip_address
);
printf
(
"{
\"
measure_type
\"
:
\"
packet_timestamps
\"
,\
\"
props_names
\"
: [
\"
user_space
\"
,
\"
kernel_space
\"
],\
\"
units
\"
: [
\"
us
\"
,
\"
us
\"
],\
\"
props
\"
: ["
);
for
(
int
i
=
0
;
i
<
NB_HISTOGRAMS
;
i
++
)
{
int
max_hist_val
=
MAX_HIST_VAL
;
for
(
int
j
=
0
;
j
<
MAX_HIST_VAL
;
j
++
)
max_hist_val
=
histograms
[
i
][
j
]
?
j
:
max_hist_val
;
printf
(
"["
);
for
(
int
j
=
0
;
j
<
max_hist_val
;
j
++
)
{
if
(
j
+
1
<
max_hist_val
)
printf
(
"%"
PRIi64
", "
,
histograms
[
i
][
j
]);
else
printf
(
"%"
PRIi64
,
histograms
[
i
][
j
]);
}
}
else
if
(
param
->
tsn_task
==
RTT_TASK
)
{
if
(
i
+
1
<
NB_HISTOGRAMS
)
printf
(
"], "
);
else
printf
(
"]"
);
}
clock_gettime
(
CLOCK_MONOTONIC
,
&
t1
)
;
int
interval
=
param
->
interval
/
1000
;
send_udp_packet
(
param
->
enable_etf
,
param
->
enable_timestamps
,
next_txtime
,
param
->
ip_address
)
;
uint64_t
duration
=
interval
*
param
->
stats
.
nb_cycles
;
recv_udp_packet
(
param
->
sockfd
);
int
duration_hour
=
duration
/
(
1000000l
*
3600
);
clock_gettime
(
CLOCK_MONOTONIC
,
&
t2
);
int
duration_minutes
=
duration
/
(
1000000l
*
60
)
-
(
duration_hour
*
60
);
param
->
stats
.
rtt
=
calcdiff_ns
(
t2
,
t1
);
printf
(
"], "
);
}
printf
(
"
\"
props_type
\"
:
\"
histogram
\"
,
\"
metadata
\"
: {
\"
i
\"
:
\"
%dus
\"
,
\"
duration
\"
:
\"
%dh%d
\"
}}
\n
"
,
interval
,
duration_hour
,
duration_minutes
);
}
}
static
void
help
(
char
*
argv
[])
{
static
void
sigint_handler
(
int
sig_num
)
{
printf
(
"Usage: %s [-abet] [-d BUF_LEN] [-f IF] [-i USEC] [-l N] [-p PRIO] [-r USEC]
\n\n
"
,
argv
[
0
]);
(
void
)
sig_num
;
printf
(
" -a Run the real time thread on CPU1
\n
"
);
if
(
param
->
enable_histograms
)
printf
(
" -b Measure RTT
\n
"
);
print_histograms
();
printf
(
" -d BUF_LEN Set the length of tx buffer
\n
"
);
exit
(
EXIT_SUCCESS
);
printf
(
" -e Set a txtime (to be used in an ETF qdisc)
\n
"
);
printf
(
" -f IF Set the network interface to be used
\n
"
);
printf
(
" -i USEC Wake up the real time thread every USEC microseconds (Default: 10ms)
\n
"
);
printf
(
" -l N Wake up the real time thread N times (Default: 0)
\n
"
);
printf
(
" -p PRIO Run the real time thread at priority PRIO
\n
"
);
printf
(
" -r USEC Refresh the non real time main thread every USEC microseconds (Default: 50ms)
\n
"
);
printf
(
" -t Enable timestamps
\n
"
);
printf
(
"
\n
"
);
}
}
static
void
process_options
(
int
argc
,
char
*
argv
[],
thread_param_t
*
param
,
static
void
process_options
(
int
argc
,
char
*
argv
[],
thread_param_t
*
param
,
main_param_t
*
main_param
)
{
main_param_t
*
main_param
)
{
for
(;;)
{
for
(;;)
{
int
c
=
getopt
(
argc
,
argv
,
"abd:ef:
hi:l:p:q:r:t
"
);
int
c
=
getopt
(
argc
,
argv
,
"abd:ef:
ghi:l:p:q:r:tv
"
);
if
(
c
==
-
1
)
break
;
if
(
c
==
-
1
)
break
;
switch
(
c
)
{
switch
(
c
)
{
case
'a'
:
case
'a'
:
param
->
enable_affinity
=
1
;
param
->
enable_affinity
=
1
;
break
;
break
;
case
'b'
:
case
'b'
:
param
->
tsn_task
=
RTT_TASK
;
param
->
tsn_task
=
RTT_TASK
;
break
;
break
;
case
'd'
:
case
'd'
:
main_param
->
tx_buffer_len
=
atoi
(
optarg
);
main_param
->
tx_buffer_len
=
atoi
(
optarg
);
if
(
main_param
->
tx_buffer_len
<
1
)
{
if
(
main_param
->
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
);
}
break
;
case
'e'
:
param
->
enable_etf
=
1
;
break
;
case
'f'
:
strcpy
(
param
->
network_if
,
optarg
);
break
;
case
'h'
:
help
(
argv
);
exit
(
EXIT_SUCCESS
);
break
;
case
'i'
:
param
->
interval
=
atoi
(
optarg
)
*
1000
;
break
;
case
'l'
:
param
->
max_cycles
=
atoi
(
optarg
);
break
;
case
'p'
:
param
->
priority
=
atoi
(
optarg
);
break
;
case
'q'
:
main_param
->
packet_priority
=
atoi
(
optarg
);
break
;
case
'r'
:
main_param
->
refresh_rate
=
atoi
(
optarg
);
break
;
case
't'
:
param
->
enable_timestamps
=
1
;
break
;
default:
help
(
argv
);
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
break
;
}
break
;
case
'e'
:
param
->
enable_etf
=
1
;
break
;
case
'f'
:
strcpy
(
param
->
network_if
,
optarg
);
break
;
case
'g'
:
param
->
enable_histograms
=
1
;
break
;
case
'h'
:
help
(
argv
);
exit
(
EXIT_SUCCESS
);
break
;
case
'i'
:
param
->
interval
=
atoi
(
optarg
)
*
1000
;
break
;
case
'l'
:
param
->
max_cycles
=
atoi
(
optarg
);
break
;
case
'p'
:
param
->
priority
=
atoi
(
optarg
);
break
;
case
'q'
:
main_param
->
packet_priority
=
atoi
(
optarg
);
break
;
case
'r'
:
main_param
->
refresh_rate
=
atoi
(
optarg
);
break
;
case
't'
:
param
->
enable_timestamps
=
1
;
break
;
case
'v'
:
main_param
->
verbose
=
1
;
break
;
default:
help
(
argv
);
exit
(
EXIT_FAILURE
);
break
;
}
}
}
}
...
...
packet-exchange/src/send_packet.c
View file @
31441586
...
@@ -41,7 +41,7 @@
...
@@ -41,7 +41,7 @@
#define MESSAGE ((uint32_t)0x00FACADE)
#define MESSAGE ((uint32_t)0x00FACADE)
static
void
process_timestamps
(
struct
packet_timestamps
*
packet_ts
);
static
void
process_timestamps
(
struct
packet_timestamps
*
packet_ts
,
int64_t
histograms
[
NB_HISTOGRAMS
][
MAX_HIST_VAL
]
);
static
void
init_tx_buffer
(
size_t
_tx_buffer_len
);
static
void
init_tx_buffer
(
size_t
_tx_buffer_len
);
static
int
so_priority
=
3
;
static
int
so_priority
=
3
;
...
@@ -148,7 +148,8 @@ uint64_t get_txtime() {
...
@@ -148,7 +148,8 @@ uint64_t get_txtime() {
*/
*/
struct
packet_timestamps
send_udp_packet
(
int
use_etf
,
int
use_timestamps
,
struct
packet_timestamps
send_udp_packet
(
int
use_etf
,
int
use_timestamps
,
uint64_t
txtime
,
uint64_t
txtime
,
const
char
*
server_ip
)
{
const
char
*
server_ip
,
int64_t
histograms
[
NB_HISTOGRAMS
][
MAX_HIST_VAL
])
{
char
control
[
CMSG_SPACE
(
sizeof
(
txtime
))]
=
{};
char
control
[
CMSG_SPACE
(
sizeof
(
txtime
))]
=
{};
struct
sockaddr_in
sin
;
struct
sockaddr_in
sin
;
struct
cmsghdr
*
cmsg
;
struct
cmsghdr
*
cmsg
;
...
@@ -205,7 +206,7 @@ struct packet_timestamps send_udp_packet(int use_etf, int use_timestamps,
...
@@ -205,7 +206,7 @@ struct packet_timestamps send_udp_packet(int use_etf, int use_timestamps,
if
(
use_timestamps
)
{
if
(
use_timestamps
)
{
res
=
poll
(
&
poll_fd
,
1
,
0
);
res
=
poll
(
&
poll_fd
,
1
,
0
);
if
(
res
>
0
)
if
(
res
>
0
)
process_timestamps
(
&
packet_ts
);
process_timestamps
(
&
packet_ts
,
histograms
);
else
else
fprintf
(
stderr
,
"select failed
\n
"
);
fprintf
(
stderr
,
"select failed
\n
"
);
}
}
...
@@ -213,7 +214,27 @@ struct packet_timestamps send_udp_packet(int use_etf, int use_timestamps,
...
@@ -213,7 +214,27 @@ struct packet_timestamps send_udp_packet(int use_etf, int use_timestamps,
return
packet_ts
;
return
packet_ts
;
}
}
static
void
process_timestamps
(
struct
packet_timestamps
*
packet_ts
)
{
static
void
fill_histograms
(
struct
packet_timestamps
*
packet_ts
,
int64_t
histograms
[
NB_HISTOGRAMS
][
MAX_HIST_VAL
])
{
uint64_t
user_space_time
=
packet_ts
->
user_call_sendmsg
-
packet_ts
->
user_enter_send
;
uint64_t
kernel_space_time
=
packet_ts
->
kernel_leave
-
packet_ts
->
user_call_sendmsg
;
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
);
exit
(
EXIT_FAILURE
);
}
if
(
kernel_space_time
>
MAX_HIST_VAL
)
{
fprintf
(
stderr
,
"kernel_space_time value too high: %"
PRIu64
"us
\n
"
,
kernel_space_time
);
exit
(
EXIT_FAILURE
);
}
histograms
[
0
][
user_space_time
]
++
;
histograms
[
1
][
kernel_space_time
]
++
;
}
static
void
process_timestamps
(
struct
packet_timestamps
*
packet_ts
,
int64_t
histograms
[
NB_HISTOGRAMS
][
MAX_HIST_VAL
])
{
char
data
[
256
];
char
data
[
256
];
struct
msghdr
msg
;
struct
msghdr
msg
;
struct
iovec
entry
;
struct
iovec
entry
;
...
@@ -243,6 +264,7 @@ static void process_timestamps(struct packet_timestamps *packet_ts) {
...
@@ -243,6 +264,7 @@ static void process_timestamps(struct packet_timestamps *packet_ts) {
if
(
cmsg
->
cmsg_level
==
SOL_SOCKET
&&
cmsg
->
cmsg_type
==
SO_TIMESTAMPING
)
{
if
(
cmsg
->
cmsg_level
==
SOL_SOCKET
&&
cmsg
->
cmsg_type
==
SO_TIMESTAMPING
)
{
struct
timespec
*
stamp
=
(
struct
timespec
*
)
CMSG_DATA
(
cmsg
);
struct
timespec
*
stamp
=
(
struct
timespec
*
)
CMSG_DATA
(
cmsg
);
packet_ts
->
kernel_leave
=
ts_to_uint
(
*
stamp
);
packet_ts
->
kernel_leave
=
ts_to_uint
(
*
stamp
);
fill_histograms
(
packet_ts
,
histograms
);
}
else
{
}
else
{
#ifdef DEBUG
#ifdef DEBUG
fprintf
(
stderr
,
"process_timestamps: level %d type %d"
,
cmsg
->
cmsg_level
,
fprintf
(
stderr
,
"process_timestamps: level %d type %d"
,
cmsg
->
cmsg_level
,
...
...
packet-exchange/src/send_packet.h
View file @
31441586
...
@@ -4,6 +4,8 @@
...
@@ -4,6 +4,8 @@
#include <stdint.h>
#include <stdint.h>
#include <stdio.h>
#include <stdio.h>
#include "utilities.h"
struct
packet_timestamps
{
struct
packet_timestamps
{
uint64_t
user_enter_send
;
uint64_t
user_enter_send
;
uint64_t
user_call_sendmsg
;
uint64_t
user_call_sendmsg
;
...
@@ -11,6 +13,6 @@ struct packet_timestamps {
...
@@ -11,6 +13,6 @@ struct packet_timestamps {
};
};
void
init_udp_send
(
int
use_etf
,
int
use_timestamps
,
int
so_priority
,
char
*
network_if
,
size_t
tx_buffer_len
);
void
init_udp_send
(
int
use_etf
,
int
use_timestamps
,
int
so_priority
,
char
*
network_if
,
size_t
tx_buffer_len
);
struct
packet_timestamps
send_udp_packet
(
int
use_etf
,
int
use_timestamps
,
uint64_t
txtime
,
const
char
*
server_ip
);
struct
packet_timestamps
send_udp_packet
(
int
use_etf
,
int
use_timestamps
,
uint64_t
txtime
,
const
char
*
server_ip
,
int64_t
histograms
[
NB_HISTOGRAMS
][
MAX_HIST_VAL
]
);
#endif
#endif
packet-exchange/src/server.c
View file @
31441586
...
@@ -98,7 +98,7 @@ static void *packet_receiving_thread(void *p) {
...
@@ -98,7 +98,7 @@ static void *packet_receiving_thread(void *p) {
for
(
stats
->
packets_received
=
0
;;
stats
->
packets_received
++
)
{
for
(
stats
->
packets_received
=
0
;;
stats
->
packets_received
++
)
{
if
(
param
->
tsn_task
==
RTT_TASK
)
{
if
(
param
->
tsn_task
==
RTT_TASK
)
{
recv_udp_packet
(
param
->
sockfd
);
recv_udp_packet
(
param
->
sockfd
);
send_udp_packet
(
0
,
0
,
0
,
param
->
ip_address
);
send_udp_packet
(
0
,
0
,
0
,
param
->
ip_address
,
NULL
);
}
else
if
(
param
->
tsn_task
==
RECV_PACKET_TASK
)
{
}
else
if
(
param
->
tsn_task
==
RECV_PACKET_TASK
)
{
recv_udp_packet
(
param
->
sockfd
);
recv_udp_packet
(
param
->
sockfd
);
...
...
packet-exchange/src/utilities.h
View file @
31441586
...
@@ -10,6 +10,8 @@
...
@@ -10,6 +10,8 @@
#define NSEC_PER_SEC UINT64_C(1000000000)
#define NSEC_PER_SEC UINT64_C(1000000000)
#define SERVER_PORT "50000"
#define SERVER_PORT "50000"
#define SERVER_PORT_INT 50000
#define SERVER_PORT_INT 50000
#define MAX_HIST_VAL 1000
#define NB_HISTOGRAMS 3
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
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment