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