stats.c revision f2fc321be9b4df7748e8c31a5edd154b0177b139
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include "config.h"
#include <stdio.h>
#include <fcntl.h>
#ifdef HAVE_SYSINFO
#endif
#ifdef HAVE_LIBKSTAT
#include <kstat.h>
#endif /* HAVE_LIBKSTAT */
#include <stdarg.h>
#include "filebench.h"
#include "flowop.h"
#include "vars.h"
#include "stats.h"
/*
* A set of routines for collecting and dumping various filebench
* run statistics.
*/
/* Global statistics */
static hrtime_t stats_cputime = 0;
#ifdef HAVE_LIBKSTAT
/*
* to obtain cpu statistics. Collects statistics for each cpu, initializes
* a local pointer to the sysinfo kstat, and returns the sum of user and
* kernel time for all the cpus.
*/
static vinteger_t
kstats_read_cpu(void)
{
int ncpus;
int i;
return (-1);
}
}
/*
* Per-CPU statistics
*/
ncpus = 0;
ncpus++;
if ((cpu_stat_list =
return (-1);
}
ncpus = 0;
if (ncpus == 0) {
"kstats can't find any cpu statistics");
return (0);
}
if (sysinfo_ksp == NULL)
/* Sum across all CPUs */
for (i = 0; i < ncpus; i++) {
int j;
(void *) &cpu_stats);
for (j = 0; j < CPU_STATES; j++)
}
return (10000000LL * cputime);
}
#else /* HAVE_LIBKSTAT */
#ifdef HAVE_PROC_STAT
kstats_read_cpu(void)
{
/*
* The entry for cpu is
* cpu 1636 67 1392 208671 5407 20 12
* cpu0 626 8 997 104476 2499 7 7
* cpu1 1010 58 395 104195 2907 13 5
*
* The number of jiffies (1/100ths of a second) that the
* system spent in user mode, user mode with low priority
* (nice), system mode, and the idle task, respectively.
*/
if (statfd == 0) {
if (statfd < 0) {
return (-1);
}
}
return (-1);
}
/* convert jiffies to nanosecs */
}
#else /* HAVE_PROC_STAT */
kstats_read_cpu(void)
{
return (0);
}
#endif
#endif /* HAVE_LIBKSTAT */
/*
* Returns the net cpu time used since the beginning of the run.
* Just calls kstat_read_cpu() and subtracts stats_cputime which
* is set at the beginning of the filebench run.
*/
static hrtime_t
kstats_read_cpu_relative(void)
{
cputime = kstats_read_cpu();
return (cputime - stats_cputime);
}
/*
* IO Overhead CPU is the amount of CPU that is incurred running
* the benchmark infrastructure.
*
* It is computed as the sum of micro-state cpu time for each
* thread around the op being tested.
*
* Overhead time is computed for each flow.
*
* System overhead is computed as the overhead for I/O flows
* plus all other time running non-io related flowops
*
*/
/*
* Computes and returns the overhead CPU time attibutable to
* IO type flowops.
*/
static hrtime_t
io_stats_ohead(void)
{
"Computing overhead as %lld + %lld - %lld - %lld",
}
/*
* Returns the total overhead CPU time.
*/
static hrtime_t
gl_stats_ohead(void)
{
}
/*
* Places the value represented by "name" into the var_integer field of the
* supplied var_t. Compares the supplied "name" with a set of predefined
* names and calculates the value from the appropriate globalstats field(s).
*/
var_t *
{
if (globalstats == NULL)
return (var);
}
/* LINTED E_ASSIGMENT_CAUSE_LOSS_PREC */
return (var);
}
/* LINTED E_ASSIGMENT_CAUSE_LOSS_PREC */
return (var);
}
/* LINTED E_ASSIGMENT_CAUSE_LOSS_PREC */
return (var);
}
/* LINTED E_ASSIGMENT_CAUSE_LOSS_PREC */
var->var_integer =
return (var);
}
return (var);
}
return (var);
}
return (var);
}
return (var);
}
/* LINTED E_ASSIGMENT_CAUSE_LOSS_PREC */
return (var);
}
return (var);
}
"error reading stats %s", name);
return (NULL);
}
/*
* Initializes the static variable "stats_cputime" with the
* current cpu time, for use by kstats_read_cpu_relative.
*/
void
stats_init(void)
{
#if defined(HAVE_LIBKSTAT) || defined(LINUX_PORT)
#else
stats_cputime = 0;
#endif /* HAVE_LIBKSTAT */
}
/*
* Add a flowstat b to a, leave sum in a.
*/
static void
{
int i;
for (i = 0; i < FLOW_MSTATES; i++)
}
/*
* Takes a "snapshot" of the global statistics. Actually, it calculates
* them from the local statistics maintained by each flowop.
* First the routine pauses filebench, then rolls the statistics for
* each flowop into its associated FLOW_MASTER flowop.
* Next all the FLOW_MASTER flowops' statistics are written
* to the log file followed by the global totals. Then filebench
* operation is allowed to resume.
*/
void
stats_snap(void)
{
char *str;
if (globalstats == NULL) {
"'stats snap' called before 'stats clear'");
return;
}
/* Freeze statistics during update */
while (flowop) {
continue;
}
/* Roll up per-flowop into global stats */
}
if (flowop_master) {
/* Roll up per-flow stats into master */
} else {
"flowop_stats could not find %s",
}
"flowop %-20s-%4d - %5d ops, %5.1lf, ops/s %5.1lfmb/s "
}
#if defined(HAVE_LIBKSTAT) || defined(LINUX_PORT)
#endif /* HAVE_LIBKSTAT */
"cputime = %lld, ohead = %lld",
cputime / 1000000000,
io_stats_ohead() / 1000000000);
(cputime > io_stats_ohead()) ?
(cputime - io_stats_ohead()) : 0;
(cputime > gl_stats_ohead()) ?
(cputime - gl_stats_ohead()) : 0;
while (flowop) {
char line[1024];
continue;
}
}
"\nIO Summary: %5d ops %5.1lf ops/s, (%0.0lf/%0.0lf r/w) "
filebench_shm->bequiet = 0;
}
/*
* Dumps the per-operation statistics and global statistics to the dump file.
*/
void
stats_dump(char *filename)
{
if (filebench_shm->dump_fd > 0) {
}
while (flowop) {
continue;
}
"%-20s %8.0lfops/s %5.1lfmb/s "
}
"IO Summary: %8d ops %8.1lf ops/s, %8.0lf/%0.0lf r/w"
}
/*
* Same as stats_dump, but in xml format.
*/
void
stats_xmldump(char *filename)
{
if (filebench_shm->dump_fd > 0) {
}
while (flowop) {
continue;
}
}
while (flowop) {
continue;
}
}
}
/*
* Clears all the statistics variables (fo_stats) for every defined flowop.
* It also creates a global flowstat table if one doesn't already exist and
* clears it.
*/
void
stats_clear(void)
{
#ifdef HAVE_LIBKSTAT
#else
stats_cputime = 0;
#endif /* HAVE_LIBKSTAT */
if (globalstats == NULL)
while (flowop) {
}
}