GCC Code Coverage Report
Directory: cvmfs/ Exec Total Coverage
File: cvmfs/statistics.h Lines: 27 27 100.0 %
Date: 2019-02-03 02:48:13 Branches: 0 0 - %

Line Branch Exec Source
1
/**
2
 * This file is part of the CernVM File System.
3
 */
4
5
#ifndef CVMFS_STATISTICS_H_
6
#define CVMFS_STATISTICS_H_
7
8
#include <pthread.h>
9
#include <stdint.h>
10
11
#include <map>
12
#include <string>
13
#include <vector>
14
15
#include "atomic.h"
16
17
#ifdef CVMFS_NAMESPACE_GUARD
18
namespace CVMFS_NAMESPACE_GUARD {
19
#endif
20
21
22
namespace perf {
23
24
/**
25
 * A wrapper around an atomic 64bit signed integer.
26
 */
27
class Counter {
28
 public:
29
10520
  Counter() { atomic_init64(&counter_); }
30
97833
  void Inc() { atomic_inc64(&counter_); }
31
66
  void Dec() { atomic_dec64(&counter_); }
32
50
  int64_t Get() { return atomic_read64(&counter_); }
33
476
  void Set(const int64_t val) { atomic_write64(&counter_, val); }
34
1453
  int64_t Xadd(const int64_t delta) { return atomic_xadd64(&counter_, delta); }
35
36
  std::string Print();
37
  std::string PrintK();
38
  std::string PrintKi();
39
  std::string PrintM();
40
  std::string PrintMi();
41
  std::string PrintRatio(Counter divider);
42
  std::string ToString();
43
44
 private:
45
  atomic_int64 counter_;
46
};
47
48
// perf::Func(Counter) is more clear to read in the code
49
64
inline void Dec(class Counter *counter) { counter->Dec(); }
50
97832
inline void Inc(class Counter *counter) { counter->Inc(); }
51
1452
inline int64_t Xadd(class Counter *counter, const int64_t delta) {
52
1452
  return counter->Xadd(delta);
53
}
54
55
56
/**
57
 * A collection of Counter objects with a name and a description.  Counters in
58
 * a Statistics class have a name and a description.  Thread-safe.
59
 */
60
class Statistics {
61
 public:
62
  enum PrintOptions {
63
    kPrintSimple = 0,
64
    kPrintHeader
65
  };
66
67
  Statistics();
68
  ~Statistics();
69
  Statistics *Fork();
70
  Counter *Register(const std::string &name, const std::string &desc);
71
  Counter *Lookup(const std::string &name) const;
72
  std::string LookupDesc(const std::string &name);
73
  std::string PrintList(const PrintOptions print_options);
74
75
 private:
76
  Statistics(const Statistics &other);
77
  Statistics& operator=(const Statistics &other);
78
10440
  struct CounterInfo {
79
10518
    explicit CounterInfo(const std::string &desc) : desc(desc) {
80
10518
      atomic_init32(&refcnt);
81
10518
      atomic_inc32(&refcnt);
82
10518
    }
83
    atomic_int32 refcnt;
84
    Counter counter;
85
    std::string desc;
86
  };
87
  std::map<std::string, CounterInfo *> counters_;
88
  mutable pthread_mutex_t *lock_;
89
};
90
91
92
/**
93
 * Allows multiple instance of the same class to use the same Statistics
94
 * instance.  The "name_major" part is used to contruct counter names in the
95
 * form name_major.<provided name>
96
 */
97
1993
class StatisticsTemplate {
98
 public:
99
553
  StatisticsTemplate(const std::string &name_major, Statistics *statistics)
100
553
    : name_major_(name_major), statistics_(statistics)
101
553
  { }
102
198
  StatisticsTemplate(const std::string &name_sub,
103
                     const StatisticsTemplate &statistics)
104
    : name_major_(statistics.name_major_ + "." + name_sub)
105
198
    , statistics_(statistics.statistics_)
106
198
  { }
107
108
5861
  Counter *RegisterTemplated(const std::string &name_minor,
109
                             const std::string &desc)
110
  {
111
5861
    return statistics_->Register(name_major_ + "." + name_minor, desc);
112
  }
113
114
  Statistics *statistics() { return statistics_; }
115
116
 private:
117
  std::string name_major_;
118
  Statistics *statistics_;
119
};
120
121
122
/**
123
 * Keeps track of events over time.  Can be used to query the number of events
124
 * between now and a point in time in the past.  The time range should be
125
 * smaller than capacity_s seconds.  Uses a monotonic clock.  Not thread-safe.
126
 */
127
2007
class Recorder {
128
 public:
129
  Recorder(uint32_t resolution_s, uint32_t capacity_s);
130
131
  void Tick();
132
  void TickAt(uint64_t timestamp);
133
  uint64_t GetNoTicks(uint32_t retrospect_s) const;
134
135
13
  uint32_t capacity_s() const { return capacity_s_; }
136
  uint32_t resolution_s() const { return resolution_s_; }
137
138
 private:
139
  /**
140
   * Records number of ticks (events) per unit of resolution.  A ring buffer.
141
   * Entries older than capacity_s get overwritten by new events.
142
   */
143
  std::vector<uint32_t> bins_;
144
145
  /**
146
   * When the most recent tick occured.
147
   */
148
  uint64_t last_timestamp_;
149
150
  /**
151
   * Time window in seconds that the recorder is supposed to remember.
152
   */
153
  uint32_t capacity_s_;
154
155
  /**
156
   * Size of the bins for the tick counters.
157
   */
158
  uint32_t resolution_s_;
159
160
  /**
161
   * Shorthand for bins_.size(), constant during lifetime of the recorder.
162
   */
163
  unsigned no_bins_;
164
};
165
166
167
/**
168
 * Writes to multiple recorders.  Recorders with coarsed-grained resolution and
169
 * a large capacity are combined with precise recorders with shorter capacity.
170
 * Preferred recorders should be added first because GetNoTicks will use the
171
 * first recorder with a capacity >= retrospect_s (or the last recorder).
172
 */
173
222
class MultiRecorder {
174
 public:
175
  void Tick();
176
  void TickAt(uint64_t timestamp);
177
  uint64_t GetNoTicks(uint32_t retrospect_s) const;
178
179
  void AddRecorder(uint32_t resolution_s, uint32_t capacity_s);
180
181
 private:
182
  std::vector<Recorder> recorders_;
183
};
184
185
}  // namespace perf
186
187
#ifdef CVMFS_NAMESPACE_GUARD
188
}  // namespace CVMFS_NAMESPACE_GUARD
189
#endif
190
191
#endif  // CVMFS_STATISTICS_H_