[netperf-dev] netperf2 commit notice r171 - trunk/src
raj at netperf.org
raj at netperf.org
Fri Jan 18 15:22:24 PST 2008
Author: raj
Date: 2008-01-18 15:22:23 -0800 (Fri, 18 Jan 2008)
New Revision: 171
Modified:
trunk/src/nettest_omni.c
Log:
start working confidence intervals into omni
Modified: trunk/src/nettest_omni.c
===================================================================
--- trunk/src/nettest_omni.c 2008-01-18 00:16:27 UTC (rev 170)
+++ trunk/src/nettest_omni.c 2008-01-18 23:22:23 UTC (rev 171)
@@ -132,6 +132,8 @@
int direction;
int remote_send_size = -1;
int remote_recv_size = -1;
+int remote_send_size_req = -1;
+int remote_recv_size_req = -1;
int remote_use_sendfile;
int remote_send_dirty_count;
int remote_recv_dirty_count;
@@ -165,6 +167,8 @@
#include <sys/sendfile.h>
#endif /* HAVE_SENDFILE && (__linux || __sun) */
+static int confidence_iteration;
+
static char local_cpu_method;
static char remote_cpu_method;
@@ -623,93 +627,12 @@
/* initialize a few counters */
- bytes_xferd = 0.0;
- remote_bytes_xferd = 0.0;
- times_up = 0;
need_socket = 1;
if (connection_test)
pick_next_port_number(local_res,remote_res);
- data_socket = create_data_socket(local_res);
- if (data_socket == INVALID_SOCKET) {
- perror("netperf: send_omni: unable to create data socket");
- exit(1);
- }
- need_socket = 0;
-
- /* we need to consider if this is a request/response test, if we are
- receiving, if we are sending, etc, when setting-up our recv and
- send buffer rings. raj 2008-01-07 */
- if (direction & NETPERF_XMIT) {
- if (req_size > 0) {
- /* request/response test */
- if (send_width == 0) send_width = 1;
- bytes_to_send = req_size;
- }
- else {
- /* stream test */
- if (send_size == 0) {
- if (lss_size > 0) {
- send_size = lss_size;
- }
- else {
- send_size = 4096;
- }
- }
- if (send_width == 0)
- send_width = (lss_size/send_size) + 1;
- if (send_width == 1) send_width++;
- bytes_to_send = send_size;
- }
-
- send_ring = allocate_buffer_ring(send_width,
- bytes_to_send,
- local_send_align,
- local_send_offset);
- if (debug) {
- fprintf(where,
- "send_omni: %d entry send_ring obtained...\n",
- send_width);
- }
- }
-
- if (direction & NETPERF_RECV) {
- if (rsp_size > 0) {
- if (recv_width == 0) recv_width = 1;
- bytes_to_recv = rsp_size;
- }
- else {
- /* stream test */
- if (recv_size == 0) {
- if (lsr_size > 0) {
- recv_size = lsr_size;
- }
- else {
- recv_size = 4096;
- }
- }
- if (recv_width == 0) {
- recv_width = (lsr_size/recv_size) + 1;
- if (recv_width == 1) recv_width++;
- }
- bytes_to_recv = recv_size;
- }
-
- recv_ring = allocate_buffer_ring(recv_width,
- bytes_to_recv,
- local_recv_align,
- local_recv_offset);
- if (debug) {
- fprintf(where,
- "send_omni: %d entry recv_ring obtained...\n",
- recv_width);
- }
- }
-
-
-
/* If the user has requested cpu utilization measurements, we must */
/* calibrate the cpu(s). We will perform this task within the tests */
/* themselves. If the user has specified the cpu rate, then */
@@ -721,559 +644,671 @@
local_cpu_rate = calibrate_local_cpu(local_cpu_rate);
}
- if (!no_control) {
-
- /* Tell the remote end to do a listen or otherwise prepare for
- what is to come. The server alters the socket paramters on the
- other side at this point, hence the reason for all the values
- being passed in the setup message. If the user did not specify
- any of the parameters, they will be passed as values which will
- indicate to the remote that no changes beyond the system's
- default should be used. Alignment is the exception, it will
- default to 8, which will probably be no alignment
- alterations. */
-
- netperf_request.content.request_type = DO_OMNI;
- omni_request->send_buf_size = rss_size_req;
- omni_request->send_size = remote_send_size;
- omni_request->send_alignment = remote_send_align;
- omni_request->send_offset = remote_send_offset;
- omni_request->send_width = 1; /* FIX THIS */
- omni_request->request_size = req_size;
+ confidence_iteration = 1;
+ init_stat();
- omni_request->recv_buf_size = rsr_size_req;
- omni_request->receive_size = remote_recv_size;
- omni_request->recv_alignment = remote_recv_align;
- omni_request->recv_offset = remote_recv_offset;
- omni_request->recv_width = 1; /* FIX THIS */
- omni_request->response_size = rsp_size;
+ send_ring = NULL;
+ recv_ring = NULL;
- omni_request->no_delay = rem_nodelay;
- omni_request->use_sendfile = remote_use_sendfile;
- omni_request->connect_test = connection_test;
+ /* you will keep running the test until you get it right! :) */
+ while (((confidence < 0) && (confidence_iteration < iteration_max)) ||
+ (confidence_iteration <= iteration_min)) {
- omni_request->measure_cpu = remote_cpu_usage;
- omni_request->cpu_rate = remote_cpu_rate;
- if (test_time) {
- omni_request->test_length = test_time;
+ bytes_xferd = 0.0;
+ remote_bytes_xferd = 0.0;
+ times_up = 0;
+ bytes_sent = 0;
+ bytes_received = 0;
+
+ data_socket = create_data_socket(local_res);
+
+ if (data_socket == INVALID_SOCKET) {
+ perror("netperf: send_omni: unable to create data socket");
+ exit(1);
}
- else {
- omni_request->test_length = test_trans * -1;
+ need_socket = 0;
+
+ /* we need to consider if this is a request/response test, if we
+ are receiving, if we are sending, etc, when setting-up our recv
+ and send buffer rings. we should only need to do this once, and
+ that would be when the relevant _ring variable is NULL. raj
+ 2008-01-18 */
+ if ((direction & NETPERF_XMIT) && (NULL == send_ring)) {
+ if (req_size > 0) {
+ /* request/response test */
+ if (send_width == 0) send_width = 1;
+ bytes_to_send = req_size;
+ }
+ else {
+ /* stream test */
+ if (send_size == 0) {
+ if (lss_size > 0) {
+ send_size = lss_size;
+ }
+ else {
+ send_size = 4096;
+ }
+ }
+ if (send_width == 0)
+ send_width = (lss_size/send_size) + 1;
+ if (send_width == 1) send_width++;
+ bytes_to_send = send_size;
+ }
+
+ send_ring = allocate_buffer_ring(send_width,
+ bytes_to_send,
+ local_send_align,
+ local_send_offset);
+ if (debug) {
+ fprintf(where,
+ "send_omni: %d entry send_ring obtained...\n",
+ send_width);
+ }
}
- omni_request->so_rcvavoid = rem_rcvavoid;
- omni_request->so_sndavoid = rem_sndavoid;
- omni_request->send_dirty_count = remote_send_dirty_count;
- omni_request->recv_dirty_count = remote_recv_dirty_count;
- omni_request->recv_clean_count = remote_recv_clean_count;
-
- omni_request->checksum_off = remote_checksum_off;
- omni_request->data_port = atoi(remote_data_port);
- omni_request->ipfamily = af_to_nf(remote_res->ai_family);
- omni_request->socket_type = hst_to_nst(socket_type);
- omni_request->protocol = protocol;
-
- omni_request->direction = 0;
- /* yes, the sense here is correct - if we are transmitting, they
- receive, if we are receiving, they are transmitting... */
- if (direction & NETPERF_XMIT)
- omni_request->direction |= NETPERF_RECV;
- if (direction & NETPERF_RECV)
- omni_request->direction |= NETPERF_XMIT;
-
- /* some tests may require knowledge of our local addressing. such
- tests will for the time being require that the user specify a
- local IP/name so we can extract them from the data_socket. */
- getsockname(data_socket, (struct sockaddr *)&my_addr, &my_addr_len);
- ret = get_sockaddr_family_addr_port(&my_addr,
- nf_to_af(omni_request->ipfamily),
- omni_request->ipaddr,
- &(omni_request->netperf_port));
- if (debug > 1) {
- fprintf(where,"netperf: send_omni: requesting OMNI test\n");
+ if ((direction & NETPERF_RECV) && (NULL == recv_ring)) {
+ if (rsp_size > 0) {
+ if (recv_width == 0) recv_width = 1;
+ bytes_to_recv = rsp_size;
+ }
+ else {
+ /* stream test */
+ if (recv_size == 0) {
+ if (lsr_size > 0) {
+ recv_size = lsr_size;
+ }
+ else {
+ recv_size = 4096;
+ }
+ }
+ if (recv_width == 0) {
+ recv_width = (lsr_size/recv_size) + 1;
+ if (recv_width == 1) recv_width++;
+ }
+ bytes_to_recv = recv_size;
+ }
+
+ recv_ring = allocate_buffer_ring(recv_width,
+ bytes_to_recv,
+ local_recv_align,
+ local_recv_offset);
+ if (debug) {
+ fprintf(where,
+ "send_omni: %d entry recv_ring obtained...\n",
+ recv_width);
+ }
}
- send_request();
+ if (!no_control) { /* foo */
+
+ /* Tell the remote end to do a listen or otherwise prepare for
+ what is to come. The server alters the socket paramters on the
+ other side at this point, hence the reason for all the values
+ being passed in the setup message. If the user did not specify
+ any of the parameters, they will be passed as values which will
+ indicate to the remote that no changes beyond the system's
+ default should be used. Alignment is the exception, it will
+ default to 8, which will probably be no alignment
+ alterations. */
+
+ netperf_request.content.request_type = DO_OMNI;
+ omni_request->send_buf_size = rss_size_req;
+ omni_request->send_size = remote_send_size_req;
+ omni_request->send_alignment = remote_send_align;
+ omni_request->send_offset = remote_send_offset;
+ omni_request->send_width = 1; /* FIX THIS */
+ omni_request->request_size = req_size;
+
+ omni_request->recv_buf_size = rsr_size_req;
+ omni_request->receive_size = remote_recv_size_req;
+ omni_request->recv_alignment = remote_recv_align;
+ omni_request->recv_offset = remote_recv_offset;
+ omni_request->recv_width = 1; /* FIX THIS */
+ omni_request->response_size = rsp_size;
+
+ omni_request->no_delay = rem_nodelay;
+ omni_request->use_sendfile = remote_use_sendfile;
+ omni_request->connect_test = connection_test;
+
+ omni_request->measure_cpu = remote_cpu_usage;
+ omni_request->cpu_rate = remote_cpu_rate;
+ if (test_time)
+ omni_request->test_length = test_time;
+ else
+ omni_request->test_length = test_trans * -1;
+ omni_request->so_rcvavoid = rem_rcvavoid;
+ omni_request->so_sndavoid = rem_sndavoid;
+ omni_request->send_dirty_count = remote_send_dirty_count;
+ omni_request->recv_dirty_count = remote_recv_dirty_count;
+ omni_request->recv_clean_count = remote_recv_clean_count;
+
+ omni_request->checksum_off = remote_checksum_off;
+ omni_request->data_port = atoi(remote_data_port);
+ omni_request->ipfamily = af_to_nf(remote_res->ai_family);
+ omni_request->socket_type = hst_to_nst(socket_type);
+ omni_request->protocol = protocol;
+
+ omni_request->direction = 0;
+ /* yes, the sense here is correct - if we are transmitting, they
+ receive, if we are receiving, they are transmitting... */
+ if (direction & NETPERF_XMIT)
+ omni_request->direction |= NETPERF_RECV;
+ if (direction & NETPERF_RECV)
+ omni_request->direction |= NETPERF_XMIT;
- /* The response from the remote will contain all of the relevant
- socket parameters for this test type. We will put them back
- into the variables here so they can be displayed if desired.
- The remote will have calibrated CPU if necessary, and will have
- done all the needed set-up we will have calibrated the cpu
- locally before sending the request, and will grab the counter
- value right after the connect returns. The remote will grab the
- counter right after the accept call. This saves the hassle of
- extra messages being sent for the TCP tests. */
+ /* some tests may require knowledge of our local addressing. such
+ tests will for the time being require that the user specify a
+ local IP/name so we can extract them from the data_socket. */
+ getsockname(data_socket, (struct sockaddr *)&my_addr, &my_addr_len);
+ ret = get_sockaddr_family_addr_port(&my_addr,
+ nf_to_af(omni_request->ipfamily),
+ omni_request->ipaddr,
+ &(omni_request->netperf_port));
+
+ if (debug > 1) {
+ fprintf(where,"netperf: send_omni: requesting OMNI test\n");
+ }
+
+
+ send_request();
+
+
+ /* the response from the remote should contain all the relevant
+ socket and other parameters we need to know for this test.
+ so, we can shove them back into the relevant variables here
+ and be on our way. it would seem that this is as good a
+ place as any to put the "while" loop for confidence intervals
+ and have a send_request at the bottom that just tells the
+ remote to do again, and have them sit waiting for that
+ message, or control connection shutdown after each iteration.
+ raj 2008-01-18 */
+
+ recv_response();
- recv_response();
-
- if (!netperf_response.content.serv_errno) {
- rsr_size = omni_response->recv_buf_size;
- remote_recv_size = omni_response->receive_size;
- rss_size = omni_response->send_buf_size;
- remote_send_size = omni_response->send_size;
- rem_nodelay = omni_response->no_delay;
- remote_use_sendfile = omni_response->use_sendfile;
- remote_cpu_usage = omni_response->measure_cpu;
- remote_cpu_rate = omni_response->cpu_rate;
- /* make sure that port numbers are in network order */
- set_port_number(remote_res,
- (unsigned short)omni_response->data_port);
-
- if (debug) {
- fprintf(where,"remote listen done.\n");
- fprintf(where,"remote port is %u\n",get_port_number(remote_res));
+ if (!netperf_response.content.serv_errno) {
+ rsr_size = omni_response->recv_buf_size;
+ remote_recv_size = omni_response->receive_size;
+ rss_size = omni_response->send_buf_size;
+ remote_send_size = omni_response->send_size;
+ rem_nodelay = omni_response->no_delay;
+ remote_use_sendfile = omni_response->use_sendfile;
+ remote_cpu_usage = omni_response->measure_cpu;
+ remote_cpu_rate = omni_response->cpu_rate;
+ /* make sure that port numbers are in network order because
+ recv_response will have put everything into host order */
+ set_port_number(remote_res,
+ (unsigned short)omni_response->data_port);
+
+ if (debug) {
+ fprintf(where,"remote listen done.\n");
+ fprintf(where,"remote port is %u\n",get_port_number(remote_res));
+ fflush(where);
+ }
+ }
+ else {
+ Set_errno(netperf_response.content.serv_errno);
+ fprintf(where,
+ "netperf: remote error %d",
+ netperf_response.content.serv_errno);
+ perror("");
fflush(where);
+ exit(1);
}
+
}
- else {
- Set_errno(netperf_response.content.serv_errno);
- fprintf(where,
- "netperf: remote error %d",
- netperf_response.content.serv_errno);
- perror("");
- fflush(where);
- exit(1);
- }
- }
+
#ifdef WANT_DEMO
- DEMO_RR_SETUP(100);
+ DEMO_RR_SETUP(100);
#endif
- /* if we are not a connectionless protocol, we need to connect. at
- some point even if we are a connectionless protocol, we may still
- want to "connect" for convenience raj 2008-01-14 */
- need_to_connect = (protocol != IPPROTO_UDP);
-
- /* Set-up the test end conditions. For tests over a
- "reliable/connection-oriented" transport (eg TCP, SCTP, etc) this
- can be either time or byte/transaction count based. for
- unreliable transport or connection tests it can only be time
- based. having said that, we rely entirely on other code to
- enforce this before we even get here. raj 2008-01-08 */
-
- if (test_time) {
- /* The user wanted to end the test after a period of time. */
- times_up = 0;
- units_remaining = 0;
- start_timer(test_time);
- }
- else {
- /* The tester wanted to send a number of bytes or exchange a
- number of transactions. */
- if ((direction & NETPERF_XMIT) && (direction & NETPERF_RECV))
- units_remaining = test_trans;
- else
- units_remaining = test_bytes;
- times_up = 1;
- }
-
- /* grab the current time, and if necessary any starting information
- for the gathering of CPU utilization at this end. */
- cpu_start(local_cpu_usage);
-
+ /* if we are not a connectionless protocol, we need to connect. at
+ some point even if we are a connectionless protocol, we may
+ still want to "connect" for convenience raj 2008-01-14 */
+ need_to_connect = (protocol != IPPROTO_UDP);
+
+ /* Set-up the test end conditions. For tests over a
+ "reliable/connection-oriented" transport (eg TCP, SCTP, etc) this
+ can be either time or byte/transaction count based. for
+ unreliable transport or connection tests it can only be time
+ based. having said that, we rely entirely on other code to
+ enforce this before we even get here. raj 2008-01-08 */
+
+ if (test_time) {
+ /* The user wanted to end the test after a period of time. if
+ we are a recv-only test, we need to protect ourself against
+ the remote going poof, but we want to make sure we don't
+ give-up before they finish, so we will add a PAD_TIME to the
+ timer. if we are RR or XMIT, there should be no need for
+ padding */
+ times_up = 0;
+ units_remaining = 0;
+ if ((!no_control) && (NETPERF_RECV_ONLY(direction)))
+ start_timer(test_time + PAD_TIME);
+ else
+ start_timer(test_time);
+ }
+ else {
+ /* The tester wanted to send a number of bytes or exchange a
+ number of transactions. */
+ if (NETPERF_IS_RR(direction))
+ units_remaining = test_trans;
+ else
+ units_remaining = test_bytes;
+ times_up = 1;
+ }
+
+ /* grab the current time, and if necessary any starting information
+ for the gathering of CPU utilization at this end. */
+ cpu_start(local_cpu_usage);
+
#ifdef WANT_DEMO
- if (demo_mode) {
- HIST_timestamp(demo_one_ptr);
- }
+ if (demo_mode) {
+ HIST_timestamp(demo_one_ptr);
+ }
#endif
-
- /* the "OR" here allows us to control test length by either
- byte/transaction count or by timer. when the test is
- byte/transaction count based the time test will always evaluate
- false. when the test is controlled by time, the byte/transaction
- count will always evaluate to false. when the test is finished
- the whole expression will go false and we will stop sending
- data. at least that is the plan :) raj 2008-01-08 */
+
+ /* the "OR" here allows us to control test length by either
+ byte/transaction count or by timer. when the test is
+ byte/transaction count based the time test will always evaluate
+ false. when the test is controlled by time, the byte/transaction
+ count will always evaluate to false. when the test is finished
+ the whole expression will go false and we will stop sending
+ data. at least that is the plan :) raj 2008-01-08 */
+
+ while ((!times_up) || (units_remaining > 0)) {
- while ((!times_up) || (units_remaining > 0)) {
-
#ifdef WANT_HISTOGRAM
- /* only pull the timestamp if we are actually going to use the
- results of the work. we put the call here so it can work for
- any sort of test - connection, request/response, or stream.
- no, it isn't "perfect" for all of them - for some it will
- include a few more "if's" than a purpose-written routine, but
- it _should_ be the case that the time spent up here is epsilon
- compared to time spent elsewhere in the stack so it should not
- be a big deal. famous last words of raj 2008-01-08 */
- if (verbosity > 1) {
- HIST_timestamp(&time_one);
- }
+ /* only pull the timestamp if we are actually going to use the
+ results of the work. we put the call here so it can work for
+ any sort of test - connection, request/response, or stream.
+ no, it isn't "perfect" for all of them - for some it will
+ include a few more "if's" than a purpose-written routine, but
+ it _should_ be the case that the time spent up here is
+ epsilon compared to time spent elsewhere in the stack so it
+ should not be a big deal. famous last words of raj
+ 2008-01-08 */
+ if (verbosity > 1) {
+ HIST_timestamp(&time_one);
+ }
#endif /* WANT_HISTOGRAM */
-again:
+ again:
- if (need_socket) {
- if (connection_test)
- pick_next_port_number(local_res,remote_res);
+ if (need_socket) {
+ if (connection_test)
+ pick_next_port_number(local_res,remote_res);
- data_socket = create_data_socket(local_res);
+ data_socket = create_data_socket(local_res);
- if (data_socket == INVALID_SOCKET) {
- perror("netperf: send_omni: unable to create data socket");
- exit(1);
+ if (data_socket == INVALID_SOCKET) {
+ perror("netperf: send_omni: unable to create data socket");
+ exit(1);
+ }
+ need_socket = 0;
}
- need_socket = 0;
- }
- /* only connect if and when we need to */
- if (need_to_connect) {
- /* assign to data_socket since connect_data_socket returns
- SOCKET and not int thanks to Windows. */
- ret = connect_data_socket(data_socket,remote_res);
- if (ret == 0) {
- connected = 1;
- need_to_connect = 0;
+ /* only connect if and when we need to */
+ if (need_to_connect) {
+ /* assign to data_socket since connect_data_socket returns
+ SOCKET and not int thanks to Windows. */
+ ret = connect_data_socket(data_socket,remote_res);
+ if (ret == 0) {
+ connected = 1;
+ need_to_connect = 0;
+ }
+ else if (ret == -1) {
+ times_up = 1;
+ break;
+ }
+ else if ((ret == -2) && connection_test) {
+ /* transient error on a connection test means go around and
+ try again with another local port number */
+ fprintf(where,"transient! transient! torpedo in the water!\n");
+ fflush(where);
+ close(data_socket);
+ connected = 0; /* probably redundant but what the heck... */
+ need_socket = 1;
+ need_to_connect = 1;
+ /* this will stuff the next local port number within bounds
+ into our local res, and then when the goto has us
+ allocating a new socket it will do the right thing with the
+ bind() call */
+ pick_next_port_number(local_res,remote_res);
+ goto again;
+ }
+ else {
+ /* either this was a hard failure (-3) or a soft failure on
+ something other than a connection test */
+ perror("netperf: send_omni: connect_data_socket failed");
+ exit(1);
+ }
}
- else if (ret == -1) {
- times_up = 1;
- break;
- }
- else if ((ret == -2) && connection_test) {
- /* transient error on a connection test means go around and
- try again with another local port number */
- fprintf(where,"transient! transient! torpedo in the water!\n");
- fflush(where);
- close(data_socket);
- connected = 0; /* probably redundant but what the heck... */
- need_socket = 1;
- need_to_connect = 1;
- /* this will stuff the next local port number within bounds
- into our local res, and then when the goto has us
- allocating a new socket it will do the right thing with the
- bind() call */
- pick_next_port_number(local_res,remote_res);
- goto again;
- }
- else {
- /* either this was a hard failure (-3) or a soft failure on
- something other than a connection test */
- perror("netperf: send_omni: connect_data_socket failed");
- exit(1);
- }
- }
- /* if we should try to send something, then by all means, let us
- try to send something. */
- if (direction & NETPERF_XMIT) {
- ret = send_data(data_socket,
- send_ring,
- bytes_to_send,
- (connected) ? NULL : remote_res->ai_addr,
- /* if the destination above is NULL, this is ignored */
- remote_res->ai_addrlen);
- /* the order of these if's will seem a triffle strange, but they
- are my best guess as to order of probabilty and/or importance
- to the overhead raj 2008-01-09*/
- if (ret == bytes_to_send) {
- /* if this is a send-only test controlled by byte count we
- decrement units_remaining by the bytes sent */
- if (!(direction & NETPERF_RECV) && (units_remaining > 0)) {
- units_remaining -= ret;
+ /* if we should try to send something, then by all means, let us
+ try to send something. */
+ if (direction & NETPERF_XMIT) {
+ ret = send_data(data_socket,
+ send_ring,
+ bytes_to_send,
+ (connected) ? NULL : remote_res->ai_addr,
+ /* if the destination above is NULL, this is ignored */
+ remote_res->ai_addrlen);
+ /* the order of these if's will seem a triffle strange, but they
+ are my best guess as to order of probabilty and/or importance
+ to the overhead raj 2008-01-09*/
+ if (ret == bytes_to_send) {
+ /* if this is a send-only test controlled by byte count we
+ decrement units_remaining by the bytes sent */
+ if (!(direction & NETPERF_RECV) && (units_remaining > 0)) {
+ units_remaining -= ret;
+ }
+ bytes_sent += ret;
+ send_ring = send_ring->next;
+ local_send_calls++;
}
- bytes_sent += ret;
- send_ring = send_ring->next;
- local_send_calls++;
+ else if (ret == -2) {
+ /* what to do here -2 means a non-fatal error - probably
+ ENOBUFS and so our send didn't happen. in the old code for
+ UDP_STREAM we would just continue in the while loop. it
+ isn't clear that is what to do here, so we will simply
+ increment the failed_sends stat and fall-through. If this
+ is a UDP_STREAM style of test, the net effect should be the
+ same. if this is a UDP_RR with a really-big burst count, I
+ don't think we were checking for ENOBUFS there anyway and
+ so would have failed. Here we can just let things
+ slide. */
+ failed_sends++;
+ }
+ else if (ret == 0) {
+ /* was this a zero-byte send? if it was, then ostensibly we
+ would hit the ret == bytes_to_send case which means we'd
+ never get here as we are using blocking semantics */
+ }
+ else if (ret == -1) {
+ times_up = 1;
+ break;
+ }
+ else {
+ perror("netperf: send_omni: send_data failed");
+ exit(1);
+ }
+
}
- else if (ret == -2) {
- /* what to do here -2 means a non-fatal error - probably
- ENOBUFS and so our send didn't happen. in the old code for
- UDP_STREAM we would just continue in the while loop. it
- isn't clear that is what to do here, so we will simply
- increment the failed_sends stat and fall-through. If this
- is a UDP_STREAM style of test, the net effect should be the
- same. if this is a UDP_RR with a really-big burst count, I
- don't think we were checking for ENOBUFS there anyway and
- so would have failed. Here we can just let things
- slide. */
- failed_sends++;
- }
- else if (ret == 0) {
- /* was this a zero-byte send? if it was, then ostensibly we
- would hit the ret == bytes_to_send case which means we'd
- never get here as we are using blocking semantics */
- }
- else if (ret == -1) {
- times_up = 1;
- break;
- }
- else {
- perror("netperf: send_omni: send_data failed");
- exit(1);
- }
- }
-
- if (direction & NETPERF_RECV) {
- ret = recv_data(data_socket,
- recv_ring,
- bytes_to_recv,
- (connected) ? NULL : (struct sockaddr *)&remote_addr,
- /* if remote_addr NULL this is ignored */
- &remote_addr_len,
- /* if XMIT also set this is RR so waitall */
- (direction & NETPERF_XMIT) ? NETPERF_WAITALL: 0,
- &temp_recvs);
- if (ret > 0) {
- /* if this is a recv-only test controlled by byte count we
- decrement the units_remaining by the bytes received */
- if (!(direction & NETPERF_XMIT) && (units_remaining > 0)) {
- units_remaining -= ret;
+ if (direction & NETPERF_RECV) {
+ ret = recv_data(data_socket,
+ recv_ring,
+ bytes_to_recv,
+ (connected) ? NULL : (struct sockaddr *)&remote_addr,
+ /* if remote_addr NULL this is ignored */
+ &remote_addr_len,
+ /* if XMIT also set this is RR so waitall */
+ (direction & NETPERF_XMIT) ? NETPERF_WAITALL: 0,
+ &temp_recvs);
+ if (ret > 0) {
+ /* if this is a recv-only test controlled by byte count we
+ decrement the units_remaining by the bytes received */
+ if (!(direction & NETPERF_XMIT) && (units_remaining > 0)) {
+ units_remaining -= ret;
+ }
+ bytes_received += ret;
+ local_receive_calls += temp_recvs;
}
- bytes_received += ret;
- local_receive_calls += temp_recvs;
- }
- else if (ret == 0) {
- /* is this the end of a test, just a zero-byte recv, or
- something else? that is an exceedingly good question and
- one for which I don't presently have a good answer, but
- that won't stop me from guessing :) raj 2008-01-09 */
- if (!((connection_test) || (null_message_ok))) {
- /* if it is neither a connection_test nor null_message_ok it
- must be the end of the test */
+ else if (ret == 0) {
+ /* is this the end of a test, just a zero-byte recv, or
+ something else? that is an exceedingly good question and
+ one for which I don't presently have a good answer, but
+ that won't stop me from guessing :) raj 2008-01-09 */
+ if (!((connection_test) || (null_message_ok))) {
+ /* if it is neither a connection_test nor null_message_ok it
+ must be the end of the test */
+ times_up = 1;
+ break;
+ }
+ local_receive_calls += temp_recvs;
+ }
+ else if (ret == -1) {
+ /* test timed-out */
times_up = 1;
break;
}
- local_receive_calls += temp_recvs;
+ else {
+ /* presently at least, -2 and -3 are equally bad on recv */
+ perror("netperf: send_omni: recv_data failed");
+ exit(1);
+ }
+ recv_ring = recv_ring->next;
}
- else if (ret == -1) {
- /* test timed-out */
- times_up = 1;
- break;
- }
- else {
- /* presently at least, -2 and -3 are equally bad on recv */
- perror("netperf: send_omni: recv_data failed");
- exit(1);
- }
- recv_ring = recv_ring->next;
- }
- /* if this is a connection test, we want to do some stuff about
- connection close here in the test loop. raj 2008-01-08 */
- if (connection_test) {
+ /* if this is a connection test, we want to do some stuff about
+ connection close here in the test loop. raj 2008-01-08 */
+ if (connection_test) {
#ifdef __linux
- /* so, "Linux" with autotuning likes to alter the socket buffer
- sizes over the life of the connection, but only does so when
- one takes the defaults at time of socket creation. if we
- took those defaults, we should inquire as to what the values
- ultimately became. raj 2008-01-15 */
- if (lsr_size_req < 0)
- get_sock_buffer(data_socket, RECV_BUFFER, &lsr_size_end);
- if (lss_size_req < 0)
- get_sock_buffer(data_socket, SEND_BUFFER, &lss_size_end);
+ /* so, "Linux" with autotuning likes to alter the socket buffer
+ sizes over the life of the connection, but only does so when
+ one takes the defaults at time of socket creation. if we
+ took those defaults, we should inquire as to what the values
+ ultimately became. raj 2008-01-15 */
+ if (lsr_size_req < 0)
+ get_sock_buffer(data_socket, RECV_BUFFER, &lsr_size_end);
+ if (lss_size_req < 0)
+ get_sock_buffer(data_socket, SEND_BUFFER, &lss_size_end);
#endif
- ret = disconnect_data_socket(data_socket,
- (no_control) ? 1 : 0,
- 1);
- if (ret == 0) {
- /* we will need a new connection to be established next time
- around the loop */
- need_to_connect = 1;
- connected = 0;
- need_socket = 1;
- pick_next_port_number(local_res,remote_res);
+ ret = disconnect_data_socket(data_socket,
+ (no_control) ? 1 : 0,
+ 1);
+ if (ret == 0) {
+ /* we will need a new connection to be established next time
+ around the loop */
+ need_to_connect = 1;
+ connected = 0;
+ need_socket = 1;
+ pick_next_port_number(local_res,remote_res);
+ }
+ else if (ret == -1) {
+ times_up = 1;
+ break;
+ }
+ else {
+ perror("netperf: send_omni: disconnect_data_socket failed");
+ exit(1);
+ }
}
- else if (ret == -1) {
- times_up = 1;
- break;
- }
- else {
- perror("netperf: send_omni: disconnect_data_socket failed");
- exit(1);
- }
- }
#ifdef WANT_HISTOGRAM
- if (verbosity > 1) {
- HIST_timestamp(&time_two);
- HIST_add(time_hist,delta_micro(&time_one,&time_two));
- }
+ if (verbosity > 1) {
+ HIST_timestamp(&time_two);
+ HIST_add(time_hist,delta_micro(&time_one,&time_two));
+ }
#endif /* WANT_HISTOGRAM */
#ifdef WANT_DEMO
- DEMO_RR_INTERVAL(1);
+ DEMO_RR_INTERVAL(1);
#endif
- /* was this a "transaction" test? don't for get that a TCP_CC
- style test will have no xmit or recv :) so, we check for either
- both XMIT and RECV set, or neither XMIT nor RECV set */
- if (((direction & NETPERF_XMIT) && (direction & NETPERF_RECV)) ||
- !((direction & NETPERF_XMIT) || (direction & NETPERF_RECV))) {
- trans_completed++;
- if (units_remaining) {
- units_remaining--;
+ /* was this a "transaction" test? don't forget that a "TCP_CC"
+ style test will have no xmit or recv :) so, we check for either
+ both XMIT and RECV set, or neither XMIT nor RECV set. at some
+ point we need to change this to NETPERF_IS_RR(direction) */
+ if (NETPERF_IS_RR(direction)) {
+ trans_completed++;
+ if (units_remaining) {
+ units_remaining--;
+ }
}
- }
- }
+ }
- /* we are now, ostensibly, at the end of this iteration */
+ /* we are now, ostensibly, at the end of this iteration */
- /* so, if we have/had a data connection, we will want to close it
- now, and this will be independent of whether there is a control
- connection. */
+ /* so, if we have/had a data connection, we will want to close it
+ now, and this will be independent of whether there is a control
+ connection. */
- if (connected) {
+ if (connected) {
#ifdef __linux
- /* so, "Linux" with autotuning likes to alter the socket buffer
- sizes over the life of the connection, but only does so when
- one takes the defaults at time of socket creation. if we took
- those defaults, we should inquire as to what the values
- ultimately became. raj 2008-01-15 */
- if (lsr_size_req < 0)
- get_sock_buffer(data_socket, RECV_BUFFER, &lsr_size_end);
- if (lss_size_req < 0)
- get_sock_buffer(data_socket, SEND_BUFFER, &lss_size_end);
+ /* so, "Linux" with autotuning likes to alter the socket buffer
+ sizes over the life of the connection, but only does so when
+ one takes the defaults at time of socket creation. if we took
+ those defaults, we should inquire as to what the values
+ ultimately became. raj 2008-01-15 */
+ if (lsr_size_req < 0)
+ get_sock_buffer(data_socket, RECV_BUFFER, &lsr_size_end);
+ if (lss_size_req < 0)
+ get_sock_buffer(data_socket, SEND_BUFFER, &lss_size_end);
#endif
- /* CHECK PARMRS HERE; */
- ret = disconnect_data_socket(data_socket,
- 1,
- 1);
- connected = 0;
- need_socket = 1;
+ /* CHECK PARMRS HERE; */
+ ret = disconnect_data_socket(data_socket,
+ 1,
+ 1);
+ connected = 0;
+ need_socket = 1;
- }
+ }
- /* this call will always give us the elapsed time for the test, and
- will also store-away the necessaries for cpu utilization */
+ /* this call will always give us the elapsed time for the test, and
+ will also store-away the necessaries for cpu utilization */
- cpu_stop(local_cpu_usage,&elapsed_time);
+ cpu_stop(local_cpu_usage,&elapsed_time);
- if (!no_control) {
- /* Get the statistics from the remote end. The remote will have
- calculated service demand and all those interesting things. If
- it wasn't supposed to care, it will return obvious values. */
+ if (!no_control) {
+ /* Get the statistics from the remote end. The remote will have
+ calculated service demand and all those interesting things. If
+ it wasn't supposed to care, it will return obvious values. */
- recv_response();
- if (!netperf_response.content.serv_errno) {
- if (debug)
- fprintf(where,"remote results obtained\n");
- }
- else {
- Set_errno(netperf_response.content.serv_errno);
- fprintf(where,
- "netperf: remote error %d",
- netperf_response.content.serv_errno);
- perror("");
- fflush(where);
+ recv_response();
+ if (!netperf_response.content.serv_errno) {
+ if (debug)
+ fprintf(where,"remote results obtained\n");
+ }
+ else {
+ Set_errno(netperf_response.content.serv_errno);
+ fprintf(where,
+ "netperf: remote error %d",
+ netperf_response.content.serv_errno);
+ perror("");
+ fflush(where);
- exit(1);
+ exit(1);
+ }
}
- }
- /* so, what was the end result? */
+ /* so, what was the end result? */
- /* why? because some stacks want to be clever and autotune their
- socket buffer sizes, which means that if we accept the defaults,
- the size we get from getsockopt() at the beginning of a
- connection may not be what we would get at the end of the
- connection... */
- rsr_size_end = omni_result->recv_buf_size;
- rss_size_end = omni_result->send_buf_size;
+ /* why? because some stacks want to be clever and autotune their
+ socket buffer sizes, which means that if we accept the defaults,
+ the size we get from getsockopt() at the beginning of a
+ connection may not be what we would get at the end of the
+ connection... */
+ rsr_size_end = omni_result->recv_buf_size;
+ rss_size_end = omni_result->send_buf_size;
- /* to we need to pull something from omni_results here? */
- bytes_xferd = bytes_sent + bytes_received;
- thruput = calc_thruput(bytes_xferd);
- remote_bytes_xferd = omni_result->bytes_received +
- omni_result->bytes_sent;
+ /* to we need to pull something from omni_results here? */
+ bytes_xferd = bytes_sent + bytes_received;
+ thruput = calc_thruput(bytes_xferd);
+ remote_bytes_xferd = omni_result->bytes_received +
+ omni_result->bytes_sent;
- printf("bytes xfered %g remote %g trans %d elapsed %g\n",
- bytes_xferd,
- remote_bytes_xferd,
- omni_result->trans_received,
- elapsed_time);
+ printf("bytes xfered %g remote %g trans %d elapsed %g\n",
+ bytes_xferd,
+ remote_bytes_xferd,
+ omni_result->trans_received,
+ elapsed_time);
- printf("lss_size_req %d lsr_size_req %d rss_size_req %d rsr_size_req %d\n",
- lss_size_req,
- lsr_size_req,
- rss_size_req,
- rsr_size_req);
+ printf("lss_size_req %d lsr_size_req %d rss_size_req %d rsr_size_req %d\n",
+ lss_size_req,
+ lsr_size_req,
+ rss_size_req,
+ rsr_size_req);
- printf("lss_size %d lsr_size %d rss_size %d rsr_size %d\n",
- lss_size,
- lsr_size,
- rss_size,
- rsr_size);
+ printf("lss_size %d lsr_size %d rss_size %d rsr_size %d\n",
+ lss_size,
+ lsr_size,
+ rss_size,
+ rsr_size);
- printf("lss_size_end %d lsr_size_end %d rss_size_end %d rsr_size_end %d\n",
- lss_size_end,
- lsr_size_end,
- rss_size_end,
- rsr_size_end);
+ printf("lss_size_end %d lsr_size_end %d rss_size_end %d rsr_size_end %d\n",
+ lss_size_end,
+ lsr_size_end,
+ rss_size_end,
+ rsr_size_end);
- if (local_cpu_usage || remote_cpu_usage) {
- /* We must now do a little math for service demand and cpu */
- /* utilization for the system(s) */
- /* Of course, some of the information might be bogus because */
- /* there was no idle counter in the kernel(s). We need to make */
- /* a note of this for the user's benefit...*/
- if (local_cpu_usage) {
- if (local_cpu_rate == 0.0) {
- fprintf(where,
- "WARNING WARNING WARNING WARNING WARNING WARNING WARNING!\n");
- fprintf(where,
- "Local CPU usage numbers based on process information only!\n");
- fflush(where);
+
+ if (local_cpu_usage || remote_cpu_usage) {
+ /* We must now do a little math for service demand and cpu */
+ /* utilization for the system(s) */
+ /* Of course, some of the information might be bogus because */
+ /* there was no idle counter in the kernel(s). We need to make */
+ /* a note of this for the user's benefit...*/
+ if (local_cpu_usage) {
+ if (local_cpu_rate == 0.0) {
+ fprintf(where,
+ "WARNING WARNING WARNING WARNING WARNING WARNING WARNING!\n");
+ fprintf(where,
+ "Local CPU usage numbers based on process information only!\n");
+ fflush(where);
+ }
+ local_cpu_utilization = calc_cpu_util(0.0);
+
+ /* we need to decide what to feed the service demand beast,
+ which will, ultimately, depend on what sort of test it is and
+ whether or not the user asked for something specific - as in
+ per KB even on a TCP_RR test if it is being (ab)used as a
+ bidirectional bulk-transfer test. raj 2008-01-14 */
+ local_service_demand =
+ calc_service_demand((sd_kb) ? bytes_xferd : (double)trans_completed * 1024,
+ 0.0,
+ 0.0,
+ 0);
}
- local_cpu_utilization = calc_cpu_util(0.0);
-
- /* we need to decide what to feed the service demand beast,
- which will, ultimately, depend on what sort of test it is and
- whether or not the user asked for something specific - as in
- per KB even on a TCP_RR test if it is being (ab)used as a
- bidirectional bulk-transfer test. raj 2008-01-14 */
- local_service_demand =
- calc_service_demand((sd_kb) ? bytes_xferd : (double)trans_completed * 1024,
- 0.0,
- 0.0,
- 0);
- }
- else {
- local_cpu_utilization = (float) -1.0;
- local_service_demand = (float) -1.0;
- }
+ else {
+ local_cpu_utilization = (float) -1.0;
+ local_service_demand = (float) -1.0;
+ }
- if (remote_cpu_usage) {
- if (remote_cpu_rate == 0.0) {
- fprintf(where,
- "DANGER DANGER DANGER DANGER DANGER DANGER DANGER!\n");
- fprintf(where,
- "Remote CPU usage numbers based on process information only!\n");
- fflush(where);
+ if (remote_cpu_usage) {
+ if (remote_cpu_rate == 0.0) {
+ fprintf(where,
+ "DANGER DANGER DANGER DANGER DANGER DANGER DANGER!\n");
+ fprintf(where,
+ "Remote CPU usage numbers based on process information only!\n");
+ fflush(where);
+ }
+ remote_cpu_utilization = omni_result->cpu_util;
+ /* since calc_service demand is doing ms/Kunit we will */
+ /* multiply the number of transaction by 1024 to get */
+ /* "good" numbers */
+ remote_service_demand = calc_service_demand((sd_kb) ? bytes_xferd :
+ (double) trans_completed * 1024,
+ 0.0,
+ remote_cpu_utilization,
+ omni_result->num_cpus);
}
- remote_cpu_utilization = omni_result->cpu_util;
- /* since calc_service demand is doing ms/Kunit we will */
- /* multiply the number of transaction by 1024 to get */
- /* "good" numbers */
- remote_service_demand = calc_service_demand((sd_kb) ? bytes_xferd :
-(double) trans_completed * 1024,
- 0.0,
- remote_cpu_utilization,
- omni_result->num_cpus);
+ else {
+ remote_cpu_utilization = (float) -1.0;
+ remote_service_demand = (float) -1.0;
+ }
+
+ /* at some point we may want to actually display some results :) */
+
+
}
else {
- remote_cpu_utilization = (float) -1.0;
- remote_service_demand = (float) -1.0;
+ /* The tester did not wish to measure service demand. */
+
}
-
- /* at some point we may want to actually display some results :) */
-
+ /* this this is the end of the confidence while loop? */
+ confidence_iteration++;
}
- else {
- /* The tester did not wish to measure service demand. */
-
- }
/* likely as not we are going to do something slightly different here */
if (verbosity > 1) {
@@ -1421,6 +1456,7 @@
else bytes_to_send = 4096;
}
else bytes_to_send = omni_request->send_size;
+ omni_response->send_size = bytes_to_send;
/* set the send_width */
if (omni_request->send_width == 0) {
send_width = (lss_size/bytes_to_send) + 1;
@@ -1451,6 +1487,7 @@
else {
bytes_to_recv = omni_request->receive_size;
}
+ omni_response->receive_size = bytes_to_recv;
/* set the recv_width */
if (omni_request->recv_width == 0) {
recv_width = (lsr_size/bytes_to_recv) + 1;
@@ -1552,13 +1589,21 @@
cpu_start(omni_request->measure_cpu);
- /* The loop will exit when the sender does a shutdown, which will */
- /* return a length of zero */
-
+ /* if the test is timed, set a timer of suitable length. if the
+ test is by byte/transaction count, we don't need a timer - or
+ rather we rely on the netperf to only ask us to do transaction
+ counts over "reliable" protocols. perhaps at some point we
+ should add a check herebouts to verify that... */
+
if (omni_request->test_length > 0) {
times_up = 0;
units_remaining = 0;
- start_timer(omni_request->test_length + PAD_TIME);
+ /* if we are the sender and only sending, then we don't need/want
+ the padding */
+ if (NETPERF_XMIT_ONLY(omni_request->direction))
+ start_timer(omni_request->test_length);
+ else
+ start_timer(omni_request->test_length + PAD_TIME);
}
else {
times_up = 1;
@@ -1566,6 +1611,8 @@
}
trans_completed = 0;
+ bytes_sent = 0;
+ bytes_received = 0;
while ((!times_up) || (units_remaining > 0)) {
@@ -1984,7 +2031,7 @@
direction |= NETPERF_XMIT;
}
if (arg2[0]) {
- remote_send_size = convert(arg2);
+ remote_send_size_req = convert(arg2);
direction |= NETPERF_RECV;
}
break;
@@ -1994,7 +2041,7 @@
will add XMIT to direction */
break_args_explicit(optarg,arg1,arg2);
if (arg1[0]) {
- remote_recv_size = convert(arg1);
+ remote_recv_size_req = convert(arg1);
direction |= NETPERF_XMIT;
}
if (arg2[0]) {
More information about the netperf-dev
mailing list