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