1 /********************* */
2 /*! \file statistics_registry.cpp
4 ** Top contributors (to current version):
5 ** Morgan Deters, Tim King, Kshitij Bansal
6 ** This file is part of the CVC4 project.
7 ** Copyright (c) 2009-2019 by the authors listed in the file AUTHORS
8 ** in the top-level source directory) and their institutional affiliations.
9 ** All rights reserved. See the file COPYING in the top-level source
10 ** directory for licensing information.\endverbatim
12 ** \brief [[ Add one-line brief description here ]]
14 ** [[ Add lengthier description here ]]
15 ** \todo document this file
18 #include "util/statistics_registry.h"
23 #include "base/check.h"
24 #include "lib/clock_gettime.h"
25 #include "util/ostream_util.h"
27 #ifdef CVC4_STATISTICS_ON
28 # define CVC4_USE_STATISTICS true
30 # define CVC4_USE_STATISTICS false
34 /****************************************************************************/
35 /* Some utility functions for timespec */
36 /****************************************************************************/
39 /** Compute the sum of two timespecs. */
40 inline timespec
& operator+=(timespec
& a
, const timespec
& b
) {
42 // assumes a.tv_nsec and b.tv_nsec are in range
43 const long nsec_per_sec
= 1000000000L; // one thousand million
44 CheckArgument(a
.tv_nsec
>= 0 && a
.tv_nsec
< nsec_per_sec
, a
);
45 CheckArgument(b
.tv_nsec
>= 0 && b
.tv_nsec
< nsec_per_sec
, b
);
47 long nsec
= a
.tv_nsec
+ b
.tv_nsec
;
53 if(nsec
>= nsec_per_sec
) {
57 Assert(nsec
>= 0 && nsec
< nsec_per_sec
);
62 /** Compute the difference of two timespecs. */
63 inline timespec
& operator-=(timespec
& a
, const timespec
& b
) {
65 // assumes a.tv_nsec and b.tv_nsec are in range
66 const long nsec_per_sec
= 1000000000L; // one thousand million
67 CheckArgument(a
.tv_nsec
>= 0 && a
.tv_nsec
< nsec_per_sec
, a
);
68 CheckArgument(b
.tv_nsec
>= 0 && b
.tv_nsec
< nsec_per_sec
, b
);
70 long nsec
= a
.tv_nsec
- b
.tv_nsec
;
75 if(nsec
>= nsec_per_sec
) {
79 Assert(nsec
>= 0 && nsec
< nsec_per_sec
);
84 /** Add two timespecs. */
85 inline timespec
operator+(const timespec
& a
, const timespec
& b
) {
90 /** Subtract two timespecs. */
91 inline timespec
operator-(const timespec
& a
, const timespec
& b
) {
97 * Compare two timespecs for equality.
98 * This must be kept in sync with the copy in test/util/stats_black.h
100 inline bool operator==(const timespec
& a
, const timespec
& b
) {
101 // assumes a.tv_nsec and b.tv_nsec are in range
102 return a
.tv_sec
== b
.tv_sec
&& a
.tv_nsec
== b
.tv_nsec
;
105 /** Compare two timespecs for disequality. */
106 inline bool operator!=(const timespec
& a
, const timespec
& b
) {
107 // assumes a.tv_nsec and b.tv_nsec are in range
111 /** Compare two timespecs, returning true iff a < b. */
112 inline bool operator<(const timespec
& a
, const timespec
& b
) {
113 // assumes a.tv_nsec and b.tv_nsec are in range
114 return a
.tv_sec
< b
.tv_sec
||
115 (a
.tv_sec
== b
.tv_sec
&& a
.tv_nsec
< b
.tv_nsec
);
118 /** Compare two timespecs, returning true iff a > b. */
119 inline bool operator>(const timespec
& a
, const timespec
& b
) {
120 // assumes a.tv_nsec and b.tv_nsec are in range
121 return a
.tv_sec
> b
.tv_sec
||
122 (a
.tv_sec
== b
.tv_sec
&& a
.tv_nsec
> b
.tv_nsec
);
125 /** Compare two timespecs, returning true iff a <= b. */
126 inline bool operator<=(const timespec
& a
, const timespec
& b
) {
127 // assumes a.tv_nsec and b.tv_nsec are in range
131 /** Compare two timespecs, returning true iff a >= b. */
132 inline bool operator>=(const timespec
& a
, const timespec
& b
) {
133 // assumes a.tv_nsec and b.tv_nsec are in range
137 /** Output a timespec on an output stream. */
138 std::ostream
& operator<<(std::ostream
& os
, const timespec
& t
) {
139 // assumes t.tv_nsec is in range
140 StreamFormatScope
format_scope(os
);
141 return os
<< t
.tv_sec
<< "."
142 << std::setfill('0') << std::setw(9) << std::right
<< t
.tv_nsec
;
146 /** Construct a statistics registry */
147 StatisticsRegistry::StatisticsRegistry(const std::string
& name
) : Stat(name
)
150 if(CVC4_USE_STATISTICS
) {
151 PrettyCheckArgument(d_name
.find(s_regDelim
) == std::string::npos
, name
,
152 "StatisticsRegistry names cannot contain the string \"%s\"",
157 void StatisticsRegistry::registerStat(Stat
* s
)
159 #ifdef CVC4_STATISTICS_ON
160 PrettyCheckArgument(d_stats
.find(s
) == d_stats
.end(), s
,
161 "Statistic `%s' was not registered with this registry.",
162 s
->getName().c_str());
164 #endif /* CVC4_STATISTICS_ON */
165 }/* StatisticsRegistry::registerStat_() */
167 void StatisticsRegistry::unregisterStat(Stat
* s
)
169 #ifdef CVC4_STATISTICS_ON
170 AlwaysAssert(s
!= nullptr);
171 AlwaysAssert(d_stats
.erase(s
) > 0)
172 << "Statistic `" << s
->getName()
173 << "' was not registered with this registry.";
174 #endif /* CVC4_STATISTICS_ON */
175 } /* StatisticsRegistry::unregisterStat() */
177 void StatisticsRegistry::flushStat(std::ostream
&out
) const {
178 #ifdef CVC4_STATISTICS_ON
179 flushInformation(out
);
180 #endif /* CVC4_STATISTICS_ON */
183 void StatisticsRegistry::flushInformation(std::ostream
&out
) const {
184 #ifdef CVC4_STATISTICS_ON
185 this->StatisticsBase::flushInformation(out
);
186 #endif /* CVC4_STATISTICS_ON */
189 void StatisticsRegistry::safeFlushInformation(int fd
) const {
190 #ifdef CVC4_STATISTICS_ON
191 this->StatisticsBase::safeFlushInformation(fd
);
192 #endif /* CVC4_STATISTICS_ON */
195 void TimerStat::start() {
196 if(CVC4_USE_STATISTICS
) {
197 PrettyCheckArgument(!d_running
, *this, "timer already running");
198 clock_gettime(CLOCK_MONOTONIC
, &d_start
);
201 }/* TimerStat::start() */
203 void TimerStat::stop() {
204 if(CVC4_USE_STATISTICS
) {
205 AlwaysAssert(d_running
) << "timer not running";
207 clock_gettime(CLOCK_MONOTONIC
, &end
);
208 d_data
+= end
- d_start
;
211 }/* TimerStat::stop() */
213 bool TimerStat::running() const {
215 }/* TimerStat::running() */
217 timespec
TimerStat::getData() const {
218 ::timespec data
= d_data
;
219 if(CVC4_USE_STATISTICS
&& d_running
) {
221 clock_gettime(CLOCK_MONOTONIC
, &end
);
222 data
+= end
- d_start
;
227 SExpr
TimerStat::getValue() const {
228 ::timespec data
= d_data
;
229 if(CVC4_USE_STATISTICS
&& d_running
) {
231 clock_gettime(CLOCK_MONOTONIC
, &end
);
232 data
+= end
- d_start
;
234 std::stringstream ss
;
235 ss
<< std::fixed
<< std::setprecision(8) << data
;
236 return SExpr(Rational::fromDecimal(ss
.str()));
237 }/* TimerStat::getValue() */
240 RegisterStatistic::RegisterStatistic(StatisticsRegistry
* reg
, Stat
* stat
)
243 CheckArgument(reg
!= NULL
, reg
,
244 "You need to specify a statistics registry"
245 "on which to set the statistic");
246 d_reg
->registerStat(d_stat
);
249 RegisterStatistic::~RegisterStatistic() {
250 d_reg
->unregisterStat(d_stat
);
253 }/* CVC4 namespace */
255 #undef CVC4_USE_STATISTICS