-
Notifications
You must be signed in to change notification settings - Fork 2
/
attr_stats.hh
186 lines (172 loc) · 6.52 KB
/
attr_stats.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/*
* Copyright (c) 2016 Zhao DAI <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any
* later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see accompanying file LICENSE.txt
* or <http://www.gnu.org/licenses/>.
*/
/**
* @file
* @brief Program statistics and profiling.
* APIs for profiling program based on lock-free, thread-safe counters.
* @n Each counter is called an @em attribute, identified by an positive integer. You can put as
* many attributes in program as you want.
* @author Zhao DAI
*/
#ifndef DOZERG_ATTR_STATS_H_20130606
#define DOZERG_ATTR_STATS_H_20130606
#include "impl/attr_stats_impl.hh"
NS_SERVER_BEGIN
/**
* @brief Increase an attribute atomically.
* An example usage shows below:
* @code{.cpp}
* // init statistics APIs before use
* ATTR_INIT();
* ...
* ...
* // attributes 100, 101, 102 and 103 are used to save number
* // of commands for Login, Logout, Query and others, respectively.
* void process(Command & cmd){
* switch(cmd.type){
* case Login: ATTR_ADD(100, 1); break;
* case Logout:ATTR_ADD(101, 1); break;
* case Query: ATTR_ADD(102, 1); break;
* default: ATTR_ADD(103, 1); break;
* }
* }
* @endcode
* @param attr A positive number identifying the attribute
* @param val A non-negative number to add to the attribute
* @note For performance reason, @c attr must be a [constant expression]
* (http://en.cppreference.com/w/cpp/language/constant_expression), i.e. can be evaluated at
* compile time. And this is the recommended way of usage.
* @n But if that is not the case, please use @ref ATTR_ADD_SLOW instead.
* @sa ATTR_ADD_SLOW
* @hideinitializer
*/
#define ATTR_ADD(attr, val) \
do{ \
__UNUSED typedef NS_SERVER::NS_IMPL::__AttrDummy<attr> attr_must_be_constant; \
static uint64_t * __Attr = NULL; \
if(!__Attr){ \
__Attr = NS_SERVER::NS_IMPL::CAttrStats::Inst().attrAdd(attr, val); \
}else \
NS_SERVER::NS_IMPL::CAttrStats::attrAdd(__Attr, val); \
}while(0)
/**
* @brief Initialize statistics APIs.
* This function must be called @em once only @em before any other statistics APIs.
* @param capacity The maximum number of attributes in the program
* @return @c true if succeeded; otherwise @c false
*/
inline bool ATTR_INIT(size_t capacity = 1000)
{
return NS_IMPL::CAttrStats::Inst().init(capacity);
}
/**
* @brief Increase an attribute atomically.
* @param attr A positive number identifying the attribute
* @param val A non-negative number to add to the attribute
* @return @c true if succeeded; otherwise @c false
* @sa ATTR_ADD
*/
inline bool ATTR_ADD_SLOW(int attr, uint64_t val)
{
return (NULL != NS_IMPL::CAttrStats::Inst().attrAdd(attr, val));
}
/**
* @brief Modify an attribute atomically.
* An example usage shows below:
* @code{.cpp}
* // init statistics APIs before use
* ATTR_INIT();
* ...
* // a message queue shared between threads or processes
* MessageQueue queue;
* ...
* // attributes 104 is used to monitor the length of 'queue' in a dedicated thread
* void monitorThread(){
* for(;;sleep(1)){
* ATTR_SET(104, queue.length());
* }
* }
* @endcode
* @param attr A positive number identifying the attribute
* @param val A non-negative number
* @note For performance reason, @c attr must be a [constant expression]
* (http://en.cppreference.com/w/cpp/language/constant_expression), i.e. can be evaluated at
* compile time. And this is the recommended way of usage.
* @n But if that is not the case, please use @ref ATTR_SET_SLOW instead.
* @sa ATTR_SET_SLOW
* @hideinitializer
*/
#define ATTR_SET(attr, val) \
do{ \
__UNUSED typedef NS_SERVER::NS_IMPL::__AttrDummy<attr> attr_must_be_constant; \
static uint64_t * __Attr = NULL; \
if(!__Attr){ \
__Attr = NS_SERVER::NS_IMPL::CAttrStats::Inst().attrSet(attr, val); \
}else \
NS_SERVER::NS_IMPL::CAttrStats::attrSet(__Attr, val); \
}while(0)
/**
* @brief Get an attribute and then modify it atomically.
* @param[in] attr A positive number identifying the attribute
* @param[in] val A non-negative number
* @param[out] old Pointer to a variable to receive the value of attribute @em before modification; or
* @c NULL if not interested
* @note For performance reason, @c attr must be a [constant expression]
* (http://en.cppreference.com/w/cpp/language/constant_expression), i.e. can be evaluated at
* compile time. And this is the recommended way of usage.
* @n But if that is not the case, please use @ref ATTR_SET_SLOW instead.
* @sa ATTR_SET_SLOW
* @hideinitializer
*/
#define ATTR_SET_EX(attr, val, old) \
do{ \
__UNUSED typedef NS_SERVER::NS_IMPL::__AttrDummy<attr> attr_must_be_constant; \
static uint64_t * __Attr = NULL; \
if(!__Attr){ \
__Attr = NS_SERVER::NS_IMPL::CAttrStats::Inst().attrSet(attr, val, old); \
}else \
NS_SERVER::NS_IMPL::CAttrStats::attrSet(__Attr, val, old); \
}while(0)
/**
* @brief Get an attribute and then modify it atomically.
* @param[in] attr A positive number identifying the attribute
* @param[in] val A non-negative number
* @param[out] old Pointer to a variable to receive the value of attribute @em before modification; or
* @c NULL if not interested
* @sa ATTR_SET ATTR_SET_EX
*/
inline bool ATTR_SET_SLOW(int attr, uint64_t val, uint64_t * old = NULL)
{
return (NULL != NS_IMPL::CAttrStats::Inst().attrSet(attr, val, old));
}
/**
* @brief Iterate and apply an operation to all attributes.
* @param op Operation to apply to all attributes, should implement:
* @code{.cpp} void operator ()(int attr, uint64_t value) const; @endcode
* In which:
* @li @c attr is a positive number identifying the attribute
* @li @c value is the current value of the attribute
* @note After the operation, each attribute will be reset to 0 for a new turn of counting.
*/
template<class Op>
inline void ATTR_ITERATE(Op op)
{
return NS_IMPL::CAttrStats::Inst().iterate(op);
}
NS_SERVER_END
#endif