1 //===-- Statistics.h --------------------------------------------*- C++ -*-===//
2 //
3 //                     The KLEE Symbolic Virtual Machine
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef KLEE_STATISTICS_H
11 #define KLEE_STATISTICS_H
12 
13 #include "Statistic.h"
14 
15 #include <vector>
16 #include <string>
17 #include <string.h>
18 
19 namespace klee {
20   class Statistic;
21   class StatisticRecord {
22     friend class StatisticManager;
23 
24   private:
25     uint64_t *data;
26 
27   public:
28     StatisticRecord();
29     StatisticRecord(const StatisticRecord &s);
~StatisticRecord()30     ~StatisticRecord() { delete[] data; }
31 
32     void zero();
33 
34     uint64_t getValue(const Statistic &s) const;
35     void incrementValue(const Statistic &s, uint64_t addend) const;
36     StatisticRecord &operator =(const StatisticRecord &s);
37     StatisticRecord &operator +=(const StatisticRecord &sr);
38   };
39 
40   class StatisticManager {
41   private:
42     bool enabled;
43     std::vector<Statistic*> stats;
44     uint64_t *globalStats;
45     uint64_t *indexedStats;
46     StatisticRecord *contextStats;
47     unsigned index;
48 
49   public:
50     StatisticManager();
51     ~StatisticManager();
52 
53     void useIndexedStats(unsigned totalIndices);
54 
55     StatisticRecord *getContext();
56     void setContext(StatisticRecord *sr); /* null to reset */
57 
setIndex(unsigned i)58     void setIndex(unsigned i) { index = i; }
getIndex()59     unsigned getIndex() { return index; }
getNumStatistics()60     unsigned getNumStatistics() { return stats.size(); }
getStatistic(unsigned i)61     Statistic &getStatistic(unsigned i) { return *stats[i]; }
62 
63     void registerStatistic(Statistic &s);
64     void incrementStatistic(Statistic &s, uint64_t addend);
65     uint64_t getValue(const Statistic &s) const;
66     void incrementIndexedValue(const Statistic &s, unsigned index,
67                                uint64_t addend) const;
68     uint64_t getIndexedValue(const Statistic &s, unsigned index) const;
69     void setIndexedValue(const Statistic &s, unsigned index, uint64_t value);
70     int getStatisticID(const std::string &name) const;
71     Statistic *getStatisticByName(const std::string &name) const;
72   };
73 
74   extern StatisticManager *theStatisticManager;
75 
incrementStatistic(Statistic & s,uint64_t addend)76   inline void StatisticManager::incrementStatistic(Statistic &s,
77                                                    uint64_t addend) {
78     if (enabled) {
79       globalStats[s.id] += addend;
80       if (indexedStats) {
81         indexedStats[index*stats.size() + s.id] += addend;
82         if (contextStats)
83           contextStats->data[s.id] += addend;
84       }
85     }
86   }
87 
getContext()88   inline StatisticRecord *StatisticManager::getContext() {
89     return contextStats;
90   }
setContext(StatisticRecord * sr)91   inline void StatisticManager::setContext(StatisticRecord *sr) {
92     contextStats = sr;
93   }
94 
zero()95   inline void StatisticRecord::zero() {
96     ::memset(data, 0, sizeof(*data)*theStatisticManager->getNumStatistics());
97   }
98 
StatisticRecord()99   inline StatisticRecord::StatisticRecord()
100     : data(new uint64_t[theStatisticManager->getNumStatistics()]) {
101     zero();
102   }
103 
StatisticRecord(const StatisticRecord & s)104   inline StatisticRecord::StatisticRecord(const StatisticRecord &s)
105     : data(new uint64_t[theStatisticManager->getNumStatistics()]) {
106     ::memcpy(data, s.data,
107              sizeof(*data)*theStatisticManager->getNumStatistics());
108   }
109 
110   inline StatisticRecord &StatisticRecord::operator=(const StatisticRecord &s) {
111     ::memcpy(data, s.data,
112              sizeof(*data)*theStatisticManager->getNumStatistics());
113     return *this;
114   }
115 
incrementValue(const Statistic & s,uint64_t addend)116   inline void StatisticRecord::incrementValue(const Statistic &s,
117                                               uint64_t addend) const {
118     data[s.id] += addend;
119   }
getValue(const Statistic & s)120   inline uint64_t StatisticRecord::getValue(const Statistic &s) const {
121     return data[s.id];
122   }
123 
124   inline StatisticRecord &
125   StatisticRecord::operator +=(const StatisticRecord &sr) {
126     unsigned nStats = theStatisticManager->getNumStatistics();
127     for (unsigned i=0; i<nStats; i++)
128       data[i] += sr.data[i];
129     return *this;
130   }
131 
getValue(const Statistic & s)132   inline uint64_t StatisticManager::getValue(const Statistic &s) const {
133     return globalStats[s.id];
134   }
135 
incrementIndexedValue(const Statistic & s,unsigned index,uint64_t addend)136   inline void StatisticManager::incrementIndexedValue(const Statistic &s,
137                                                       unsigned index,
138                                                       uint64_t addend) const {
139     indexedStats[index*stats.size() + s.id] += addend;
140   }
141 
getIndexedValue(const Statistic & s,unsigned index)142   inline uint64_t StatisticManager::getIndexedValue(const Statistic &s,
143                                                     unsigned index) const {
144     return indexedStats[index*stats.size() + s.id];
145   }
146 
setIndexedValue(const Statistic & s,unsigned index,uint64_t value)147   inline void StatisticManager::setIndexedValue(const Statistic &s,
148                                                 unsigned index,
149                                                 uint64_t value) {
150     indexedStats[index*stats.size() + s.id] = value;
151   }
152 }
153 
154 #endif /* KLEE_STATISTICS_H */
155