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
stats_init(int ext)49 stats_init(int ext)
50 {
51 Ext = ext;
52 }
53
54 void
stats_fini(void)55 stats_fini(void)
56 {
57 }
58
59 static struct stats *
stats_new(const char * name,const char * desc,enum stats_type t)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
stats_delete(struct stats * sp)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 *
stats_new_counter(const char * name,const char * desc,int ext)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
stats_counter_bump(struct stats * sp)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
stats_counter_add(struct stats * sp,int n)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
stats_counter_reset(struct stats * sp)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
stats_counter_value(struct stats * sp)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 *
stats_new_elapse(const char * name,const char * desc,int ext)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
stats_elapse_start(struct stats * sp)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
stats_elapse_stop(struct stats * sp)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 *
stats_new_string(const char * name,const char * desc,int ext)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
stats_string_set(struct stats * sp,const char * s)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
stats_publish(void)230 stats_publish(void)
231 {
232 /* nothing to do for eft */
233 }
234