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