1
/*********************************************************
2
* Copyright (C) 2003 VMware, Inc. All rights reserved.
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms of the GNU Lesser General Public License as published
6
* by the Free Software Foundation version 2.1 and no later version.
8
* This program is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10
* or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public
11
* License for more details.
13
* You should have received a copy of the GNU Lesser General Public License
14
* along with this program; if not, write to the Free Software Foundation, Inc.,
15
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17
*********************************************************/
19
#define INCLUDE_ALLOW_MODULE
20
#define INCLUDE_ALLOW_USERLEVEL
21
#define INCLUDE_ALLOW_VMCORE
22
#include "includeCheck.h"
25
* stats_user_setup.h --
27
* The machinery to define statcounters for user at userlevel. This is
28
* something of a collapsing of stats_setup.h and genstats_setup.h
29
* combined with simplifying to eliminate the monitor entanglements.
30
* The goals are to be simpler to read than the monitor statcounter
31
* code and also (relatedly) easier to use in libs.
33
* Expects at least one of the following:
34
* - SETUP_DECLARE_VARS: Declares the enum for the statcounters (this
35
* is what you need in order to STAT_INC() / DEC() / etc.
36
* - SETUP_DEFINE_VARS: Declares the actual StatsUserBlock with all the
37
* information-- stat names, storage for the counters, etc.
39
* Orthogonally, one can also supply:
40
* - SETUP_WANT_GETVAL: If the includer wants to also {declare, define}
41
* a function to retrieve named stat counter values.
45
* This file can be included more than once and should clean up its own
46
* defines before finishing each invocation.
49
#define STAT_NAME_PREFIX STATS
50
#define STAT_VAR_PREFIX stats
53
#error "stats_user_setup.h must be included with STATS_MODULE defined"
56
#if !defined(STATS_COUNTERS_FILE) && !defined(STATS_COUNTERS_INLINE) && \
57
!defined(STATS_COUNTERS_NONE)
58
#error "stats_user_setup.h must be included with statcounters defined"
61
#include "vm_basic_defs.h"
63
#ifdef SETUP_DECLARE_VARS
64
#define STAT(_name, _ignore, _explanation) STATS_USER_NAME(_name),
65
#define STAT_INST(_name, _ignore, _explanation)
67
#ifdef STATS_COUNTERS_FILE
68
#include STATS_COUNTERS_FILE
70
#ifdef STATS_COUNTERS_INLINE
73
STAT(Last, unused, "So we always know the number of counters")
78
#define STAT(_name, _ignore, _explanation)
79
#define STAT_INST(_name, _ignore, _explanation) STATS_USER_INST_NAME(_name),
81
#ifdef STATS_COUNTERS_FILE
82
#include STATS_COUNTERS_FILE
84
#ifdef STATS_COUNTERS_INLINE
87
STAT_INST(Last, unused, "So we always know the number of counters")
90
EXTERN StatsUserBlock STATS_USER_BLKVAR;
91
EXTERN void STATS_USER_LOG_FN(STATS_MODULE)(unsigned int epoch,
92
void (*LogFunc)(const char *fmt, ...));
94
#ifdef SETUP_WANT_GETVAL
95
EXTERN Bool STATS_USER_GETVAL_FN(STATS_MODULE)(const char *name,
97
#endif /* SETUP_WANT_GETVAL */
104
#ifdef SETUP_DEFINE_VARS
106
* Build a table of counter names so we can log them.
108
#define STAT(_name, _ignore, _explanation) XSTR(XXCONC(STATS_MODULE, XCONC(_,_name))),
109
#define STAT_INST(_name, _ignore, _explanation)
110
#define STATS_USER_STR_TABLE XCONC(STAT_USER_VAR_PREFIX, StrTable)
111
static const char *STATS_USER_STR_TABLE[] = {
112
#ifdef STATS_COUNTERS_FILE
113
#include STATS_COUNTERS_FILE
115
#ifdef STATS_COUNTERS_INLINE
116
STATS_COUNTERS_INLINE
118
XSTR(XCONC(STATS_MODULE, _Last))
123
#define STAT(_name, _ignore, _explanation)
124
#define STAT_INST(_name, _ignore, _explanation) XSTR(_name),
125
#define STATS_USER_INST_STR_TABLE XCONC(STAT_USER_VAR_PREFIX, InstStrTable)
126
static const char *STATS_USER_INST_STR_TABLE[] = {
127
#ifdef STATS_COUNTERS_FILE
128
#include STATS_COUNTERS_FILE
130
#ifdef STATS_COUNTERS_INLINE
131
STATS_COUNTERS_INLINE
133
XSTR(XCONC(STATS_MODULE, _Last))
139
* Define the StatsUserBlock itself for this module.
141
StatsUserBlock STATS_USER_BLKVAR;
145
*----------------------------------------------------------------------
147
* STATS_USER_LOG_FN --
149
* For logging purposes, we auto-generate a (non-INLINE) function to
150
* iterate over all the counters and dump them. This seems nicer than
151
* making all clients cookie-cutter this code or else link against an
152
* external binary to get this functionality.
159
*----------------------------------------------------------------------
163
STATS_USER_LOG_FN(STATS_MODULE)(unsigned int epoch,
164
void (*LogFunc)(const char *fmt, ...))
169
if (!STATS_IS_INITIALIZED()) {
173
for (i = 0; i < STATS_USER_BLKVAR.size; i++) {
174
if (STATS_USER_BLKVAR.counters[i].count > 0) {
175
LogFunc("STAT %u %-26s %10d\n", epoch,
176
STATS_USER_STR_TABLE[i], STATS_USER_BLKVAR.counters[i].count);
179
for (cur = STATS_USER_BLKVAR.next; cur != NULL; cur = cur->next) {
180
for (i = 0; i < cur->size; i++) {
181
if (cur->counters[i].count > 0) {
182
LogFunc("STATINST %u %s:%-20s %-15s %10d\n",
183
epoch, XSTR(STATS_MODULE), cur->name,
184
STATS_USER_INST_STR_TABLE[i], cur->counters[i].count);
190
#ifdef SETUP_WANT_GETVAL
192
*----------------------------------------------------------------------
194
* STATS_USER_GETVAL_FN --
196
* Retrieves the value of a named user stat counter. Returns
197
* TRUE iff NAME is a recognized user stat counter, and sets
198
* *VAL to the current value of that counter.
200
* This is an optional function. If a library needs it, use
201
* SETUP_WANT_GETVAL (see top of the header).
209
*----------------------------------------------------------------------
213
STATS_USER_GETVAL_FN(STATS_MODULE)(const char *name, // IN: counter name
214
uint32 *val) // OUT: counter val
218
if (!STATS_IS_INITIALIZED()) {
222
for (i = 0; i < STATS_USER_BLKVAR.size; i++) {
223
if (strcmp(STATS_USER_STR_TABLE[i], name) == 0) {
224
*val = STATS_USER_BLKVAR.counters[i].count;
230
#endif /* SETUP_WANT_GETVAL */
232
#undef STATS_USER_STR_TABLE
233
#undef STATS_USER_INST_STR_TABLE
236
#if defined(SETUP_DECLARE_VARS) || defined(SETUP_DEFINE_VARS)
240
* Initializes Stats at user-level. The user-level variables statsCount,
241
* and statsInfoTable are defined by including "stats_user_setup.h" with
242
* the appropriate parameters.
244
#define STATS_USER_INIT_MODULE() \
246
STATS_USER_BLKVAR.counters = \
247
Util_SafeCalloc(STATS_USER_NAME(Last), sizeof(StatsUserEntry)); \
248
STATS_USER_BLKVAR.size = STATS_USER_NAME(Last); \
249
STATS_USER_BLKVAR.name = XSTR(STATS_MODULE); \
252
#define STATS_USER_INIT_MODULE_ONCE() \
254
if (!STATS_IS_INITIALIZED()) { \
255
STATS_USER_INIT_MODULE(); \
259
#define STATS_USER_EXIT_MODULE() \
261
free(STATS_USER_BLKVAR.counters); \
262
STATS_USER_BLKVAR.counters = NULL; \
266
#ifndef STATS_USER_INIT_INST
268
*----------------------------------------------------------------------
270
* STATS_USER_INIT_INST --
272
* Stats Instancing: Some stats are by their nature per-adapter /
273
* per-handle, etc. so we allow the code to dynamically create extra
274
* statcounters and we return a pointer that can be used when setting
275
* them later. We keep all the instances in a list hanging off
276
* STATS_USER_BLKVAR so we can enumerate all of them at logging time.
279
* The new instance of stats.
282
* Some memory allocation
283
*----------------------------------------------------------------------
286
static INLINE StatsUserBlock *
287
STATS_USER_INIT_INST_FN(STATS_MODULE)(const char *instanceName)
290
if (STATS_USER_BLKVAR.next == NULL) {
291
e = STATS_USER_BLKVAR.next = Util_SafeCalloc(1, sizeof *e);
293
StatsUserBlock *cur = STATS_USER_BLKVAR.next;
294
for (; cur->next != NULL; cur = cur->next) {
295
if (strcmp(instanceName, cur->name) == 0) { return cur; }
297
if (strcmp(instanceName, cur->name) == 0) { return cur; }
298
cur->next = e = Util_SafeCalloc(1, sizeof *e);
300
e->size = STATS_USER_INST_NAME(Last);
301
e->counters = Util_SafeCalloc(e->size, sizeof(StatsUserEntry));
302
if (e->name == NULL) { e->name = strdup(instanceName); }
307
#define STATS_USER_INIT_INST(name) \
308
STATS_USER_INIT_INST_FN(STATS_MODULE)(name)
312
#undef SETUP_DECLARE_VARS
313
#undef SETUP_DEFINE_VARS
314
#undef STAT_NAME_PREFIX
315
#undef STAT_VAR_PREFIX