summaryrefslogtreecommitdiffstats
path: root/src/bin/perfdhcp/rate_control.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/perfdhcp/rate_control.cc')
-rw-r--r--src/bin/perfdhcp/rate_control.cc80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/bin/perfdhcp/rate_control.cc b/src/bin/perfdhcp/rate_control.cc
new file mode 100644
index 0000000..5faad79
--- /dev/null
+++ b/src/bin/perfdhcp/rate_control.cc
@@ -0,0 +1,80 @@
+// Copyright (C) 2013-2019 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <config.h>
+
+#include <perfdhcp/rate_control.h>
+
+#include <exceptions/exceptions.h>
+
+
+namespace isc {
+namespace perfdhcp {
+
+using namespace boost::posix_time;
+
+RateControl::RateControl()
+ : rate_(0), total_pkts_sent_count_(0) {
+}
+
+RateControl::RateControl(const unsigned int rate)
+ : rate_(rate), total_pkts_sent_count_(0) {
+}
+
+uint64_t
+RateControl::getOutboundMessageCount(bool const waiting_to_exit /* = false */) {
+ if (total_pkts_sent_count_ == 0) {
+ start_time_ = currentTime();
+ total_pkts_sent_count_ = 1;
+ return 1;
+ }
+
+ // If rate is not limited, then each time send 1 packet.
+ if (getRate() == 0) {
+ return 1;
+ }
+
+ // If we've entered exit wait time's zone, stop sending.
+ if (waiting_to_exit) {
+ return 0;
+ }
+
+ // Estimate number of packets to sent. If we are behind of time we will
+ // try to catch up to upkeep request rate by sending more packets in one cycle.
+ auto now = currentTime();
+ time_period period(start_time_, now);
+ time_duration duration = period.length();
+ uint64_t should_sent_pkts_count = static_cast<double>(getRate()) / static_cast<double>(time_duration::ticks_per_second()) * duration.ticks();
+ if (should_sent_pkts_count <= total_pkts_sent_count_) {
+ return 0;
+ }
+ auto pending_pkts_count = should_sent_pkts_count - total_pkts_sent_count_;
+
+ // Reduce bursts to have more uniform traffic.
+ if (pending_pkts_count > 3) {
+ pending_pkts_count = 3;
+ }
+ total_pkts_sent_count_ += pending_pkts_count;
+
+ return pending_pkts_count;
+}
+
+boost::posix_time::ptime
+RateControl::currentTime() {
+ return (microsec_clock::universal_time());
+}
+
+void
+RateControl::setRate(const int rate) {
+ if (rate < 0) {
+ isc_throw(isc::BadValue, "invalid value of rate " << rate
+ << ", expected non-negative value");
+ }
+ rate_ = rate;
+}
+
+} // namespace perfdhcp
+} // namespace isc