Home | History | Annotate | Download | only in eversholt
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  *
     25  * stats.c -- simple stats tracking table module
     26  *
     27  * this version of stats.c links with eft and implements the
     28  * stats using the fmd's stats API.
     29  */
     30 
     31 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     32 
     33 #include <sys/types.h>
     34 #include <strings.h>
     35 #include "stats.h"
     36 #include "alloc.h"
     37 #include "out.h"
     38 #include "stats_impl.h"
     39 #include <fm/fmd_api.h>
     40 
     41 extern fmd_hdl_t *Hdl;		/* handle from eft.c */
     42 
     43 static int Ext;			/* true if extended stats are enabled */
     44 
     45 /*
     46  * stats_init -- initialize the stats module
     47  *
     48  */
     49 
     50 void
     51 stats_init(int ext)
     52 {
     53 	Ext = ext;
     54 }
     55 
     56 void
     57 stats_fini(void)
     58 {
     59 }
     60 
     61 static struct stats *
     62 stats_new(const char *name, const char *desc, enum stats_type t)
     63 {
     64 	struct stats *ret = MALLOC(sizeof (*ret));
     65 
     66 	bzero(ret, sizeof (*ret));
     67 	ret->t = t;
     68 
     69 	(void) strlcpy(ret->fmd_stats.fmds_desc, desc,
     70 	    sizeof (ret->fmd_stats.fmds_desc));
     71 
     72 	/* NULL name means generate a unique name */
     73 	if (name == NULL) {
     74 		static int uniqstat;
     75 
     76 		(void) snprintf(ret->fmd_stats.fmds_name,
     77 		    sizeof (ret->fmd_stats.fmds_name),
     78 		    "stat.rules%d", uniqstat++);
     79 	} else {
     80 		(void) strlcpy(ret->fmd_stats.fmds_name, name,
     81 		    sizeof (ret->fmd_stats.fmds_name));
     82 	}
     83 
     84 	switch (t) {
     85 	case STATS_COUNTER:
     86 		ret->fmd_stats.fmds_type = FMD_TYPE_INT32;
     87 		break;
     88 
     89 	case STATS_ELAPSE:
     90 		ret->fmd_stats.fmds_type = FMD_TYPE_TIME;
     91 		break;
     92 
     93 	case STATS_STRING:
     94 		ret->fmd_stats.fmds_type = FMD_TYPE_STRING;
     95 		break;
     96 
     97 	default:
     98 		out(O_DIE, "stats_new: unknown type %d", t);
     99 	}
    100 
    101 	(void) fmd_stat_create(Hdl, FMD_STAT_NOALLOC, 1, &(ret->fmd_stats));
    102 
    103 	return (ret);
    104 }
    105 
    106 void
    107 stats_delete(struct stats *sp)
    108 {
    109 	if (sp == NULL)
    110 		return;
    111 
    112 	fmd_stat_destroy(Hdl, 1, &(sp->fmd_stats));
    113 	FREE(sp);
    114 }
    115 
    116 struct stats *
    117 stats_new_counter(const char *name, const char *desc, int ext)
    118 {
    119 	if (ext && !Ext)
    120 		return (NULL);		/* extended stats not enabled */
    121 
    122 	return (stats_new(name, desc, STATS_COUNTER));
    123 }
    124 
    125 void
    126 stats_counter_bump(struct stats *sp)
    127 {
    128 	if (sp == NULL)
    129 		return;
    130 
    131 	ASSERT(sp->t == STATS_COUNTER);
    132 
    133 	sp->fmd_stats.fmds_value.i32++;
    134 }
    135 
    136 void
    137 stats_counter_add(struct stats *sp, int n)
    138 {
    139 	if (sp == NULL)
    140 		return;
    141 
    142 	ASSERT(sp->t == STATS_COUNTER);
    143 
    144 	sp->fmd_stats.fmds_value.i32 += n;
    145 }
    146 
    147 void
    148 stats_counter_reset(struct stats *sp)
    149 {
    150 	if (sp == NULL)
    151 		return;
    152 
    153 	ASSERT(sp->t == STATS_COUNTER);
    154 
    155 	sp->fmd_stats.fmds_value.i32 = 0;
    156 }
    157 
    158 int
    159 stats_counter_value(struct stats *sp)
    160 {
    161 	if (sp == NULL)
    162 		return (0);
    163 
    164 	ASSERT(sp->t == STATS_COUNTER);
    165 
    166 	return (sp->fmd_stats.fmds_value.i32);
    167 }
    168 
    169 struct stats *
    170 stats_new_elapse(const char *name, const char *desc, int ext)
    171 {
    172 	if (ext && !Ext)
    173 		return (NULL);		/* extended stats not enabled */
    174 
    175 	return (stats_new(name, desc, STATS_ELAPSE));
    176 }
    177 
    178 void
    179 stats_elapse_start(struct stats *sp)
    180 {
    181 	if (sp == NULL)
    182 		return;
    183 
    184 	ASSERT(sp->t == STATS_ELAPSE);
    185 
    186 	sp->start = gethrtime();
    187 }
    188 
    189 void
    190 stats_elapse_stop(struct stats *sp)
    191 {
    192 	if (sp == NULL)
    193 		return;
    194 
    195 	ASSERT(sp->t == STATS_ELAPSE);
    196 
    197 	sp->stop = gethrtime();
    198 	sp->fmd_stats.fmds_value.ui64 = sp->stop - sp->start;
    199 }
    200 
    201 struct stats *
    202 stats_new_string(const char *name, const char *desc, int ext)
    203 {
    204 	struct stats *r;
    205 
    206 	if (ext && !Ext)
    207 		return (NULL);		/* extended stats not enabled */
    208 
    209 	r = stats_new(name, desc, STATS_STRING);
    210 	return (r);
    211 }
    212 
    213 void
    214 stats_string_set(struct stats *sp, const char *s)
    215 {
    216 	if (sp == NULL)
    217 		return;
    218 
    219 	ASSERT(sp->t == STATS_STRING);
    220 
    221 	if (sp->fmd_stats.fmds_value.str)
    222 		fmd_hdl_strfree(Hdl, sp->fmd_stats.fmds_value.str);
    223 	sp->fmd_stats.fmds_value.str = fmd_hdl_strdup(Hdl, s, FMD_SLEEP);
    224 }
    225 
    226 /*
    227  * stats_publish -- spew all stats
    228  *
    229  */
    230 
    231 void
    232 stats_publish(void)
    233 {
    234 	/* nothing to do for eft */
    235 }
    236