ewmscp  ..
throttle.h
Go to the documentation of this file.
1 #ifndef __thottle_h__
2 #define __thottle_h__
3 #include <Options.h>
4 #include <chrono>
5 #include <mutex>
6 #include <thread>
7 
8 namespace throttle {
9  typedef std::chrono::system_clock clock_type ;
10  static auto start = clock_type::now();
18  class watch {
23  double rateIntegral;
24  double lastRate;
25  clock_type::time_point lastStop;
26  std::mutex updateMutex;
27  public:
28  watch(const std::string& name):
29  desiredRate('\0', name + "-rate", "throttle rate for " + name, 0),
30  tau('\0', name + "-tau", "time constant for " + name, 1),
31  p('\0', name + "-p", "prop constant for " + name, 1),
32  i('\0', name + "-i", "integral constant for " + name, 1),
33  lastStop(clock_type::now()) {
34  }
35  void update(double units = 1.0) {
36  if (desiredRate == 0) {
37  return;
38  }
39  std::unique_lock<decltype(updateMutex)> lock(updateMutex);
40  auto now = clock_type::now();
41  auto dt = std::chrono::duration_cast<std::chrono::duration<double>>(now - lastStop).count();
42  auto factor = dt / tau;
43  if (factor > 1) {
44  factor = 1;
45  }
46  lastRate = units / dt * factor + (1 - factor) * lastRate;
47  rateIntegral += (lastRate - desiredRate) * dt;
48  lastStop = now;
49  }
50  void wait() {
51  if (desiredRate == 0) {
52  return;
53  }
54  auto dRate = (lastRate - desiredRate) * p + rateIntegral * i;
55  if (dRate <= 0) {
56  return;
57  }
58  auto w = dRate / desiredRate;
59  if (w > 1) {
60  w = 1;
61  }
62  std::this_thread::sleep_for(std::chrono::duration<double>(w));
63  }
64  template <typename T, class ... Types> T action(T (*f)(Types...), Types ... args) {
65  wait();
66  auto result = f(args ...);
67  update();
68  return result;
69  }
70  };
71  class action {
73  double units;
74  public:
75  action(watch& aWatch, double aUnits = 1.0):
76  lWatch(aWatch),
77  units(aUnits) {
78  lWatch.wait();
79  }
80  ~action() {
82  }
83  };
84 
85 } // end namespace throttle
86 #endif
throttle::watch::lastRate
double lastRate
Definition: throttle.h:24
throttle::action::units
double units
Definition: throttle.h:73
options::single< double >
throttle::watch::desiredRate
options::single< double > desiredRate
Definition: throttle.h:19
throttle::watch::watch
watch(const std::string &name)
Definition: throttle.h:28
throttle::watch::action
T action(T(*f)(Types...), Types ... args)
Definition: throttle.h:64
throttle::watch::p
options::single< double > p
Definition: throttle.h:21
throttle
Definition: throttle.h:8
throttle::watch::i
options::single< double > i
Definition: throttle.h:22
Options.h
throttle::watch
class for limiting process load.
Definition: throttle.h:18
throttle::action::~action
~action()
Definition: throttle.h:80
throttle::action
Definition: throttle.h:71
throttle::start
static auto start
Definition: throttle.h:10
throttle::action::lWatch
watch & lWatch
Definition: throttle.h:72
throttle::clock_type
std::chrono::system_clock clock_type
Definition: throttle.h:9
throttle::watch::tau
options::single< double > tau
Definition: throttle.h:20
throttle::watch::lastStop
clock_type::time_point lastStop
Definition: throttle.h:25
throttle::watch::wait
void wait()
Definition: throttle.h:50
throttle::watch::updateMutex
std::mutex updateMutex
Definition: throttle.h:26
throttle::watch::rateIntegral
double rateIntegral
Definition: throttle.h:23
f
int f(int a, int line)
Definition: cctest.cpp:4
throttle::watch::update
void update(double units=1.0)
Definition: throttle.h:35
throttle::action::action
action(watch &aWatch, double aUnits=1.0)
Definition: throttle.h:75