Fixing bug in SimulatedNetwork where packets stop.

Bug: webrtc:9952
Change-Id: I68491f1d18fee317165999453776a35cea41e71f
Reviewed-on: https://webrtc-review.googlesource.com/c/109009
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Christoffer Rodbro <crodbro@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25531}
This commit is contained in:
Sebastian Jansson
2018-11-06 19:18:28 +01:00
committed by Commit Bot
parent 0f54f211e6
commit 2cd3b4c819
3 changed files with 28 additions and 17 deletions

View File

@ -260,6 +260,9 @@ rtc_source_set("simulated_network") {
]
deps = [
"../api:simulated_network_api",
"../api/units:data_rate",
"../api/units:data_size",
"../api/units:time_delta",
"../rtc_base:rtc_base_approved",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/types:optional",

View File

@ -13,6 +13,7 @@
#include <algorithm>
#include <cmath>
#include <utility>
#include "api/units/data_rate.h"
namespace webrtc {
@ -26,6 +27,9 @@ SimulatedNetwork::~SimulatedNetwork() = default;
void SimulatedNetwork::SetConfig(const SimulatedNetwork::Config& config) {
rtc::CritScope crit(&config_lock_);
if (config_.link_capacity_kbps != config.link_capacity_kbps) {
reset_capacity_delay_error_ = true;
}
config_ = config; // Shallow copy of the struct.
double prob_loss = config.loss_percent / 100.0;
if (config_.avg_burst_loss_length == -1) {
@ -64,42 +68,45 @@ bool SimulatedNetwork::EnqueuePacket(PacketInFlightInfo packet) {
// Too many packet on the link, drop this one.
return false;
}
// Delay introduced by the link capacity.
int64_t capacity_delay_ms = 0;
if (config.link_capacity_kbps > 0) {
// Using bytes per millisecond to avoid losing precision.
const int64_t bytes_per_millisecond = config.link_capacity_kbps / 8;
// To round to the closest millisecond we add half a milliseconds worth of
// bytes to the delay calculation.
capacity_delay_ms = (packet.size + capacity_delay_error_bytes_ +
bytes_per_millisecond / 2) /
bytes_per_millisecond;
capacity_delay_error_bytes_ +=
packet.size - capacity_delay_ms * bytes_per_millisecond;
}
int64_t network_start_time_us = packet.send_time_us;
{
rtc::CritScope crit(&config_lock_);
if (reset_capacity_delay_error_) {
capacity_delay_error_bytes_ = 0;
reset_capacity_delay_error_ = false;
}
if (pause_transmission_until_us_) {
network_start_time_us =
std::max(network_start_time_us, *pause_transmission_until_us_);
pause_transmission_until_us_.reset();
}
}
// Delay introduced by the link capacity.
TimeDelta capacity_delay = TimeDelta::Zero();
if (config.link_capacity_kbps > 0) {
const DataRate link_capacity = DataRate::kbps(config.link_capacity_kbps);
int64_t compensated_size =
static_cast<int64_t>(packet.size) + capacity_delay_error_bytes_;
capacity_delay = DataSize::bytes(compensated_size) / link_capacity;
capacity_delay_error_bytes_ +=
packet.size - (capacity_delay * link_capacity).bytes();
}
// Check if there already are packets on the link and change network start
// time forward if there is.
if (!capacity_link_.empty() &&
network_start_time_us < capacity_link_.back().arrival_time_us)
network_start_time_us = capacity_link_.back().arrival_time_us;
int64_t arrival_time_us = network_start_time_us + capacity_delay_ms * 1000;
int64_t arrival_time_us = network_start_time_us + capacity_delay.us();
capacity_link_.push({packet, arrival_time_us});
return true;
}
absl::optional<int64_t> SimulatedNetwork::NextDeliveryTimeUs() const {
rtc::CritScope crit(&process_lock_);
if (!delay_link_.empty())
return delay_link_.begin()->arrival_time_us;
return absl::nullopt;

View File

@ -49,6 +49,7 @@ class SimulatedNetwork : public NetworkBehaviorInterface {
int64_t arrival_time_us;
};
rtc::CriticalSection config_lock_;
bool reset_capacity_delay_error_ RTC_GUARDED_BY(config_lock_) = false;
// |process_lock| guards the data structures involved in delay and loss
// processes, such as the packet queues.
@ -56,7 +57,7 @@ class SimulatedNetwork : public NetworkBehaviorInterface {
std::queue<PacketInfo> capacity_link_ RTC_GUARDED_BY(process_lock_);
Random random_;
std::deque<PacketInfo> delay_link_;
std::deque<PacketInfo> delay_link_ RTC_GUARDED_BY(process_lock_);
// Link configuration.
Config config_ RTC_GUARDED_BY(config_lock_);