[netperf-dev] netperf2 commit notice r193 - trunk/src
raj at netperf.org
raj at netperf.org
Wed Jan 30 16:57:06 PST 2008
Author: raj
Date: 2008-01-30 16:57:05 -0800 (Wed, 30 Jan 2008)
New Revision: 193
Modified:
trunk/src/nettest_omni.c
Log:
the omni o and O options now optionally take a filename to specify the output to provide
Modified: trunk/src/nettest_omni.c
===================================================================
--- trunk/src/nettest_omni.c 2008-01-30 02:08:26 UTC (rev 192)
+++ trunk/src/nettest_omni.c 2008-01-31 00:57:05 UTC (rev 193)
@@ -226,6 +226,9 @@
#define NETPERF_CC(x) (!(x & NETPERF_XMIT) && !(x & NETPERF_RECV))
/* a boatload of globals while I settle things out */
+char *csv_selection_file = NULL;
+char *human_selection_file = NULL;
+
double result_confid_pct = -1.0;
double loc_cpu_confid_pct = -1.0;
double rem_cpu_confid_pct = -1.0;
@@ -757,6 +760,295 @@
fflush(where);
}
+#define MY_MAX(a,b) (a > b) ? a : b
+
+#define NETPERF_LINE_MAX(x) \
+ MY_MAX(MY_MAX(MY_MAX(strlen(netperf_output_source[x].line[0]),\
+ strlen(netperf_output_source[x].line[1])),\
+ strlen(netperf_output_source[x].line[2])),\
+ strlen(netperf_output_source[x].line[3]))
+
+#define NETPERF_LINE_TOT(x) \
+ strlen(netperf_output_source[x].line[0]) +\
+ strlen(netperf_output_source[x].line[1]) +\
+ strlen(netperf_output_source[x].line[2]) +\
+ strlen(netperf_output_source[x].line[3]) + 4
+
+enum netperf_output_name
+match_string_to_output(char *candidate)
+{
+ char *h1,*temp;
+ enum netperf_output_name name;
+ int k,len;
+
+ /* at some point we may need/want to worry about leading and
+ trailing spaces, but for now we will leave that onus on the
+ user. */
+
+ for (name = OUTPUT_NONE; name < NETPERF_OUTPUT_MAX; name++) {
+ /* try for a match based on the nmemonic/enum */
+ if (!strcasecmp(candidate,netperf_output_enum_to_str(name)))
+ return name;
+
+ /* try for a match on the actual header text */
+ temp = malloc(NETPERF_LINE_TOT(name));
+ h1 = temp;
+ if (h1 != NULL) {
+ for (k = 0; ((k < 4) &&
+ (NULL != netperf_output_source[name].line[k]) &&
+ (strcmp("",netperf_output_source[name].line[k]))); k++) {
+ len = sprintf(h1,
+ "%s",
+ netperf_output_source[name].line[k]);
+ *(h1 + len) = ' ';
+ /* now move to the next starting column. for csv we aren't worried
+ about alignment between the header and the value lines */
+ h1 += len + 1;
+ }
+ /* this time we want null termination please */
+ *(h1 - 1) = 0;
+ if (!strcasecmp(candidate,temp)) {
+ free(temp);
+ return name;
+ }
+ else
+ free(temp);
+ }
+ }
+ /* if we get here it means there was no match */
+ return OUTPUT_NONE;
+}
+
+void
+parse_output_csv_selection_file(char *selection_file) {
+ FILE *selections;
+ char name[81]; /* best be more than enough */
+ int namepos;
+ int c;
+ int j;
+ enum netperf_output_name match;
+ int line,column;
+
+ selections = fopen(selection_file,"r");
+ if (!selections) {
+ perror("Could Not Open output selection file");
+ exit(-1);
+ }
+
+ /* should this really be necessary? */
+ rewind(selections);
+
+ line = 0;
+ column = 1;
+ namepos = 0;
+ name[0] = 0;
+ name[80] = 0;
+ j = 0;
+ while (((c = fgetc(selections)) != EOF) && (line < 1)) {
+ if (namepos == 80) {
+ /* too long */
+
+ fprintf(where,
+ "Output selection starting column %d on line %d is too long\n",
+ line + 1,
+ column);
+ fflush(where);
+ exit(-1);
+ }
+ if (c == ',') {
+ /* time to check for a match, but only if we won't overflow the
+ current row of the array */
+ if (j == NETPERF_OUTPUT_MAX) {
+ fprintf(where,"Too many output selectors on line %d\n",line);
+ fflush(where);
+ exit(-1);
+ }
+ name[namepos] = 0;
+ output_csv_list[j++] = match_string_to_output(name);
+ namepos = 0;
+ }
+ else if (c == '\n') {
+ /* move to the next line after checking for a match */
+ name[namepos] = 0;
+ output_csv_list[j++] = match_string_to_output(name);
+ line++;
+ namepos = 0;
+ j = 0;
+ }
+ else if (isprint(c)) {
+ name[namepos++] = c;
+ }
+ column++;
+ }
+
+ /* ok, do we need/want to do anything here? at present we will
+ silently ignore the rest of the file if we exit the loop on line
+ count */
+ if ((c == EOF) && (namepos > 0)) {
+ name[namepos] = 0;
+ output_csv_list[j] = match_string_to_output(name);
+ }
+}
+void
+parse_output_human_selection_file(char *selection_file) {
+ FILE *selections;
+ char name[81]; /* best be more than enough */
+ int namepos;
+ char c;
+ int j;
+ enum netperf_output_name match;
+ int line,column;
+
+ selections = fopen(selection_file,"r");
+ if (!selections) {
+ perror("Could Not Open output selection file");
+ exit(-1);
+ }
+
+ line = 0;
+ column = 1;
+ namepos = 0;
+ name[0] = 0;
+ name[80] = 0;
+ j = 0;
+ while (((c = fgetc(selections)) != EOF) && (line < 4)) {
+ if (namepos == 80) {
+ /* too long */
+
+ fprintf(where,
+ "Output selection starting column %d on line %d is too long\n",
+ line + 1,
+ column);
+ fflush(where);
+ exit(-1);
+ }
+ if (c == ',') {
+ /* time to check for a match, but only if we won't overflow the
+ current row of the array */
+ if (j == NETPERF_OUTPUT_MAX) {
+ fprintf(where,"Too many output selectors on line %d\n",line);
+ fflush(where);
+ exit(-1);
+ }
+ name[namepos] = 0;
+ output_human_list[line][j++] = match_string_to_output(name);
+ namepos = 0;
+ }
+ else if (c == '\n') {
+ /* move to the next line after checking for a match */
+ name[namepos] = 0;
+ output_human_list[line++][j++] = match_string_to_output(name);
+ namepos = 0;
+ j = 0;
+ }
+ else if (isprint(c)) {
+ name[namepos++] = c;
+ }
+ column++;
+ }
+
+ /* ok, do we need/want to do anything here? at present we will
+ silently ignore the rest of the file if we exit the loop on line
+ count */
+ if ((c == EOF) && (namepos > 0)) {
+ name[namepos] = 0;
+ output_human_list[line][j] = match_string_to_output(name);
+ }
+
+}
+
+void
+set_output_csv_list_default() {
+
+ int i = 0;
+ output_csv_list[i++] = SOCKET_TYPE;
+ output_csv_list[i++] = PROTOCOL;
+ output_csv_list[i++] = DIRECTION;
+ output_csv_list[i++] = LSS_SIZE_REQ;
+ output_csv_list[i++] = LSS_SIZE;
+ output_csv_list[i++] = LSS_SIZE_END;
+ output_csv_list[i++] = RSS_SIZE_REQ;
+ output_csv_list[i++] = RSS_SIZE;
+ output_csv_list[i++] = RSS_SIZE_END;
+ output_csv_list[i++] = LOCAL_SEND_SIZE;
+ output_csv_list[i++] = LOCAL_RECV_SIZE;
+ output_csv_list[i++] = REQUEST_SIZE;
+ output_csv_list[i++] = REMOTE_SEND_SIZE;
+ output_csv_list[i++] = REMOTE_RECV_SIZE;
+ output_csv_list[i++] = RESPONSE_SIZE;
+ output_csv_list[i++] = THROUGHPUT;
+ output_csv_list[i++] = THROUGHPUT_UNITS;
+ output_csv_list[i++] = LOCAL_CPU_UTIL;
+ output_csv_list[i++] = LOCAL_SD;
+ output_csv_list[i++] = LOCAL_CPU_BIND;
+ output_csv_list[i++] = LOCAL_CPU_COUNT;
+ output_csv_list[i++] = REMOTE_CPU_UTIL;
+ output_csv_list[i++] = REMOTE_SD;
+ output_csv_list[i++] = SD_UNITS;
+ output_csv_list[i++] = REMOTE_CPU_BIND;
+ output_csv_list[i++] = REMOTE_CPU_COUNT;
+ output_csv_list[i++] = CONFIDENCE_LEVEL;
+ output_csv_list[i++] = CONFIDENCE_INTERVAL;
+ output_csv_list[i++] = THROUGHPUT_CONFID;
+ output_csv_list[i++] = LOCAL_CPU_CONFID;
+ output_csv_list[i++] = REMOTE_CPU_CONFID;
+ output_csv_list[i++] = CONFIDENCE_ITERATION;
+ output_csv_list[i++] = RT_LATENCY;
+ output_csv_list[i++] = BURST_SIZE;
+ output_csv_list[i++] = TRANSPORT_MSS;
+ output_csv_list[i++] = LOCAL_BYTES_SENT;
+ output_csv_list[i++] = LOCAL_SEND_CALLS;
+ output_csv_list[i++] = LOCAL_BYTES_PER_SEND;
+ output_csv_list[i++] = LOCAL_BYTES_RECVD;
+ output_csv_list[i++] = LOCAL_RECV_CALLS;
+ output_csv_list[i++] = LOCAL_BYTES_PER_RECV;
+ output_csv_list[i++] = LOCAL_SEND_DIRTY_COUNT;
+ output_csv_list[i++] = LOCAL_RECV_DIRTY_COUNT;
+ output_csv_list[i++] = LOCAL_RECV_CLEAN_COUNT;
+ output_csv_list[i++] = LOCAL_NODELAY;
+ output_csv_list[i++] = LOCAL_CORK;
+ output_csv_list[i++] = REMOTE_BYTES_SENT;
+ output_csv_list[i++] = REMOTE_SEND_CALLS;
+ output_csv_list[i++] = REMOTE_BYTES_PER_SEND;
+ output_csv_list[i++] = REMOTE_BYTES_RECVD;
+ output_csv_list[i++] = REMOTE_RECV_CALLS;
+ output_csv_list[i++] = REMOTE_BYTES_PER_RECV;
+ output_csv_list[i++] = REMOTE_SEND_DIRTY_COUNT;
+ output_csv_list[i++] = REMOTE_RECV_DIRTY_COUNT;
+ output_csv_list[i++] = REMOTE_RECV_CLEAN_COUNT;
+ output_csv_list[i++] = REMOTE_NODELAY;
+ output_csv_list[i++] = REMOTE_CORK;
+ output_csv_list[i++] = RESULT_BRAND;
+ output_csv_list[i++] = COMMAND_LINE;
+
+}
+
+void
+set_output_human_list_default() {
+
+ int i, j; /* line, column */
+
+ /* Line One */
+ i = 0;
+ j = 0;
+ output_human_list[i][j++] = LSS_SIZE_REQ;
+ output_human_list[i][j++] = LSS_SIZE;
+ output_human_list[i][j++] = LSS_SIZE_END;
+
+ /* Line Two */
+ i = 1;
+ j = 0;
+ output_human_list[i][j++] = COMMAND_LINE;
+
+ /* Line Three */
+ i = 2;
+ j = 0;
+
+ /* Line Four */
+ i = 3;
+ j = 0;
+
+}
/* lots of boring, repetitive code */
void
print_omni_init() {
@@ -781,20 +1073,6 @@
netperf_output_source[i].display_value = NULL;
}
-#define MY_MAX(a,b) (a > b) ? a : b
-
-#define NETPERF_LINE_MAX(x) \
- MY_MAX(MY_MAX(MY_MAX(strlen(netperf_output_source[x].line[0]),\
- strlen(netperf_output_source[x].line[1])),\
- strlen(netperf_output_source[x].line[2])),\
- strlen(netperf_output_source[x].line[3]))
-
-#define NETPERF_LINE_TOT(x) \
- strlen(netperf_output_source[x].line[0]) +\
- strlen(netperf_output_source[x].line[1]) +\
- strlen(netperf_output_source[x].line[2]) +\
- strlen(netperf_output_source[x].line[3]) + 4
-
netperf_output_source[OUTPUT_NONE].output_name = OUTPUT_NONE;
netperf_output_source[OUTPUT_NONE].format = "%s";
netperf_output_source[OUTPUT_NONE].display_value = &" ";
@@ -1688,82 +1966,33 @@
netperf_output_source[OUTPUT_END].tot_line_len =
NETPERF_LINE_TOT(OUTPUT_END);
+ /* belts and suspenders */
for (i = OUTPUT_NONE; i < NETPERF_OUTPUT_MAX; i++)
output_csv_list[i] = OUTPUT_END;
- /* the default for csv is the kitchen-sink. ultimately it will be
- possible to override by providing one's own list in a file */
-
- i = 0;
- output_csv_list[i++] = SOCKET_TYPE;
- output_csv_list[i++] = PROTOCOL;
- output_csv_list[i++] = DIRECTION;
- output_csv_list[i++] = LSS_SIZE_REQ;
- output_csv_list[i++] = LSS_SIZE;
- output_csv_list[i++] = LSS_SIZE_END;
- output_csv_list[i++] = RSS_SIZE_REQ;
- output_csv_list[i++] = RSS_SIZE;
- output_csv_list[i++] = RSS_SIZE_END;
- output_csv_list[i++] = LOCAL_SEND_SIZE;
- output_csv_list[i++] = LOCAL_RECV_SIZE;
- output_csv_list[i++] = REQUEST_SIZE;
- output_csv_list[i++] = REMOTE_SEND_SIZE;
- output_csv_list[i++] = REMOTE_RECV_SIZE;
- output_csv_list[i++] = RESPONSE_SIZE;
- output_csv_list[i++] = THROUGHPUT;
- output_csv_list[i++] = THROUGHPUT_UNITS;
- output_csv_list[i++] = LOCAL_CPU_UTIL;
- output_csv_list[i++] = LOCAL_SD;
- output_csv_list[i++] = LOCAL_CPU_BIND;
- output_csv_list[i++] = LOCAL_CPU_COUNT;
- output_csv_list[i++] = REMOTE_CPU_UTIL;
- output_csv_list[i++] = REMOTE_SD;
- output_csv_list[i++] = SD_UNITS;
- output_csv_list[i++] = REMOTE_CPU_BIND;
- output_csv_list[i++] = REMOTE_CPU_COUNT;
- output_csv_list[i++] = CONFIDENCE_LEVEL;
- output_csv_list[i++] = CONFIDENCE_INTERVAL;
- output_csv_list[i++] = THROUGHPUT_CONFID;
- output_csv_list[i++] = LOCAL_CPU_CONFID;
- output_csv_list[i++] = REMOTE_CPU_CONFID;
- output_csv_list[i++] = CONFIDENCE_ITERATION;
- output_csv_list[i++] = RT_LATENCY;
- output_csv_list[i++] = BURST_SIZE;
- output_csv_list[i++] = TRANSPORT_MSS;
- output_csv_list[i++] = LOCAL_BYTES_SENT;
- output_csv_list[i++] = LOCAL_SEND_CALLS;
- output_csv_list[i++] = LOCAL_BYTES_PER_SEND;
- output_csv_list[i++] = LOCAL_BYTES_RECVD;
- output_csv_list[i++] = LOCAL_RECV_CALLS;
- output_csv_list[i++] = LOCAL_BYTES_PER_RECV;
- output_csv_list[i++] = LOCAL_SEND_DIRTY_COUNT;
- output_csv_list[i++] = LOCAL_RECV_DIRTY_COUNT;
- output_csv_list[i++] = LOCAL_RECV_CLEAN_COUNT;
- output_csv_list[i++] = LOCAL_NODELAY;
- output_csv_list[i++] = LOCAL_CORK;
- output_csv_list[i++] = REMOTE_BYTES_SENT;
- output_csv_list[i++] = REMOTE_SEND_CALLS;
- output_csv_list[i++] = REMOTE_BYTES_PER_SEND;
- output_csv_list[i++] = REMOTE_BYTES_RECVD;
- output_csv_list[i++] = REMOTE_RECV_CALLS;
- output_csv_list[i++] = REMOTE_BYTES_PER_RECV;
- output_csv_list[i++] = REMOTE_SEND_DIRTY_COUNT;
- output_csv_list[i++] = REMOTE_RECV_DIRTY_COUNT;
- output_csv_list[i++] = REMOTE_RECV_CLEAN_COUNT;
- output_csv_list[i++] = REMOTE_NODELAY;
- output_csv_list[i++] = REMOTE_CORK;
- output_csv_list[i++] = RESULT_BRAND;
- output_csv_list[i++] = COMMAND_LINE;
-
for (j = 0; j < NETPERF_MAX_BLOCKS; j++)
for (i = OUTPUT_NONE; i < NETPERF_OUTPUT_MAX; i++)
output_human_list[j][i] = OUTPUT_END;
- output_human_list[0][0] = LSS_SIZE_REQ;
- output_human_list[0][1] = LSS_SIZE;
- output_human_list[0][2] = LSS_SIZE_END;
- output_human_list[1][0] = COMMAND_LINE;
+ /* the default for csv is the kitchen-sink. ultimately it will be
+ possible to override by providing one's own list in a file */
+
+ if (csv) {
+ if (csv_selection_file)
+ /* name of file, list to fill, number of rows/lines */
+ parse_output_csv_selection_file(csv_selection_file);
+ else
+ set_output_csv_list_default(output_csv_list);
+ }
+ else {
+ if (human_selection_file)
+ parse_output_human_selection_file(human_selection_file);
+ else
+ set_output_human_list_default(output_human_list);
+ }
+
+
}
/* why? because one cannot simply pass a pointer to snprintf :) for
@@ -1866,7 +2095,7 @@
netperf_output_source[output_csv_list[j]].format);
fflush(where);
}
- vallen += 1;
+ vallen += 1; /* forget not the terminator */
}
else
vallen = 0;
@@ -1901,22 +2130,25 @@
(output_csv_list[j] != OUTPUT_END));
j++) {
int len;
+ len = 0;
if (print_headers) {
- len = sprintf(h1,
- "%s %s %s %s",
- netperf_output_source[output_csv_list[j]].line[0],
- netperf_output_source[output_csv_list[j]].line[1],
- netperf_output_source[output_csv_list[j]].line[2],
- netperf_output_source[output_csv_list[j]].line[3]);
-
- *(h1 + len) = ',';
- /* now move to the next starting column. for csv we aren't worried
- about alignment between the header and the value lines */
- h1 += len + 1;
+ for (k = 0; ((k < 4) &&
+ (NULL !=
+ netperf_output_source[output_csv_list[j]].line[k]) &&
+ (strcmp("",netperf_output_source[output_csv_list[j]].line[k]))); k++) {
+
+ len = sprintf(h1,
+ "%s",
+ netperf_output_source[output_csv_list[j]].line[k]);
+ *(h1 + len) = ' ';
+ /* now move to the next starting column. for csv we aren't worried
+ about alignment between the header and the value lines */
+ h1 += len + 1;
+ }
+ *(h1 - 1) = ',';
}
if ((netperf_output_source[output_csv_list[j]].format != NULL) &&
(netperf_output_source[output_csv_list[j]].display_value != NULL)) {
- int len;
/* tot_line_len is bogus here, but should be "OK" ? */
len = my_snprintf(v1,
netperf_output_source[output_csv_list[j]].tot_line_len,
@@ -4149,9 +4381,39 @@
break;
case 'o':
csv = 1;
+ /* obliterate any previous file name */
+ if (human_selection_file) {
+ free(human_selection_file);
+ human_selection_file = NULL;
+ }
+ if (csv_selection_file) {
+ free(csv_selection_file);
+ csv_selection_file = NULL;
+ }
+ if (argv[optind] && ((unsigned char)argv[optind][0] != '-')) {
+ /* we assume that what follows is the name of a file with the
+ list of desired output values. */
+ csv_selection_file = strdup(argv[optind]);
+ optind++;
+ }
break;
case 'O':
csv = 0;
+ /* obliterate any previous file name */
+ if (human_selection_file) {
+ free(human_selection_file);
+ human_selection_file = NULL;
+ }
+ if (csv_selection_file) {
+ free(csv_selection_file);
+ csv_selection_file = NULL;
+ }
+ if (argv[optind] && ((unsigned char)argv[optind][0] != '-')) {
+ /* we assume that what follows is the name of a file with the
+ list of desired output values */
+ human_selection_file = strdup(argv[optind]);
+ optind++;
+ }
break;
case 'p':
/* set the min and max port numbers for the TCP_CRR and TCP_TRR */
More information about the netperf-dev
mailing list