u8 is_connected;
/* Our event queue */
- svm_queue_t *our_event_queue;
+ svm_msg_q_t *our_event_queue;
/* $$$ single thread only for the moment */
- svm_queue_t *vpp_event_queue;
+ svm_msg_q_t *vpp_event_queue;
/* $$$$ hack: cut-through session index */
volatile u32 cut_through_session_index;
uword *segments_table;
u8 do_echo;
+ u8 have_return;
+ u64 bytes_to_send;
} udp_echo_main_t;
#if CLIB_DEBUG > 0
stats_signal (int signum)
{
udp_echo_main_t *um = &udp_echo_main;
-
um->time_to_print_stats = 1;
}
}
utm->our_event_queue =
- uword_to_pointer (mp->app_event_queue_address, svm_queue_t *);
+ uword_to_pointer (mp->app_event_queue_address, svm_msg_q_t *);
}
static void
u8 *test_data = utm->connect_test_data;
int test_buf_offset = 0;
u64 bytes_sent = 0;
- u32 bytes_to_snd;
+ u32 bytes_to_snd, enq_space, min_chunk;
int rv;
+ min_chunk = clib_min (65536, s->tx_fifo->nitems);
bytes_to_snd = (bytes == 0) ? vec_len (test_data) : bytes;
if (bytes_to_snd > vec_len (test_data))
bytes_to_snd = vec_len (test_data);
while (bytes_to_snd > 0 && !utm->time_to_stop)
{
+ enq_space = svm_fifo_max_enqueue (s->tx_fifo);
+ if (enq_space < clib_min (bytes_to_snd, min_chunk))
+ continue;
+
rv = app_send (s, test_data + test_buf_offset, bytes_to_snd, 0);
if (rv > 0)
{
void
client_send_data (udp_echo_main_t * utm)
{
- u8 *test_data;
+ f64 start_time, end_time, delta;
app_session_t *session;
+ char *transfer_type;
u32 n_iterations;
+ u8 *test_data;
int i;
- vec_validate (utm->connect_test_data, 64 * 1024 - 1);
+ vec_validate (utm->connect_test_data, 1024 * 1024 - 1);
for (i = 0; i < vec_len (utm->connect_test_data); i++)
utm->connect_test_data[i] = i & 0xff;
ASSERT (vec_len (test_data) > 0);
vec_validate (utm->rx_buf, vec_len (test_data) - 1);
- n_iterations = NITER;
+ n_iterations = utm->bytes_to_send / vec_len (test_data);
+ if (!n_iterations)
+ n_iterations = 1;
+ start_time = clib_time_now (&utm->clib_time);
for (i = 0; i < n_iterations; i++)
{
send_test_chunk (utm, session, 0);
- recv_test_chunk (utm, session);
+ if (utm->have_return)
+ recv_test_chunk (utm, session);
if (utm->time_to_stop)
break;
}
- f64 timeout = clib_time_now (&utm->clib_time) + 5;
- while (clib_time_now (&utm->clib_time) < timeout)
+ if (utm->have_return)
{
- recv_test_chunk (utm, session);
+ f64 timeout = clib_time_now (&utm->clib_time) + 5;
+ while (clib_time_now (&utm->clib_time) < timeout)
+ recv_test_chunk (utm, session);
}
+ end_time = clib_time_now (&utm->clib_time);
+ delta = end_time - start_time;
+ transfer_type = utm->have_return ? "full-duplex" : "half-duplex";
+ clib_warning ("%lld bytes (%lld mbytes, %lld gbytes) in %.2f seconds",
+ utm->bytes_to_send, utm->bytes_to_send / (1ULL << 20),
+ utm->bytes_to_send / (1ULL << 30), delta);
+ clib_warning ("%.2f bytes/second %s", ((f64) utm->bytes_to_send) / (delta),
+ transfer_type);
+ clib_warning ("%.4f gbit/second %s",
+ (((f64) utm->bytes_to_send * 8.0) / delta / 1e9),
+ transfer_type);
}
static void
sizeof (ip46_address_t));
session->transport.is_ip4 = mp->lcl_is_ip4;
session->transport.lcl_port = mp->lcl_port;
- session->vpp_evt_q = uword_to_pointer (mp->vpp_evt_q, svm_queue_t *);
+ session->vpp_evt_q = uword_to_pointer (mp->vpp_evt_q, svm_msg_q_t *);
utm->state = utm->is_connected ? STATE_BOUND : STATE_READY;
}
start_time = clib_time_now (&utm->clib_time);
utm->vpp_event_queue = uword_to_pointer (mp->vpp_event_queue_address,
- svm_queue_t *);
+ svm_msg_q_t *);
rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
{
clib_warning ("cut-through session");
utm->our_event_queue = uword_to_pointer (mp->server_event_queue_address,
- svm_queue_t *);
+ svm_msg_q_t *);
rx_fifo->master_session_index = session_index;
tx_fifo->master_session_index = session_index;
utm->cut_through_session_index = session_index;
session->rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
session->tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
session->vpp_evt_q = uword_to_pointer (mp->vpp_event_queue_address,
- svm_queue_t *);
+ svm_msg_q_t *);
/* Cut-through case */
if (mp->client_event_queue_address)
{
clib_warning ("cut-through session");
utm->cut_through_session_index = session - utm->sessions;
utm->vpp_event_queue = uword_to_pointer (mp->vpp_event_queue_address,
- svm_queue_t *);
+ svm_msg_q_t *);
utm->our_event_queue = uword_to_pointer (mp->client_event_queue_address,
- svm_queue_t *);
+ svm_msg_q_t *);
utm->do_echo = 1;
}
else
{
utm->connected_session = session - utm->sessions;
utm->vpp_event_queue = uword_to_pointer (mp->vpp_event_queue_address,
- svm_queue_t *);
+ svm_msg_q_t *);
clib_memcpy (&session->transport.lcl_ip, mp->lcl_ip,
sizeof (ip46_address_t));
void
server_handle_event_queue (udp_echo_main_t * utm)
{
- session_fifo_event_t _e, *e = &_e;
+ session_fifo_event_t *e;
+ svm_msg_q_msg_t msg;
while (utm->state != STATE_READY)
sleep (5);
while (1)
{
- svm_queue_sub (utm->our_event_queue, (u8 *) e, SVM_Q_WAIT, 0);
+ if (svm_msg_q_sub (utm->our_event_queue, &msg, SVM_Q_WAIT, 0))
+ {
+ clib_warning ("svm msg q returned");
+ continue;
+ }
+ e = svm_msg_q_msg_data (utm->our_event_queue, &msg);
switch (e->event_type)
{
case FIFO_EVENT_APP_RX:
break;
case FIFO_EVENT_DISCONNECT:
- return;
+ utm->time_to_stop = 1;
+ break;
default:
clib_warning ("unknown event type %d", e->event_type);
break;
}
+ svm_msg_q_free_msg (utm->our_event_queue, &msg);
if (PREDICT_FALSE (utm->time_to_stop == 1))
return;
if (PREDICT_FALSE (utm->time_to_print_stats == 1))
main (int argc, char **argv)
{
udp_echo_main_t *utm = &udp_echo_main;
- u8 *uri = (u8 *) "udp://0.0.0.0/1234";
+ u8 *uri = (u8 *) "udp://6.0.1.1/1234";
unformat_input_t _argv, *a = &_argv;
int i_am_server = 1;
app_session_t *session;
int i;
clib_mem_init (0, 256 << 20);
-
heap = clib_mem_get_per_cpu_heap ();
h = mheap_header (heap);
-
/* make the main heap thread-safe */
h->flags |= MHEAP_FLAG_THREAD_SAFE;
+ svm_fifo_segment_main_init (0x200000000ULL, 20);
vec_validate (utm->rx_buf, 8192);
-
utm->session_index_by_vpp_handles = hash_create (0, sizeof (uword));
utm->my_pid = getpid ();
utm->configured_segment_size = 1 << 20;
utm->segments_table = hash_create_vec (0, sizeof (u8), sizeof (u64));
-
+ utm->have_return = 1;
+ utm->bytes_to_send = 1024;
+ utm->fifo_size = 128 << 10;
+ utm->segment_main = &svm_fifo_segment_main;
+ utm->cut_through_session_index = ~0;
clib_time_init (&utm->clib_time);
+
init_error_string_table (utm);
- svm_fifo_segment_main_init (0x200000000ULL, 20);
unformat_init_command_line (a, argv);
- utm->fifo_size = 128 << 10;
-
while (unformat_check_input (a) != UNFORMAT_END_OF_INPUT)
{
if (unformat (a, "chroot prefix %s", &chroot_prefix))
i_am_server = 1;
else if (unformat (a, "client"))
i_am_server = 0;
+ else if (unformat (a, "no-return"))
+ utm->have_return = 0;
+ else if (unformat (a, "mbytes %d", &tmp))
+ utm->bytes_to_send = (u64) tmp << 20;
+ else if (unformat (a, "fifo-size %d", &tmp))
+ utm->fifo_size = tmp << 10;
else
{
fformat (stderr, "%s: usage [server|client]\n");
}
}
- utm->cut_through_session_index = ~0;
utm->i_am_server = i_am_server;
- utm->segment_main = &svm_fifo_segment_main;
setup_signal_handlers ();
tcp_echo_api_hookup (utm);
if (i_am_server == 0)
{
client_test (utm);
- exit (0);
+ goto done;
}
/* $$$$ hack preallocation */
udp_server_test (utm);
+done:
vl_client_disconnect_from_vlib ();
exit (0);
}