ewmscp  ..
timer.h
Go to the documentation of this file.
1 #ifndef __timer_h__
2 #define __timer_h__
3 
4 #include <errMsgQueue.h>
5 #include <set>
6 #include <chrono>
7 #include <atomic>
8 #include <string.h>
9 #include <mutex>
10 #include <iostream>
11 
12 #if defined(__has_builtin) // we probably use CLANG
13 #if __has_builtin(__builtin_FUNCTION)
14 #define __useBuiltinFunction__
15 #endif
16 #else // we probably use GCC
17 #define __useBuiltinFunction__
18 #endif
19 
20 namespace timer {
21  typedef std::chrono::high_resolution_clock clock_type;
22  class anchor {
23  friend class instanceUnscoped;
24  friend class pointerCompare;
25  const char*subfunc;
26  const char*function;
27  const char*file;
28  int line;
29 
31  public:
32  bool operator () (const anchor* lhs,
33  const anchor* rhs) const {
34  auto cmp = strcmp(lhs->file, rhs->file);
35  if (cmp < 0) {
36  return true;
37  }
38  if (cmp > 0) {
39  return false;
40  }
41  return lhs->line < rhs->line;
42  }
43  };
44 
45  std::atomic<int> counter;
46  std::atomic<std::uint64_t> timeSpent;
47  std::atomic<std::int64_t> maxTimeSpent;
48  static std::mutex listMutex;
49  static std::set<anchor*, pointerCompare>& getList() {
50  static std::set<anchor*, pointerCompare> list;
51  return list;
52  }
53 
54  public:
55  #ifdef __useBuiltinFunction__
56  anchor(const char *aSubFunc,
57  const char *aFunc = __builtin_FUNCTION(),
58  int aLine = __builtin_LINE(),
59  const char *aFile = __builtin_FILE()):
60  #else // no info available....
61  anchor(const char * aSubFunc,
62  const char *aFunc = "unknown",
63  int aLine = 0,
64  const char *aFile = "unknown"):
65  #endif
66  subfunc(aSubFunc),
67  function(aFunc),
68  file(aFile),
69  line(aLine),
70  counter(0) {
71  std::unique_lock<decltype(listMutex)> lock(listMutex);
72  getList().emplace(this);
73  }
74  const char* getFunc() const {
75  return function;
76  };
77  const char* getFile() const {
78  return file;
79  };
80  int getLine() const {
81  return line;
82  };
83 
84 
85  static void print(std::ostream& out, const std::string& prefix);
86  static void reset() {
87  std::unique_lock<decltype(listMutex)> lock(listMutex);
88  for (auto item : getList()) {
89  item->timeSpent = 0;
90  item->counter = 0;
91  item->maxTimeSpent = 0;
92  }
93  }
94  };
97  clock_type::time_point start;
98  public:
99  instanceUnscoped(anchor& aAnchor): lAnchor(aAnchor) {
100  start = clock_type::now();
101  }
102  static inline void updateMax(std::atomic<std::int64_t>& max, std::int64_t val) {
103  auto oldMax = max.load();
104  while (val > oldMax &&
105  !max.compare_exchange_weak(oldMax, val));
106  }
107  void stop() {
108  lAnchor.counter++;
109  auto timeSpent = clock_type::now() - start;
110  auto timeSpentNs = std::chrono::duration_cast<std::chrono::nanoseconds>(timeSpent).count();
111  lAnchor.timeSpent += timeSpentNs;
112  updateMax(lAnchor.maxTimeSpent, timeSpentNs);
113  }
114  static inline const std::string& stringy(const std::string& s) {
115  return s;
116  }
117  static inline const std::string stringy(const std::vector<char>& s) {
118  return std::string(s.data());
119  }
120 
121  template <class T> void stop(clock_type::duration timeout, const T& object) {
122  lAnchor.counter++;
123  auto timeSpent = clock_type::now() - start;
124  auto timeSpentNs = std::chrono::duration_cast<std::chrono::nanoseconds>(timeSpent).count();
125  lAnchor.timeSpent += timeSpentNs;
126  updateMax(lAnchor.maxTimeSpent, timeSpentNs);
127  if (timeSpent > timeout) {
128  const std::string& oref(stringy(object));
130  oref, lAnchor.subfunc, "tardy action took ", std::chrono::duration_cast<std::chrono::duration<double>>(timeSpent).count(), "s");
131  }
132  }
133  void restart() {
134  start = clock_type::now();
135  }
136  };
137  class instance: private instanceUnscoped {
138  public:
139  instance(anchor& aAnchor): instanceUnscoped(aAnchor) {};
141  stop();
142  }
143  };
144  template <class T> class instanceWithTimeout: private instanceUnscoped {
145  clock_type::duration timeout;
146  const T& object;
147  public:
148  instanceWithTimeout(anchor& aAnchor, clock_type::duration aTimeout, const T& aObject): instanceUnscoped(aAnchor),
149  timeout(aTimeout),
150  object(aObject) {};
152  stop(timeout, object);
153  }
154  };
155 
156 };
157 #define timerInst(subfunc) static timer::anchor aUniqueName##subfunc(#subfunc); timer::instance iUniqueName##subfunc(aUniqueName##subfunc)
158 #define timerInstTO(subfunc,timeout,object) static timer::anchor aUniqueName##subfunc(#subfunc); timer::instanceWithTimeout<decltype(object)> iUniqueName##subfunc(aUniqueName##subfunc, timeout, object)
159 
160 
161 #undef __useBuiltinFunction__
162 #endif
timer::instanceUnscoped::restart
void restart()
Definition: timer.h:133
timer::instanceUnscoped::updateMax
static void updateMax(std::atomic< std::int64_t > &max, std::int64_t val)
Definition: timer.h:102
timer::instanceWithTimeout::timeout
clock_type::duration timeout
Definition: timer.h:145
errMsgQueue.h
timer::instanceWithTimeout::instanceWithTimeout
instanceWithTimeout(anchor &aAnchor, clock_type::duration aTimeout, const T &aObject)
Definition: timer.h:148
timer::instance::instance
instance(anchor &aAnchor)
Definition: timer.h:139
timer::anchor::getFunc
const char * getFunc() const
Definition: timer.h:74
timer::instanceUnscoped::instanceUnscoped
instanceUnscoped(anchor &aAnchor)
Definition: timer.h:99
errMsg::location
class for defining the location of a error message in the source code.
Definition: errMsgQueue.h:14
timer::instanceUnscoped::lAnchor
anchor & lAnchor
Definition: timer.h:96
timer::anchor::getLine
int getLine() const
Definition: timer.h:80
timer::instanceWithTimeout::~instanceWithTimeout
~instanceWithTimeout()
Definition: timer.h:151
timer::instanceWithTimeout
Definition: timer.h:144
timer::instanceUnscoped::stringy
static const std::string stringy(const std::vector< char > &s)
Definition: timer.h:117
timer
Definition: timer.cpp:3
timer::anchor::pointerCompare
Definition: timer.h:30
timer::anchor::file
const char * file
Definition: timer.h:27
timer::anchor::line
int line
Definition: timer.h:28
errMsg::level::debug
@ debug
timer::anchor::anchor
anchor(const char *aSubFunc, const char *aFunc=__builtin_FUNCTION(), int aLine=__builtin_LINE(), const char *aFile=__builtin_FILE())
Definition: timer.h:56
timer::anchor::pointerCompare::operator()
bool operator()(const anchor *lhs, const anchor *rhs) const
Definition: timer.h:32
timer::instanceUnscoped::stringy
static const std::string & stringy(const std::string &s)
Definition: timer.h:114
timer::anchor::print
static void print(std::ostream &out, const std::string &prefix)
Definition: timer.cpp:5
timer::anchor::counter
std::atomic< int > counter
Definition: timer.h:45
timer::instanceUnscoped::stop
void stop()
Definition: timer.h:107
timer::anchor::reset
static void reset()
Definition: timer.h:86
timer::instanceUnscoped::stop
void stop(clock_type::duration timeout, const T &object)
Definition: timer.h:121
timer::instanceUnscoped
Definition: timer.h:95
timer::instance::~instance
~instance()
Definition: timer.h:140
timer::anchor
Definition: timer.h:22
timer::anchor::getFile
const char * getFile() const
Definition: timer.h:77
timer::anchor::timeSpent
std::atomic< std::uint64_t > timeSpent
Definition: timer.h:46
timer::instanceWithTimeout::object
const T & object
Definition: timer.h:146
timer::clock_type
std::chrono::high_resolution_clock clock_type
Definition: timer.h:21
errMsg::emit
void emit(level aLogLevel, const location &loc, const std::string &aObject, const std::string &aAction, const Args &... args)
function to create and enqueue a message, this is the only way that messages should be created!
Definition: errMsgQueue.h:148
timer::anchor::getList
static std::set< anchor *, pointerCompare > & getList()
Definition: timer.h:49
timer::anchor::subfunc
const char * subfunc
Definition: timer.h:25
timer::anchor::listMutex
static std::mutex listMutex
Definition: timer.h:48
timer::instanceUnscoped::start
clock_type::time_point start
Definition: timer.h:97
timer::anchor::function
const char * function
Definition: timer.h:26
timer::anchor::maxTimeSpent
std::atomic< std::int64_t > maxTimeSpent
Definition: timer.h:47
timer::instance
Definition: timer.h:137