BIND 10 trac3181, updated. 13cb26e18540a27e77a96736eb7d8029997f1ccf [3181] Added a RateControl class omitted in the previous commit.
BIND 10 source code commits
bind10-changes at lists.isc.org
Fri Dec 6 13:14:53 UTC 2013
The branch, trac3181 has been updated
via 13cb26e18540a27e77a96736eb7d8029997f1ccf (commit)
from 3c33b14cb434d745187877e56dd3858648343281 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 13cb26e18540a27e77a96736eb7d8029997f1ccf
Author: Marcin Siodelski <marcin at isc.org>
Date: Fri Dec 6 14:14:47 2013 +0100
[3181] Added a RateControl class omitted in the previous commit.
-----------------------------------------------------------------------
Summary of changes:
tests/tools/perfdhcp/rate_control.cc | 136 ++++++++++++++++++++++++++++
tests/tools/perfdhcp/rate_control.h | 163 ++++++++++++++++++++++++++++++++++
2 files changed, 299 insertions(+)
create mode 100644 tests/tools/perfdhcp/rate_control.cc
create mode 100644 tests/tools/perfdhcp/rate_control.h
-----------------------------------------------------------------------
diff --git a/tests/tools/perfdhcp/rate_control.cc b/tests/tools/perfdhcp/rate_control.cc
new file mode 100644
index 0000000..04cfa81
--- /dev/null
+++ b/tests/tools/perfdhcp/rate_control.cc
@@ -0,0 +1,136 @@
+// Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <exceptions/exceptions.h>
+#include <tests/tools/perfdhcp/rate_control.h>
+
+namespace isc {
+namespace perfdhcp {
+
+using namespace boost::posix_time;
+
+RateControl::RateControl()
+ : send_due_(currentTime()), last_sent_(currentTime()),
+ aggressivity_(1), rate_(0), late_sent_(false) {
+}
+
+RateControl::RateControl(const int rate, const int aggressivity)
+ : send_due_(currentTime()), last_sent_(currentTime()),
+ aggressivity_(aggressivity), rate_(rate), late_sent_(false) {
+ if (aggressivity < 1) {
+ isc_throw(isc::BadValue, "invalid value of aggressivity "
+ << aggressivity << ", expected value is greater than 0");
+ }
+}
+
+uint64_t
+RateControl::getOutboundMessageCount() {
+
+ // We need calculate the due time for sending next set of messages.
+ updateSendDue();
+
+ // Get current time. If we are behind due time, we have to calculate
+ // how many messages to send to catch up with the rate.
+ ptime now = currentTime();
+ if (now >= send_due_) {
+ // Reset number of exchanges.
+ uint64_t due_exchanges = 0;
+ // If rate is specified from the command line we have to
+ // synchornize with it.
+ if (getRate() != 0) {
+ time_period period(send_due_, now);
+ time_duration duration = period.length();
+ // due_factor indicates the number of seconds that
+ // sending next chunk of packets will take.
+ double due_factor = duration.fractional_seconds() /
+ time_duration::ticks_per_second();
+ due_factor += duration.total_seconds();
+ // Multiplying due_factor by expected rate gives the number
+ // of exchanges to be initiated.
+ due_exchanges = static_cast<uint64_t>(due_factor * getRate());
+ // We want to make sure that at least one packet goes out.
+ if (due_exchanges == 0) {
+ due_exchanges = 1;
+ }
+ // We should not exceed aggressivity as it could have been
+ // restricted from command line.
+ if (due_exchanges > getAggressivity()) {
+ due_exchanges = getAggressivity();
+ }
+ } else {
+ // Rate is not specified so we rely on aggressivity
+ // which is the number of packets to be sent in
+ // one chunk.
+ due_exchanges = getAggressivity();
+ }
+ return (due_exchanges);
+ }
+ return (0);
+}
+
+boost::posix_time::ptime
+RateControl::currentTime() {
+ return (microsec_clock::universal_time());
+}
+
+void
+RateControl::updateSendDue() {
+ // There is no sense to update due time if the current due time is in the
+ // future. The due time is calculated as a duration between the moment
+ // when the last message of the given type was sent and the time when
+ // next one is supposed to be sent based on a given rate. The former value
+ // will not change until we send the next message, which we don't do
+ // until we reach the due time.
+ if (send_due_ > currentTime()) {
+ return;
+ }
+ // This is initialized in the class constructor, so if it is not initialized
+ // it is a programmatic error.
+ if (last_sent_.is_not_a_date_time()) {
+ isc_throw(isc::Unexpected, "timestamp of the last sent packet not"
+ " initialized");
+ }
+ // If rate was not specified we will wait just one clock tick to
+ // send next packet. This simulates best effort conditions.
+ long duration = 1;
+ if (getRate() != 0) {
+ // We use number of ticks instead of nanoseconds because
+ // nanosecond resolution may not be available on some
+ // machines. Number of ticks guarantees the highest possible
+ // timer resolution.
+ duration = time_duration::ticks_per_second() / getRate();
+ }
+ // Calculate due time to initiate next chunk of exchanges.
+ send_due_ = last_sent_ + time_duration(0, 0, 0, duration);
+ if (send_due_ > currentTime()) {
+ late_sent_ = true;
+ } else {
+ late_sent_ = false;
+ }
+}
+
+void
+RateControl::setRelativeDue(const int offset) {
+ send_due_ = offset > 0 ?
+ currentTime() + seconds(abs(offset)) :
+ currentTime() - seconds(abs(offset));
+}
+
+void
+RateControl::updateSendTime() {
+ last_sent_ = currentTime();
+}
+
+} // namespace perfdhcp
+} // namespace isc
diff --git a/tests/tools/perfdhcp/rate_control.h b/tests/tools/perfdhcp/rate_control.h
new file mode 100644
index 0000000..32d8447
--- /dev/null
+++ b/tests/tools/perfdhcp/rate_control.h
@@ -0,0 +1,163 @@
+// Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef RATE_CONTROL_H
+#define RATE_CONTROL_H
+
+#include <boost/date_time/posix_time/posix_time.hpp>
+
+namespace isc {
+namespace perfdhcp {
+
+/// \brief A message sending rate control class for perfdhcp.
+///
+/// This class provides the means to control the rate at which messages
+/// of the specific type are sent by perfdhcp. Each message type,
+/// for which the desired rate can be specified, has a corresponding
+/// \c RateControl object. So, the perfdhcp is using up to three objects
+/// of this type in the same time, to control the rate of the following
+/// messages being sent:
+/// - Discover(DHCPv4) or Solicit (DHCPv6)
+/// - Renew (DHCPv6) or Request (DHCPv4) to renew leases.
+/// - Release
+///
+/// The purpose of the RateControl class is to track the due time for
+/// sending next message (or bunch of messages) to keep outbound rate
+/// of particular messages on the desired level. The due time is calculated
+/// using the desired rate value and the timestamp when the last message of
+/// the particular type has been sent. That puts the responsibility on the
+/// \c TestControl class to invoke the \c RateControl::updateSendDue, every
+/// time the message is sent.
+///
+/// The \c RateControl object returns the number of messages to be sent at
+/// the time. Typically the number returned is 0, if perfdhcp shouldn't send
+/// any messages yet, or 1 (sometimes more) if the send due time has been
+/// reached.
+class RateControl {
+public:
+
+ /// \brief Default constructor.
+ RateControl();
+
+ /// \brief Constructor which sets desired rate and aggressivity.
+ ///
+ /// \param rate A desired rate.
+ /// \param aggressivity A desired aggressivity.
+ RateControl(const int rate, const int aggressivity);
+
+ /// \brief Returns the value of aggressivity.
+ int getAggressivity() const {
+ return (aggressivity_);
+ }
+
+ /// \brief Returns current due time to send next message.
+ boost::posix_time::ptime getDue() const {
+ return (send_due_);
+ }
+
+ /// \brief Returns number of messages to be sent "now".
+ ///
+ /// This function calculates how many masseges of the given type should
+ /// be sent immediately when the call to the function returns, to catch
+ /// up with the desired message rate.
+ ///
+ /// The value returned depends on the due time calculated with the
+ /// \c RateControl::updateSendDue function and the current time. If
+ /// the due time has been hit, the non-zero number of messages is returned.
+ /// If the due time hasn't been hit, the number returned is 0.
+ ///
+ /// \return A number of messages to be sent immediately.
+ uint64_t getOutboundMessageCount();
+
+ /// \brief Returns the rate.
+ int getRate() const {
+ return (rate_);
+ }
+
+ /// \brief Returns the value of the late send flag.
+ ///
+ /// The flag returned by this function indicates whether the new due time
+ /// calculated by the \c RateControl::updateSendDue has been in the past.
+ /// This value is used by the \c TestControl object to increment the counter
+ /// of the late sent messages in the \c StatsMgr.
+ bool isLateSent() const {
+ return (late_sent_);
+ }
+
+ /// \brief Sets the value of aggressivity.
+ ///
+ /// \param aggressivity A new value of aggressivity.
+ void setAggressivity(const int aggressivity) {
+ aggressivity_ = aggressivity;
+ }
+
+ /// \brief Sets the new rate.
+ ///
+ /// \param A new value of rate.
+ void setRate(const int rate) {
+ rate_ = rate;
+ }
+
+ /// \brief Sets the value of the due time.
+ ///
+ /// This function is intended for unit testing. It manipulates the value of
+ /// the due time. The parameter passed to this function specifies the
+ /// (positive or negative) number of seconds relative to current time.
+ ///
+ /// \param A number of seconds relative to current time which constitutes
+ /// the new due time.
+ void setRelativeDue(const int offset);
+
+ /// \brief Sets the timestamp of the last sent message to current time.
+ void updateSendTime();
+
+protected:
+
+ /// \brief Convenience function returning current time.
+ ///
+ /// \return current time.
+ static boost::posix_time::ptime currentTime();
+
+ /// \brief Calculates the send due.
+ ///
+ /// This function calculates the send due timestamp using the current time
+ /// and desired rate. The due timestamp is calculated as a sum of the
+ /// timestamp when the last message was sent and the reciprocal of the rate
+ /// in micro or nanoseconds (depending on the timer resolution). If the rate
+ /// is not specified, the duration between two consecutive sends is one
+ /// timer tick.
+ void updateSendDue();
+
+ /// \brief Holds a timestamp when the next message should be sent.
+ boost::posix_time::ptime send_due_;
+
+ /// \brief Holds a timestamp when the last message was sent.
+ boost::posix_time::ptime last_sent_;
+
+ /// \brief Holds an aggressivity value.
+ int aggressivity_;
+
+ /// \brief Holds a desired rate value.
+ int rate_;
+
+ /// \brief A flag which indicates that the calculated due time is in the
+ /// past.
+ bool late_sent_;
+
+};
+
+}
+}
+
+#endif
More information about the bind10-changes
mailing list