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