Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(29)

Side by Side Diff: net/quic/quic_write_blocked_list.h

Issue 1472563002: Let QUIC streams write 16k before ceding. Behind FLAG_quic_batch_writes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@107581674
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/quic/quic_session_test.cc ('k') | net/quic/quic_write_blocked_list.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 #ifndef NET_QUIC_QUIC_WRITE_BLOCKED_LIST_H_ 5 #ifndef NET_QUIC_QUIC_WRITE_BLOCKED_LIST_H_
6 #define NET_QUIC_QUIC_WRITE_BLOCKED_LIST_H_ 6 #define NET_QUIC_QUIC_WRITE_BLOCKED_LIST_H_
7 7
8 #include <set> 8 #include <set>
9 9
10 #include "net/base/net_export.h" 10 #include "net/base/net_export.h"
11 #include "net/quic/quic_flags.h"
11 #include "net/quic/quic_protocol.h" 12 #include "net/quic/quic_protocol.h"
12 #include "net/spdy/write_blocked_list.h" 13 #include "net/spdy/write_blocked_list.h"
13 14
14 namespace net { 15 namespace net {
15 16
16 // Keeps tracks of the QUIC streams that have data to write, sorted by 17 // Keeps tracks of the QUIC streams that have data to write, sorted by
17 // priority. QUIC stream priority order is: 18 // priority. QUIC stream priority order is:
18 // Crypto stream > Headers stream > Data streams by requested priority. 19 // Crypto stream > Headers stream > Data streams by requested priority.
19 class NET_EXPORT_PRIVATE QuicWriteBlockedList { 20 class NET_EXPORT_PRIVATE QuicWriteBlockedList {
20 private: 21 private:
21 typedef WriteBlockedList<QuicStreamId> QuicWriteBlockedListBase; 22 typedef WriteBlockedList<QuicStreamId> QuicWriteBlockedListBase;
22 23
23 public: 24 public:
24 static const QuicPriority kHighestPriority; 25 static const QuicPriority kHighestPriority =
25 static const QuicPriority kLowestPriority; 26 static_cast<QuicPriority>(net::kHighestPriority);
27 static const QuicPriority kLowestPriority =
28 static_cast<QuicPriority>(net::kLowestPriority);
26 29
27 QuicWriteBlockedList(); 30 QuicWriteBlockedList();
28 ~QuicWriteBlockedList(); 31 ~QuicWriteBlockedList();
29 32
30 bool HasWriteBlockedDataStreams() const { 33 bool HasWriteBlockedDataStreams() const {
31 return base_write_blocked_list_.HasWriteBlockedStreams(); 34 return base_write_blocked_list_.HasWriteBlockedStreams();
32 } 35 }
33 36
34 bool HasWriteBlockedCryptoOrHeadersStream() const { 37 bool HasWriteBlockedCryptoOrHeadersStream() const {
35 return crypto_stream_blocked_ || headers_stream_blocked_; 38 return crypto_stream_blocked_ || headers_stream_blocked_;
36 } 39 }
37 40
38 size_t NumBlockedStreams() const { 41 size_t NumBlockedStreams() const {
39 size_t num_blocked = base_write_blocked_list_.NumBlockedStreams(); 42 size_t num_blocked = base_write_blocked_list_.NumBlockedStreams();
40 if (crypto_stream_blocked_) { 43 if (crypto_stream_blocked_) {
41 ++num_blocked; 44 ++num_blocked;
42 } 45 }
43 if (headers_stream_blocked_) { 46 if (headers_stream_blocked_) {
44 ++num_blocked; 47 ++num_blocked;
45 } 48 }
46 49
47 return num_blocked; 50 return num_blocked;
48 } 51 }
49 52
53 // Pops the highest priorty stream, special casing crypto and headers streams.
54 // Latches the most recently popped data stream for batch writing purposes.
50 QuicStreamId PopFront() { 55 QuicStreamId PopFront() {
51 if (crypto_stream_blocked_) { 56 if (crypto_stream_blocked_) {
52 crypto_stream_blocked_ = false; 57 crypto_stream_blocked_ = false;
53 return kCryptoStreamId; 58 return kCryptoStreamId;
54 } 59 }
55 60
56 if (headers_stream_blocked_) { 61 if (headers_stream_blocked_) {
57 headers_stream_blocked_ = false; 62 headers_stream_blocked_ = false;
58 return kHeadersStreamId; 63 return kHeadersStreamId;
59 } 64 }
60 65
61 SpdyPriority priority = 66 SpdyPriority priority =
62 base_write_blocked_list_.GetHighestPriorityWriteBlockedList(); 67 base_write_blocked_list_.GetHighestPriorityWriteBlockedList();
63 QuicStreamId id = base_write_blocked_list_.PopFront(priority); 68 QuicStreamId id = base_write_blocked_list_.PopFront(priority);
69
70 if (base_write_blocked_list_.NumBlockedStreams(priority) == 0) {
71 // If no streams are blocked, don't bother latching. This stream will be
72 // the first popped for its priority anyway.
73 batch_write_stream_id_[priority] = 0;
74 } else if (batch_write_stream_id_[priority] != id) {
75 // If newly latching this batch write stream, let it write 16k.
76 batch_write_stream_id_[priority] = id;
77 bytes_left_for_batch_write_[priority] = 16000;
78 last_priority_popped_ = priority;
79 }
80
64 return id; 81 return id;
65 } 82 }
66 83
67 void PushBack(QuicStreamId stream_id, QuicPriority priority) { 84 void UpdateBytesForStream(QuicStreamId stream_id, size_t bytes) {
85 if (batch_write_stream_id_[last_priority_popped_] == stream_id) {
86 // If this was the last data stream popped by PopFront, update the
87 // bytes remaining in its batch write.
88 bytes_left_for_batch_write_[last_priority_popped_] -= bytes;
89 } else {
90 // If a batch write stream was set, it should only be preempted by the
91 // crypto or headers streams. Any higher priority data stream would
92 // *become* the new batch write stream.
93 if (FLAGS_respect_send_alarm &&
94 FLAGS_quic_batch_writes) {
95 DCHECK(stream_id == kCryptoStreamId || stream_id == kHeadersStreamId ||
96 batch_write_stream_id_[last_priority_popped_] == 0 ||
97 bytes == 0);
98 }
99 }
100 }
101
102 // Pushes a stream to the back of the std::list for this priority level *unles s* it
103 // is latched for doing batched writes in which case it goes to the front of
104 // the std::list for this priority level.
105 // Headers and crypto streams are special cased to always resume first.
106 void AddStream(QuicStreamId stream_id, QuicPriority priority) {
68 if (stream_id == kCryptoStreamId) { 107 if (stream_id == kCryptoStreamId) {
69 DCHECK_EQ(kHighestPriority, priority); 108 DCHECK_EQ(kHighestPriority, priority);
70 // TODO(avd) Add DCHECK(!crypto_stream_blocked_) 109 // TODO(avd) Add DCHECK(!crypto_stream_blocked_)
71 crypto_stream_blocked_ = true; 110 crypto_stream_blocked_ = true;
72 return; 111 return;
73 } 112 }
74 113
75 if (stream_id == kHeadersStreamId) { 114 if (stream_id == kHeadersStreamId) {
76 DCHECK_EQ(kHighestPriority, priority); 115 DCHECK_EQ(kHighestPriority, priority);
77 // TODO(avd) Add DCHECK(!headers_stream_blocked_); 116 // TODO(avd) Add DCHECK(!headers_stream_blocked_);
78 headers_stream_blocked_ = true; 117 headers_stream_blocked_ = true;
79 return; 118 return;
80 } 119 }
81 120 if (FLAGS_quic_batch_writes &&
82 base_write_blocked_list_.PushBack( 121 stream_id == batch_write_stream_id_[last_priority_popped_] &&
83 stream_id, static_cast<SpdyPriority>(priority)); 122 bytes_left_for_batch_write_[last_priority_popped_] > 0) {
123 // If the batch write stream has more data to write, push it to the front
124 // for its priority level.
125 base_write_blocked_list_.PushFront(
126 stream_id, static_cast<SpdyPriority>(priority));
127 } else {
128 base_write_blocked_list_.PushBack(
129 stream_id, static_cast<SpdyPriority>(priority));
130 }
84 return; 131 return;
85 } 132 }
86 133
87 bool crypto_stream_blocked() const { return crypto_stream_blocked_; } 134 bool crypto_stream_blocked() const { return crypto_stream_blocked_; }
88 bool headers_stream_blocked() const { return headers_stream_blocked_; } 135 bool headers_stream_blocked() const { return headers_stream_blocked_; }
89 136
90 private: 137 private:
91 QuicWriteBlockedListBase base_write_blocked_list_; 138 QuicWriteBlockedListBase base_write_blocked_list_;
139
140 // If performing batch writes, this will be the stream ID of the stream doing
141 // batch writes for this priority level. We will allow this stream to write
142 // until it has written kBatchWriteSize bytes, it has no more data to write,
143 // or a higher priority stream preempts.
144 QuicStreamId batch_write_stream_id_[kLowestPriority + 1];
145 // Set to kBatchWriteSize when we set a new batch_write_stream_id_ for a given
146 // priority. This is decremented with each write the stream does until it is
147 // done with its batch write.
148 int32 bytes_left_for_batch_write_[kLowestPriority + 1];
149 // Tracks the last priority popped for UpdateBytesForStream.
150 QuicPriority last_priority_popped_;
151
92 bool crypto_stream_blocked_; 152 bool crypto_stream_blocked_;
93 bool headers_stream_blocked_; 153 bool headers_stream_blocked_;
94 154
95 DISALLOW_COPY_AND_ASSIGN(QuicWriteBlockedList); 155 DISALLOW_COPY_AND_ASSIGN(QuicWriteBlockedList);
96 }; 156 };
97 157
98 } // namespace net 158 } // namespace net
99 159
100 160
101 #endif // NET_QUIC_QUIC_WRITE_BLOCKED_LIST_H_ 161 #endif // NET_QUIC_QUIC_WRITE_BLOCKED_LIST_H_
OLDNEW
« no previous file with comments | « net/quic/quic_session_test.cc ('k') | net/quic/quic_write_blocked_list.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698