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