[netperf-dev] makeup netperf4 commit notice r18 - trunk/src
burger at netperf.org
burger at netperf.org
Thu Nov 17 12:00:54 PST 2005
Author: burger
Date: 2005-11-16 20:17:04 -0800 (Wed, 16 Nov 2005)
New Revision: 18
Modified:
trunk/src/netmsg.c
trunk/src/netperf.c
trunk/src/netperf.h
trunk/src/nettest_bsd.c
trunk/src/nettest_bsd.h
Log:
fixes for timing windows and deadlocks.
redesign of tcp test to remove timing windows and make code easier to maintain.
Stephen Burger
Modified: trunk/src/netmsg.c
===================================================================
--- trunk/src/netmsg.c 2005-11-14 22:43:30 UTC (rev 17)
+++ trunk/src/netmsg.c 2005-11-17 04:17:04 UTC (rev 18)
@@ -132,6 +132,10 @@
xmlNodePtr cur;
struct msgs *which_msg;
+ if (debug) {
+ fprintf(where,"process_message: entered\n");
+ fflush(where);
+ }
msg = xmlDocGetRootElement(doc);
if (msg == NULL) {
@@ -185,6 +189,10 @@
}
}
xmlFreeDoc(doc);
+ if (debug) {
+ fprintf(where,"process_message: exiting\n");
+ fflush(where);
+ }
return(rc);
}
@@ -356,9 +364,9 @@
if (test != NULL) {
if (debug) {
fprintf(where,
- "clear_stats_message: test_state = %d calling %p\n",
- test->state,
- test->test_clear);
+ "clear_stats_message: test_state = %d calling %p\n",
+ test->state,
+ test->test_clear);
fflush(where);
}
rc = (test->test_clear)(test);
@@ -388,10 +396,10 @@
if (test != NULL) {
if (debug) {
fprintf(where,
- "clear_sys_stats_message: test %p test_state = %d calling %p\n",
- test,
- test->state,
- test->test_clear);
+ "clear_sys_stats_message: test %p test_state = %d calling %p\n",
+ test,
+ test->state,
+ test->test_clear);
fflush(where);
}
rc = (test->test_clear)(test);
@@ -715,7 +723,6 @@
xmlChar *testid;
test_t *test;
-
testid = xmlGetProp(msg,(const xmlChar *)"tid");
test = find_test_in_hash(testid);
if (test != NULL) {
@@ -745,6 +752,10 @@
xmlChar *testid;
+ if (debug) {
+ fprintf(where,"entering test_message\n");
+ fflush(where);
+ }
if (server->state != server->state_req) {
/* set netserver state to NSRV_WORK because receiving a test message
shows that netperf accepted our version message */
@@ -755,7 +766,7 @@
if (xmlStrcmp(test_node->name,(const xmlChar *)"test")) {
if (debug) {
fprintf(where,"test_message: skipped a non-test node\n");
- fflush(where);
+ fflush(where);
}
test_node = test_node->next;
continue;
@@ -794,7 +805,7 @@
fprintf(where,
"test_message: about to launch thread for test %d using func %p\n",
new_test->tid,
- new_test->test_func);
+ new_test->test_func);
fflush(where);
}
rc = launch_thread(&new_test->tid,new_test->test_func,new_test);
@@ -851,7 +862,6 @@
test_t *test;
xmlNodePtr stats;
-
testid = xmlGetProp(msg,(const xmlChar *)"tid");
test = find_test_in_hash(testid);
if (debug || loc_debug) {
Modified: trunk/src/netperf.c
===================================================================
--- trunk/src/netperf.c 2005-11-14 22:43:30 UTC (rev 17)
+++ trunk/src/netperf.c 2005-11-17 04:17:04 UTC (rev 18)
@@ -1198,6 +1198,7 @@
}
set_elt = set_elt->next;
}
+ xmlSetProp(cmd,(const xmlChar *)"tid", test_set->id);
} else {
test = find_test_in_hash(tid);
if (test) {
@@ -1248,7 +1249,6 @@
report_stats_command(xmlNodePtr my_cmd, uint32_t junk)
{
int rc = NPE_SUCCESS;
- xmlChar *string;
xmlDocPtr doc;
xmlNodePtr commands;
xmlNodePtr cmd;
@@ -1257,6 +1257,7 @@
char *output_file;
char *report_flags;
xmlChar *set_name;
+ xmlChar *string;
char *desired_level;
char *dsrd_interval;
tset_t *test_set;
@@ -1296,15 +1297,33 @@
if (commands == NULL) {
max_count = 1;
+ min_count = 1;
}
test_set = find_test_set_in_hash(set_name);
+ if (debug) {
+ fprintf(where,
+ "report_stats_command: found test_set = '%p'\n",
+ test_set);
+ fprintf(where,
+ "report_stats_command: max_count = %d min_count = %d\n",
+ max_count, min_count);
+ fflush(where);
+ }
if (test_set) {
+ if (debug) {
+ fprintf(where,
+ "report_stats_command: test_set = '%s'\n",
+ test_set->id);
+ fflush(where);
+ }
test_set->confidence.max_count = max_count;
test_set->confidence.min_count = min_count;
test_set->confidence.value = -100.0;
test_set->report_data = NULL;
+ test_set->debug = debug;
+ test_set->where = where;
/* The report function is responsible for the allocation and clean up
of any report_data structures that are required across the multiple
invocations that occur during the loop. */
@@ -1326,6 +1345,8 @@
while (cmd != NULL && rc == NPE_SUCCESS) {
if (debug) {
fprintf(where,"report_stats_command: calling process_command\n");
+ fprintf(where,"report_stats_command: name '%s' tid '%s'\n",
+ cmd->name, xmlGetProp(cmd,(const xmlChar *)"tid"));
fflush(where);
}
rc = process_command(cmd);
@@ -1627,6 +1648,7 @@
}
set_elt = set_elt->next;
}
+ xmlSetProp(cmd,(const xmlChar *)"tid", test_set->id);
} else {
test = find_test_in_hash(tid);
if (test) {
Modified: trunk/src/netperf.h
===================================================================
--- trunk/src/netperf.h 2005-11-14 22:43:30 UTC (rev 17)
+++ trunk/src/netperf.h 2005-11-17 04:17:04 UTC (rev 18)
@@ -268,6 +268,11 @@
int num_tests; /* the number of tests linked into
this test set */
+ uint32_t debug; /* should the report generation routine
+ produce debug output */
+
+ FILE *where; /* where that debug output should go */
+
void *report_data; /* data buffer to hold report generation
specific data between invocations of
the same report generation routine */
Modified: trunk/src/nettest_bsd.c
===================================================================
--- trunk/src/nettest_bsd.c 2005-11-14 22:43:30 UTC (rev 17)
+++ trunk/src/nettest_bsd.c 2005-11-17 04:17:04 UTC (rev 18)
@@ -67,10 +67,13 @@
/* */
/* send_tcp_stream() perform a tcp stream test */
/* recv_tcp_stream() catch a tcp stream test */
+/* send_tcp_rr() perform a tcp req/rsp test */
+/* recv_tcp_rr() catch a tcp req/rsp test */
/* */
/****************************************************************/
+
#include <stdio.h>
#include <values.h>
#include <unistd.h>
@@ -133,6 +136,144 @@
}
static void
+set_test_state(test_t *test, uint32_t new_state)
+{
+ int curr_state;
+ int state;
+ int valid = 0;
+ char *state_name;
+ char error_msg[1024];
+
+ curr_state = GET_TEST_STATE;
+
+ if (curr_state != TEST_ERROR) {
+ if (curr_state != new_state) {
+ switch (curr_state) {
+ case TEST_PREINIT:
+ state = TEST_INIT;
+ valid = 1;
+ break;
+ case TEST_INIT:
+ state_name = "TEST_INIT";
+ if (new_state == TEST_IDLE) {
+ state = TEST_IDLE;
+ valid = 1;
+ }
+ break;
+ case TEST_IDLE:
+ state_name = "TEST_IDLE";
+ if (new_state == TEST_LOADED) {
+ state = TEST_LOADED;
+ valid = 1;
+ }
+ if (new_state == TEST_DEAD) {
+ state = TEST_DEAD;
+ valid = 1;
+ }
+ break;
+ case TEST_LOADED:
+ state_name = "TEST_LOADED";
+ if (new_state == TEST_MEASURE) {
+ state = TEST_MEASURE;
+ valid = 1;
+ }
+ if (new_state == TEST_IDLE) {
+ state = TEST_IDLE;
+ valid = 1;
+ }
+ break;
+ case TEST_MEASURE:
+ state_name = "TEST_MEASURE";
+ if (new_state == TEST_LOADED) {
+ state = TEST_LOADED;
+ valid = 1;
+ }
+ break;
+ case TEST_ERROR:
+ /* an error occured while processing in the current state
+ return and we should drop into wait_to_die so that
+ netperf4 can retrieve the error information before killing
+ the test */
+ state_name = "TEST_ERROR";
+ break;
+ default:
+ state_name = "ILLEGAL";
+ }
+ if (valid) {
+ test->new_state = state;
+ } else {
+ sprintf(error_msg,"bad state transition from %s state",state_name);
+ report_test_failure( test,
+ "set_test_state",
+ BSDE_REQUESTED_STATE_INVALID,
+ strdup(error_msg));
+ }
+ }
+ }
+}
+
+void
+wait_to_die(test_t *test)
+{
+ while (GET_TEST_STATE != TEST_DEAD) {
+ if (CHECK_REQ_STATE == TEST_DEAD) {
+ free(test->test_specific_data);
+ test->test_specific_data = NULL;
+ test->new_state = TEST_DEAD;
+ }
+ }
+}
+
+#ifdef OFF
+/* the following lines are a template for any test
+ just copy the 37 lines for generic_test change
+ the procedure name and write you own TEST_SPECIFC_XXX
+ functions. Have Fun sgb 2005-10-26 */
+
+void
+generic_test(test_t *test)
+{
+ uint32_t state, new_state;
+ TEST_SPECIFIC_INITIALIZE(test);
+ state = GET_TEST_STATE;
+ while ((state != TEST_ERROR) &&
+ (state != TEST_DEAD )) {
+ switch(state) {
+ case TEST_PREINIT:
+ TEST_SPECIFIC_PREINIT(test);
+ new_state = TEST_INIT;
+ break;
+ case TEST_INIT:
+ new_state = CHECK_REQ_STATE;
+ if (new_state == TEST_IDLE) {
+ new_state = TEST_SPECIFIC_INIT(test);
+ }
+ break;
+ case TEST_IDLE:
+ new_state = CHECK_REQ_STATE;
+ if (new_state == TEST_IDLE) {
+ sleep(1);
+ }
+ break;
+ case TEST_MEASURE:
+ new_state = TEST_SPECIFIC_MEASURE(test);
+ break;
+ case TEST_LOADED:
+ new_state = TEST_SPECIFIC_LOAD(test);
+ break;
+ default:
+ break;
+ } /* end of switch */
+ set_test_state(test, new_state);
+ state = GET_TEST_STATE;
+ } /* end of while */
+ wait_to_die(test);
+}
+
+#endif /* OFF end of generic_test example code sgb 2005-10-26 */
+
+
+static void
dump_addrinfo(FILE *dumploc, struct addrinfo *info,
xmlChar *host, xmlChar *port, int family)
{
@@ -147,7 +288,7 @@
fprintf(dumploc,
"\tcannonical name: '%s'\n",temp->ai_canonname);
fprintf(dumploc,
- "\tflags: % family: %d: socktype: %d protocol %d addrlen %d\n",
+ "\tflags: %d family: %d: socktype: %d protocol %d addrlen %d\n",
temp->ai_flags,
temp->ai_family,
temp->ai_socktype,
@@ -423,7 +564,6 @@
int type = my_data->locaddr->ai_socktype;
int lss_size = my_data->send_buf_size;
int lsr_size = my_data->recv_buf_size;
- int loc_nodelay = my_data->no_delay;
int loc_sndavoid = my_data->send_avoid;
int loc_rcvavoid = my_data->recv_avoid;
@@ -431,6 +571,12 @@
int one;
int sock_opt_len;
+ if (test->debug) {
+ fprintf(test->where,
+ "create_data_socket: calling socket family = %d type = %d\n",
+ family, type);
+ fflush(test->where);
+ }
/*set up the data socket */
temp_socket = socket(family,
type,
@@ -445,7 +591,9 @@
}
if (test->debug) {
- fprintf(test->where,"create_data_socket: socket %d obtained...\n",temp_socket);
+ fprintf(test->where,
+ "create_data_socket: socket %d obtained...\n",
+ temp_socket);
fflush(test->where);
}
@@ -588,7 +736,7 @@
/* will cause an error to be displayed */
#ifdef TCP_NODELAY
- if (loc_nodelay) {
+ if (my_data->no_delay) {
one = 1;
if(setsockopt(temp_socket,
getprotobyname("tcp")->p_proto,
@@ -609,7 +757,7 @@
}
#else /* TCP_NODELAY */
- loc_nodelay = 0;
+ my_data->no_delay = 0;
#endif /* TCP_NODELAY */
@@ -618,15 +766,7 @@
}
-
-void
-bsd_test_free(test_t *test)
-{
- free(test->test_specific_data);
- test->test_specific_data = NULL;
-}
-
bsd_data_t *
bsd_test_init(test_t *test, int type, int protocol)
{
@@ -637,7 +777,6 @@
xmlChar *localhost;
xmlChar *localport;
int localfam;
- FILE *fill_source;
int count;
int error;
@@ -659,7 +798,7 @@
}
break;
}
-
+
/* probably a good idea to make sure that new_data is real */
if ((args != NULL) &&
(NULL != new_data)) {
@@ -667,11 +806,9 @@
memset(new_data,0,sizeof(bsd_data_t));
string = xmlGetProp(args,(const xmlChar *)"fill_file");
- /* fopen the fill file it will be used when allocating buffer
- rings. only call fopen if there is really a "fill_file"
- property present... */
+ /* fopen the fill file it will be used when allocating buffer rings */
if (string) {
- fill_source = fopen((char *)string,"r");
+ new_data->fill_source = fopen((char *)string,"r");
}
/* we are relying on the good graces of the validating and
@@ -704,25 +841,22 @@
string = xmlGetProp(args,(const xmlChar *)"port_min");
if (string) {
new_data->port_min = atoi((char *)string);
- }
- else {
+ } else {
new_data->port_min = -1;
}
string = xmlGetProp(args,(const xmlChar *)"port_max");
if (string) {
new_data->port_max = atoi((char *)string);
- }
- else {
+ } else {
new_data->port_max = -1;
}
-
+
string = xmlGetProp(args,(const xmlChar *)"send_width");
new_data->send_width = atoi((char *)string);
if (new_data->send_width == 0) {
new_data->send_width = new_data->send_buf_size/new_data->send_size + 1;
if (new_data->send_width == 1) new_data->send_width = 2;
-
}
string = xmlGetProp(args,(const xmlChar *)"recv_width");
@@ -757,7 +891,6 @@
localport = xmlGetProp(args,(const xmlChar *)"local_service"),
count = 0;
do {
-
error = getaddrinfo( (char *)localhost, (char *)localport,
&hints, &local_ai);
count += 1;
@@ -835,11 +968,10 @@
void
bsd_test_decode_stats(xmlNodePtr stats,test_t *test)
{
- xmlChar *value;
- xmlChar *name;
-
- if (stats && test) {
- name = NULL;
+ if (test->debug) {
+ fprintf(test->where,"bsd_test_decode_stats: entered for %s test %s\n",
+ test->id, test->test_name);
+ fflush(test->where);
}
}
@@ -923,7 +1055,7 @@
}
if (ap == NULL) {
xmlFreeNode(stats);
- stats == NULL;
+ stats = NULL;
}
}
if (test->debug) {
@@ -932,13 +1064,470 @@
fflush(test->where);
}
return(stats);
+} /* end of bsd_test_get_stats */
+
+
+static void
+recv_tcp_stream_preinit(test_t *test)
+{
+ int rc;
+ int s_listen;
+ bsd_data_t *my_data;
+ char *proc_name;
+ struct sockaddr myaddr;
+ int mylen;
+
+ my_data = test->test_specific_data;
+ proc_name = "recv_tcp_stream_preinit";
+ mylen = sizeof(myaddr);
+
+ my_data->recv_ring = allocate_buffer_ring(my_data->recv_width,
+ my_data->recv_size,
+ my_data->recv_align,
+ my_data->recv_offset,
+ my_data->fill_source);
+ s_listen = create_data_socket(test);
+ my_data->s_listen = s_listen;
+ if (test->debug) {
+ dump_addrinfo(test->where, my_data->locaddr,
+ (xmlChar *)NULL, (xmlChar *)NULL, -1);
+ fprintf(test->where,
+ "%s:create_data_socket returned %d\n",
+ proc_name, s_listen);
+ fflush(test->where);
+ }
+ rc = bind(s_listen, my_data->locaddr->ai_addr, my_data->locaddr->ai_addrlen);
+ if (test->debug) {
+ fprintf(test->where,
+ "%s:bind returned %d errno=%d\n",
+ proc_name, rc, errno);
+ fflush(test->where);
+ }
+ if (rc == -1) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_BIND_FAILED,
+ "data socket bind failed");
+ } else if (listen(s_listen,5) == -1) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_LISTEN_FAILED,
+ "data socket listen failed");
+ } else if (getsockname(s_listen,&myaddr,&mylen) == -1) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_GETSOCKNAME_FAILED,
+ "getting the listen socket name failed");
+ } else {
+ memcpy(my_data->locaddr->ai_addr,&myaddr,mylen);
+ my_data->locaddr->ai_addrlen = mylen;
+ set_dependent_data(test);
+ }
}
+static uint32_t
+recv_tcp_stream_init(test_t *test)
+{
+ int s_data;
+ bsd_data_t *my_data;
+ char *proc_name;
+ struct sockaddr peeraddr;
+ int peerlen;
+
+ my_data = test->test_specific_data;
+ proc_name = "recv_tcp_stream_preinit";
+ peerlen = sizeof(peeraddr);
+
+ if (test->debug) {
+ fprintf(test->where, "%s:waiting in accept\n", proc_name);
+ fflush(test->where);
+ }
+ if ((s_data = accept(my_data->s_listen,
+ &peeraddr,
+ &peerlen)) == -1) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_ACCEPT_FAILED,
+ "listen socket accept failed");
+ } else {
+ if (test->debug) {
+ fprintf(test->where,
+ "%s:accept returned successfully %d\n",
+ proc_name, s_data);
+ fflush(test->where);
+ }
+ my_data->s_data = s_data;
+ }
+ return(TEST_IDLE);
+}
+
+static void
+recv_tcp_stream_idle_link(test_t *test, int last_len)
+{
+ uint32_t new_state;
+ bsd_data_t *my_data;
+ char *proc_name;
+ struct sockaddr peeraddr;
+ int peerlen;
+ int len;
+
+ my_data = test->test_specific_data;
+ proc_name = "recv_tcp_stream_idle_link";
+ peerlen = sizeof(peeraddr);
+ len = last_len;
+
+ while (len > 0) {
+ if ((len=recv(my_data->s_data,
+ my_data->recv_ring->buffer_ptr,
+ my_data->recv_size,
+ 0)) != 0) {
+ /* this macro hides windows differences */
+ if (CHECK_FOR_RECV_ERROR(len)) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_DATA_RECV_ERROR,
+ "data_recv_error");
+ }
+ }
+ }
+
+ new_state = CHECK_REQ_STATE;
+ if (test->debug) {
+ fprintf(test->where,"**** %s:new_state = %d\n",proc_name,new_state);
+ fflush(test->where);
+ }
+ while (new_state == TEST_LOADED) {
+ sleep(1);
+ new_state = CHECK_REQ_STATE;
+ }
+ if (test->debug) {
+ fprintf(test->where,"**** %s:new_state = %d\n",proc_name,new_state);
+ fflush(test->where);
+ }
+ if (new_state == TEST_IDLE) {
+ if (shutdown(my_data->s_data,SHUT_WR) == -1) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_SOCKET_SHUTDOWN_FAILED,
+ "failure shuting down data socket");
+ } else {
+ close(my_data->s_data);
+ if (test->debug) {
+ fprintf(test->where,"%s: waiting in accept\n",proc_name);
+ fflush(test->where);
+ }
+ if ((my_data->s_data=accept(my_data->s_listen,
+ &peeraddr,
+ &peerlen)) == -1) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_ACCEPT_FAILED,
+ "listen socket accept failed");
+ } else {
+ if (test->debug) {
+ fprintf(test->where,
+ "%s: accept returned successfully %d\n",
+ proc_name,
+ my_data->s_data);
+ fflush(test->where);
+ }
+ }
+ }
+ } else {
+ /* a transition to a state other than TEST_IDLE was requested
+ after the link was closed in the TEST_LOADED state */
+ report_test_failure(test,
+ proc_name,
+ BSDE_DATA_CONNECTION_CLOSED_ERROR,
+ "data connection closed and non idle state requested");
+
+ }
+}
+
+static uint32_t
+recv_tcp_stream_meas(test_t *test)
+{
+ int len;
+ uint32_t new_state;
+ bsd_data_t *my_data;
+ char *proc_name;
+ my_data = test->test_specific_data;
+ proc_name = "recv_tcp_stream_meas";
+ HISTOGRAM_VARS;
+ /* code to make data dirty macro enabled by DIRTY */
+ MAKE_DIRTY(my_data, my_data->recv_ring);
+ /* code to timestamp enabled by HISTOGRAM */
+ HIST_TIMESTAMP(&time_one);
+ /* recv data for the test */
+ if ((len=recv(my_data->s_data,
+ my_data->recv_ring->buffer_ptr,
+ my_data->recv_size,
+ 0)) != 0) {
+ /* this macro hides windows differences */
+ if (CHECK_FOR_RECV_ERROR(len)) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_DATA_RECV_ERROR,
+ "data_recv_error");
+ } else {
+ my_data->stats.named.bytes_received += len;
+ my_data->stats.named.recv_calls++;
+ my_data->recv_ring = my_data->recv_ring->next;
+ }
+ } else {
+ /* how do we deal with a closed connection in the loaded state */
+ report_test_failure(test,
+ proc_name,
+ BSDE_DATA_CONNECTION_CLOSED_ERROR,
+ "data connection closed during TEST_MEASURE state");
+ }
+ /* code to timestamp enabled by HISTOGRAM */
+ HIST_TIMESTAMP(&time_two);
+ HIST_ADD(my_data->time_hist,delta_macro(&time_one,&time_two));
+ new_state = CHECK_REQ_STATE;
+ if (new_state == TEST_LOADED) {
+ /* transitioning to loaded state from measure state
+ set current timestamp and update elapsed time */
+ gettimeofday(&(my_data->curr_time), NULL);
+ update_elapsed_time(my_data);
+ }
+ return(new_state);
+}
+
+static uint32_t
+recv_tcp_stream_load(test_t *test)
+{
+ int len;
+ uint32_t new_state;
+ bsd_data_t *my_data;
+ char *proc_name;
+
+ my_data = test->test_specific_data;
+ proc_name = "recv_tcp_stream_load";
+
+ /* code to make data dirty macro enabled by DIRTY */
+ MAKE_DIRTY(my_data, my_data->recv_ring);
+ /* recv data for the test */
+ if ((len=recv(my_data->s_data,
+ my_data->recv_ring->buffer_ptr,
+ my_data->recv_size,
+ 0)) != 0) {
+ /* this macro hides windows differences */
+ if (CHECK_FOR_RECV_ERROR(len)) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_DATA_RECV_ERROR,
+ "data_recv_error");
+ } else {
+ my_data->recv_ring = my_data->recv_ring->next;
+ }
+ }
+ /* check for state transition */
+ new_state = CHECK_REQ_STATE;
+ if ((len == 0) ||
+ (new_state == TEST_IDLE)) {
+ /* just got a data connection close or
+ a request to transition to the idle state */
+ recv_tcp_stream_idle_link(test,len);
+ new_state = TEST_IDLE;
+ } else {
+ if (new_state == TEST_MEASURE) {
+ /* transitioning to measure state from loaded state
+ set previous timestamp */
+ gettimeofday(&(my_data->prev_time), NULL);
+ }
+ }
+ return(new_state);
+}
+
+
+static void
+send_tcp_stream_preinit(test_t *test)
+{
+ bsd_data_t *my_data;
+
+ my_data = test->test_specific_data;
+
+ if (my_data->s_data == 0) {
+ my_data->send_ring = allocate_buffer_ring(my_data->send_width,
+ my_data->send_size,
+ my_data->send_align,
+ my_data->send_offset,
+ my_data->fill_source);
+ get_dependency_data(test, SOCK_STREAM, IPPROTO_TCP);
+ my_data->s_data = create_data_socket(test);
+ } else {
+ fprintf(test->where,"entered send_tcp_stream_preinit more than once\n");
+ fflush(test->where);
+ }
+}
+
+static uint32_t
+send_tcp_stream_init(test_t *test)
+{
+ bsd_data_t *my_data;
+ char *proc_name;
+
+ my_data = test->test_specific_data;
+ proc_name = "send_tcp_stream_init";
+
+ if (test->debug) {
+ fprintf(test->where,"%s: in INIT state making connect call\n",proc_name);
+ fflush(test->where);
+ }
+ if (connect(my_data->s_data,
+ my_data->remaddr->ai_addr,
+ my_data->remaddr->ai_addrlen) < 0) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_CONNECT_FAILED,
+ "data socket connect failed");
+ } else {
+ if (test->debug) {
+ fprintf(test->where,"%s: connected and moving to IDLE\n",proc_name);
+ fflush(test->where);
+ }
+ }
+ return(TEST_IDLE);
+}
+
+static void
+send_tcp_stream_idle_link(test_t *test)
+{
+ int len;
+ uint32_t new_state;
+ bsd_data_t *my_data;
+ char *proc_name;
+
+ my_data = test->test_specific_data;
+ proc_name = "send_tcp_stream_idle_link";
+
+ if (test->debug) {
+ fprintf(test->where,"%s: transition from LOAD to IDLE\n",proc_name);
+ fflush(test->where);
+ }
+ if (shutdown(my_data->s_data,SHUT_WR) == -1) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_SOCKET_SHUTDOWN_FAILED,
+ "failure shuting down data socket");
+ } else {
+ recv(my_data->s_data,
+ my_data->send_ring->buffer_ptr,
+ my_data->send_size, 0);
+ close(my_data->s_data);
+ my_data->s_data = create_data_socket(test);
+ if (test->debug) {
+ fprintf(test->where,"%s: connecting from LOAD state\n",proc_name);
+ fflush(test->where);
+ }
+ if (connect(my_data->s_data,
+ my_data->remaddr->ai_addr,
+ my_data->remaddr->ai_addrlen) < 0) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_CONNECT_FAILED,
+ "data socket connect failed");
+ } else {
+ if (test->debug) {
+ fprintf(test->where,"%s: connected moving to IDLE\n", proc_name);
+ fflush(test->where);
+ }
+ }
+ }
+}
+
+static uint32_t
+send_tcp_stream_meas(test_t *test)
+{
+ int len;
+ uint32_t new_state;
+ bsd_data_t *my_data;
+ char *proc_name;
+
+ my_data = test->test_specific_data;
+ proc_name = "send_tcp_stream_meas";
+ HISTOGRAM_VARS;
+ /* code to make data dirty macro enabled by DIRTY */
+ MAKE_DIRTY(my_data,my_data->send_ring);
+ /* code to timestamp enabled by HISTOGRAM */
+ HIST_TIMESTAMP(&time_one);
+ /* send data for the test */
+ if((len=send(my_data->s_data,
+ my_data->send_ring->buffer_ptr,
+ my_data->send_size,
+ 0)) != my_data->send_size) {
+ /* this macro hides windows differences */
+ if (CHECK_FOR_SEND_ERROR(len)) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_DATA_SEND_ERROR,
+ "data send error");
+ }
+ }
+ my_data->stats.named.bytes_sent += len;
+ my_data->stats.named.send_calls++;
+ my_data->send_ring = my_data->send_ring->next;
+ /* code to timestamp enabled by HISTOGRAM */
+ HIST_TIMESTAMP(&time_two);
+ HIST_ADD(my_data->time_hist,delta_macro(&time_one,&time_two));
+ new_state = CHECK_REQ_STATE;
+ if (new_state == TEST_LOADED) {
+ /* transitioning to loaded state from measure state
+ set current timestamp and update elapsed time */
+ gettimeofday(&(my_data->curr_time), NULL);
+ update_elapsed_time(my_data);
+ }
+ return(new_state);
+}
+
+static uint32_t
+send_tcp_stream_load(test_t *test)
+{
+ int len;
+ uint32_t new_state;
+ bsd_data_t *my_data;
+ char *proc_name;
+
+ my_data = test->test_specific_data;
+ proc_name = "send_tcp_stream_load";
+
+ HISTOGRAM_VARS;
+ /* code to make data dirty macro enabled by DIRTY */
+ MAKE_DIRTY(my_data,my_data->send_ring);
+ /* code to timestamp enabled by HISTOGRAM */
+ HIST_TIMESTAMP(&time_one);
+ /* send data for the test */
+ if((len=send(my_data->s_data,
+ my_data->send_ring->buffer_ptr,
+ my_data->send_size,
+ 0)) != my_data->send_size) {
+ /* this macro hides windows differences */
+ if (CHECK_FOR_SEND_ERROR(len)) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_DATA_SEND_ERROR,
+ "data send_error");
+ }
+ }
+ my_data->send_ring = my_data->send_ring->next;
+ /* check for state transition */
+ new_state = CHECK_REQ_STATE;
+ if (new_state == TEST_MEASURE) {
+ /* transitioning to measure state from loaded state
+ set previous timestamp */
+ gettimeofday(&(my_data->prev_time), NULL);
+ }
+ if (new_state == TEST_IDLE) {
+ send_tcp_stream_idle_link(test);
+ }
+ return(new_state);
+}
+
int
recv_tcp_stream_clear_stats(test_t *test)
{
- bsd_data_t *my_data = GET_TEST_DATA(test);
- return(bsd_test_clear_stats(my_data));
+ return(bsd_test_clear_stats(GET_TEST_DATA(test)));
}
@@ -958,8 +1547,7 @@
int
send_tcp_stream_clear_stats(test_t *test)
{
- bsd_data_t *my_data = GET_TEST_DATA(test);
- return(bsd_test_clear_stats(my_data));
+ return(bsd_test_clear_stats(GET_TEST_DATA(test)));
}
xmlNodePtr
@@ -974,464 +1562,674 @@
bsd_test_decode_stats(stats,test);
}
-
+
/* This routine implements the server-side of the TCP unidirectional data */
/* transfer test (a.k.a. stream) for the sockets interface. It receives */
/* its parameters via the xml node contained in the test structure. */
/* results are collected by the procedure recv_tcp_stream_get_stats */
+
void
recv_tcp_stream(test_t *test)
{
- bsd_data_t *my_data;
- ring_elt_ptr recv_ring;
- int s_listen;
- int s_data;
- int recv_size;
- int len;
- int rc;
- int firsttime = 1;
- struct sockaddr myaddr;
- int mylen=sizeof(myaddr);
- struct sockaddr peeraddr;
- int peerlen=sizeof(peeraddr);
-
- HISTOGRAM_VARS;
-
- /* create data socket s_listen */
- /* bind to get addressing information */
- /* need to pass in IP if multi-homed */
- /* listen for connection on s_listen */
- /* call getsockname to set the port */
- /* report dependency data IP, port & family */
- /* accept connection */
-
- my_data = bsd_test_init(test, SOCK_STREAM, IPPROTO_TCP);
-
- my_data->recv_ring = allocate_buffer_ring(my_data->recv_width,
- my_data->recv_size,
- my_data->recv_align,
- my_data->recv_offset,
- my_data->fill_source);
-
- s_listen = create_data_socket(test);
-
-
- while ((GET_TEST_STATE != TEST_ERROR) &&
- (GET_TEST_STATE != TEST_DEAD)) {
- switch (GET_TEST_STATE) {
+ uint32_t state, new_state;
+ bsd_test_init(test, SOCK_STREAM, IPPROTO_TCP);
+ state = GET_TEST_STATE;
+ while ((state != TEST_ERROR) &&
+ (state != TEST_DEAD )) {
+ switch(state) {
case TEST_PREINIT:
- if (firsttime) {
- firsttime = 0;
- recv_ring = my_data->recv_ring;
- recv_size = my_data->recv_size;
- if (test->debug) {
- dump_addrinfo(test->where, my_data->locaddr,
- (xmlChar *)NULL, (xmlChar *)NULL, -1);
- }
- if (test->debug) {
- fprintf(test->where,"recv_tcp_stream:create_data_socket returned %d\n",
- s_listen);
- fflush(test->where);
- }
- rc = bind(s_listen, my_data->locaddr->ai_addr,
- my_data->locaddr->ai_addrlen);
- if (test->debug) {
- fprintf(test->where,"recv_tcp_stream:bind returned %d errno=%d\n",
- rc,errno);
- fflush(test->where);
- }
- if (len == -1) {
- report_test_failure(test,
- "recv_tcp_stream",
- BSDE_BIND_FAILED,
- "data socket bind failed");
- } else if (listen(s_listen,5) == -1) {
- report_test_failure(test,
- "recv_tcp_stream",
- BSDE_LISTEN_FAILED,
- "data socket listen failed");
- } else if (getsockname(s_listen,
- &myaddr,
- &mylen) == -1) {
- report_test_failure(test,
- "recv_tcp_stream",
- BSDE_GETSOCKNAME_FAILED,
- "getting the listen socket name failed");
- } else {
- memcpy(my_data->locaddr->ai_addr,&myaddr,mylen);
- my_data->locaddr->ai_addrlen = mylen;
- set_dependent_data(test);
- SET_TEST_STATE(TEST_INIT);
- }
- } else {
- report_test_failure(test,
- "recv_tcp_stream",
- BSDE_TEST_STATE_CORRUPTED,
- "test found in ILLEGAL TEST_PREINIT state");
- }
+ recv_tcp_stream_preinit(test);
+ new_state = TEST_INIT;
break;
case TEST_INIT:
- if (CHECK_REQ_STATE == TEST_IDLE) {
- peerlen = sizeof(peeraddr);
- if (test->debug) {
- fprintf(test->where,"recv_tcp_stream:waiting in accept\n");
- fflush(test->where);
- }
- if ((s_data=accept(s_listen,
- &peeraddr,
- &peerlen)) == -1) {
- report_test_failure(test,
- "recv_tcp_stream",
- BSDE_ACCEPT_FAILED,
- "listen socket accept failed");
- } else {
- if (test->debug) {
- fprintf(test->where,"recv_tcp_stream:accept returned successfully %d\n",
- s_data);
- fflush(test->where);
- }
- SET_TEST_STATE(TEST_IDLE);
- }
- } else {
- report_test_failure(test,
- "recv_tcp_stream",
- BSDE_REQUESTED_STATE_INVALID,
- "bad state requested for TEST_INIT state");
+ new_state = CHECK_REQ_STATE;
+ if (new_state == TEST_IDLE) {
+ new_state = recv_tcp_stream_init(test);
}
break;
case TEST_IDLE:
- /* check for state transition */
- if (CHECK_REQ_STATE == TEST_IDLE) {
+ new_state = CHECK_REQ_STATE;
+ if (new_state == TEST_IDLE) {
sleep(1);
- } else if (CHECK_REQ_STATE == TEST_LOADED) {
- SET_TEST_STATE(TEST_LOADED);
- } else if (CHECK_REQ_STATE == TEST_DEAD) {
- SET_TEST_STATE(TEST_DEAD);
- } else {
- report_test_failure(test,
- "recv_tcp_stream",
- BSDE_REQUESTED_STATE_INVALID,
- "in IDLE requested to go to illegal state");
}
break;
case TEST_MEASURE:
- my_data->stats.named.bytes_received += len;
- my_data->stats.named.recv_calls++;
- /* check for state transition */
- if (CHECK_REQ_STATE != TEST_MEASURE) {
- if (CHECK_REQ_STATE == TEST_LOADED) {
- /* transitioning to loaded state from measure state
- set current timestamp and update elapsed time */
- gettimeofday(&(my_data->curr_time), NULL);
- update_elapsed_time(my_data);
- SET_TEST_STATE(TEST_LOADED);
- } else {
- report_test_failure(test,
- "recv_tcp_stream",
- BSDE_REQUESTED_STATE_INVALID,
- "in MEASURE requested to go to illegal state");
- }
- }
+ new_state = recv_tcp_stream_meas(test);
+ break;
case TEST_LOADED:
- /* code to make data dirty macro enabled by DIRTY */
- MAKE_DIRTY(my_data,recv_ring);
- /* code to timestamp enabled by HISTOGRAM */
- HIST_TIMESTAMP(&time_one);
- /* recv data for the test */
- if ((len=recv(s_data,
- recv_ring->buffer_ptr,
- recv_size,
- 0)) != 0) {
- /* this macro hides windows differences */
- if (CHECK_FOR_RECV_ERROR(len)) {
- report_test_failure(test,
- "recv_tcp_stream",
- BSDE_DATA_RECV_ERROR,
- "data_recv_error");
- }
- } else {
- /* how do we deal with a closed connection in the loaded state */
- fprintf(test->where,"\nWE JUST GOT A CLOSE INDICATION !!!!!!!!!!!!!!!!\n\n");
- fflush(test->where);
- }
- /* code to timestamp enabled by HISTOGRAM */
- HIST_TIMESTAMP(&time_two);
- HIST_ADD(my_data->time_hist,delta_macro(&time_one,&time_two));
- recv_ring = recv_ring->next;
- /* check for state transition */
- if ((GET_TEST_STATE == TEST_LOADED) &&
- (CHECK_REQ_STATE != TEST_LOADED)) {
- if (CHECK_REQ_STATE == TEST_MEASURE) {
- SET_TEST_STATE(TEST_MEASURE);
- /* transitioning to measure state from loaded state
- set previous timestamp */
- gettimeofday(&(my_data->prev_time), NULL);
- } else if (CHECK_REQ_STATE == TEST_IDLE) {
- if (shutdown(s_data,1) == -1) {
- report_test_failure(test,
- "recv_tcp_stream",
- BSDE_SOCKET_SHUTDOWN_FAILED,
- "failure shuting down data socket");
- } else {
- close(s_data);
- peerlen = sizeof(peeraddr);
- if (test->debug) {
- fprintf(test->where,"recv_tcp_stream:waiting in accept\n");
- fflush(test->where);
- }
- if ((s_data=accept(s_listen,
- &peeraddr,
- &peerlen)) == -1) {
- report_test_failure(test,
- "recv_tcp_stream",
- BSDE_ACCEPT_FAILED,
- "listen socket accept failed");
- } else {
- if (test->debug) {
- fprintf(test->where,
- "recv_tcp_stream:accept returned successfully %d\n",
- s_data);
- fflush(test->where);
- }
- SET_TEST_STATE(TEST_IDLE);
- }
- }
- } else {
- report_test_failure(test,
- "recv_tcp_stream",
- BSDE_REQUESTED_STATE_INVALID,
- "in LOADED requested to go to illegal state");
- }
- }
+ new_state = recv_tcp_stream_load(test);
break;
default:
- report_test_failure(test,
- "recv_tcp_stream",
- BSDE_TEST_STATE_CORRUPTED,
- "test found in ILLEGAL state");
- } /* end of switch in while loop */
- } /* end of while for test */
+ break;
+ } /* end of switch */
+ set_test_state(test, new_state);
+ state = GET_TEST_STATE;
+ } /* end of while */
+ wait_to_die(test);
+} /* end of recv_tcp_stream */
- /* perform a shutdown to signal the sender that */
- /* we have received all the data sent. raj 4/93 */
- shutdown(s_data,1);
-
- close(s_listen);
- close(s_data);
-
- while (GET_TEST_STATE != TEST_DEAD) {
- if (CHECK_REQ_STATE == TEST_DEAD) {
- bsd_test_free(test);
- SET_TEST_STATE(TEST_DEAD);
- }
- }
-}
-
-
+
/* This routine implements the TCP unidirectional data transfer test */
/* (a.k.a. stream) for the sockets interface. It receives its */
/* parameters via the xml node contained in the test structure */
/* output to the standard output. */
/* results are collected by the procedure send_tcp_stream_get_stats */
+
void
send_tcp_stream(test_t *test)
{
- bsd_data_t *my_data;
- ring_elt_ptr send_ring;
- int send_socket;
- int len;
- int send_size;
- int firsttime = 1;
+ uint32_t state, new_state;
+ bsd_test_init(test, SOCK_STREAM, IPPROTO_TCP);
+ state = GET_TEST_STATE;
+ while ((state != TEST_ERROR) &&
+ (state != TEST_DEAD )) {
+ switch(state) {
+ case TEST_PREINIT:
+ send_tcp_stream_preinit(test);
+ new_state = TEST_INIT;
+ break;
+ case TEST_INIT:
+ new_state = CHECK_REQ_STATE;
+ if (new_state == TEST_IDLE) {
+ new_state = send_tcp_stream_init(test);
+ }
+ break;
+ case TEST_IDLE:
+ new_state = CHECK_REQ_STATE;
+ if (new_state == TEST_IDLE) {
+ sleep(1);
+ }
+ break;
+ case TEST_MEASURE:
+ new_state = send_tcp_stream_meas(test);
+ break;
+ case TEST_LOADED:
+ new_state = send_tcp_stream_load(test);
+ break;
+ default:
+ break;
+ } /* end of switch */
+ set_test_state(test, new_state);
+ state = GET_TEST_STATE;
+ } /* end of while */
+ wait_to_die(test);
+} /* end of send_tcp_stream */
+
- HISTOGRAM_VARS;
+static void
+recv_tcp_rr_preinit(test_t *test)
+{
+ int rc;
+ int s_listen;
+ bsd_data_t *my_data;
+ char *proc_name;
+ struct sockaddr myaddr;
+ int mylen;
- /* setup server with remote ip address and family*/
- /* create_data_socket AF_INET,SOCK_STREAM */
- /* connect using created data socket and server structure for remote */
+ my_data = test->test_specific_data;
+ proc_name = "recv_tcp_rr_preinit";
+ mylen = sizeof(myaddr);
- my_data = bsd_test_init(test, SOCK_STREAM, IPPROTO_TCP);
-
+ my_data->recv_ring = allocate_buffer_ring(my_data->recv_width,
+ my_data->req_size,
+ my_data->recv_align,
+ my_data->recv_offset,
+ my_data->fill_source);
my_data->send_ring = allocate_buffer_ring(my_data->send_width,
- my_data->send_size,
+ my_data->rsp_size,
my_data->send_align,
my_data->send_offset,
my_data->fill_source);
+ s_listen = create_data_socket(test);
+ my_data->s_listen = s_listen;
+ if (test->debug) {
+ dump_addrinfo(test->where, my_data->locaddr,
+ (xmlChar *)NULL, (xmlChar *)NULL, -1);
+ fprintf(test->where,
+ "%s:create_data_socket returned %d\n",
+ proc_name, s_listen);
+ fflush(test->where);
+ }
+ rc = bind(s_listen, my_data->locaddr->ai_addr, my_data->locaddr->ai_addrlen);
+ if (test->debug) {
+ fprintf(test->where,
+ "%s:bind returned %d errno=%d\n",
+ proc_name, rc, errno);
+ fflush(test->where);
+ }
+ if (rc == -1) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_BIND_FAILED,
+ "data socket bind failed");
+ } else if (listen(s_listen,5) == -1) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_LISTEN_FAILED,
+ "data socket listen failed");
+ } else if (getsockname(s_listen,&myaddr,&mylen) == -1) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_GETSOCKNAME_FAILED,
+ "getting the listen socket name failed");
+ } else {
+ memcpy(my_data->locaddr->ai_addr,&myaddr,mylen);
+ my_data->locaddr->ai_addrlen = mylen;
+ set_dependent_data(test);
+ }
+}
- get_dependency_data(test, SOCK_STREAM, IPPROTO_TCP);
- send_socket = create_data_socket(test);
-
- while ((GET_TEST_STATE != TEST_ERROR) &&
- (GET_TEST_STATE != TEST_DEAD)) {
- switch (GET_TEST_STATE) {
- case TEST_PREINIT:
- if (firsttime) {
- firsttime = 0;
- send_ring = my_data->send_ring;
- send_size = my_data->send_size;
- SET_TEST_STATE(TEST_INIT);
+static uint32_t
+recv_tcp_rr_init(test_t *test)
+{
+ int s_data;
+ bsd_data_t *my_data;
+ char *proc_name;
+ struct sockaddr peeraddr;
+ int peerlen;
+
+ my_data = test->test_specific_data;
+ proc_name = "recv_tcp_stream_init";
+ peerlen = sizeof(peeraddr);
+
+ if (test->debug) {
+ fprintf(test->where, "%s:waiting in accept\n", proc_name);
+ fflush(test->where);
+ }
+ if ((s_data = accept(my_data->s_listen,
+ &peeraddr,
+ &peerlen)) == -1) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_ACCEPT_FAILED,
+ "listen socket accept failed");
+ } else {
+ if (test->debug) {
+ fprintf(test->where,
+ "%s:accept returned successfully %d\n",
+ proc_name, s_data);
+ fflush(test->where);
+ }
+ my_data->s_data = s_data;
+ }
+ return(TEST_IDLE);
+}
+
+static void
+recv_tcp_rr_idle_link(test_t *test, int last_len)
+{
+ int len;
+ uint32_t new_state;
+ bsd_data_t *my_data;
+ char *proc_name;
+ struct sockaddr peeraddr;
+ int peerlen;
+
+ my_data = test->test_specific_data;
+ proc_name = "recv_tcp_rr_idle_link";
+ len = last_len;
+ peerlen = sizeof(peeraddr);
+
+ new_state = CHECK_REQ_STATE;
+ while (new_state == TEST_LOADED) {
+ sleep(1);
+ new_state = CHECK_REQ_STATE;
+ }
+
+ if (new_state == TEST_IDLE) {
+ if (test->debug) {
+ fprintf(test->where,"%s: transition from LOAD to IDLE\n",proc_name);
+ fflush(test->where);
+ }
+ if (shutdown(my_data->s_data,SHUT_WR) == -1) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_SOCKET_SHUTDOWN_FAILED,
+ "data_recv_error");
+ } else {
+ while (len > 0) {
+ len=recv(my_data->s_data,
+ my_data->recv_ring->buffer_ptr,
+ my_data->req_size, 0);
+ }
+ close(my_data->s_data);
+ if (test->debug) {
+ fprintf(test->where,"%s: waiting in accept\n",proc_name);
+ fflush(test->where);
+ }
+ if ((my_data->s_data=accept(my_data->s_listen,
+ &peeraddr,
+ &peerlen)) == -1) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_ACCEPT_FAILED,
+ "listen socket accept failed");
} else {
- report_test_failure(test,
- "send_tcp_stream",
- BSDE_TEST_STATE_CORRUPTED,
- "test found in ILLEGAL TEST_PREINIT state");
- }
- break;
- case TEST_INIT:
- if (CHECK_REQ_STATE == TEST_IDLE) {
if (test->debug) {
- fprintf(test->where,"send_tcp_stream: in INIT state making connect call\n");
+ fprintf(test->where,
+ "%s: accept returned successfully %d\n",
+ proc_name,
+ my_data->s_data);
fflush(test->where);
}
- if (connect(send_socket,
- my_data->remaddr->ai_addr,
- my_data->remaddr->ai_addrlen) < 0) {
- report_test_failure(test,
- "send_tcp_stream",
- BSDE_CONNECT_FAILED,
- "data socket connect failed");
- } else {
- if (test->debug) {
- fprintf(test->where,"send_tcp_stream: connected and moving to IDLE\n");
- fflush(test->where);
- }
- SET_TEST_STATE(TEST_IDLE);
- }
- } else {
+ }
+ }
+ } else {
+ /* a transition to a state other than TEST_IDLE was requested
+ after the link was closed in the TEST_LOADED state */
+ report_test_failure(test,
+ proc_name,
+ BSDE_DATA_CONNECTION_CLOSED_ERROR,
+ "data connection closed and non idle state requested");
+ }
+}
+
+static uint32_t
+recv_tcp_rr_meas(test_t *test)
+{
+ int len;
+ int bytes_left;
+ char *req_ptr;
+ uint32_t new_state;
+ bsd_data_t *my_data;
+ char *proc_name;
+
+ HISTOGRAM_VARS;
+ my_data = test->test_specific_data;
+ proc_name = "recv_tcp_rr_meas";
+
+ /* code to timestamp enabled by HISTOGRAM */
+ HIST_TIMESTAMP(&time_one);
+ /* recv the request for the test */
+ req_ptr = my_data->recv_ring->buffer_ptr;
+ bytes_left = my_data->req_size;
+ while (bytes_left > 0) {
+ if ((len=recv(my_data->s_data,
+ req_ptr,
+ bytes_left,
+ 0)) != 0) {
+ /* this macro hides windows differences */
+ if (CHECK_FOR_RECV_ERROR(len)) {
report_test_failure(test,
- "send_tcp_stream",
- BSDE_REQUESTED_STATE_INVALID,
- "test found in TEST_INIT state");
+ proc_name,
+ BSDE_DATA_RECV_ERROR,
+ "data_recv_error");
+ break;
}
+ req_ptr += len;
+ bytes_left -= len;
+ } else {
+ /* just got a data connection close break out of while loop */
break;
- case TEST_IDLE:
- /* check for state transition */
- if (CHECK_REQ_STATE == TEST_IDLE) {
- sleep(1);
- } else if (CHECK_REQ_STATE == TEST_LOADED) {
- SET_TEST_STATE(TEST_LOADED);
- } else if (CHECK_REQ_STATE == TEST_DEAD) {
- SET_TEST_STATE(TEST_DEAD);
- } else {
+ }
+ }
+ if (len == 0) {
+ /* how do we deal with a closed connection in the measured state */
+ report_test_failure(test,
+ proc_name,
+ BSDE_DATA_CONNECTION_CLOSED_ERROR,
+ "data connection closed during TEST_MEASURE state");
+ } else {
+ my_data->stats.named.trans_received++;
+ if ((len=send(my_data->s_data,
+ my_data->send_ring->buffer_ptr,
+ my_data->rsp_size,
+ 0)) != my_data->rsp_size) {
+ /* this macro hides windows differences */
+ if (CHECK_FOR_SEND_ERROR(len)) {
report_test_failure(test,
- "send_tcp_stream",
- BSDE_REQUESTED_STATE_INVALID,
- "in IDLE requested to move to illegal state");
+ proc_name,
+ BSDE_DATA_SEND_ERROR,
+ "data_send_error");
}
+ }
+ }
+ /* code to timestamp enabled by HISTOGRAM */
+ HIST_TIMESTAMP(&time_two);
+ HIST_ADD(my_data->time_hist,delta_macro(&time_one,&time_two));
+ my_data->recv_ring = my_data->recv_ring->next;
+ my_data->send_ring = my_data->send_ring->next;
+ new_state = CHECK_REQ_STATE;
+ if (new_state == TEST_LOADED) {
+ /* transitioning to loaded state from measure state
+ set current timestamp and update elapsed time */
+ gettimeofday(&(my_data->curr_time), NULL);
+ update_elapsed_time(my_data);
+ }
+ return(new_state);
+}
+
+static uint32_t
+recv_tcp_rr_load(test_t *test)
+{
+ int len;
+ int bytes_left;
+ char *req_ptr;
+ uint32_t new_state;
+ bsd_data_t *my_data;
+ char *proc_name;
+
+ my_data = test->test_specific_data;
+ proc_name = "recv_tcp_rr_load";
+
+ /* recv the request for the test */
+ req_ptr = my_data->recv_ring->buffer_ptr;
+ bytes_left = my_data->req_size;
+ while (bytes_left > 0) {
+ if ((len=recv(my_data->s_data,
+ req_ptr,
+ bytes_left,
+ 0)) != 0) {
+ /* this macro hides windows differences */
+ if (CHECK_FOR_RECV_ERROR(len)) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_DATA_RECV_ERROR,
+ "data_recv_error");
+ break;
+ }
+ req_ptr += len;
+ bytes_left -= len;
+ } else {
+ /* just got a data connection close break out of while loop */
break;
- case TEST_MEASURE:
- my_data->stats.named.bytes_sent += send_size;
- my_data->stats.named.send_calls++;
- /* check for state transition */
- if (CHECK_REQ_STATE != TEST_MEASURE) {
- if (CHECK_REQ_STATE == TEST_LOADED) {
- /* transitioning to loaded state from measure state
- set current timestamp and update elapsed time */
- gettimeofday(&(my_data->curr_time), NULL);
- update_elapsed_time(my_data);
- SET_TEST_STATE(TEST_LOADED);
- } else {
- report_test_failure(test,
- "send_tcp_stream",
- BSDE_REQUESTED_STATE_INVALID,
- "in MEASURE requested to move to illegal state");
- }
+ }
+ }
+ /* check for state transition */
+ new_state = CHECK_REQ_STATE;
+ if ((len == 0) ||
+ (new_state == TEST_IDLE)) {
+ /* just got a data connection close or
+ a request to transition to the idle state */
+ recv_tcp_rr_idle_link(test,len);
+ new_state = TEST_IDLE;
+ } else {
+ if ((len=send(my_data->s_data,
+ my_data->send_ring->buffer_ptr,
+ my_data->rsp_size,
+ 0)) != my_data->rsp_size) {
+ /* this macro hides windows differences */
+ if (CHECK_FOR_SEND_ERROR(len)) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_DATA_SEND_ERROR,
+ "data_send_error");
}
- case TEST_LOADED:
- /* code to make data dirty macro enabled by DIRTY */
- MAKE_DIRTY(my_data,send_ring);
- /* code to timestamp enabled by HISTOGRAM */
- HIST_TIMESTAMP(&time_one);
- /* send data for the test */
- if((len=send(send_socket,
- send_ring->buffer_ptr,
- send_size,
- 0)) != send_size) {
- /* this macro hides windows differences */
- if ((CHECK_FOR_SEND_ERROR(len)) &&
- (CHECK_REQ_STATE != TEST_IDLE)) {
- report_test_failure(test,
- "send_tcp_stream",
- BSDE_DATA_SEND_ERROR,
- "data_send_error");
- }
+ }
+ my_data->recv_ring = my_data->recv_ring->next;
+ my_data->send_ring = my_data->send_ring->next;
+ if (new_state == TEST_MEASURE) {
+ /* transitioning to measure state from loaded state
+ set previous timestamp */
+ gettimeofday(&(my_data->prev_time), NULL);
+ }
+ }
+ return(new_state);
+}
+
+static void
+send_tcp_rr_preinit(test_t *test)
+{
+ bsd_data_t *my_data;
+
+ my_data = test->test_specific_data;
+
+ my_data->recv_ring = allocate_buffer_ring(my_data->recv_width,
+ my_data->rsp_size,
+ my_data->recv_align,
+ my_data->recv_offset,
+ my_data->fill_source);
+ my_data->send_ring = allocate_buffer_ring(my_data->send_width,
+ my_data->req_size,
+ my_data->send_align,
+ my_data->send_offset,
+ my_data->fill_source);
+
+ get_dependency_data(test, SOCK_STREAM, IPPROTO_TCP);
+ my_data->s_data = create_data_socket(test);
+}
+
+static uint32_t
+send_tcp_rr_init(test_t *test)
+{
+ bsd_data_t *my_data;
+ char *proc_name;
+
+ my_data = test->test_specific_data;
+ proc_name = "send_tcp_rr_init";
+
+ if (test->debug) {
+ fprintf(test->where,"%s: in INIT state making connect call\n",proc_name);
+ fflush(test->where);
+ }
+ if (connect(my_data->s_data,
+ my_data->remaddr->ai_addr,
+ my_data->remaddr->ai_addrlen) < 0) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_CONNECT_FAILED,
+ "data socket connect failed");
+ } else {
+ if (test->debug) {
+ fprintf(test->where,"%s: connected and moving to IDLE\n",proc_name);
+ fflush(test->where);
+ }
+ }
+ return(TEST_IDLE);
+}
+
+static void
+send_tcp_rr_idle_link(test_t *test, int last_len)
+{
+ int len;
+ uint32_t new_state;
+ bsd_data_t *my_data;
+ char *proc_name;
+
+ my_data = test->test_specific_data;
+ proc_name = "send_tcp_rr_idle_link";
+ len = last_len;
+
+ new_state = CHECK_REQ_STATE;
+ while (new_state == TEST_LOADED) {
+ sleep(1);
+ new_state = CHECK_REQ_STATE;
+ }
+ if (new_state == TEST_IDLE) {
+ if (test->debug) {
+ fprintf(test->where,"%s: transition from LOAD to IDLE\n",proc_name);
+ fflush(test->where);
+ }
+ if (shutdown(my_data->s_data,SHUT_WR) == -1) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_SOCKET_SHUTDOWN_FAILED,
+ "failure shuting down data socket");
+ } else {
+ while (len > 0) {
+ len = recv(my_data->s_data,
+ my_data->recv_ring->buffer_ptr,
+ my_data->rsp_size, 0);
}
- /* code to timestamp enabled by HISTOGRAM */
- HIST_TIMESTAMP(&time_two);
- HIST_ADD(my_data->time_hist,delta_macro(&time_one,&time_two));
- send_ring = send_ring->next;
- /* check for state transition */
- if ((GET_TEST_STATE == TEST_LOADED) &&
- (CHECK_REQ_STATE != TEST_LOADED)) {
- if (CHECK_REQ_STATE == TEST_MEASURE) {
- SET_TEST_STATE(TEST_MEASURE);
- /* transitioning to measure state from loaded state
- set previous timestamp */
- gettimeofday(&(my_data->prev_time), NULL);
- } else if (CHECK_REQ_STATE == TEST_IDLE) {
- if (shutdown(send_socket,1) == -1) {
- report_test_failure(test,
- "send_tcp_stream",
- BSDE_SOCKET_SHUTDOWN_FAILED,
- "failure shuting down data socket");
- } else {
- recv(send_socket, send_ring->buffer_ptr, send_size, 0);
- close(send_socket);
- send_socket = create_data_socket(test);
- if (GET_TEST_STATE != TEST_ERROR) {
- if (test->debug) {
- fprintf(test->where,"send_tcp_stream: connecting from LOAD state\n");
- fflush(test->where);
- }
- if (connect(send_socket,
- my_data->remaddr->ai_addr,
- my_data->remaddr->ai_addrlen) < 0) {
- report_test_failure(test,
- "send_tcp_stream",
- BSDE_CONNECT_FAILED,
- "data socket connect failed");
- } else {
- if (test->debug) {
- fprintf(test->where,"send_tcp_stream: connected moving to IDLE\n");
- fflush(test->where);
- }
- SET_TEST_STATE(TEST_IDLE);
- }
- }
- }
- } else {
- report_test_failure(test,
- "send_tcp_stream",
- BSDE_REQUESTED_STATE_INVALID,
- "in LOADED requested to move to illegal state");
+ close(my_data->s_data);
+ my_data->s_data = create_data_socket(test);
+ if (test->debug) {
+ fprintf(test->where,"%s: connecting from LOAD state\n",proc_name);
+ fflush(test->where);
+ }
+ if (connect(my_data->s_data,
+ my_data->remaddr->ai_addr,
+ my_data->remaddr->ai_addrlen) < 0) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_CONNECT_FAILED,
+ "data socket connect failed");
+ } else {
+ if (test->debug) {
+ fprintf(test->where,"%s: connected moving to IDLE\n",proc_name);
+ fflush(test->where);
}
}
- break;
- default:
- report_test_failure(test,
- "send_tcp_stream",
- BSDE_TEST_STATE_CORRUPTED,
- "test found in ILLEGAL state");
- } /* end of switch in while loop */
- } /* end of while for test */
+ }
+ } else {
+ /* a transition to a state other than TEST_IDLE was requested
+ after the link was closed in the TEST_LOADED state */
+ report_test_failure(test,
+ proc_name,
+ BSDE_DATA_CONNECTION_CLOSED_ERROR,
+ "data connection closed and non idle state requested");
- close(send_socket);
+ }
+}
- while (GET_TEST_STATE != TEST_DEAD) {
- if (CHECK_REQ_STATE == TEST_DEAD) {
- bsd_test_free(test);
- SET_TEST_STATE(TEST_DEAD);
+static uint32_t
+send_tcp_rr_meas(test_t *test)
+{
+ uint32_t new_state;
+ int len;
+ int bytes_left;
+ char *rsp_ptr;
+ bsd_data_t *my_data;
+ char *proc_name;
+
+ my_data = test->test_specific_data;
+ proc_name = "send_tcp_stream_meas";
+ HISTOGRAM_VARS;
+ /* code to make data dirty macro enabled by DIRTY */
+ MAKE_DIRTY(my_data,my_data->send_ring);
+ /* code to timestamp enabled by HISTOGRAM */
+ HIST_TIMESTAMP(&time_one);
+ /* send data for the test */
+ if((len=send(my_data->s_data,
+ my_data->send_ring->buffer_ptr,
+ my_data->req_size,
+ 0)) != my_data->req_size) {
+ /* this macro hides windows differences */
+ if (CHECK_FOR_SEND_ERROR(len)) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_DATA_SEND_ERROR,
+ "data send error");
}
}
+ /* recv the request for the test */
+ rsp_ptr = my_data->recv_ring->buffer_ptr;
+ bytes_left = my_data->rsp_size;
+ while (bytes_left > 0) {
+ if ((len=recv(my_data->s_data,
+ rsp_ptr,
+ bytes_left,
+ 0)) != 0) {
+ /* this macro hides windows differences */
+ if (CHECK_FOR_RECV_ERROR(len)) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_DATA_RECV_ERROR,
+ "data_recv_error");
+ break;
+ }
+ rsp_ptr += len;
+ bytes_left -= len;
+ } else {
+ /* len is 0 the connection was closed exit the while loop */
+ break;
+ }
+ }
+ /* code to timestamp enabled by HISTOGRAM */
+ HIST_TIMESTAMP(&time_two);
+ HIST_ADD(my_data->time_hist,delta_macro(&time_one,&time_two));
+ my_data->stats.named.trans_sent++;
+ my_data->recv_ring = my_data->recv_ring->next;
+ my_data->send_ring = my_data->send_ring->next;
+ if (len == 0) {
+ /* how do we deal with a closed connection in the measured state */
+ report_test_failure(test,
+ proc_name,
+ BSDE_DATA_CONNECTION_CLOSED_ERROR,
+ "data connection closed during TEST_MEASURE state");
+ }
+ new_state = CHECK_REQ_STATE;
+ if (new_state == TEST_LOADED) {
+ /* transitioning to loaded state from measure state
+ set current timestamp and update elapsed time */
+ gettimeofday(&(my_data->curr_time), NULL);
+ update_elapsed_time(my_data);
+ }
+ return(new_state);
+}
-} /* end of send_tcp_stream */
+static uint32_t
+send_tcp_rr_load(test_t *test)
+{
+ uint32_t new_state;
+ int len;
+ int bytes_left;
+ char *rsp_ptr;
+ bsd_data_t *my_data;
+ char *proc_name;
+ my_data = test->test_specific_data;
+ proc_name = "send_tcp_stream_load";
+ /* code to make data dirty macro enabled by DIRTY */
+ MAKE_DIRTY(my_data,my_data->send_ring);
+ /* send data for the test */
+ if((len=send(my_data->s_data,
+ my_data->send_ring->buffer_ptr,
+ my_data->req_size,
+ 0)) != my_data->req_size) {
+ /* this macro hides windows differences */
+ if (CHECK_FOR_SEND_ERROR(len)) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_DATA_SEND_ERROR,
+ "data send error");
+ }
+ }
+ /* recv the request for the test */
+ rsp_ptr = my_data->recv_ring->buffer_ptr;
+ bytes_left = my_data->rsp_size;
+ while (bytes_left > 0) {
+ if ((len=recv(my_data->s_data,
+ rsp_ptr,
+ bytes_left,
+ 0)) != 0) {
+ /* this macro hides windows differences */
+ if (CHECK_FOR_RECV_ERROR(len)) {
+ report_test_failure(test,
+ proc_name,
+ BSDE_DATA_RECV_ERROR,
+ "data_recv_error");
+ break;
+ }
+ rsp_ptr += len;
+ bytes_left -= len;
+ } else {
+ /* len is 0 the connection was closed exit the while loop */
+ break;
+ }
+ }
+ my_data->recv_ring = my_data->recv_ring->next;
+ my_data->send_ring = my_data->send_ring->next;
+ new_state = CHECK_REQ_STATE;
+ if ((len == 0) ||
+ (new_state == TEST_IDLE)) {
+ send_tcp_rr_idle_link(test,len);
+ new_state = TEST_IDLE;
+ } else {
+ if (new_state == TEST_MEASURE) {
+ /* transitioning to measure state from loaded state
+ set previous timestamp */
+ gettimeofday(&(my_data->prev_time), NULL);
+ }
+ }
+ return(new_state);
+}
int
recv_tcp_rr_clear_stats(test_t *test)
{
- bsd_data_t *my_data = GET_TEST_DATA(test);
- return(bsd_test_clear_stats(my_data));
+ return(bsd_test_clear_stats(GET_TEST_DATA(test)));
}
@@ -1451,8 +2249,7 @@
int
send_tcp_rr_clear_stats(test_t *test)
{
- bsd_data_t *my_data = GET_TEST_DATA(test);
- return(bsd_test_clear_stats(my_data));
+ return(bsd_test_clear_stats(GET_TEST_DATA(test)));
}
xmlNodePtr
@@ -1467,599 +2264,188 @@
bsd_test_decode_stats(stats,test);
}
-
+
/* This routine implements the server-side of the TCP request/response */
/* test (a.k.a. rr) for the sockets interface. It receives its */
/* parameters via the xml node contained in the test structure. */
/* results are collected by the procedure recv_tcp_rr_get_stats */
+
void
recv_tcp_rr(test_t *test)
{
- bsd_data_t *my_data;
- ring_elt_ptr recv_ring;
- ring_elt_ptr send_ring;
- char * req_ptr;
- int s_listen;
- int s_data;
- int bytes_left;
- int recv_size;
- int send_size;
- int len;
- int rc;
- int firsttime = 1;
- int go_on = 1;
- struct sockaddr myaddr;
- int mylen=sizeof(myaddr);
- struct sockaddr peeraddr;
- int peerlen=sizeof(peeraddr);
-
- HISTOGRAM_VARS;
-
- /* create data socket s_listen */
- /* bind to get addressing information */
- /* need to pass in IP if multi-homed */
- /* listen for connection on s_listen */
- /* call getsockname to set the port */
- /* report dependency data IP, port & family */
- /* accept connection */
-
- my_data = bsd_test_init(test, SOCK_STREAM, IPPROTO_TCP);
-
- my_data->recv_ring = allocate_buffer_ring(my_data->recv_width,
- my_data->recv_size,
- my_data->recv_align,
- my_data->recv_offset,
- my_data->fill_source);
-
- my_data->send_ring = allocate_buffer_ring(my_data->send_width,
- my_data->send_size,
- my_data->send_align,
- my_data->send_offset,
- my_data->fill_source);
-
- s_listen = create_data_socket(test);
-
-
- while ((GET_TEST_STATE != TEST_ERROR) &&
- (GET_TEST_STATE != TEST_DEAD)) {
- switch (GET_TEST_STATE) {
+ uint32_t state, new_state;
+ bsd_test_init(test, SOCK_STREAM, IPPROTO_TCP);
+ state = GET_TEST_STATE;
+ while ((state != TEST_ERROR) &&
+ (state != TEST_DEAD )) {
+ switch(state) {
case TEST_PREINIT:
- if (firsttime) {
- firsttime = 0;
- recv_ring = my_data->recv_ring;
- recv_size = my_data->recv_size;
- send_ring = my_data->send_ring;
- send_size = my_data->send_size;
- if (test->debug) {
- dump_addrinfo(test->where, my_data->locaddr,
- (xmlChar *)NULL, (xmlChar *)NULL, -1);
- }
- if (test->debug) {
- fprintf(test->where,"recv_tcp_rr:create_data_socket returned %d\n",
- s_listen);
- fflush(test->where);
- }
- rc = bind(s_listen, my_data->locaddr->ai_addr,
- my_data->locaddr->ai_addrlen);
- if (test->debug) {
- fprintf(test->where,"recv_tcp_rr:bind returned %d errno=%d\n",
- rc,errno);
- fflush(test->where);
- }
- if (len == -1) {
- report_test_failure(test,
- "recv_tcp_rr",
- BSDE_BIND_FAILED,
- "data socket bind failed");
- } else if (listen(s_listen,5) == -1) {
- report_test_failure(test,
- "recv_tcp_rr",
- BSDE_LISTEN_FAILED,
- "data socket listen failed");
- } else if (getsockname(s_listen,
- &myaddr,
- &mylen) == -1) {
- report_test_failure(test,
- "recv_tcp_rr",
- BSDE_GETSOCKNAME_FAILED,
- "getting the listen socket name failed");
- } else {
- memcpy(my_data->locaddr->ai_addr,&myaddr,mylen);
- my_data->locaddr->ai_addrlen = mylen;
- set_dependent_data(test);
- SET_TEST_STATE(TEST_INIT);
- }
- } else {
- report_test_failure(test,
- "recv_tcp_rr",
- BSDE_TEST_STATE_CORRUPTED,
- "test found in ILLEGAL TEST_PREINIT state");
- }
+ recv_tcp_rr_preinit(test);
+ new_state = TEST_INIT;
break;
case TEST_INIT:
- if (CHECK_REQ_STATE == TEST_IDLE) {
- peerlen = sizeof(peeraddr);
- if (test->debug) {
- fprintf(test->where,"recv_tcp_rr:waiting in accept\n");
- fflush(test->where);
- }
- if ((s_data=accept(s_listen,
- &peeraddr,
- &peerlen)) == -1) {
- report_test_failure(test,
- "recv_tcp_rr",
- BSDE_ACCEPT_FAILED,
- "listen socket accept failed");
- } else {
- if (test->debug) {
- fprintf(test->where,"recv_tcp_rr:accept returned successfully %d\n",
- s_data);
- fflush(test->where);
- }
- SET_TEST_STATE(TEST_IDLE);
- }
- } else {
- report_test_failure(test,
- "recv_tcp_rr",
- BSDE_REQUESTED_STATE_INVALID,
- "bad state requested for TEST_INIT state");
+ new_state = CHECK_REQ_STATE;
+ if (new_state == TEST_IDLE) {
+ new_state = recv_tcp_rr_init(test);
}
break;
case TEST_IDLE:
- /* check for state transition */
- if (CHECK_REQ_STATE == TEST_IDLE) {
+ new_state = CHECK_REQ_STATE;
+ if (new_state == TEST_IDLE) {
sleep(1);
- } else if (CHECK_REQ_STATE == TEST_LOADED) {
- SET_TEST_STATE(TEST_LOADED);
- } else if (CHECK_REQ_STATE == TEST_DEAD) {
- SET_TEST_STATE(TEST_DEAD);
- } else {
- report_test_failure(test,
- "recv_tcp_rr",
- BSDE_REQUESTED_STATE_INVALID,
- "in IDLE requested to move to illegal state");
}
break;
case TEST_MEASURE:
- my_data->stats.named.trans_received++;
- /* check for state transition */
- if (CHECK_REQ_STATE != TEST_MEASURE) {
- if (CHECK_REQ_STATE == TEST_LOADED) {
- /* transitioning to loaded state from measure state
- set current timestamp and update elapsed time */
- gettimeofday(&(my_data->curr_time), NULL);
- update_elapsed_time(my_data);
- SET_TEST_STATE(TEST_LOADED);
- } else {
- report_test_failure(test,
- "recv_tcp_rr",
- BSDE_REQUESTED_STATE_INVALID,
- "in MEASURE requested to move to illegal state");
- }
- }
+ new_state = recv_tcp_rr_meas(test);
+ break;
case TEST_LOADED:
- /* code to timestamp enabled by HISTOGRAM */
- HIST_TIMESTAMP(&time_one);
- /* recv the request for the test */
- req_ptr = recv_ring->buffer_ptr;
- bytes_left = recv_size;
- while (bytes_left > 0) {
- if ((len=recv(s_data,
- req_ptr,
- bytes_left,
- 0)) != 0) {
- /* this macro hides windows differences */
- if (CHECK_FOR_RECV_ERROR(len)) {
- report_test_failure(test,
- "recv_tcp_rr",
- BSDE_DATA_RECV_ERROR,
- "data_recv_error");
- break;
- }
- req_ptr += len;
- bytes_left -= len;
- }
- if ((CHECK_REQ_STATE != TEST_LOADED) &&
- (CHECK_REQ_STATE != TEST_MEASURE)) {
- break;
- }
- }
-
- if ((CHECK_REQ_STATE == TEST_LOADED) ||
- (CHECK_REQ_STATE == TEST_MEASURE)) {
- if ((len=send(s_data,
- send_ring->buffer_ptr,
- send_size,
- 0)) != send_size) {
- /* this macro hides windows differences */
- if ((CHECK_FOR_SEND_ERROR(len)) &&
- ((CHECK_REQ_STATE != TEST_IDLE) ||
- (GET_TEST_STATE != TEST_ERROR))) {
- report_test_failure(test,
- "recv_tcp_rr",
- BSDE_DATA_SEND_ERROR,
- "data_send_error");
- }
- }
- }
-
- /* code to timestamp enabled by HISTOGRAM */
- HIST_TIMESTAMP(&time_two);
- HIST_ADD(my_data->time_hist,delta_macro(&time_one,&time_two));
-
- recv_ring = recv_ring->next;
- send_ring = send_ring->next;
-
- /* check for state transition */
- if ((GET_TEST_STATE == TEST_LOADED) &&
- (CHECK_REQ_STATE != TEST_LOADED)) {
- if (CHECK_REQ_STATE == TEST_MEASURE) {
- SET_TEST_STATE(TEST_MEASURE);
- /* transitioning to measure state from loaded state
- set previous timestamp */
- gettimeofday(&(my_data->prev_time), NULL);
- } else if (CHECK_REQ_STATE == TEST_IDLE) {
- if (shutdown(s_data,1) == -1) {
- report_test_failure(test,
- "recv_tcp_rr",
- BSDE_SOCKET_SHUTDOWN_FAILED,
- "failure shuting down data socket");
- } else {
- recv(s_data, send_ring->buffer_ptr, send_size, 0);
- close(s_data);
- peerlen = sizeof(peeraddr);
- if (test->debug) {
- fprintf(test->where,"recv_tcp_rr:waiting in accept\n");
- fflush(test->where);
- }
- if ((s_data=accept(s_listen,
- &peeraddr,
- &peerlen)) == -1) {
- report_test_failure(test,
- "recv_tcp_rr",
- BSDE_ACCEPT_FAILED,
- "listen socket accept failed");
- } else {
- if (test->debug) {
- fprintf(test->where,"recv_tcp_rr:accept returned successfully %d\n",
- s_data);
- fflush(test->where);
- }
- SET_TEST_STATE(TEST_IDLE);
- }
- }
- } else {
- report_test_failure(test,
- "recv_tcp_rr",
- BSDE_REQUESTED_STATE_INVALID,
- "in LOADED requested to move to illegal state");
- }
- }
+ new_state = recv_tcp_rr_load(test);
break;
default:
- report_test_failure(test,
- "recv_tcp_rr",
- BSDE_TEST_STATE_CORRUPTED,
- "test found in ILLEGAL state");
- } /* end of switch in while loop */
- } /* end of while for test */
+ break;
+ } /* end of switch */
+ set_test_state(test, new_state);
+ state = GET_TEST_STATE;
+ } /* end of while */
+ wait_to_die(test);
+} /* end of recv_tcp_rr */
- /* perform a shutdown to signal the sender that */
- /* we have received all the data sent. raj 4/93 */
- shutdown(s_data,1);
-
- close(s_listen);
- close(s_data);
-
- while (GET_TEST_STATE != TEST_DEAD) {
- if (CHECK_REQ_STATE == TEST_DEAD) {
- bsd_test_free(test);
- SET_TEST_STATE(TEST_DEAD);
- }
- }
-}
-
-
+
/* This routine implements the TCP request/responce test */
/* (a.k.a. rr) for the sockets interface. It receives its */
/* parameters via the xml node contained in the test structure */
/* output to the standard output. */
/* results are collected by the procedure send_tcp_rr_get_stats */
+
void
send_tcp_rr(test_t *test)
{
- bsd_data_t *my_data;
- ring_elt_ptr recv_ring;
- ring_elt_ptr send_ring;
- char *rsp_ptr;
- int send_socket;
- int bytes_left;
- int len;
- int recv_size;
- int send_size;
- int firsttime = 1;
-
- HISTOGRAM_VARS;
-
- /* setup server with remote ip address and family*/
- /* create_data_socket AF_INET,SOCK_STREAM */
- /* connect using created data socket and server structure for remote */
-
- my_data = bsd_test_init(test, SOCK_STREAM, IPPROTO_TCP);
-
- my_data->recv_ring = allocate_buffer_ring(my_data->recv_width,
- my_data->recv_size,
- my_data->recv_align,
- my_data->recv_offset,
- my_data->fill_source);
-
- my_data->send_ring = allocate_buffer_ring(my_data->send_width,
- my_data->send_size,
- my_data->send_align,
- my_data->send_offset,
- my_data->fill_source);
-
- get_dependency_data(test, SOCK_STREAM, IPPROTO_TCP);
- send_socket = create_data_socket(test);
-
- while ((GET_TEST_STATE != TEST_ERROR) &&
- (GET_TEST_STATE != TEST_DEAD)) {
- switch (GET_TEST_STATE) {
+ uint32_t state, new_state;
+ bsd_test_init(test, SOCK_STREAM, IPPROTO_TCP);
+ state = GET_TEST_STATE;
+ while ((state != TEST_ERROR) &&
+ (state != TEST_DEAD )) {
+ switch(state) {
case TEST_PREINIT:
- if (firsttime) {
- firsttime = 0;
- recv_ring = my_data->recv_ring;
- recv_size = my_data->recv_size;
- send_ring = my_data->send_ring;
- send_size = my_data->send_size;
- SET_TEST_STATE(TEST_INIT);
- } else {
- report_test_failure(test,
- "send_tcp_rr",
- BSDE_TEST_STATE_CORRUPTED,
- "test found in ILLEGAL TEST_PREINIT state");
- }
+ send_tcp_rr_preinit(test);
+ new_state = TEST_INIT;
break;
case TEST_INIT:
- if (CHECK_REQ_STATE == TEST_IDLE) {
- if (test->debug) {
- fprintf(test->where,"send_tcp_rr: in INIT state making connect call\n");
- fflush(test->where);
- }
- if (connect(send_socket,
- my_data->remaddr->ai_addr,
- my_data->remaddr->ai_addrlen) < 0) {
- report_test_failure(test,
- "send_tcp_rr",
- BSDE_CONNECT_FAILED,
- "data socket connect failed");
- } else {
- if (test->debug) {
- fprintf(test->where,"send_tcp_rr: connected and moving to IDLE\n");
- fflush(test->where);
- }
- SET_TEST_STATE(TEST_IDLE);
- }
- } else {
- report_test_failure(test,
- "send_tcp_rr",
- BSDE_REQUESTED_STATE_INVALID,
- "test found in TEST_INIT state");
+ new_state = CHECK_REQ_STATE;
+ if (new_state == TEST_IDLE) {
+ new_state = send_tcp_rr_init(test);
}
break;
case TEST_IDLE:
- /* check for state transition */
- if (CHECK_REQ_STATE == TEST_IDLE) {
+ new_state = CHECK_REQ_STATE;
+ if (new_state == TEST_IDLE) {
sleep(1);
- } else if (CHECK_REQ_STATE == TEST_LOADED) {
- SET_TEST_STATE(TEST_LOADED);
- /* add code for DO_FIRST_BURST if desired */
- } else if (CHECK_REQ_STATE == TEST_DEAD) {
- SET_TEST_STATE(TEST_DEAD);
- } else {
- report_test_failure(test,
- "send_tcp_rr",
- BSDE_REQUESTED_STATE_INVALID,
- "in IDLE requested to move to illegal state");
}
break;
case TEST_MEASURE:
- my_data->stats.named.trans_sent++;
- /* check for state transition */
- if (CHECK_REQ_STATE != TEST_MEASURE) {
- if (CHECK_REQ_STATE == TEST_LOADED) {
- /* transitioning to loaded state from measure state
- set current timestamp and update elapsed time */
- gettimeofday(&(my_data->curr_time), NULL);
- update_elapsed_time(my_data);
- SET_TEST_STATE(TEST_LOADED);
- } else {
- report_test_failure(test,
- "send_tcp_rr",
- BSDE_REQUESTED_STATE_INVALID,
- "in MEASURE requested to move to illegal state");
- }
- }
+ new_state = send_tcp_rr_meas(test);
+ break;
case TEST_LOADED:
- /* code to make data dirty macro enabled by DIRTY */
- MAKE_DIRTY(my_data,send_ring);
- /* code to timestamp enabled by HISTOGRAM */
- HIST_TIMESTAMP(&time_one);
- /* send data for the test */
- if((len=send(send_socket,
- send_ring->buffer_ptr,
- send_size,
- 0)) != send_size) {
- /* this macro hides windows differences */
- if ((CHECK_FOR_SEND_ERROR(len)) &&
- (CHECK_REQ_STATE != TEST_IDLE)) {
- report_test_failure(test,
- "send_tcp_rr",
- BSDE_DATA_SEND_ERROR,
- "data_send_error");
- }
- }
-
- /* receive the response for the test */
- rsp_ptr = recv_ring->buffer_ptr;
- bytes_left = recv_size;
- while (bytes_left > 0) {
- if ((len=recv(send_socket,
- rsp_ptr,
- bytes_left,
- 0)) != 0) {
- /* this macro hides windows differences */
- if (CHECK_FOR_RECV_ERROR(len)) {
- report_test_failure(test,
- "send_tcp_rr",
- BSDE_DATA_RECV_ERROR,
- "data_recv_error");
- break;
- }
- rsp_ptr += len;
- bytes_left -= len;
- }
- if ((CHECK_REQ_STATE != TEST_LOADED) &&
- (CHECK_REQ_STATE != TEST_MEASURE)) {
- break;
- }
- }
-
- /* code to timestamp enabled by HISTOGRAM */
- HIST_TIMESTAMP(&time_two);
- HIST_ADD(my_data->time_hist,delta_macro(&time_one,&time_two));
-
- recv_ring = recv_ring->next;
- send_ring = send_ring->next;
-
- /* check for state transition */
- if ((GET_TEST_STATE == TEST_LOADED) &&
- (CHECK_REQ_STATE != TEST_LOADED)) {
- if (CHECK_REQ_STATE == TEST_MEASURE) {
- SET_TEST_STATE(TEST_MEASURE);
- /* transitioning to measure state from loaded state
- set previous timestamp */
- gettimeofday(&(my_data->prev_time), NULL);
- } else if (CHECK_REQ_STATE == TEST_IDLE) {
- close(send_socket);
- send_socket = create_data_socket(test);
- if (GET_TEST_STATE != TEST_ERROR) {
- if (test->debug) {
- fprintf(test->where,"send_tcp_rr: connecting from LOAD state\n");
- fflush(test->where);
- }
- if (connect(send_socket,
- my_data->remaddr->ai_addr,
- my_data->remaddr->ai_addrlen) < 0) {
- report_test_failure(test,
- "send_tcp_rr",
- BSDE_CONNECT_FAILED,
- "data socket connect failed");
- } else {
- if (test->debug) {
- fprintf(test->where,"send_tcp_rr: connected moving to IDLE\n");
- fflush(test->where);
- }
- SET_TEST_STATE(TEST_IDLE);
- }
- }
- } else {
- report_test_failure(test,
- "send_tcp_rr",
- BSDE_REQUESTED_STATE_INVALID,
- "in LOADED requested to move to illegal state");
- }
- }
+ new_state = send_tcp_rr_load(test);
break;
default:
- report_test_failure(test,
- "send_tcp_rr",
- BSDE_TEST_STATE_CORRUPTED,
- "test found in ILLEGAL state");
- } /* end of switch in while loop */
- } /* end of while for test */
-
- close(send_socket);
-
- while (GET_TEST_STATE != TEST_DEAD) {
- if (CHECK_REQ_STATE == TEST_DEAD) {
- bsd_test_free(test);
- SET_TEST_STATE(TEST_DEAD);
- }
- }
-
+ break;
+ } /* end of switch */
+ set_test_state(test, new_state);
+ state = GET_TEST_STATE;
+ } /* end of while */
+ wait_to_die(test);
} /* end of send_tcp_rr */
-
+
/* This implementation of report_bsd_test_results will generate strange
results if transaction count and throughput tests are included in the
same test set. The first test in the set sets the headers and algorithm
for computing service demand */
void
-report_bsd_test_results(tset_t *test_set, char *report_flags, char *output)
+bsd_test_results_init(tset_t *test_set,char *report_flags,char *output)
{
- bsd_results_t *my_data = test_set->report_data;
- int count = test_set->confidence.count - 1;
- int max_count = test_set->confidence.max_count;
- int min_count = test_set->confidence.min_count;
- int sys_stats_count = 0;
- int test_stats_count = 0;
- int test_stats;
- double sd_denominator = 0.0;
- double local_cpus;
+ bsd_results_t *rd;
+ FILE *outfd;
+ int max_count;
- /* Summary report variables */
- double result_measured_mean;
- double xmit_measured_mean;
- double recv_measured_mean;
- double cpu_util_measured_mean;
- double service_demand_measured_mean;
- double confidence;
- double result_confidence;
- double xmit_confidence;
- double recv_confidence;
- double cpu_util_confidence;
- double serv_demand_confidence;
- double ave_time;
+ rd = test_set->report_data;
+ max_count = test_set->confidence.max_count;
+
+ if (output) {
+ if (test_set->debug) {
+ fprintf(test_set->where,
+ "bsd_test_results_init: report going to file %s\n",
+ output);
+ fflush(test_set->where);
+ }
+ outfd = fopen(output,"a");
+ } else {
+ if (test_set->debug) {
+ fprintf(test_set->where,
+ "report_bsd_test_results: report going to file stdout\n");
+ fflush(test_set->where);
+ }
+ outfd = stdout;
+ }
+ /* allocate and initialize report data */
+ rd = malloc(sizeof(bsd_results_t) + 7 * max_count * sizeof(double));
+ if (rd) {
+ memset(rd, 0,
+ sizeof(sizeof(bsd_results_t) + 7 * max_count * sizeof(double)));
+ rd->max_count = max_count;
+ rd->results = &(rd->results_start);
+ rd->xmit_results = &(rd->results[max_count]);
+ rd->recv_results = &(rd->xmit_results[max_count]);
+ rd->trans_results = &(rd->recv_results[max_count]);
+ rd->utilization = &(rd->trans_results[max_count]);
+ rd->servdemand = &(rd->utilization[max_count]);
+ rd->run_time = &(rd->servdemand[max_count]);
+ rd->result_minimum = MAXDOUBLE;
+ rd->result_maximum = MINDOUBLE;
+ rd->outfd = outfd;
+ rd->sd_denominator = 0.0;
+ if (!strcmp(report_flags,"PRINT_RUN")) {
+ rd->print_run = 1;
+ }
+ if (!strcmp(report_flags,"PRINT_TESTS")) {
+ rd->print_test = 1;
+ }
+ if (!strcmp(report_flags,"PRINT_ALL")) {
+ rd->print_run = 1;
+ rd->print_test = 1;
+ }
+ if (test_set->debug) {
+ rd->print_run = 1;
+ rd->print_test = 1;
+ }
+ test_set->report_data = rd;
+ } else {
+ /* could not allocate memory can't generate report */
+ fprintf(outfd,
+ "bsd_test_results_init: malloc failed can't generate report\n");
+ fflush(outfd);
+ exit;
+ }
+}
- /* Per Run report variables */
- double acc_results;
- double acc_xmit_rate;
- double acc_recv_rate;
- double service_demand;
- double run_time;
+void
+process_test_stats(tset_t *test_set, xmlNodePtr stats, xmlChar *tid)
+{
+ int i;
+ int count;
+ int index;
+ FILE *outfd;
+ bsd_results_t *rd;
- /* Per Test variables */
double elapsed_seconds;
- double sys_seconds;
- double sys_util;
- double calibration;
- double local_idle;
- double local_busy;
double result;
double xmit_rate;
double recv_rate;
double xmit_trans_rate;
double recv_trans_rate;
- int i;
- int flags;
- int last_hdr = 0;
- xmlNodePtr stats;
- xmlNodePtr prev_stats;
- FILE *outfd = NULL;
- test_t *test;
- tset_elt_t *set_elt;
-
-#define BSD_SUMMARY_FLAG 1
-#define BSD_PER_RUN_FLAG 2
-#define BSD_PER_TEST_FLAG 4
-
-#define BSD_SUMMARY_HDR 1
-#define BSD_PER_RUN_HDR BSD_PER_RUN_FLAG
-#define BSD_PER_TEST_HDR BSD_PER_TEST_FLAG
-
#define TST_E_SEC 0
#define TST_E_USEC 1
#define TST_X_BYTES 5
@@ -2084,12 +2470,119 @@
"cntr7_value"
};
+ rd = test_set->report_data;
+ count = test_set->confidence.count;
+ outfd = rd->outfd;
+ index = count - 1;
+
+ /* process test statistics */
+ if (test_set->debug) {
+ fprintf(test_set->where,"\tprocessing test_stats\n");
+ fflush(test_set->where);
+ }
+ for (i=0; i<MAX_TEST_CNTRS; i++) {
+ char *value_str =
+ (char *)xmlGetProp(stats, (const xmlChar *)cntr_name[i]);
+ if (value_str) {
+ test_cntr[i] = strtod(value_str,NULL);
+ if (test_cntr[i] == 0.0) {
+ uint64_t x;
+ sscanf(value_str,"%llx",&x);
+ test_cntr[i] = (double)x;
+ }
+ } else {
+ test_cntr[i] = 0.0;
+ }
+ if (test_set->debug) {
+ fprintf(test_set->where,"\t%12s test_cntr[%2d] = %10g\t'%s'\n",
+ cntr_name[i], i, test_cntr[i],
+ xmlGetProp(stats, (const xmlChar *)cntr_name[i]));
+ }
+ }
+ elapsed_seconds = test_cntr[TST_E_SEC] + test_cntr[TST_E_USEC]/1000000;
+ xmit_rate = test_cntr[TST_X_BYTES]*8/(elapsed_seconds*1000000);
+ recv_rate = test_cntr[TST_R_BYTES]*8/(elapsed_seconds*1000000);
+ xmit_trans_rate = test_cntr[TST_X_TRANS]/elapsed_seconds;
+ recv_trans_rate = test_cntr[TST_R_TRANS]/elapsed_seconds;
+ if (test_set->debug) {
+ fprintf(test_set->where,"\txmit_rate = %7g\t%7g\n",
+ xmit_rate, test_cntr[TST_X_BYTES]);
+ fprintf(test_set->where,"\trecv_rate = %7g\t%7g\n",
+ recv_rate, test_cntr[TST_R_BYTES]);
+ fprintf(test_set->where,"\txmit_trans_rate = %7g\t%7g\n",
+ xmit_trans_rate, test_cntr[TST_X_TRANS]);
+ fprintf(test_set->where,"\trecv_trans_rate = %7g\t%7g\n",
+ recv_trans_rate, test_cntr[TST_X_TRANS]);
+ fflush(test_set->where);
+ }
+ if (rd->sd_denominator == 0.0) {
+ if (xmit_rate > 0.0 || recv_rate > 0.0) {
+ rd->sd_denominator = 1000000.0/(8.0*1024.0);
+ } else {
+ rd->sd_denominator = 1.0;
+ }
+ }
+ if (test_set->debug) {
+ fprintf(test_set->where,"\tsd_denominator = %f\n",rd->sd_denominator);
+ fflush(test_set->where);
+ }
+ if (rd->sd_denominator != 1.0) {
+ result = recv_rate + xmit_rate;
+ } else {
+ result = recv_trans_rate + xmit_trans_rate;
+ }
+ if (test_set->debug) {
+ fprintf(test_set->where,"\tresult = %f\n",result);
+ fflush(test_set->where);
+ }
+ /* accumulate results for the run */
+ rd->run_time[index] += elapsed_seconds;
+ rd->results[index] += result;
+ rd->xmit_results[index] += xmit_rate;
+ rd->recv_results[index] += recv_rate;
+ rd->trans_results[index] += xmit_trans_rate;
+ rd->trans_results[index] += recv_trans_rate;
+
+ if (rd->print_test) {
+ /* Display per test results */
+ fprintf(outfd,"%3d ", count); /* 0,5 */
+ fprintf(outfd,"%-6s ", tid); /* 5,7 */
+ fprintf(outfd,"%-6.2f ",elapsed_seconds); /* 12,7 */
+ if (rd->sd_denominator != 1.0) {
+ fprintf(outfd,"%7.2f ",result); /* 19,8 */
+ fprintf(outfd,"%7.2f ",xmit_rate); /* 27,8 */
+ fprintf(outfd,"%7.2f ",recv_rate); /* 35,8 */
+ } else {
+ fprintf(outfd,"%10.2f ",result); /* 19,11 */
+ }
+ fprintf(outfd,"\n");
+ fflush(outfd);
+ }
+ /* end of printing bsd per test instance results */
+}
+
+void
+process_sys_stats(tset_t *test_set, xmlNodePtr stats, xmlChar *tid)
+{
+ int i;
+ int count;
+ int index;
+ FILE *outfd;
+ bsd_results_t *rd;
+ double elapsed_seconds;
+ double sys_util;
+ double calibration;
+ double local_idle;
+ double local_busy;
+ double local_cpus;
+
#define MAX_SYS_CNTRS 10
#define E_SEC 0
#define E_USEC 1
#define NUM_CPU 4
#define CALIBRATE 5
#define IDLE 6
+
double sys_cntr[MAX_SYS_CNTRS];
const char *sys_cntr_name[] = {
"elapsed_sec",
@@ -2099,587 +2592,423 @@
"number_cpus",
"calibration",
"idle_count",
- "user_count",
- "sys_count",
- "int_count"
+ "",
+ "",
+ ""
};
- flags = BSD_PER_TEST_FLAG + BSD_PER_RUN_FLAG;
+ rd = test_set->report_data;
+ count = test_set->confidence.count;
+ outfd = rd->outfd;
+ index = count - 1;
- /* SOMETHING THAT NEEDS TO BE FIXED!!! if we are keying off of the
- test_t for tihngs like debug and where the debug output is to go,
- we kind of need test set up here where these decisions are being
- made, which suggests that a lot of this has to go inside the
- later while with some sort of "have we done this part already"
- protection. */
-
- if (my_data == NULL) {
- if (output) {
- if (1) {
- fprintf(stderr,"report_bsd_test_results: report going to file %s\n",
- output);
- fflush(stderr);
+ if (test_set->debug) {
+ fprintf(test_set->where,"\tprocessing sys_stats\n");
+ fflush(test_set->where);
+ }
+ for (i=0; i<MAX_SYS_CNTRS; i++) {
+ char *value_str =
+ (char *)xmlGetProp(stats, (const xmlChar *)sys_cntr_name[i]);
+ if (value_str) {
+ sys_cntr[i] = strtod(value_str,NULL);
+ if (sys_cntr[i] == 0.0) {
+ uint64_t x;
+ sscanf(value_str,"%llx",&x);
+ sys_cntr[i] = (double)x;
}
- outfd = fopen(output,"a");
} else {
- if (1) {
- fprintf(stderr,"report_bsd_test_results: report going to file stdout\n");
- fflush(stderr);
- }
- outfd = stdout;
+ sys_cntr[i] = 0.0;
}
- /* allocate and initialize report data if first time */
- my_data = malloc(sizeof(bsd_results_t) + 6 * max_count * sizeof(double));
- memset(my_data, 0,
- sizeof(sizeof(bsd_results_t) + 6 * max_count * sizeof(double)));
- my_data->max_count = max_count;
- my_data->results = &(my_data->results_start);
- my_data->xmit_results = &(my_data->results[max_count]);
- my_data->recv_results = &(my_data->xmit_results[max_count]);
- my_data->utilization = &(my_data->recv_results[max_count]);
- my_data->servdemand = &(my_data->utilization[max_count]);
- my_data->run_time = &(my_data->servdemand[max_count]);
- my_data->outfd = outfd;
- } else {
- outfd = my_data->outfd;
+ if (test_set->debug) {
+ fprintf(test_set->where,"\t%12s sys_stats[%d] = %10g '%s'\n",
+ sys_cntr_name[i], i, sys_cntr[i],
+ xmlGetProp(stats, (const xmlChar *)sys_cntr_name[i]));
+ }
}
- if (max_count != my_data->max_count) {
- /* someone is playing games don't generate report*/
- fprintf(stderr,"Max_count changed between invocations of %s\n",
- "report_bsd_test_results");
- fprintf(stderr,"exiting netperf now!!\n");
- fflush(stderr);
- exit;
+ local_cpus = sys_cntr[NUM_CPU];
+ elapsed_seconds = sys_cntr[E_SEC] + sys_cntr[E_USEC]/1000000;
+ calibration = sys_cntr[CALIBRATE];
+ local_idle = sys_cntr[IDLE] / calibration;
+ local_busy = (calibration-sys_cntr[IDLE])/calibration;
+
+ if (test_set->debug) {
+ fprintf(test_set->where,"\tnum_cpus = %f\n",local_cpus);
+ fprintf(test_set->where,"\telapsed_seconds = %7.2f\n",elapsed_seconds);
+ fprintf(test_set->where,"\tidle_cntr = %e\n",sys_cntr[IDLE]);
+ fprintf(test_set->where,"\tcalibrate_cntr = %e\n",sys_cntr[CALIBRATE]);
+ fprintf(test_set->where,"\tlocal_idle = %e\n",local_idle);
+ fprintf(test_set->where,"\tlocal_busy = %e\n",local_busy);
+ fflush(test_set->where);
}
-
- /* process statistics for this run */
- acc_results = 0.0;
- acc_xmit_rate = 0.0;
- acc_recv_rate = 0.0;
- run_time = 0.0;
- sys_seconds = 0.0;
- sys_util = 0.0;
- set_elt = test_set->tests;
- if (1) {
- fprintf(stderr,"test_set %s has %d tests looking for statistics\n",
- test_set->id,test_set->num_tests);
- fflush(stderr);
+ rd->utilization[index] += local_busy;
+ if (rd->print_test) {
+ /* Display per test results */
+ fprintf(outfd,"%3d ", count); /* 0,5 */
+ fprintf(outfd,"%-6s ", tid); /* 5,7 */
+ fprintf(outfd,"%-6.2f ",elapsed_seconds); /* 12,7 */
+ if (rd->sd_denominator != 1.0) {
+ fprintf(outfd,"%24s",""); /* 19,24*/
+ } else {
+ fprintf(outfd,"%11s",""); /* 19,11*/
+ }
+ fprintf(outfd,"%7.1e ",calibration); /* 43,8 */
+ fprintf(outfd,"%6.3f ",local_idle*100.0); /* 51,7 */
+ fprintf(outfd,"%6.3f ",local_busy*100.0); /* 58,7 */
+ fprintf(outfd,"\n"); /* 79,1 */
+ fflush(outfd);
}
+ /* end of printing sys stats instance results */
+}
+
+void
+process_stats_for_run(tset_t *test_set)
+{
+ bsd_results_t *rd;
+ test_t *test;
+ tset_elt_t *set_elt;
+ char *proc_name;
+ xmlNodePtr stats;
+ xmlNodePtr prev_stats;
+ int count;
+ int index;
+
+ rd = test_set->report_data;
+ proc_name = "process_stats_for_run";
+ set_elt = test_set->tests;
+ count = test_set->confidence.count;
+ index = count - 1;
+
+ if (test_set->debug) {
+ fprintf(test_set->where,
+ "test_set %s has %d tests looking for statistics\n",
+ test_set->id,test_set->num_tests);
+ fflush(test_set->where);
+ }
+
+ if (test_set->debug) {
+ fprintf(test_set->where, "%s count = %d\n", proc_name, count);
+ fflush(test_set->where);
+ }
+
+ rd->results[index] = 0.0;
+ rd->xmit_results[index] = 0.0;
+ rd->recv_results[index] = 0.0;
+ rd->utilization[index] = 0.0;
+ rd->servdemand[index] = 0.0;
+ rd->run_time[index] = 0.0;
+
while (set_elt != NULL) {
int stats_for_test;
-
- test = set_elt->test;
- stats = test->received_stats->xmlChildrenNode;
-
- if (test->debug) {
+ test = set_elt->test;
+ stats = test->received_stats->xmlChildrenNode;
+ if (test_set->debug) {
if (stats) {
- fprintf(test->where,"\ttest %s has '%s' statistics\n", test->id,stats->name);
+ fprintf(test_set->where,
+ "\ttest %s has '%s' statistics\n",
+ test->id,stats->name);
} else {
- fprintf(test->where,"\ttest %s has no statistics available!\n", test->id);
+ fprintf(test_set->where,
+ "\ttest %s has no statistics available!\n",
+ test->id);
}
- fflush(test->where);
+ fflush(test_set->where);
}
-
stats_for_test = 0;
while(stats != NULL) {
/* process all the statistics records for this test */
- if (test->debug) {
- fprintf(test->where,"\tfound some statistics");
- fflush(test->where);
+ if (test_set->debug) {
+ fprintf(test_set->where,"\tfound some statistics");
+ fflush(test_set->where);
}
if(!xmlStrcmp(stats->name,(const xmlChar *)"sys_stats")) {
/* process system statistics */
- test_stats = 0;
- if (test->debug) {
- fprintf(test->where,"\tprocessing sys_stats\n");
- fflush(test->where);
- }
- for (i=0; i<MAX_SYS_CNTRS; i++) {
- char *value_str =
- (char *)xmlGetProp(stats, (const xmlChar *)sys_cntr_name[i]);
- if (value_str) {
- sys_cntr[i] = strtod(value_str,NULL);
- if (sys_cntr[i] == 0.0) {
- uint64_t x;
- sscanf(value_str,"%llx",&x);
- sys_cntr[i] = (double)x;
- }
- } else {
- sys_cntr[i] = 0.0;
- }
- if (test->debug) {
- fprintf(test->where,"\t%12s sys_stats[%d] = %10g '%s'\n",
- sys_cntr_name[i], i, sys_cntr[i],
- xmlGetProp(stats, (const xmlChar *)sys_cntr_name[i]));
- }
- }
- local_cpus = sys_cntr[NUM_CPU];
- elapsed_seconds = sys_cntr[E_SEC] + sys_cntr[E_USEC]/1000000;
- result = 0.0;
- xmit_rate = 0.0;
- recv_rate = 0.0;
- calibration = sys_cntr[CALIBRATE];
- local_idle = sys_cntr[IDLE] / calibration;
- local_busy = (calibration-sys_cntr[IDLE])/calibration;
-
- if (test->debug) {
- fprintf(test->where,"\tnum_cpus = %f\n",local_cpus);
- fprintf(test->where,"\telapsed_seconds = %7.2f\n",elapsed_seconds);
- fprintf(test->where,"\tidle_cntr = %e\n",sys_cntr[IDLE]);
- fprintf(test->where,"\tcalibrate_cntr = %e\n",sys_cntr[CALIBRATE]);
- fprintf(test->where,"\tlocal_idle = %e\n",local_idle);
- fprintf(test->where,"\tlocal_busy = %e\n",local_busy);
- fflush(test->where);
- }
- if (stats_for_test == 0) {
- sys_stats_count++;
- }
+ process_sys_stats(test_set, stats, test->id);
stats_for_test++;
- sys_seconds += elapsed_seconds;
- sys_util += local_busy;
- } /* end of processing system statistics */
-
+ }
if(!xmlStrcmp(stats->name,(const xmlChar *)"test_stats")) {
/* process test statistics */
- test_stats = 1;
- if (test->debug) {
- fprintf(test->where,"\tprocessing test_stats\n");
- fflush(test->where);
- }
- for (i=0; i<MAX_TEST_CNTRS; i++) {
- char *value_str =
- (char *)xmlGetProp(stats, (const xmlChar *)cntr_name[i]);
- if (value_str) {
- test_cntr[i] = strtod(value_str,NULL);
- if (test_cntr[i] == 0.0) {
- uint64_t x;
- sscanf(value_str,"%llx",&x);
- test_cntr[i] = (double)x;
- }
- } else {
- test_cntr[i] = 0.0;
- }
- if (test->debug) {
- fprintf(test->where,"\t%12s test_cntr[%2d] = %10g\t'%s'\n",
- cntr_name[i], i, test_cntr[i],
- xmlGetProp(stats, (const xmlChar *)cntr_name[i]));
- }
- }
- elapsed_seconds = test_cntr[TST_E_SEC] + test_cntr[TST_E_USEC]/1000000;
- xmit_rate = test_cntr[TST_X_BYTES]*8/(elapsed_seconds*1000000);
- recv_rate = test_cntr[TST_R_BYTES]*8/(elapsed_seconds*1000000);
- xmit_trans_rate = test_cntr[TST_X_TRANS]/elapsed_seconds;
- recv_trans_rate = test_cntr[TST_R_TRANS]/elapsed_seconds;
- if (test->debug) {
- fprintf(test->where,"\txmit_rate = %7g\t%7g\n",
- xmit_rate, test_cntr[TST_X_BYTES]);
- fprintf(test->where,"\trecv_rate = %7g\t%7g\n",
- recv_rate, test_cntr[TST_R_BYTES]);
- fprintf(test->where,"\txmit_trans_rate = %7g\t%7g\n",
- xmit_trans_rate, test_cntr[TST_X_TRANS]);
- fprintf(test->where,"\trecv_trans_rate = %7g\t%7g\n",
- recv_trans_rate, test_cntr[TST_X_TRANS]);
- fflush(test->where);
- }
- if (sd_denominator == 0.0) {
- if (xmit_rate > 0.0 || recv_rate > 0.0) {
- sd_denominator = 1000000.0/(8.0*1024.0);
- } else {
- sd_denominator = 1.0;
- }
- }
- if (test->debug) {
- fprintf(test->where,"\tsd_denominator = %f\n",sd_denominator);
- fflush(test->where);
- }
- if (sd_denominator != 1.0) {
- result = recv_rate + xmit_rate;
- } else {
- result = recv_trans_rate + xmit_trans_rate;
- }
- if (test->debug) {
- fprintf(test->where,"\tresult = %f\n",result);
- fflush(test->where);
- }
- if (stats_for_test == 0) {
- test_stats_count++;
- }
+ process_test_stats(test_set, stats, test->id);
stats_for_test++;
-
- /* accumulate results for the run */
- run_time += elapsed_seconds;
- acc_results += result;
- acc_xmit_rate += xmit_rate;
- acc_recv_rate += recv_rate;
- } /* other types of nodes just get skipped by this report routine */
-
+ }
+ /* other types of nodes just get skipped by this report routine */
/* delete statistics entry from test */
prev_stats = stats;
stats = stats->next;
xmlUnlinkNode(prev_stats);
xmlFreeNode(prev_stats);
- } /* end of while to process all the statistics records for this test */
-
- /* should only have one stats record for this test otherwise error */
+ }
+ /* should only have one stats record for each test otherwise error */
if (stats_for_test > 1) {
/* someone is playing games don't generate report*/
- fprintf(test->where,"More than one statistics measurement for test %d\n",
+ fprintf(test_set->where,
+ "More than one statistics measurement for test %d\n",
stats_for_test);
- fprintf(test->where,"%s was not designed to deal with this.\n",
- "report_bsd_test_results");
- fprintf(test->where,"exiting netperf now!!\n");
- fflush(test->where);
+ fprintf(test_set->where,
+ "%s was not designed to deal with this.\n",
+ proc_name);
+ fprintf(test_set->where,
+ "exiting netperf now!!\n");
+ fflush(test_set->where);
exit;
}
-
+ set_elt = set_elt->next;
+ }
+ if (rd->result_minimum > rd->results[index]) {
+ rd->result_minimum = rd->results[index];
+ }
+ if (rd->result_maximum < rd->results[index]) {
+ rd->result_maximum = rd->results[index];
+ }
+}
- /* start printing bsd per statistics instance results */
- if ((flags && BSD_PER_TEST_FLAG) &&
- (last_hdr != BSD_PER_TEST_HDR)) {
- /* Display per test header */
- fprintf(outfd,"\n");
- fprintf(outfd,"INST ");
- fprintf(outfd,"TEST ");
- fprintf(outfd,"TEST ");
- if (sd_denominator != 1.0) {
- fprintf(outfd," DATA ");
- fprintf(outfd," XMIT ");
- fprintf(outfd," RECV ");
- } else {
- fprintf(outfd," TRANS ");
- }
- fprintf(outfd," CPU ");
- fprintf(outfd," CPU ");
-#ifndef HPUX_1123
- fprintf(outfd," CPU ");
-#else
- fprintf(outfd," CPU ");
- fprintf(outfd," CPU ");
- fprintf(outfd," CPU ");
-#endif
- fprintf(outfd,"\n");
+void
+update_results_and_confidence(tset_t *test_set)
+{
+ bsd_results_t *rd;
+ double confidence;
- fprintf(outfd,"NUM ");
- fprintf(outfd,"Name ");
- fprintf(outfd,"Time ");
- if (sd_denominator != 1.0) {
- fprintf(outfd," RATE ");
- fprintf(outfd," RATE ");
- fprintf(outfd," RATE ");
- } else {
- fprintf(outfd," RATE ");
- }
- fprintf(outfd," CALI ");
- fprintf(outfd," IDLE ");
-#ifndef HPUX_1123
- fprintf(outfd," BUSY ");
-#else
- fprintf(outfd," USER ");
- fprintf(outfd," SYS ");
- fprintf(outfd," INTR ");
-#endif
- fprintf(outfd,"\n");
+ rd = test_set->report_data;
- fprintf(outfd," ");
- fprintf(outfd," ");
- fprintf(outfd,"sec ");
- if (sd_denominator != 1.0) {
- fprintf(outfd," mb/s ");
- fprintf(outfd," mb/s ");
- fprintf(outfd," mb/s ");
- } else {
- fprintf(outfd," trans/s ");
- }
- fprintf(outfd," cnt/s ");
- fprintf(outfd," %% ");
-#ifndef HPUX_1123
- fprintf(outfd," %% ");
-#else
- fprintf(outfd," %% ");
- fprintf(outfd," %% ");
- fprintf(outfd," %% ");
-#endif
- fprintf(outfd,"\n");
- fflush(outfd);
- last_hdr = BSD_PER_TEST_HDR;
+ /* calculate confidence and summary result values */
+ confidence = get_confidence(rd->run_time,
+ &(test_set->confidence),
+ &(rd->ave_time));
+ rd->result_confidence = get_confidence(rd->results,
+ &(test_set->confidence),
+ &(rd->result_measured_mean));
+ rd->cpu_util_confidence = get_confidence(rd->utilization,
+ &(test_set->confidence),
+ &(rd->cpu_util_measured_mean));
+ rd->service_demand_confidence = get_confidence(rd->servdemand,
+ &(test_set->confidence),
+ &(rd->service_demand_measured_mean));
+ if (rd->result_confidence > rd->cpu_util_confidence) {
+ if (rd->cpu_util_confidence > rd->service_demand_confidence) {
+ confidence = rd->service_demand_confidence;
+ } else {
+ confidence = rd->cpu_util_confidence;
}
-
- if (flags && BSD_PER_TEST_FLAG) {
- /* Display per test results */
- /* Display per run results */
- fprintf(outfd,"%-3d ", count+1); /* 0,5 */
- fprintf(outfd,"%-6s ", test->id); /* 5,7 */
- fprintf(outfd,"%-6.2f ",elapsed_seconds); /* 12,7 */
- if (test_stats) {
- if (sd_denominator != 1.0) {
- fprintf(outfd,"%7.2f ",result); /* 19,8 */
- fprintf(outfd,"%7.2f ",xmit_rate); /* 27,8 */
- fprintf(outfd,"%7.2f ",recv_rate); /* 35,8 */
- } else {
- fprintf(outfd,"%10.2f ",result); /* 19,11 */
- }
- } else {
- if (sd_denominator != 1.0) {
- fprintf(outfd,"%24s",""); /* 19,24*/
- } else {
- fprintf(outfd,"%11s",""); /* 19,11*/
- }
- fprintf(outfd,"%7.1e ",calibration); /* 43,8 */
- fprintf(outfd,"%6.3f ",local_idle*100.0); /* 51,7 */
-#ifndef HPUX_1123
- fprintf(outfd,"%6.3f ",local_busy*100.0); /* 58,7 */
-#else
- fprintf(outfd,"%6.3f ",local_user*100.0); /* 58,7 */
- fprintf(outfd,"%6.3f ",local_syst*100.0); /* 65,7 */
- fprintf(outfd,"%6.3f ",local_intr*100.0); /* 72,7 */
-#endif
- }
- fprintf(outfd,"\n"); /* 79,1 */
+ } else {
+ if (rd->result_confidence > rd->service_demand_confidence) {
+ confidence = rd->service_demand_confidence;
+ } else {
+ confidence = rd->result_confidence;
}
- /* end of printing bsd per test instance results */
+ }
+ test_set->confidence.value = confidence;
+}
- set_elt = set_elt->next;
- } /* end of while loop to collect per run results */
+void
+print_run_results(tset_t *test_set)
+{
+ bsd_results_t *rd;
+ FILE *outfd;
+ int i;
+ int count;
+ int index;
- /* should only have one system stats count otherwise error */
- if (sys_stats_count > 1) {
- /* someone is playing games don't generate report*/
- fprintf(test->where,"More than one system statistics measurement %d\n",
- sys_stats_count);
- fprintf(test->where,"%s was not designed to deal with this.\n",
- "report_bsd_test_results");
- fprintf(test->where,"exiting netperf now!!\n");
- fflush(test->where);
- exit;
- }
-
- run_time = run_time / test_stats_count;
- service_demand = 1000000*local_cpus*sys_util/(acc_results*sd_denominator);
+#define HDR_LINES 3
+ char *field1[HDR_LINES] = { "INST", "NUM", " " }; /* 4 */
+ char *field2[HDR_LINES] = { "SET", "Name", " " }; /* 6 */
+ char *field3[HDR_LINES] = { "RUN", "Time", "sec" }; /* 6 */
+ char *field4A[HDR_LINES] = { "DATA", "RATE", "mb/s" }; /* 7 */
+ char *field4B[HDR_LINES] = { "TRANS", "RATE", "tran/s" }; /* 7 */
+ char *field5[HDR_LINES] = { "XMIT", "Rate", "mb/s" }; /* 7 */
+ char *field6[HDR_LINES] = { "RECV", "Rate", "mb/s" }; /* 7 */
+ char *field7[HDR_LINES] = { "SD", "usec", "/KB" }; /* 7 */
+ char *field8[HDR_LINES] = { "CPU", "Util", "%/100" }; /* 6 */
+#ifdef OFF
+ char *field9[HDR_LINES] = { "???", "???", "???" }; /* 6 */
+ char *field10[HDR_LINES] = { "???", "???", "???" }; /* 6 */
+ char *field11[HDR_LINES] = { "???", "???", "???" }; /* 6 */
+#endif
- /* save per run results for confidence calculations */
- my_data->results[count] = acc_results;
- my_data->xmit_results[count] = acc_xmit_rate;
- my_data->recv_results[count] = acc_recv_rate;
- my_data->utilization[count] = sys_util;
- my_data->servdemand[count] = service_demand;
- my_data->run_time[count] = run_time;
- count++;
-
- /* start printing bsd per run result summary */
- if ((flags && BSD_PER_RUN_FLAG) &&
- (last_hdr != BSD_PER_RUN_HDR)) {
- fprintf(outfd,"\n");
- /* Display per run header */
- fprintf(outfd,"INST ");
- fprintf(outfd,"SET ");
- fprintf(outfd,"RUN ");
- if (sd_denominator != 1.0) {
- fprintf(outfd," DATA ");
- fprintf(outfd," XMIT ");
- fprintf(outfd," RECV ");
- } else {
- fprintf(outfd," TRANS ");
- }
- fprintf(outfd," SD ");
- fprintf(outfd," CPU ");
- fprintf(outfd," ");
- fprintf(outfd," ");
- fprintf(outfd," ");
- fprintf(outfd,"\n");
+ rd = test_set->report_data;
+ count = test_set->confidence.count;
+ outfd = rd->outfd;
+ index = count - 1;
- fprintf(outfd,"NUM ");
- fprintf(outfd,"Name ");
- fprintf(outfd,"Time ");
- if (sd_denominator != 1.0) {
- fprintf(outfd," RATE ");
- fprintf(outfd," Rate ");
- fprintf(outfd," Rate ");
- } else {
- fprintf(outfd," RATE ");
- }
- fprintf(outfd," usec ");
- fprintf(outfd," Util ");
- fprintf(outfd," ");
- fprintf(outfd," ");
- fprintf(outfd," ");
- fprintf(outfd,"\n");
- fprintf(outfd," ");
- fprintf(outfd," ");
- fprintf(outfd,"sec ");
- if (sd_denominator != 1.0) {
- fprintf(outfd," mb/s ");
- fprintf(outfd," mb/s ");
- fprintf(outfd," mb/s ");
+ /* Display per run header */
+ fprintf(outfd,"\n");
+ for (i=0;i < HDR_LINES; i++) {
+ fprintf(outfd,"%-4s ",field1[i]); /* 0,5 */
+ fprintf(outfd,"%-6s ",field2[i]); /* 5,7 */
+ fprintf(outfd,"%-6s ",field3[i]); /* 12,7 */
+ if (rd->sd_denominator != 1.0) {
+ fprintf(outfd,"%7s ",field4A[i]); /* 19,8 */
+ fprintf(outfd,"%7s ",field5[i]); /* 27,8 */
+ fprintf(outfd,"%7s ",field6[i]); /* 35,8 */
} else {
- fprintf(outfd," trans/s ");
+ fprintf(outfd,"%10s ",field4B[i]); /* 19,11 */
}
- fprintf(outfd," /KB ");
- fprintf(outfd," %%/100 ");
- fprintf(outfd," ");
- fprintf(outfd," ");
- fprintf(outfd," ");
+ fprintf(outfd,"%7s ",field7[i]); /* 43,8 */
+ fprintf(outfd,"%6s ",field8[i]); /* 51,7 */
+#ifdef OFF
+ fprintf(outfd,"%6s ",field9[i]); /* 58,7 */
+ fprintf(outfd,"%6s ",field10[i]); /* 65,7 */
+ fprintf(outfd,"%6s ",field11[i]); /* 72,7 */
+#endif
fprintf(outfd,"\n");
- fflush(outfd);
- last_hdr = BSD_PER_RUN_HDR;
}
-
- if (flags && BSD_PER_RUN_FLAG) {
- /* Display per run results */
- fprintf(outfd,"%-3d ", count); /* 0,5 */
- fprintf(outfd,"%-6s ", test_set->id); /* 5,7 */
- fprintf(outfd,"%-6.2f ",run_time); /* 12,7 */
- if (sd_denominator != 1.0) {
- fprintf(outfd,"%7.2f ",acc_results); /* 19,8 */
- fprintf(outfd,"%7.2f ",acc_xmit_rate); /* 27,8 */
- fprintf(outfd,"%7.2f ",acc_recv_rate); /* 35,8 */
- } else {
- fprintf(outfd,"%10.2f ",acc_results); /* 19,11*/
- }
- fprintf(outfd,"%7.3f ",service_demand); /* 43,8 */
- fprintf(outfd,"%6.4f ",sys_util); /* 51,7 */
+
+ /* Display per run results */
+ fprintf(outfd,"%-3d ", count); /* 0,5 */
+ fprintf(outfd,"%-6s ", test_set->id); /* 5,7 */
+ fprintf(outfd,"%-6.2f ",rd->run_time[index]); /* 12,7 */
+ if (rd->sd_denominator != 1.0) {
+ fprintf(outfd,"%7.2f ",rd->results[index]); /* 19,8 */
+ fprintf(outfd,"%7.2f ",rd->xmit_results[index]); /* 27,8 */
+ fprintf(outfd,"%7.2f ",rd->recv_results[index]); /* 35,8 */
+ } else {
+ fprintf(outfd,"%10.2f ",rd->results[index]); /* 19,11*/
+ }
+ fprintf(outfd,"%7.3f ",rd->servdemand[index]); /* 43,8 */
+ fprintf(outfd,"%6.4f ",rd->utilization[index]); /* 51,7 */
#ifdef OFF
- fprintf(outfd,"%6.4f ",something to be added later); /* 58,7 */
- fprintf(outfd,"%6.4f ",something to be added later); /* 65,7 */
- fprintf(outfd,"%6.4f ",something to be added later); /* 72,7 */
+ fprintf(outfd,"%6.4f ",something to be added later); /* 58,7 */
+ fprintf(outfd,"%6.4f ",something to be added later); /* 65,7 */
+ fprintf(outfd,"%6.4f ",something to be added later); /* 72,7 */
#endif
- fprintf(outfd,"\n"); /* 79,1 */
- }
- /* end of printing bsd per run result summary */
- /* start printing bsd per run result summary */
-
- /* calculate confidence and summary result values */
- elapsed_seconds = get_confidence(my_data->run_time,
- &(test_set->confidence),
- &ave_time);
- result_confidence = get_confidence(my_data->results,
- &(test_set->confidence),
- &result_measured_mean);
- cpu_util_confidence = get_confidence(my_data->utilization,
- &(test_set->confidence),
- &cpu_util_measured_mean);
- serv_demand_confidence = get_confidence(my_data->servdemand,
- &(test_set->confidence),
- &service_demand_measured_mean);
- xmit_confidence = get_confidence(my_data->xmit_results,
- &(test_set->confidence),
- &xmit_measured_mean);
- recv_confidence = get_confidence(my_data->recv_results,
- &(test_set->confidence),
- &recv_measured_mean);
- if (result_confidence > cpu_util_confidence) {
- if (cpu_util_confidence > serv_demand_confidence) {
- confidence = serv_demand_confidence;
- } else {
- confidence = cpu_util_confidence;
+ fprintf(outfd,"\n"); /* 79,1 */
+ fflush(outfd);
+}
+
+void
+print_results_summary(tset_t *test_set)
+{
+ bsd_results_t *rd;
+ FILE *outfd;
+ int i;
+
+#define HDR_LINES 3
+ /* field
+ width*/
+ char *field1[HDR_LINES] = { "AVE", "Over", "Num" }; /* 4 */
+ char *field2[HDR_LINES] = { "SET", "Name", " " }; /* 6 */
+ char *field3[HDR_LINES] = { "TEST", "Time", "sec" }; /* 6 */
+ char *field4A[HDR_LINES] = { "DATA", "RATE", "mb/s" }; /* 7 */
+ char *field5A[HDR_LINES] = { "conf", "+/-", "mb/s" }; /* 7 */
+ char *field6A[HDR_LINES] = { "Min", "Rate", "mb/s" }; /* 7 */
+ char *field7A[HDR_LINES] = { "Max", "Rate", "mb/s" }; /* 7 */
+ char *field8[HDR_LINES] = { "CPU", "Util", "%/100" }; /* 6 */
+ char *field9[HDR_LINES] = { "+/-", "Util", "%/100" }; /* 6 */
+ char *field10A[HDR_LINES] = { "SD", "usec", "/KB" }; /* 6 */
+ char *field11A[HDR_LINES] = { "+/-", "usec", "/KB" }; /* 6 */
+
+ char *field4B[HDR_LINES] = { "TRANS", "RATE", "tran/s" }; /* 7 */
+ char *field5B[HDR_LINES] = { "conf", "+/-", "tran/s" }; /* 7 */
+ char *field6B[HDR_LINES] = { "Min", "Rate", "tran/s" }; /* 7 */
+ char *field7B[HDR_LINES] = { "Max", "Rate", "tran/s" }; /* 7 */
+
+ char *field10B[HDR_LINES] = { "SD", "usec", "/tran" }; /* 6 */
+ char *field11B[HDR_LINES] = { "+/-", "usec", "/tran" }; /* 6 */
+
+ char *field4[HDR_LINES];
+ char *field5[HDR_LINES];
+ char *field6[HDR_LINES];
+ char *field7[HDR_LINES];
+
+ char *field10[HDR_LINES];
+ char *field11[HDR_LINES];
+
+ rd = test_set->report_data;
+ outfd = rd->outfd;
+
+ if (rd->sd_denominator != 1.0) {
+ for (i = 0; i < HDR_LINES; i++) {
+ field4[i] = field4A[i];
+ field5[i] = field5A[i];
+ field6[i] = field6A[i];
+ field7[i] = field7A[i];
+ field10[i] = field10A[i];
+ field11[i] = field11A[i];
}
} else {
- if (result_confidence > serv_demand_confidence) {
- confidence = serv_demand_confidence;
- } else {
- confidence = result_confidence;
+ for (i = 0; i < HDR_LINES; i++) {
+ field4[i] = field4B[i];
+ field5[i] = field5B[i];
+ field6[i] = field6B[i];
+ field7[i] = field7B[i];
+ field10[i] = field10B[i];
+ field11[i] = field11B[i];
}
}
- test_set->confidence.value = confidence;
- /* start printing bsd test result summary */
- if (last_hdr != BSD_SUMMARY_HDR) {
- /* Display summary header */
+ /* Print the summary header */
+ fprintf(outfd,"\n");
+ for (i = 0; i < HDR_LINES; i++) {
+ fprintf(outfd,"%-4s ",field1[i]); /* 0,5 */
+ fprintf(outfd,"%-6s ",field2[i]); /* 5,7 */
+ fprintf(outfd,"%-6s ",field3[i]); /* 12,7 */
+ fprintf(outfd,"%7s ",field4[i]); /* 19,8 */
+ fprintf(outfd,"%7s ",field5[i]); /* 27,8 */
+ fprintf(outfd,"%7s ",field6[i]); /* 35,8 */
+ fprintf(outfd,"%7s ",field7[i]); /* 43,8 */
+ fprintf(outfd,"%6s ",field8[i]); /* 51,7 */
+ fprintf(outfd,"%6s ",field9[i]); /* 58,7 */
+ fprintf(outfd,"%6s ",field10[i]); /* 65,7 */
+ fprintf(outfd,"%6s ",field11[i]); /* 72,7 */
fprintf(outfd,"\n");
- fprintf(outfd,"AVE ");
- fprintf(outfd,"SET ");
- fprintf(outfd,"TEST ");
- if (sd_denominator != 1.0) {
- fprintf(outfd," DATA ");
- } else {
- fprintf(outfd," TRANS ");
- }
- fprintf(outfd," conf ");
- fprintf(outfd," Min ");
- fprintf(outfd," Max ");
- fprintf(outfd," CPU ");
- fprintf(outfd," +/- ");
- fprintf(outfd," SD ");
- fprintf(outfd," +/- ");
- fprintf(outfd,"\n");
+ }
- fprintf(outfd,"Over ");
- fprintf(outfd,"Name ");
- fprintf(outfd,"Time ");
- if (sd_denominator != 1.0) {
- fprintf(outfd," RATE ");
- } else {
- fprintf(outfd," RATE ");
- }
- fprintf(outfd," +/- ");
- fprintf(outfd," Rate ");
- fprintf(outfd," Rate ");
- fprintf(outfd," Util ");
- fprintf(outfd," Util ");
- fprintf(outfd," usec ");
- fprintf(outfd," usec ");
- fprintf(outfd,"\n");
+ /* print the summary results line */
+ fprintf(outfd,"A%-3d ",test_set->confidence.count); /* 0,5 */
+ fprintf(outfd,"%-6s ",test_set->id); /* 5,7 */
+ fprintf(outfd,"%-6.2f ",rd->ave_time); /* 12,7 */
+ if (rd->sd_denominator != 1.0) {
+ fprintf(outfd,"%7.2f ",rd->result_measured_mean); /* 19,8 */
+ fprintf(outfd,"%7.3f ",rd->result_confidence); /* 27,8 */
+ fprintf(outfd,"%7.2f ",rd->result_minimum); /* 35,8 */
+ fprintf(outfd,"%7.2f ",rd->result_maximum); /* 43,8 */
+ } else {
+ fprintf(outfd,"%7.0f ",rd->result_measured_mean); /* 19,8 */
+ fprintf(outfd,"%7.2f ",rd->result_confidence); /* 27,8 */
+ fprintf(outfd,"%7.0f ",rd->result_minimum); /* 35,8 */
+ fprintf(outfd,"%7.0f ",rd->result_maximum); /* 43,8 */
+ }
+ fprintf(outfd,"%6.4f ",rd->cpu_util_measured_mean); /* 51,7 */
+ fprintf(outfd,"%6.4f ",rd->cpu_util_confidence); /* 58,7 */
+ fprintf(outfd,"%6.3f ",rd->service_demand_measured_mean); /* 65,7 */
+ fprintf(outfd,"%6.3f ",rd->service_demand_confidence); /* 72,7 */
+ fprintf(outfd,"\n"); /* 79,1 */
+ fflush(outfd);
+}
- fprintf(outfd,"Num ");
- fprintf(outfd," ");
- fprintf(outfd,"sec ");
- if (sd_denominator != 1.0) {
- fprintf(outfd," mb/s ");
- fprintf(outfd," mb/s ");
- fprintf(outfd," mb/s ");
- fprintf(outfd," mb/s ");
- } else {
- fprintf(outfd," tran/s ");
- fprintf(outfd," tran/s ");
- fprintf(outfd," tran/s ");
- fprintf(outfd," tran/s ");
- }
- fprintf(outfd," %%/100 ");
- fprintf(outfd," %%/100 ");
- fprintf(outfd," /KB ");
- fprintf(outfd," /KB ");
- fprintf(outfd,"\n");
- fflush(outfd);
- last_hdr = BSD_SUMMARY_HDR;
+void
+report_bsd_test_results(tset_t *test_set, char *report_flags, char *output)
+{
+ bsd_results_t *rd;
+ int count;
+ int max_count;
+ int min_count;
+
+ rd = test_set->report_data;
+
+ if (rd == NULL) {
+ bsd_test_results_init(test_set,report_flags,output);
+ rd = test_set->report_data;
}
+
+ /* process statistics for this run */
+ process_stats_for_run(test_set);
+ /* calculate confidence and summary result values */
+ update_results_and_confidence(test_set);
+ if (rd->print_run) {
+ print_run_results(test_set);
+ }
+
+ count = test_set->confidence.count;
+ max_count = test_set->confidence.max_count;
+ min_count = test_set->confidence.min_count;
/* always print summary results at end of last call through loop */
- if ((count == max_count) || ((confidence >= 0) && (count >= min_count))) {
- double result_minimum = MAXDOUBLE;
- double result_maximum = MINDOUBLE;
- for (i = 0; i < count; i++) {
- if (result_minimum > my_data->results[i]) {
- result_minimum = my_data->results[i];
- }
- if (result_maximum < my_data->results[i]) {
- result_maximum = my_data->results[i];
- }
- }
- fprintf(outfd,"A%-3d ",count); /* 0,5 */
- fprintf(outfd,"%-6s ",test_set->id); /* 5,7 */
- fprintf(outfd,"%-6.2f ",ave_time); /* 12,7 */
- if (sd_denominator != 1.0) {
- fprintf(outfd,"%7.2f ",result_measured_mean); /* 19,8 */
- fprintf(outfd,"%7.3f ",result_confidence); /* 27,8 */
- fprintf(outfd,"%7.2f ",result_minimum); /* 35,8 */
- fprintf(outfd,"%7.2f ",result_maximum); /* 43,8 */
- } else {
- fprintf(outfd,"%7.0f ",result_measured_mean); /* 19,8 */
- fprintf(outfd,"%7.2f ",result_confidence); /* 27,8 */
- fprintf(outfd,"%7.0f ",result_minimum); /* 35,8 */
- fprintf(outfd,"%7.0f ",result_maximum); /* 43,8 */
- }
- fprintf(outfd,"%6.4f ",cpu_util_measured_mean); /* 51,7 */
- fprintf(outfd,"%6.4f ",cpu_util_confidence); /* 58,7 */
- fprintf(outfd,"%6.3f ",service_demand_measured_mean); /* 65,7 */
- fprintf(outfd,"%6.3f ",serv_demand_confidence); /* 72,7 */
- fprintf(outfd,"\n"); /* 79,1 */
- fflush(outfd);
- free(my_data);
+ if (count == max_count) {
+
+/* if ((count == max_count) ||
+ ((rd->confidence >= 0) && (count >= min_count))) */
+
+ print_results_summary(test_set);
}
- /* end of printing bsd test result summary */
- /* start printing bsd test result summary */
- /* end of printing bsd test result summary */
-
} /* end of report_bsd_test_results */
Modified: trunk/src/nettest_bsd.h
===================================================================
--- trunk/src/nettest_bsd.h 2005-11-14 22:43:30 UTC (rev 17)
+++ trunk/src/nettest_bsd.h 2005-11-17 04:17:04 UTC (rev 18)
@@ -56,9 +56,12 @@
typedef struct bsd_test_data {
/* address information */
- struct addrinfo *locaddr; /* local address informtion */
- struct addrinfo *remaddr; /* remote address informtion */
+ struct addrinfo *locaddr; /* local address informtion */
+ struct addrinfo *remaddr; /* remote address informtion */
+ int s_listen; /* listen sockets for catching type tests */
+ int s_data; /* data socket for executing tests */
+
struct ring_elt *send_ring; /* address of the send_ring */
struct ring_elt *recv_ring; /* address of the recv_ring */
FILE *fill_source; /* pointer to file for filling rings */
@@ -122,18 +125,33 @@
typedef struct bsd_results_data {
int max_count;
+ int print_test;
+ int print_run;
FILE *outfd;
double *results;
double *xmit_results;
double *recv_results;
+ double *trans_results;
double *utilization;
double *servdemand;
double *run_time;
- double results_start;
+ double ave_time;
+ double result_measured_mean;
+ double result_confidence;
+ double result_minimum;
+ double result_maximum;
+ double cpu_util_measured_mean;
+ double cpu_util_confidence;
+ double service_demand_measured_mean;
+ double service_demand_confidence;
+ double confidence;
+ double sd_denominator;
+ double results_start; /* must be the last field in structure */
} bsd_results_t;
/* Error codes to be used within nettest_bsd */
enum {
+ BSDE_MAX_ERROR = -32,
BSDE_SOCKET_SHUTDOWN_FAILED,
BSDE_BIND_FAILED,
BSDE_GETADDRINFO_ERROR,
@@ -149,6 +167,7 @@
BSDE_DATA_RECV_ERROR,
BSDE_TEST_STATE_CORRUPTED,
BSDE_CONNECT_FAILED,
+ BSDE_DATA_CONNECTION_CLOSED_ERROR,
BSDE_DATA_SEND_ERROR=-1,
BSDE_SUCCESS = 0
};
More information about the netperf-dev
mailing list