1 /********************* */
2 /*! \file statistics_registry.h
4 ** Top contributors (to current version):
5 ** Morgan Deters, Tim King, Gereon Kremer
6 ** This file is part of the CVC4 project.
7 ** Copyright (c) 2009-2021 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 Statistics utility classes
14 ** Statistics utility classes, including classes for holding (and referring
15 ** to) statistics, the statistics registry, and some other associated
18 ** This file is somewhat unique in that it is a "cvc4_private_library.h"
19 ** header. Because of this, most classes need to be marked as CVC4_EXPORT.
20 ** This is because CVC4_EXPORT is connected to the visibility of the linkage
21 ** in the object files for the class. It does not dictate what headers are
23 ** Because the StatisticsRegistry and associated classes are built into
24 ** libutil, which is used by libcvc4, and then later used by the libmain
25 ** without referring to libutil as well. Thus the without marking these as
26 ** CVC4_EXPORT the symbols would be external in libutil, internal in libcvc4,
27 ** and not be visible to libmain and linking would fail.
28 ** You can debug this using "nm" on the .so and .o files in the builds/
30 ** http://eli.thegreenplace.net/2013/07/09/library-order-in-static-linking
31 ** for a longer discussion on symbol visibility.
35 * On the design of the statistics:
37 * Stat is the abstract base class for all statistic values.
38 * It stores the name and provides (fully virtual) methods
39 * flushInformation() and safeFlushInformation().
41 * BackedStat is an abstract templated base class for statistic values
42 * that store the data themselves. It takes care of printing them already
43 * and derived classes usually only need to provide methods to set the
46 * ReferenceStat holds a reference (conceptually, it is implemented as a
47 * const pointer) to some data that is stored outside of the statistic.
49 * IntStat is a BackedStat<std::int64_t>.
51 * SizeStat holds a const reference to some container and provides the
52 * size of this container.
54 * AverageStat is a BackedStat<double>.
56 * HistogramStat counts instances of some type T. It is implemented as a
57 * std::map<T, std::uint64_t>.
59 * IntegralHistogramStat is a (conceptual) specialization of HistogramStat
60 * for types that are (convertible to) integral. This allows to use a
61 * std::vector<std::uint64_t> instead of a std::map.
63 * TimerStat uses std::chrono to collect timing information. It is
64 * implemented as BackedStat<std::chrono::duration> and provides methods
65 * start() and stop(), accumulating times it was activated. It provides
66 * the convenience class CodeTimer to allow for RAII-style usage.
69 * All statistic classes should protect their custom methods using
70 * if (CVC4_USE_STATISTICS) { ... }
71 * Output methods (flushInformation() and safeFlushInformation()) are only
72 * called when statistics are enabled and need no protection.
75 * The statistic classes try to implement a consistent interface:
76 * - if we store some generic data, we implement set()
77 * - if we (conceptually) store a set of values, we implement operator<<()
78 * - if there are standard operations for the stored data, we implement these
79 * (like operator++() or operator+=())
82 #include "cvc4_private_library.h"
84 #ifndef CVC4__STATISTICS_REGISTRY_H
85 #define CVC4__STATISTICS_REGISTRY_H
93 #ifdef CVC4_STATISTICS_ON
94 # define CVC4_USE_STATISTICS true
96 # define CVC4_USE_STATISTICS false
99 #include "base/exception.h"
100 #include "cvc4_export.h"
101 #include "util/safe_print.h"
102 #include "util/statistics.h"
103 #include "util/stats_base.h"
107 /** A statistic that contains a SExpr. */
108 class SExprStat
: public Stat
{
115 * Construct a SExpr-valued statistic with the given name and
118 SExprStat(const std::string
& name
, const SExpr
& init
) :
119 Stat(name
), d_data(init
){}
121 void flushInformation(std::ostream
& out
) const override
126 void safeFlushInformation(int fd
) const override
128 // SExprStat is only used in statistics.cpp in copyFrom, which we cannot
129 // do in a signal handler anyway.
130 safe_print(fd
, "<unsupported>");
133 SExpr
getValue() const override
{ return d_data
; }
135 };/* class SExprStat */
137 /****************************************************************************/
138 /* Statistics Registry */
139 /****************************************************************************/
142 * The main statistics registry. This registry maintains the list of
143 * currently active statistics and is able to "flush" them all.
145 class CVC4_EXPORT StatisticsRegistry
: public StatisticsBase
148 /** Private copy constructor undefined (no copy permitted). */
149 StatisticsRegistry(const StatisticsRegistry
&) = delete;
153 /** Construct an nameless statistics registry */
154 StatisticsRegistry() {}
156 void flushStat(std::ostream
& out
) const;
158 void flushInformation(std::ostream
& out
) const;
160 void safeFlushInformation(int fd
) const;
162 SExpr
getValue() const
164 std::vector
<SExpr
> v
;
165 for(StatSet::iterator i
= d_stats
.begin(); i
!= d_stats
.end(); ++i
) {
166 std::vector
<SExpr
> w
;
167 w
.push_back(SExpr((*i
)->getName()));
168 w
.push_back((*i
)->getValue());
169 v
.push_back(SExpr(w
));
174 /** Register a new statistic */
175 void registerStat(Stat
* s
);
177 /** Unregister a new statistic */
178 void unregisterStat(Stat
* s
);
180 }; /* class StatisticsRegistry */
183 * Resource-acquisition-is-initialization idiom for statistics
184 * registry. Useful for stack-based statistics (like in the driver).
185 * This RAII class only does registration and unregistration.
187 class CVC4_EXPORT RegisterStatistic
190 RegisterStatistic(StatisticsRegistry
* reg
, Stat
* stat
);
191 ~RegisterStatistic();
194 StatisticsRegistry
* d_reg
;
197 }; /* class RegisterStatistic */
201 #endif /* CVC4__STATISTICS_REGISTRY_H */