-// Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2018 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
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 (getRate() == 0) {
- // If rate was not specified we will wait just one clock tick to
- // send next packet. This simulates best effort conditions.
- long duration = 1;
- send_due_ = last_sent_ + time_duration(0, 0, 0, duration);
+ // 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;
+ send_due_ = last_sent_ + time_duration(0, 0, 0, duration);
} else {
- double offset = (double)(sent_ + 1) / (double)getRate();
- boost::posix_time::time_duration duration =
- microseconds((long)(offset * 1000000.));
- send_due_ = start_time_ + duration;
+ // New way to compute the due time from the start time,
+ // the number of sent packets and the wanted rate.
+ double offset = static_cast<double>(sent_ + 1) / getRate();
+ double seconds;
+ double fracts =
+ modf(offset, &seconds) * time_duration::ticks_per_second();
+ send_due_ = start_time_ +
+ time_duration(0, 0, static_cast<long>(seconds),
+ static_cast<long>(fracts));
}
if (send_due_ > currentTime()) {
-// Copyright (C) 2013-2015 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2018 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
/// 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 at the desired level. The due time is calculated
-/// using the desired rate value and the timestamp when the last message of
+/// using the desired rate value and the number of messages 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.
/// constitutes the new due time.
void setRelativeDue(const int offset);
- /// \brief Sets the timestamp of the last sent message to current time.
+ /// \brief Sets the timestamp of the last sent message to current time
+ /// and increment the sent counter.
void updateSendTime();
protected:
/// \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
+ /// and desired rate. The due timestamp was 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.
+ /// The way the due timestamp is calculated was fixed to not accumulate
+ /// delays and to provide the derised rate when possible: now it uses
+ /// the start timestamp, the desired not zero rate and the number of
+ /// already sent packets.
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.
+ ///
+ /// Was used to compute send_due_ for rate != 0.
boost::posix_time::ptime last_sent_;
/// \brief Holds an aggressivity value.
/// past.
bool late_sent_;
+ /// \brief Holds the timestamp when it started.
boost::posix_time::ptime start_time_;
+ /// \brief Holds the number of packets already sent.
uint64_t sent_;
-
};
}