Skip to content

Commit 000c0c2

Browse files
committed
High priority bypass CC
1 parent a90123b commit 000c0c2

File tree

5 files changed

+51
-9
lines changed

5 files changed

+51
-9
lines changed

picoquic/picoquic.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1486,6 +1486,22 @@ void picoquic_set_default_wifi_shadow_rtt(picoquic_quic_t* quic, uint64_t wifi_s
14861486
*/
14871487
void picoquic_set_default_bbr_quantum_ratio(picoquic_quic_t* quic, double quantum_ratio);
14881488

1489+
/* The experimental API 'picoquic_set_priority_limit_for_bypass'
1490+
* instruct the stack to send the high priority streams or datagrams
1491+
* immediately, even if congestion control would normally prevent it.
1492+
*
1493+
* The "priority_limit" parameter indicates the lowest priority that will
1494+
* not be bypassed. For example, if the priority limit is set to 3, streams
1495+
* or datagrams with priority 0, 1 or 2 will be sent without waiting for
1496+
* congestion control credits, but streams will priority 3 or more will
1497+
* not. By default, the limit is set to 0, meaning no stream or datagram
1498+
* will bypass congestion control.
1499+
*
1500+
* This experimental feature will not be activated in a multipath
1501+
* environment, i.e., if more that 1 path is activated.
1502+
*/
1503+
void picoquic_set_priority_limit_for_bypass(picoquic_cnx_t* cnx, uint8_t priority_limit);
1504+
14891505
/* The experimental API `picoquic_set_feedback_loss_notification` allow applications
14901506
* to turn on the "feedback lost" event notification. These events are
14911507
* passed to the congestion control algorithm, allowing it to react

picoquic/picoquic_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,6 +1448,7 @@ typedef struct st_picoquic_cnx_t {
14481448
picoquic_stream_head_t * last_output_stream;
14491449
uint64_t high_priority_stream_id;
14501450
uint64_t next_stream_id[4];
1451+
uint64_t priority_limit_for_bypass; /* Bypass CC if dtagram or stream priority lower than this, 0 means never */
14511452

14521453
/* Repeat queue contains packets with data frames that should be
14531454
* sent according to priority when congestion window opens. */

picoquic/quicctx.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4782,6 +4782,11 @@ void picoquic_set_default_bbr_quantum_ratio(picoquic_quic_t* quic, double quantu
47824782
quic->bbr_quantum_ratio = quantum_ratio;
47834783
}
47844784

4785+
void picoquic_set_priority_limit_for_bypass(picoquic_cnx_t* cnx, uint8_t priority_limit)
4786+
{
4787+
cnx->priority_limit_for_bypass = priority_limit;
4788+
}
4789+
47854790
void picoquic_set_feedback_loss_notification(picoquic_cnx_t* cnx, unsigned int should_notify)
47864791
{
47874792
cnx->is_lost_feedback_notification_required = should_notify;

picoquic/sender.c

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3150,6 +3150,7 @@ static uint8_t* picoquic_prepare_datagram_ready(picoquic_cnx_t* cnx, picoquic_pa
31503150
*/
31513151

31523152
static uint8_t* picoquic_prepare_stream_and_datagrams(picoquic_cnx_t* cnx, picoquic_path_t* path_x, uint8_t* bytes_next, uint8_t* bytes_max,
3153+
uint64_t max_priority_allowed,
31533154
int* more_data, int* is_pure_ack, int* no_data_to_send, int* ret)
31543155
{
31553156
int datagram_sent = 0;
@@ -3187,7 +3188,7 @@ static uint8_t* picoquic_prepare_stream_and_datagrams(picoquic_cnx_t* cnx, picoq
31873188
current_priority = stream_priority;
31883189
}
31893190

3190-
if (current_priority == UINT64_MAX) {
3191+
if (current_priority == UINT64_MAX || current_priority >= max_priority_allowed) {
31913192
/* Nothing to send! */
31923193
if (is_first_round) {
31933194
*no_data_to_send = 1;
@@ -3392,13 +3393,25 @@ int picoquic_prepare_packet_almost_ready(picoquic_cnx_t* cnx, picoquic_path_t* p
33923393

33933394
length = bytes_next - bytes;
33943395
if (path_x->cwin < path_x->bytes_in_transit) {
3395-
picoquic_per_ack_state_t ack_state = { 0 };
3396-
cnx->cwin_blocked = 1;
3397-
path_x->last_cwin_blocked_time = current_time;
3398-
if (cnx->congestion_alg != NULL) {
3399-
cnx->congestion_alg->alg_notify(cnx, path_x,
3400-
picoquic_congestion_notification_cwin_blocked,
3401-
&ack_state, current_time);
3396+
/* Implementation of experimental API, picoquic_set_priority_limit_for_bypass */
3397+
uint8_t* bytes_next_before_bypass = bytes_next;
3398+
if (cnx->priority_limit_for_bypass > 0 && cnx->nb_paths == 1) {
3399+
bytes_next = picoquic_prepare_stream_and_datagrams(cnx, path_x, bytes_next, bytes_max,
3400+
cnx->priority_limit_for_bypass,
3401+
&more_data, &is_pure_ack, &no_data_to_send, &ret);
3402+
}
3403+
if (bytes_next != bytes_next_before_bypass) {
3404+
length = bytes_next - bytes;
3405+
}
3406+
else {
3407+
picoquic_per_ack_state_t ack_state = { 0 };
3408+
cnx->cwin_blocked = 1;
3409+
path_x->last_cwin_blocked_time = current_time;
3410+
if (cnx->congestion_alg != NULL) {
3411+
cnx->congestion_alg->alg_notify(cnx, path_x,
3412+
picoquic_congestion_notification_cwin_blocked,
3413+
&ack_state, current_time);
3414+
}
34023415
}
34033416
}
34043417
else {
@@ -3440,6 +3453,7 @@ int picoquic_prepare_packet_almost_ready(picoquic_cnx_t* cnx, picoquic_path_t* p
34403453
}
34413454
if (ret == 0) {
34423455
bytes_next = picoquic_prepare_stream_and_datagrams(cnx, path_x, bytes_next, bytes_max,
3456+
UINT64_MAX,
34433457
&more_data, &is_pure_ack, &no_data_to_send, &ret);
34443458
}
34453459
/* TODO: replace this by posting of frame when CWIN estimated */
@@ -3774,7 +3788,7 @@ int picoquic_prepare_packet_ready(picoquic_cnx_t* cnx, picoquic_path_t* path_x,
37743788
bytes_next = picoquic_format_ack_frequency_frame(cnx, bytes_next, bytes_max, &more_data);
37753789
}
37763790
if (ret == 0) {
3777-
bytes_next = picoquic_prepare_stream_and_datagrams(cnx, path_x, bytes_next, bytes_max,
3791+
bytes_next = picoquic_prepare_stream_and_datagrams(cnx, path_x, bytes_next, bytes_max, UINT64_MAX,
37783792
&more_data, &is_pure_ack, &no_data_to_send, &ret);
37793793
}
37803794

picoquictest/mediatest.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ typedef struct st_mediatest_spec_t {
175175
double bandwidth;
176176
uint64_t latency_average;
177177
uint64_t latency_max;
178+
uint8_t priority_limit_for_bypass;
178179
int do_not_check_video2;
179180
} mediatest_spec_t;
180181

@@ -1149,6 +1150,10 @@ mediatest_ctx_t * mediatest_configure(int media_test_id, mediatest_spec_t * spe
11491150
if (spec->datagram_data_size > 0 && ret == 0) {
11501151
mt_ctx->datagram_data_requested = spec->datagram_data_size;
11511152
}
1153+
if (spec->priority_limit_for_bypass > 0) {
1154+
picoquic_set_priority_limit_for_bypass(mt_ctx->client_cnx->cnx, spec->priority_limit_for_bypass);
1155+
}
1156+
11521157

11531158
for (int i = 0; i < media_test_nb_types; i++) {
11541159
mt_ctx->media_stats[i].min_delay = UINT64_MAX;
@@ -1436,6 +1441,7 @@ int mediatest_wifi_test()
14361441
spec.data_size = 0;
14371442
spec.latency_average = 60000;
14381443
spec.latency_max = 350000;
1444+
spec.priority_limit_for_bypass = 5;
14391445
spec.do_not_check_video2 = 1;
14401446
ret = mediatest_one(mediatest_wifi, &spec);
14411447

0 commit comments

Comments
 (0)