Take into account larger frame size for prioritization

Larger frame size just destroys multiplexing and prioritization does
not work.
This commit is contained in:
Tatsuhiro Tsujikawa 2019-03-08 00:23:02 +09:00
parent dbbe4e017a
commit cfb47d30a5
2 changed files with 17 additions and 16 deletions

View File

@ -30,6 +30,7 @@
#include "nghttp2_session.h" #include "nghttp2_session.h"
#include "nghttp2_helper.h" #include "nghttp2_helper.h"
#include "nghttp2_debug.h" #include "nghttp2_debug.h"
#include "nghttp2_frame.h"
/* Maximum distance between any two stream's cycle in the same /* Maximum distance between any two stream's cycle in the same
prirority queue. Imagine stream A's cycle is A, and stream B's prirority queue. Imagine stream A's cycle is A, and stream B's
@ -40,7 +41,8 @@
words, B is really greater than or equal to A. Otherwise, A is a words, B is really greater than or equal to A. Otherwise, A is a
result of overflow, and it is actually A > B if we consider that result of overflow, and it is actually A > B if we consider that
fact. */ fact. */
#define NGHTTP2_MAX_CYCLE_DISTANCE (16384 * 256 + 255) #define NGHTTP2_MAX_CYCLE_DISTANCE \
((uint64_t)NGHTTP2_MAX_FRAME_SIZE_MAX * 256 + 255)
static int stream_less(const void *lhsx, const void *rhsx) { static int stream_less(const void *lhsx, const void *rhsx) {
const nghttp2_stream *lhs, *rhs; const nghttp2_stream *lhs, *rhs;
@ -131,14 +133,14 @@ static int stream_subtree_active(nghttp2_stream *stream) {
/* /*
* Returns next cycle for |stream|. * Returns next cycle for |stream|.
*/ */
static void stream_next_cycle(nghttp2_stream *stream, uint32_t last_cycle) { static void stream_next_cycle(nghttp2_stream *stream, uint64_t last_cycle) {
uint32_t penalty; uint64_t penalty;
penalty = (uint32_t)stream->last_writelen * NGHTTP2_MAX_WEIGHT + penalty = (uint64_t)stream->last_writelen * NGHTTP2_MAX_WEIGHT +
stream->pending_penalty; stream->pending_penalty;
stream->cycle = last_cycle + penalty / (uint32_t)stream->weight; stream->cycle = last_cycle + penalty / (uint32_t)stream->weight;
stream->pending_penalty = penalty % (uint32_t)stream->weight; stream->pending_penalty = (uint32_t)(penalty % (uint32_t)stream->weight);
} }
static int stream_obq_push(nghttp2_stream *dep_stream, nghttp2_stream *stream) { static int stream_obq_push(nghttp2_stream *dep_stream, nghttp2_stream *stream) {
@ -149,7 +151,7 @@ static int stream_obq_push(nghttp2_stream *dep_stream, nghttp2_stream *stream) {
stream_next_cycle(stream, dep_stream->descendant_last_cycle); stream_next_cycle(stream, dep_stream->descendant_last_cycle);
stream->seq = dep_stream->descendant_next_seq++; stream->seq = dep_stream->descendant_next_seq++;
DEBUGF("stream: stream=%d obq push cycle=%d\n", stream->stream_id, DEBUGF("stream: stream=%d obq push cycle=%lu\n", stream->stream_id,
stream->cycle); stream->cycle);
DEBUGF("stream: push stream %d to stream %d\n", stream->stream_id, DEBUGF("stream: push stream %d to stream %d\n", stream->stream_id,
@ -235,7 +237,7 @@ void nghttp2_stream_reschedule(nghttp2_stream *stream) {
nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry); nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry);
DEBUGF("stream: stream=%d obq resched cycle=%d\n", stream->stream_id, DEBUGF("stream: stream=%d obq resched cycle=%lu\n", stream->stream_id,
stream->cycle); stream->cycle);
dep_stream->last_writelen = stream->last_writelen; dep_stream->last_writelen = stream->last_writelen;
@ -244,9 +246,9 @@ void nghttp2_stream_reschedule(nghttp2_stream *stream) {
void nghttp2_stream_change_weight(nghttp2_stream *stream, int32_t weight) { void nghttp2_stream_change_weight(nghttp2_stream *stream, int32_t weight) {
nghttp2_stream *dep_stream; nghttp2_stream *dep_stream;
uint32_t last_cycle; uint64_t last_cycle;
int32_t old_weight; int32_t old_weight;
uint32_t wlen_penalty; uint64_t wlen_penalty;
if (stream->weight == weight) { if (stream->weight == weight) {
return; return;
@ -269,7 +271,7 @@ void nghttp2_stream_change_weight(nghttp2_stream *stream, int32_t weight) {
nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry); nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry);
wlen_penalty = (uint32_t)stream->last_writelen * NGHTTP2_MAX_WEIGHT; wlen_penalty = (uint64_t)stream->last_writelen * NGHTTP2_MAX_WEIGHT;
/* Compute old stream->pending_penalty we used to calculate /* Compute old stream->pending_penalty we used to calculate
stream->cycle */ stream->cycle */
@ -285,9 +287,8 @@ void nghttp2_stream_change_weight(nghttp2_stream *stream, int32_t weight) {
place */ place */
stream_next_cycle(stream, last_cycle); stream_next_cycle(stream, last_cycle);
if (stream->cycle < dep_stream->descendant_last_cycle && if (dep_stream->descendant_last_cycle - stream->cycle <=
(dep_stream->descendant_last_cycle - stream->cycle) <= NGHTTP2_MAX_CYCLE_DISTANCE) {
NGHTTP2_MAX_CYCLE_DISTANCE) {
stream->cycle = dep_stream->descendant_last_cycle; stream->cycle = dep_stream->descendant_last_cycle;
} }
@ -295,7 +296,7 @@ void nghttp2_stream_change_weight(nghttp2_stream *stream, int32_t weight) {
nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry); nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry);
DEBUGF("stream: stream=%d obq resched cycle=%d\n", stream->stream_id, DEBUGF("stream: stream=%d obq resched cycle=%lu\n", stream->stream_id,
stream->cycle); stream->cycle);
} }

View File

@ -148,9 +148,9 @@ struct nghttp2_stream {
/* Received body so far */ /* Received body so far */
int64_t recv_content_length; int64_t recv_content_length;
/* Base last_cycle for direct descendent streams. */ /* Base last_cycle for direct descendent streams. */
uint32_t descendant_last_cycle; uint64_t descendant_last_cycle;
/* Next scheduled time to sent item */ /* Next scheduled time to sent item */
uint32_t cycle; uint64_t cycle;
/* Next seq used for direct descendant streams */ /* Next seq used for direct descendant streams */
uint64_t descendant_next_seq; uint64_t descendant_next_seq;
/* Secondary key for prioritization to break a tie for cycle. This /* Secondary key for prioritization to break a tie for cycle. This