common: C++ RateKeeper (#29374)
* c++ RateKeeper * add to files_common * use util::random_int * improve monotor_time * remove ~ratekeeperpull/29503/head
parent
ff068dd722
commit
3eef63af9b
10 changed files with 97 additions and 23 deletions
@ -0,0 +1,38 @@ |
|||||||
|
#include "common/ratekeeper.h" |
||||||
|
|
||||||
|
#include "common/swaglog.h" |
||||||
|
#include "common/timing.h" |
||||||
|
#include "common/util.h" |
||||||
|
|
||||||
|
RateKeeper::RateKeeper(const std::string &name, float rate, float print_delay_threshold) |
||||||
|
: name(name), |
||||||
|
print_delay_threshold(std::max(0.f, print_delay_threshold)) { |
||||||
|
interval = 1 / rate; |
||||||
|
last_monitor_time = seconds_since_boot(); |
||||||
|
next_frame_time = last_monitor_time + interval; |
||||||
|
} |
||||||
|
|
||||||
|
bool RateKeeper::keepTime() { |
||||||
|
bool lagged = monitorTime(); |
||||||
|
if (remaining_ > 0) { |
||||||
|
util::sleep_for(remaining_ * 1000); |
||||||
|
} |
||||||
|
return lagged; |
||||||
|
} |
||||||
|
|
||||||
|
bool RateKeeper::monitorTime() { |
||||||
|
++frame_; |
||||||
|
last_monitor_time = seconds_since_boot(); |
||||||
|
remaining_ = next_frame_time - last_monitor_time; |
||||||
|
|
||||||
|
bool lagged = remaining_ < 0; |
||||||
|
if (lagged) { |
||||||
|
if (print_delay_threshold > 0 && remaining_ < -print_delay_threshold) { |
||||||
|
LOGW("%s lagging by %.2f ms", name.c_str(), -remaining_ * 1000); |
||||||
|
} |
||||||
|
next_frame_time = last_monitor_time + interval; |
||||||
|
} else { |
||||||
|
next_frame_time += interval; |
||||||
|
} |
||||||
|
return lagged; |
||||||
|
} |
@ -0,0 +1,22 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include <string> |
||||||
|
|
||||||
|
class RateKeeper { |
||||||
|
public: |
||||||
|
RateKeeper(const std::string &name, float rate, float print_delay_threshold = 0); |
||||||
|
~RateKeeper() {} |
||||||
|
bool keepTime(); |
||||||
|
bool monitorTime(); |
||||||
|
inline double frame() const { return frame_; } |
||||||
|
inline double remaining() const { return remaining_; } |
||||||
|
|
||||||
|
private: |
||||||
|
double interval; |
||||||
|
double next_frame_time; |
||||||
|
double last_monitor_time; |
||||||
|
double remaining_ = 0; |
||||||
|
float print_delay_threshold = 0; |
||||||
|
uint64_t frame_ = 0; |
||||||
|
std::string name; |
||||||
|
}; |
@ -1,2 +1,3 @@ |
|||||||
|
test_ratekeeper |
||||||
test_util |
test_util |
||||||
test_swaglog |
test_swaglog |
||||||
|
@ -0,0 +1,17 @@ |
|||||||
|
#define CATCH_CONFIG_MAIN |
||||||
|
#include "catch2/catch.hpp" |
||||||
|
#include "common/ratekeeper.h" |
||||||
|
#include "common/timing.h" |
||||||
|
#include "common/util.h" |
||||||
|
|
||||||
|
TEST_CASE("RateKeeper") { |
||||||
|
float freq = GENERATE(10, 50, 100); |
||||||
|
RateKeeper rk("Test RateKeeper", freq); |
||||||
|
for (int i = 0; i < freq; ++i) { |
||||||
|
double begin = seconds_since_boot(); |
||||||
|
util::sleep_for(util::random_int(0, 1000.0 / freq - 1)); |
||||||
|
bool lagged = rk.keepTime(); |
||||||
|
REQUIRE(std::abs(seconds_since_boot() - begin - (1 / freq)) < 1e-3); |
||||||
|
REQUIRE(lagged == false); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue