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 #include <sys/types.h> 32 #include <strings.h> 33 #include "stats.h" 34 #include "alloc.h" 35 #include "out.h" 36 #include "stats_impl.h" 37 #include <fm/fmd_api.h> 38 39 extern fmd_hdl_t *Hdl; /* handle from eft.c */ 40 41 static int Ext; /* true if extended stats are enabled */ 42 43 /* 44 * stats_init -- initialize the stats module 45 * 46 */ 47 48 void 49 stats_init(int ext) 50 { 51 Ext = ext; 52 } 53 54 void 55 stats_fini(void) 56 { 57 } 58 59 static struct stats * 60 stats_new(const char *name, const char *desc, enum stats_type t) 61 { 62 struct stats *ret = MALLOC(sizeof (*ret)); 63 64 bzero(ret, sizeof (*ret)); 65 ret->t = t; 66 67 (void) strlcpy(ret->fmd_stats.fmds_desc, desc, 68 sizeof (ret->fmd_stats.fmds_desc)); 69 70 /* NULL name means generate a unique name */ 71 if (name == NULL) { 72 static int uniqstat; 73 74 (void) snprintf(ret->fmd_stats.fmds_name, 75 sizeof (ret->fmd_stats.fmds_name), 76 "stat.rules%d", uniqstat++); 77 } else { 78 (void) strlcpy(ret->fmd_stats.fmds_name, name, 79 sizeof (ret->fmd_stats.fmds_name)); 80 } 81 82 switch (t) { 83 case STATS_COUNTER: 84 ret->fmd_stats.fmds_type = FMD_TYPE_INT32; 85 break; 86 87 case STATS_ELAPSE: 88 ret->fmd_stats.fmds_type = FMD_TYPE_TIME; 89 break; 90 91 case STATS_STRING: 92 ret->fmd_stats.fmds_type = FMD_TYPE_STRING; 93 break; 94 95 default: 96 out(O_DIE, "stats_new: unknown type %d", t); 97 } 98 99 (void) fmd_stat_create(Hdl, FMD_STAT_NOALLOC, 1, &(ret->fmd_stats)); 100 101 return (ret); 102 } 103 104 void 105 stats_delete(struct stats *sp) 106 { 107 if (sp == NULL) 108 return; 109 110 fmd_stat_destroy(Hdl, 1, &(sp->fmd_stats)); 111 FREE(sp); 112 } 113 114 struct stats * 115 stats_new_counter(const char *name, const char *desc, int ext) 116 { 117 if (ext && !Ext) 118 return (NULL); /* extended stats not enabled */ 119 120 return (stats_new(name, desc, STATS_COUNTER)); 121 } 122 123 void 124 stats_counter_bump(struct stats *sp) 125 { 126 if (sp == NULL) 127 return; 128 129 ASSERT(sp->t == STATS_COUNTER); 130 131 sp->fmd_stats.fmds_value.i32++; 132 } 133 134 void 135 stats_counter_add(struct stats *sp, int n) 136 { 137 if (sp == NULL) 138 return; 139 140 ASSERT(sp->t == STATS_COUNTER); 141 142 sp->fmd_stats.fmds_value.i32 += n; 143 } 144 145 void 146 stats_counter_reset(struct stats *sp) 147 { 148 if (sp == NULL) 149 return; 150 151 ASSERT(sp->t == STATS_COUNTER); 152 153 sp->fmd_stats.fmds_value.i32 = 0; 154 } 155 156 int 157 stats_counter_value(struct stats *sp) 158 { 159 if (sp == NULL) 160 return (0); 161 162 ASSERT(sp->t == STATS_COUNTER); 163 164 return (sp->fmd_stats.fmds_value.i32); 165 } 166 167 struct stats * 168 stats_new_elapse(const char *name, const char *desc, int ext) 169 { 170 if (ext && !Ext) 171 return (NULL); /* extended stats not enabled */ 172 173 return (stats_new(name, desc, STATS_ELAPSE)); 174 } 175 176 void 177 stats_elapse_start(struct stats *sp) 178 { 179 if (sp == NULL) 180 return; 181 182 ASSERT(sp->t == STATS_ELAPSE); 183 184 sp->start = gethrtime(); 185 } 186 187 void 188 stats_elapse_stop(struct stats *sp) 189 { 190 if (sp == NULL) 191 return; 192 193 ASSERT(sp->t == STATS_ELAPSE); 194 195 sp->stop = gethrtime(); 196 sp->fmd_stats.fmds_value.ui64 = sp->stop - sp->start; 197 } 198 199 struct stats * 200 stats_new_string(const char *name, const char *desc, int ext) 201 { 202 struct stats *r; 203 204 if (ext && !Ext) 205 return (NULL); /* extended stats not enabled */ 206 207 r = stats_new(name, desc, STATS_STRING); 208 return (r); 209 } 210 211 void 212 stats_string_set(struct stats *sp, const char *s) 213 { 214 if (sp == NULL) 215 return; 216 217 ASSERT(sp->t == STATS_STRING); 218 219 if (sp->fmd_stats.fmds_value.str) 220 fmd_hdl_strfree(Hdl, sp->fmd_stats.fmds_value.str); 221 sp->fmd_stats.fmds_value.str = fmd_hdl_strdup(Hdl, s, FMD_SLEEP); 222 } 223 224 /* 225 * stats_publish -- spew all stats 226 * 227 */ 228 229 void 230 stats_publish(void) 231 { 232 /* nothing to do for eft */ 233 } 234