[netperf-dev] netperf4 commit notice r189 - in trunk: src
suites/disk suites/dns suites/vst
raj at netperf.org
raj at netperf.org
Thu Jun 29 17:25:11 PDT 2006
Author: raj
Date: 2006-06-29 17:25:00 -0700 (Thu, 29 Jun 2006)
New Revision: 189
Modified:
trunk/src/netlib.c
trunk/src/netsysstats_kstat10.c
trunk/src/nettest_bsd.c
trunk/src/nettest_vst.c
trunk/suites/disk/disktest.c
trunk/suites/dns/nettest_dns.c
trunk/suites/vst/nettest_vst.c
Log:
Initial CPU util pass for Solaris 10 and workarounds for printing null strings
Modified: trunk/src/netlib.c
===================================================================
--- trunk/src/netlib.c 2006-06-29 00:24:59 UTC (rev 188)
+++ trunk/src/netlib.c 2006-06-30 00:25:00 UTC (rev 189)
@@ -1089,26 +1089,31 @@
fprintf(dumploc, "port '%s' ", port);
fprintf(dumploc, "family %d\n", family);
while (temp) {
- fprintf(dumploc,
- "\tcannonical name: '%s'\n",temp->ai_canonname);
- fprintf(dumploc,
- "\tflags: %x family: %d: socktype: %d protocol %d addrlen %d\n",
- temp->ai_flags,
- temp->ai_family,
- temp->ai_socktype,
- temp->ai_protocol,
- temp->ai_addrlen);
+ /* I was under the impression that g_fprintf would be kind with
+ things like NULL string pointers, but when porting to Solaris,
+ this started dumping core, so we start to workaround it. raj
+ 2006-06-29 */
+ g_fprintf(dumploc,
+ "\tcannonical name: '%s'\n",
+ temp->ai_canonname ? temp->ai_canonname : "n/a");
+ g_fprintf(dumploc,
+ "\tflags: %x family: %d: socktype: %d protocol %d addrlen %d\n",
+ temp->ai_flags,
+ temp->ai_family,
+ temp->ai_socktype,
+ temp->ai_protocol,
+ temp->ai_addrlen);
ai_addr = temp->ai_addr;
if (ai_addr != NULL) {
- fprintf(dumploc,
- "\tsa_family: %d sadata: %d %d %d %d %d %d\n",
- ai_addr->sa_family,
- (u_char)ai_addr->sa_data[0],
- (u_char)ai_addr->sa_data[1],
- (u_char)ai_addr->sa_data[2],
- (u_char)ai_addr->sa_data[3],
- (u_char)ai_addr->sa_data[4],
- (u_char)ai_addr->sa_data[5]);
+ g_fprintf(dumploc,
+ "\tsa_family: %d sadata: %d %d %d %d %d %d\n",
+ ai_addr->sa_family,
+ (u_char)ai_addr->sa_data[0],
+ (u_char)ai_addr->sa_data[1],
+ (u_char)ai_addr->sa_data[2],
+ (u_char)ai_addr->sa_data[3],
+ (u_char)ai_addr->sa_data[4],
+ (u_char)ai_addr->sa_data[5]);
}
temp = temp->ai_next;
}
@@ -1301,10 +1306,15 @@
}
if (debug) {
+ /* I _thought_ that g_fprintf was cool with NULL string pointers
+ until we got to the Solaris port at which point this started
+ dumping core like there was no tomorrow. rather than await a
+ fix to g_fprintf that may never come, we'll work around it. raj
+ 2006-06-29 */
g_fprintf(where,
"%s was given %s for envvar %s and pathvarispath %d\n",
__func__,
- path,
+ path ? path : "NULL",
pathvar,
pathvarispath);
fflush(where);
Modified: trunk/src/netsysstats_kstat10.c
===================================================================
--- trunk/src/netsysstats_kstat10.c 2006-06-29 00:24:59 UTC (rev 188)
+++ trunk/src/netsysstats_kstat10.c 2006-06-30 00:25:00 UTC (rev 189)
@@ -35,10 +35,63 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+# include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+
+#include <errno.h>
+
+#include <kstat.h>
+#include <sys/sysinfo.h>
+
#include "netperf.h"
#include "netsysstats.h"
+
+/* these probably need to be placed in some test-specific area */
+static kstat_ctl_t *kc = NULL;
+static kid_t kcid = 0;
+
+static void
+print_unexpected_statistic_warning(test_t *test, char *who, char *what, char *why)
+{
+ if (why) {
+ fprintf(test->where,
+ "WARNING! WARNING! WARNING! WARNING!\n");
+ fprintf(test->where,
+ "%s found an unexpected %s statistic %.16s\n",
+ who,
+ why,
+ what);
+ }
+ else {
+ fprintf(test->where,
+ "%s is ignoring statistic %.16s\n",
+ who,
+ what);
+ }
+}
+
+
int
sys_cpu_util_init(test_t *test)
{
@@ -47,46 +100,336 @@
NETPERF_DEBUG_ENTRY(test->debug,test->where);
tsd->num_cpus = 1;
+ kc = kstat_open();
+
+ if (kc == NULL) {
+ fprintf(test->where,
+ "cpu_util_init: kstat_open: errno %d %s\n",
+ errno,
+ strerror(errno));
+ fflush(test->where);
+ }
+
NETPERF_DEBUG_EXIT(test->debug, test->where);
return NPE_SUCCESS;
}
-/* slightly kludgy to get the CPU util to come-out as 100% */
-static uint64_t user,kernel,other,interrupt,idle = 0;
+static void
+get_cpu_counters(test_t *test, int cpu_num, cpu_time_counters_t *counters)
+{
+ kstat_t *ksp;
+ int found=0;
+ kid_t nkcid;
+ kstat_named_t *knp;
+ int i;
+
+ ksp = kstat_lookup(kc, "cpu", cpu_num, "sys");
+ if ((ksp) && (ksp->ks_type == KSTAT_TYPE_NAMED)) {
+ /* happiness and joy, keep going */
+ nkcid = kstat_read(kc, ksp, NULL);
+ if (nkcid != -1) {
+ /* happiness and joy, keep going. we could consider adding a
+ "found < 3" to the end conditions, but then we wouldn't
+ search to the end and find that Sun added some nsec. we
+ probably want to see if they add an nsec. raj 2005-01-28 */
+ for (i = ksp->ks_ndata, knp = ksp->ks_data;
+ i > 0;
+ knp++,i--) {
+ /* we would be hosed if the same name could appear twice */
+ if (!strcmp("cpu_nsec_idle",knp->name)) {
+ found++;
+ counters[cpu_num].idle = knp->value.ui64;
+ }
+ else if (!strcmp("cpu_nsec_user",knp->name)) {
+ found++;
+ counters[cpu_num].user = knp->value.ui64;
+ }
+ else if (!strcmp("cpu_nsec_kernel",knp->name)) {
+ found++;
+ counters[cpu_num].kernel = knp->value.ui64;
+ }
+ else if (strstr(knp->name,"nsec")) {
+ /* finding another nsec here means Sun have changed
+ something and we need to warn the user. raj 2005-01-28 */
+ print_unexpected_statistic_warning(test,
+ "get_cpu_counters",
+ knp->name,
+ "nsec");
+ }
+ else if (test->debug >=2) {
+
+ /* might want to tell people about what we are skipping.
+ however, only display other names debug >=2. raj
+ 2005-01-28
+ */
+
+ print_unexpected_statistic_warning(test,
+ "get_cpu_counters",
+ knp->name,
+ NULL);
+ }
+ }
+ if (3 == found) {
+ /* happiness and joy */
+ return;
+ }
+ else {
+ fprintf(test->where,
+ "get_cpu_counters could not find one or more of the expected counters!\n");
+ fflush(test->where);
+ /* we used to exit here but now I don't think we should */
+ }
+ }
+ else {
+ /* the kstat_read returned an error or the chain changed */
+ fprintf(test->where,
+ "get_cpu_counters: kstat_read failed or chain id changed %d %s\n",
+ errno,
+ strerror(errno));
+ fflush(test->where);
+ }
+ }
+ else {
+ /* the lookup failed or found the wrong type */
+ fprintf(test->where,
+ "get_cpu_counters: kstat_lookup failed for module 'cpu' instance %d name 'sys' and KSTAT_TYPE_NAMED: errno %d %s\n",
+ cpu_num,
+ errno,
+ strerror(errno));
+ fflush(test->where);
+ }
+}
+
+static void
+get_interrupt_counters(test_t *test, int cpu_num, cpu_time_counters_t *counters)
+{
+ kstat_t *ksp;
+ int found=0;
+ kid_t nkcid;
+ kstat_named_t *knp;
+ int i;
+
+ ksp = kstat_lookup(kc, "cpu", cpu_num, "intrstat");
+
+ counters[cpu_num].interrupt = 0;
+ if ((ksp) && (ksp->ks_type == KSTAT_TYPE_NAMED)) {
+ /* happiness and joy, keep going */
+ nkcid = kstat_read(kc, ksp, NULL);
+ if (nkcid != -1) {
+ /* happiness and joy, keep going. we could consider adding a
+ "found < 15" to the end conditions, but then we wouldn't
+ search to the end and find that Sun added some "time." we
+ probably want to see if they add a "nsec." raj 2005-01-28 */
+ for (i = ksp->ks_ndata, knp = ksp->ks_data;
+ i > 0;
+ knp++,i--) {
+ if (strstr(knp->name,"time")) {
+ found++;
+ counters[cpu_num].interrupt += knp->value.ui64;
+ }
+ else if (test->debug >=2) {
+
+ /* might want to tell people about what we are skipping.
+ however, only display other names debug >=2. raj
+ 2005-01-28
+ */
+
+ print_unexpected_statistic_warning(test,
+ "get_cpu_counters",
+ knp->name,
+ NULL);
+ }
+ }
+ if (15 == found) {
+ /* happiness and joy */
+ return;
+ }
+ else {
+ fprintf(test->where,
+ "get_cpu_counters could not find one or more of the expected counters!\n");
+ fflush(test->where);
+ }
+ }
+ else {
+ /* the kstat_read returned an error or the chain changed */
+ fprintf(test->where,
+ "get_cpu_counters: kstat_read failed or chain id changed %d %s\n",
+ errno,
+ strerror(errno));
+ fflush(test->where);
+ }
+ }
+ else {
+ /* the lookup failed or found the wrong type */
+ fprintf(test->where,
+ "get_cpu_counters: kstat_lookup failed for module 'cpu' instance %d class 'intrstat' and KSTAT_TYPE_NAMED: errno %d %s\n",
+ cpu_num,
+ errno,
+ strerror(errno));
+ fflush(test->where);
+ }
+
+}
+
void
get_cpu_time_counters(cpu_time_counters_t *res,
struct timeval *timestamp,
test_t *test)
{
- int i;
+ int i;
netsysstat_data_t *tsd = GET_TEST_DATA(test);
+ int num_cpus = tsd->num_cpus;
+ int cpu_util_kosher = 1;
+ double elapsed;
+#define CALC_PERCENT 100
+#define CALC_TENTH_PERCENT 1000
+#define CALC_HUNDREDTH_PERCENT 10000
+#define CALC_THOUSANDTH_PERCENT 100000
+#define CALC_ACCURACY CALC_THOUSANDTH_PERCENT
+ uint64_t fraction_idle;
+ uint64_t fraction_user;
+ uint64_t fraction_kernel;
+ uint64_t fraction_interrupt;
+
+ uint64_t interrupt_idle;
+ uint64_t interrupt_user;
+ uint64_t interrupt_kernel;
+
+ uint64_t total_cpu_nsec;
+
NETPERF_DEBUG_ENTRY(test->debug,test->where);
gettimeofday(timestamp,NULL);
+
- /* this should result in the CPU util being forever reported as
- 100% */
+ for (i = 0; i < num_cpus; i++) {
+ elapsed = (double)timestamp->tv_sec +
+ ((double)timestamp->tv_usec / (double)1000000);
+ res[i].calibrate = (uint64_t)elapsed * 1000000000; /* nanoseconds */
- user += 10000;
- kernel += 10000;
- interrupt += 10000;
- idle += 1;
+ /* this call will retrieve user/kernel/idle */
+ get_cpu_counters(test, i, res);
- for (i = 0; i < tsd->num_cpus; i++) {
- res[i].user = user;
- res[i].kernel = kernel;
- res[i].interrupt = interrupt;
- res[i].idle = idle;
- res[i].calibrate = res[i].user +
- res[i].kernel +
- res[i].interrupt +
- res[i].idle;
- res[i].other = 0;
+ /* this call will retrieve interrupt */
+ get_interrupt_counters(test, i, res);
+
+ /* OK, here we have to do our big stinking pile of ass-u-me-ing so
+ we can merge the user/kernel/idle counters with the interrupt
+ time because Sun has them overlapping. from netperf2 we learn:
+
+ this is now the fun part. we have the nanoseconds _allegedly_
+ spent in user, idle and kernel. We also have nanoseconds spent
+ servicing interrupts. Sadly, in the developers' finite wisdom,
+ the interrupt time accounting is in parallel (ie overlaps) with
+ the other accounting. this means that time accounted in user,
+ kernel or idle will also include time spent in interrupt. for
+ netperf's porpoises we do not _really_ care about that for user
+ and kernel, but we certainly do care for idle. the $64B
+ question becomes - how to "correct" for this?
+
+ we could just subtract interrupt time from idle. that has the
+ virtue of simplicity and also "punishes" Sun for doing
+ something that seems to be so stupid. however, we probably
+ have to be "fair" even to the allegedly stupid so the other
+ mechanism, suggested by a Sun engineer, is to subtract
+ interrupt time from each of user, kernel and idle in proportion
+ to their numbers. then we sum the corrected user, kernel and
+ idle along with the interrupt time and use that to calculate a
+ new idle percentage and thus a CPU util percentage.
+
+ that is what we will attempt to do here. raj 2005-01-28
+
+ of course, we also have to wonder what we should do if there is
+ more interrupt time than the sum of user, kernel and idle.
+ that is a theoretical possibility I suppose, but for the
+ time-being, one that we will blythly ignore, except perhaps for
+ a quick check. raj 2005-01-31
+ */
+
+ /* what differs here from netperf2 is we are trying this kludge on
+ the raw counters rather than the delta because it is code
+ "above" us that is taking the delta. this may make some of our
+ "wrap" assumptions a bit more brittle but that is life. */
+
+ total_cpu_nsec =
+ res[i].idle +
+ res[i].user +
+ res[i].kernel;
+
+ if (test->debug) {
+ fprintf(test->where,
+ "%s pre-fixup total_cpu_nsec[%d] %"PRIu64"\n",
+ __func__,
+ i,
+ total_cpu_nsec);
+ }
+
+ /* not sure if we really need this check from netperf2 but just in
+ case... raj 2006-06-29 */
+ if (res[i].interrupt > total_cpu_nsec) {
+ fprintf(test->where,
+ "WARNING! WARNING! WARNING! WARNING! WARNING! \n");
+ fprintf(test->where,
+ "%s: more interrupt time for cpu %d than user/kern/idle combined!\n",
+ i,
+ __func__);
+ fprintf(test->where,
+ "\tso CPU util cannot be reliably estimated\n");
+ fflush(test->where);
+ cpu_util_kosher = 0;
+ }
+
+ /* and now some fun with integer math. i initially tried to
+ promote things to long doubled but that didn't seem to result
+ in happiness and joy. raj 2005-01-28 */
+
+ fraction_idle = (res[i].idle * CALC_ACCURACY) / total_cpu_nsec;
+
+ fraction_user = (res[i].user * CALC_ACCURACY) / total_cpu_nsec;
+
+ fraction_kernel = (res[i].kernel * CALC_ACCURACY) / total_cpu_nsec;
+
+ /* ok, we have our fractions, now we want to take that fraction of
+ the interrupt time and subtract that from the bucket. */
+
+ interrupt_idle = ((res[i].interrupt * fraction_idle) /
+ CALC_ACCURACY);
+
+ interrupt_user = ((res[i].interrupt * fraction_user) /
+ CALC_ACCURACY);
+
+ interrupt_kernel = ((res[i].interrupt * fraction_kernel) /
+ CALC_ACCURACY);
+
+ if (test->debug) {
+ fprintf(test->where,
+ "\tcpu[%d] fraction_idle %"PRIu64" interrupt_idle %"PRIu64"\n",
+ i,
+ fraction_idle,
+ interrupt_idle);
+ fprintf(test->where,
+ "\tcpu[%d] fraction_user %"PRIu64" interrupt_user %"PRIu64"\n",
+ i,
+ fraction_user,
+ interrupt_user);
+ fprintf(test->where,
+ "\tcpu[%d] fraction_kernel %"PRIu64" interrupt_kernel %"PRIu64"\n",
+ i,
+ fraction_kernel,
+ interrupt_kernel);
+ }
+
+ /* now we do our subtraction */
+ res[i].idle = res[i].idle - interrupt_idle;
+
+ res[i].user = res[i].user - interrupt_user;
+
+ res[i].kernel = res[i].kernel - interrupt_kernel;
+
}
-
NETPERF_DEBUG_EXIT(test->debug, test->where);
}
Modified: trunk/src/nettest_bsd.c
===================================================================
--- trunk/src/nettest_bsd.c 2006-06-29 00:24:59 UTC (rev 188)
+++ trunk/src/nettest_bsd.c 2006-06-30 00:25:00 UTC (rev 189)
@@ -130,6 +130,7 @@
#endif
#include "netperf.h"
+#include "netlib.h"
#include "nettest_bsd.h"
@@ -305,6 +306,7 @@
+#ifdef notdef
static void
dump_addrinfo(FILE *dumploc, struct addrinfo *info,
xmlChar *host, xmlChar *port, int family)
@@ -343,6 +345,7 @@
fflush(dumploc);
}
+#endif
static int
strtofam(xmlChar *familystr)
@@ -3679,9 +3682,11 @@
test_cntr[i] = 0.0;
}
if (test_set->debug) {
+ unsigned char *string = NULL;
+ string = xmlGetProp(stats, (const xmlChar *)cntr_name[i]);
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]));
+ string ? (char *)string : "n/a");
}
}
elapsed_seconds = test_cntr[TST_E_SEC] + test_cntr[TST_E_USEC]/1000000.0;
@@ -3810,9 +3815,14 @@
sys_cntr[i] = 0.0;
}
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]));
+ unsigned char *string = NULL;
+ string = xmlGetProp(stats, (const xmlChar *)sys_cntr_name[i]);
+ fprintf(test_set->where,
+ "\t%12s sys_stats[%d] = %10g '%s'\n",
+ sys_cntr_name[i],
+ i,
+ sys_cntr[i],
+ string ? (char *) string : "n/a");
}
}
local_cpus = sys_cntr[NUM_CPU];
Modified: trunk/src/nettest_vst.c
===================================================================
--- trunk/src/nettest_vst.c 2006-06-29 00:24:59 UTC (rev 188)
+++ trunk/src/nettest_vst.c 2006-06-30 00:25:00 UTC (rev 189)
@@ -2458,9 +2458,11 @@
test_cntr[i] = 0.0;
}
if (test_set->debug) {
+ unsigned char *string = NULL;
+ string = xmlGetProp(stats, (const xmlChar *)cntr_name[i]);
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]));
+ string ? (char *) string : "n/a");
}
}
elapsed_seconds = test_cntr[TST_E_SEC] + test_cntr[TST_E_USEC]/1000000.0;
@@ -2582,9 +2584,11 @@
sys_cntr[i] = 0.0;
}
if (test_set->debug) {
+ unsigned char *string = NULL;
+ string = xmlGetProp(stats, (const xmlChar *)sys_cntr_name[i]);
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]));
+ string ? (char *)string : "n/a");
}
}
local_cpus = sys_cntr[NUM_CPU];
Modified: trunk/suites/disk/disktest.c
===================================================================
--- trunk/suites/disk/disktest.c 2006-06-29 00:24:59 UTC (rev 188)
+++ trunk/suites/disk/disktest.c 2006-06-30 00:25:00 UTC (rev 189)
@@ -1253,9 +1253,11 @@
test_cntr[i] = 0.0;
}
if (test_set->debug) {
+ unsigned char *string=NULL;
+ string = xmlGetProp(stats, (const xmlChar *)cntr_name[i]);
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]));
+ string ? (char *)string : "n/a");
}
}
elapsed_seconds = test_cntr[TST_E_SEC] + test_cntr[TST_E_USEC]/1000000.0;
@@ -1386,9 +1388,11 @@
sys_cntr[i] = 0.0;
}
if (test_set->debug) {
+ unsigned char *string=NULL;
+ string = xmlGetProp(stats, (const xmlChar *)sys_cntr_name[i]);
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]));
+ string ? (char *)string : "n/a");
}
}
local_cpus = sys_cntr[NUM_CPU];
Modified: trunk/suites/dns/nettest_dns.c
===================================================================
--- trunk/suites/dns/nettest_dns.c 2006-06-29 00:24:59 UTC (rev 188)
+++ trunk/suites/dns/nettest_dns.c 2006-06-30 00:25:00 UTC (rev 189)
@@ -1980,9 +1980,11 @@
test_cntr[i] = 0.0;
}
if (test_set->debug) {
+ unsigned char *string=NULL;
+ string = xmlGetProp(stats, (const xmlChar *)cntr_name[i]);
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]));
+ string ? (char *)string : "n/a");
}
}
elapsed_seconds = test_cntr[TST_E_SEC] + test_cntr[TST_E_USEC]/1000000.0;
@@ -2105,9 +2107,11 @@
sys_cntr[i] = 0.0;
}
if (test_set->debug) {
+ unsigned char *string=NULL;
+ string = xmlGetProp(stats, (const xmlChar *)sys_cntr_name[i]);
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]));
+ string ? (char *)string : "n/a");
}
}
local_cpus = sys_cntr[NUM_CPU];
Modified: trunk/suites/vst/nettest_vst.c
===================================================================
--- trunk/suites/vst/nettest_vst.c 2006-06-29 00:24:59 UTC (rev 188)
+++ trunk/suites/vst/nettest_vst.c 2006-06-30 00:25:00 UTC (rev 189)
@@ -2458,9 +2458,10 @@
test_cntr[i] = 0.0;
}
if (test_set->debug) {
+ unsigned char *string = xmlGetProp(stats, (const xmlChar *)cntr_name[i]);
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]));
+ string ? (char *)string : "n/a");
}
}
elapsed_seconds = test_cntr[TST_E_SEC] + test_cntr[TST_E_USEC]/1000000.0;
@@ -2582,9 +2583,11 @@
sys_cntr[i] = 0.0;
}
if (test_set->debug) {
+ unsigned char *string=NULL;
+ string = xmlGetProp(stats, (const xmlChar *)sys_cntr_name[i]);
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]));
+ string ? (char *) string : "n/a");
}
}
local_cpus = sys_cntr[NUM_CPU];
More information about the netperf-dev
mailing list