/* * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree.
*/ #ifndef NET_DCSCTP_TX_STREAM_SCHEDULER_H_ #define NET_DCSCTP_TX_STREAM_SCHEDULER_H_
// A parameterized stream scheduler. Currently, it implements the round robin // scheduling algorithm using virtual finish time. It is to be used as a part of // a send queue and will track all active streams (streams that have any data // that can be sent). // // The stream scheduler works with the concept of associating active streams // with a "virtual finish time", which is the time when a stream is allowed to // produce data. Streams are ordered by their virtual finish time, and the // "current virtual time" will advance to the next following virtual finish time // whenever a chunk is to be produced. // // When message interleaving is enabled, the WFQ - Weighted Fair Queueing - // scheduling algorithm will be used. And when it's not, round-robin scheduling // will be used instead. // // In the round robin scheduling algorithm, a stream's virtual finish time will // just increment by one (1) after having produced a chunk, which results in a // round-robin scheduling. // // In WFQ scheduling algorithm, a stream's virtual finish time will be defined // as the number of bytes in the next fragment to be sent, multiplied by the // inverse of the stream's priority, meaning that a high priority - or a smaller // fragment - results in a closer virtual finish time, compared to a stream with // either a lower priority or a larger fragment to be sent. class StreamScheduler { private: class VirtualTime : public webrtc::StrongAlias<class VirtualTimeTag, double> { public:
constexpr explicit VirtualTime(const UnderlyingType& v)
: webrtc::StrongAlias<class VirtualTimeTag, double>(v) {}
public: class StreamProducer { public: virtual ~StreamProducer() = default;
// Produces a fragment of data to send. The current wall time is specified // as `now` and should be used to skip chunks with expired limited lifetime. // The parameter `max_size` specifies the maximum amount of actual payload // that may be returned. If these constraints prevents the stream from // sending some data, `std::nullopt` should be returned. virtual std::optional<SendQueue::DataToSend> Produce(webrtc::Timestamp now,
size_t max_size) = 0;
// Returns the number of payload bytes that is scheduled to be sent in the // next enqueued message, or zero if there are no enqueued messages or if // the stream has been actively paused. virtual size_t bytes_to_send_in_next_message() const = 0;
};
// Will activate the stream _if_ it has any data to send. That is, if the // callback to `bytes_to_send_in_next_message` returns non-zero. If the // callback returns zero, the stream will not be made active. void MaybeMakeActive();
// Will remove the stream from the list of active streams, and will not try // to produce data from it. To make it active again, call `MaybeMakeActive`. void MakeInactive();
// Make the scheduler move to another message, or another stream. This is // used to abort the scheduler from continuing producing fragments for the // current message in case it's deleted. void ForceReschedule() { parent_.ForceReschedule(); }
// Produces a message from this stream. This will only be called on streams // that have data.
std::optional<SendQueue::DataToSend> Produce(webrtc::Timestamp now,
size_t max_size);
// The `mtu` parameter represents the maximum SCTP packet size, which should // be the same as `DcSctpOptions::mtu`.
StreamScheduler(absl::string_view log_prefix, size_t mtu)
: log_prefix_(log_prefix),
max_payload_bytes_(mtu - SctpPacket::kHeaderSize -
IDataChunk::kHeaderSize) {}
// Makes the scheduler stop producing message from the current stream and // re-evaluates which stream to produce from. void ForceReschedule() { currently_sending_a_message_ = false; }
// Produces a fragment of data to send. The current wall time is specified as // `now` and will be used to skip chunks with expired limited lifetime. The // parameter `max_size` specifies the maximum amount of actual payload that // may be returned. If no data can be produced, `std::nullopt` is returned.
std::optional<SendQueue::DataToSend> Produce(webrtc::Timestamp now,
size_t max_size);
// The current virtual time, as defined in the WFQ algorithm.
VirtualTime virtual_time_ = VirtualTime::Zero();
// The current stream to send chunks from.
Stream* current_stream_ = nullptr;
bool enable_message_interleaving_ = false;
// Indicates if the streams is currently sending a message, and should then // - if message interleaving is not enabled - continue sending from this // stream until that message has been sent in full. bool currently_sending_a_message_ = false;
// The currently active streams, ordered by virtual finish time.
webrtc::flat_set<Stream*, ActiveStreamComparator> active_streams_;
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.