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 2006 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_desc, desc, 83 sizeof (ret->fmd_stats.fmds_desc)); 84 85 /* NULL name means generate a unique name */ 86 if (name == NULL) { 87 static int uniqstat; 88 89 (void) snprintf(ret->fmd_stats.fmds_name, 90 sizeof (ret->fmd_stats.fmds_name), 91 "stat.rules%d", uniqstat++); 92 } else { 93 (void) strlcpy(ret->fmd_stats.fmds_name, name, 94 sizeof (ret->fmd_stats.fmds_name)); 95 } 96 97 switch (t) { 98 case STATS_COUNTER: 99 ret->fmd_stats.fmds_type = FMD_TYPE_INT32; 100 break; 101 102 case STATS_ELAPSE: 103 ret->fmd_stats.fmds_type = FMD_TYPE_TIME; 104 break; 105 106 case STATS_STRING: 107 ret->fmd_stats.fmds_type = FMD_TYPE_STRING; 108 break; 109 110 default: 111 out(O_DIE, "stats_new: unknown type %d", t); 112 } 113 114 (void) fmd_stat_create(Hdl, FMD_STAT_NOALLOC, 1, &(ret->fmd_stats)); 115 116 return (ret); 117 } 118 119 void 120 stats_delete(struct stats *sp) 121 { 122 if (sp == NULL) 123 return; 124 125 fmd_stat_destroy(Hdl, 1, &(sp->fmd_stats)); 126 FREE(sp); 127 } 128 129 struct stats * 130 stats_new_counter(const char *name, const char *desc, int ext) 131 { 132 if (ext && !Ext) 133 return (NULL); /* extended stats not enabled */ 134 135 return (stats_new(name, desc, STATS_COUNTER)); 136 } 137 138 void 139 stats_counter_bump(struct stats *sp) 140 { 141 if (sp == NULL) 142 return; 143 144 ASSERT(sp->t == STATS_COUNTER); 145 146 sp->fmd_stats.fmds_value.i32++; 147 } 148 149 void 150 stats_counter_add(struct stats *sp, int n) 151 { 152 if (sp == NULL) 153 return; 154 155 ASSERT(sp->t == STATS_COUNTER); 156 157 sp->fmd_stats.fmds_value.i32 += n; 158 } 159 160 void 161 stats_counter_reset(struct stats *sp) 162 { 163 if (sp == NULL) 164 return; 165 166 ASSERT(sp->t == STATS_COUNTER); 167 168 sp->fmd_stats.fmds_value.i32 = 0; 169 } 170 171 int 172 stats_counter_value(struct stats *sp) 173 { 174 if (sp == NULL) 175 return (0); 176 177 ASSERT(sp->t == STATS_COUNTER); 178 179 return (sp->fmd_stats.fmds_value.i32); 180 } 181 182 struct stats * 183 stats_new_elapse(const char *name, const char *desc, int ext) 184 { 185 if (ext && !Ext) 186 return (NULL); /* extended stats not enabled */ 187 188 return (stats_new(name, desc, STATS_ELAPSE)); 189 } 190 191 void 192 stats_elapse_start(struct stats *sp) 193 { 194 if (sp == NULL) 195 return; 196 197 ASSERT(sp->t == STATS_ELAPSE); 198 199 sp->start = gethrtime(); 200 } 201 202 void 203 stats_elapse_stop(struct stats *sp) 204 { 205 if (sp == NULL) 206 return; 207 208 ASSERT(sp->t == STATS_ELAPSE); 209 210 sp->stop = gethrtime(); 211 sp->fmd_stats.fmds_value.ui64 = sp->stop - sp->start; 212 } 213 214 struct stats * 215 stats_new_string(const char *name, const char *desc, int ext) 216 { 217 struct stats *r; 218 219 if (ext && !Ext) 220 return (NULL); /* extended stats not enabled */ 221 222 r = stats_new(name, desc, STATS_STRING); 223 return (r); 224 } 225 226 void 227 stats_string_set(struct stats *sp, const char *s) 228 { 229 if (sp == NULL) 230 return; 231 232 ASSERT(sp->t == STATS_STRING); 233 234 if (sp->fmd_stats.fmds_value.str) 235 fmd_hdl_strfree(Hdl, sp->fmd_stats.fmds_value.str); 236 sp->fmd_stats.fmds_value.str = fmd_hdl_strdup(Hdl, s, FMD_SLEEP); 237 } 238 239 /* 240 * stats_publish -- spew all stats 241 * 242 */ 243 244 void 245 stats_publish(void) 246 { 247 /* nothing to do for eft */ 248 } 249