@@ -913,228 +913,6 @@ static size_t picoquic_protect_packet(picoquic_cnx_t* cnx,
913
913
return send_length ;
914
914
}
915
915
916
- #if 0
917
- /* Compute nanosec per packet */
918
- uint64_t picoquic_packet_time_nanosec (picoquic_path_t * path_x , size_t length )
919
- {
920
- const uint64_t nanosec_per_sec = 1000000000ull ;
921
- uint64_t packet_time_nanosec = (nanosec_per_sec * length + (path_x -> pacing_rate - 1 )) / path_x -> pacing_rate ;
922
-
923
- return packet_time_nanosec ;
924
- }
925
-
926
- /* Update the leaky bucket used for pacing.
927
- */
928
- static void picoquic_update_pacing_bucket (picoquic_path_t * path_x , uint64_t current_time )
929
- {
930
- if (path_x -> pacing .bucket_nanosec < - path_x -> pacing_packet_time_nanosec ) {
931
- path_x -> pacing .bucket_nanosec = - path_x -> pacing_packet_time_nanosec ;
932
- }
933
-
934
- if (current_time > path_x -> pacing_evaluation_time ) {
935
- path_x -> pacing .bucket_nanosec += (current_time - path_x -> pacing_evaluation_time ) * 1000 ;
936
- path_x -> pacing_evaluation_time = current_time ;
937
- if (path_x -> pacing .bucket_nanosec > path_x -> pacing_bucket_max ) {
938
- path_x -> pacing .bucket_nanosec = path_x -> pacing_bucket_max ;
939
- }
940
- }
941
- }
942
-
943
- /*
944
- * Check pacing to see whether the next transmission is authorized.
945
- * If if is not, update the next wait time to reflect pacing.
946
- *
947
- * In packet train mode, the wait will last until the bucket is completely full, or
948
- * if at least N packets are received.
949
- */
950
- int picoquic_is_sending_authorized_by_pacing (picoquic_cnx_t * cnx , picoquic_path_t * path_x , uint64_t current_time , uint64_t * next_time )
951
- {
952
- int ret = 1 ;
953
-
954
- picoquic_update_pacing_bucket (path_x , current_time );
955
-
956
- if (path_x -> pacing .bucket_nanosec < path_x -> pacing_packet_time_nanosec ) {
957
- uint64_t next_pacing_time ;
958
- int64_t bucket_required ;
959
-
960
- if (cnx -> quic -> packet_train_mode || path_x -> pacing_bandwidth_pause ) {
961
- bucket_required = path_x -> pacing_bucket_max ;
962
-
963
- if (bucket_required > 10 * path_x -> pacing_packet_time_nanosec ) {
964
- bucket_required = 10 * path_x -> pacing_packet_time_nanosec ;
965
- }
966
-
967
- bucket_required -= path_x -> pacing .bucket_nanosec ;
968
- }
969
- else {
970
- bucket_required = path_x -> pacing_packet_time_nanosec - path_x -> pacing_bucket_nanosec ;
971
- }
972
-
973
- next_pacing_time = current_time + 1 + bucket_required / 1000 ;
974
- if (next_pacing_time < * next_time ) {
975
- path_x -> pacing_bandwidth_pause = 0 ;
976
- * next_time = next_pacing_time ;
977
- SET_LAST_WAKE (cnx -> quic , PICOQUIC_SENDER );
978
- }
979
- ret = 0 ;
980
- }
981
-
982
- return ret ;
983
- }
984
-
985
- /* Handle reporting of parameter updates if path is specified.
986
- */
987
-
988
- /* Reset the pacing data after recomputing the pacing rate
989
- */
990
- void picoquic_update_pacing_rate (picoquic_cnx_t * cnx , picoquic_path_t * path_x , double pacing_rate , uint64_t quantum )
991
- {
992
- #if 0
993
- const uint64_t nanosec_per_sec = 1000000000ull ;
994
-
995
- path_x -> pacing_rate = (uint64_t )pacing_rate ;
996
-
997
- if (quantum > path_x -> pacing_quantum_max ) {
998
- path_x -> pacing_quantum_max = quantum ;
999
- }
1000
- if (path_x -> pacing_rate > path_x -> pacing_rate_max ) {
1001
- path_x -> pacing_rate_max = path_x -> pacing_rate ;
1002
- }
1003
-
1004
- path_x -> pacing_packet_time_nanosec = picoquic_packet_time_nanosec (path_x , path_x -> send_mtu );
1005
-
1006
- path_x -> pacing_bucket_max = (nanosec_per_sec * quantum ) / path_x -> pacing_rate ;
1007
- if (path_x -> pacing_bucket_max <= 0 ) {
1008
- path_x -> pacing_bucket_max = 16 * path_x -> pacing_packet_time_nanosec ;
1009
- }
1010
-
1011
- #else
1012
- double packet_time = (double )path_x -> send_mtu / pacing_rate ;
1013
- double quantum_time = (double )quantum / pacing_rate ;
1014
- uint64_t rtt_nanosec = path_x -> smoothed_rtt * 1000 ;
1015
-
1016
- path_x -> pacing_rate = (uint64_t )pacing_rate ;
1017
-
1018
- if (quantum > path_x -> pacing_quantum_max ) {
1019
- path_x -> pacing_quantum_max = quantum ;
1020
- }
1021
- if (path_x -> pacing_rate > path_x -> pacing_rate_max ) {
1022
- path_x -> pacing_rate_max = path_x -> pacing_rate ;
1023
- }
1024
-
1025
- path_x -> pacing_packet_time_nanosec = (uint64_t )(packet_time * 1000000000.0 );
1026
-
1027
- if (path_x -> pacing_packet_time_nanosec <= 0 ) {
1028
- path_x -> pacing_packet_time_nanosec = 1 ;
1029
- path_x -> pacing_packet_time_microsec = 1 ;
1030
- }
1031
- else {
1032
- if ((uint64_t )path_x -> pacing_packet_time_nanosec > rtt_nanosec ) {
1033
- path_x -> pacing_packet_time_nanosec = rtt_nanosec ;
1034
- }
1035
- path_x -> pacing_packet_time_microsec = (path_x -> pacing_packet_time_nanosec + 999ull ) / 1000 ;
1036
- }
1037
-
1038
- path_x -> pacing_bucket_max = (uint64_t )(quantum_time * 1000000000.0 );
1039
- if (path_x -> pacing_bucket_max <= 0 ) {
1040
- path_x -> pacing_bucket_max = 16 * path_x -> pacing_packet_time_nanosec ;
1041
- }
1042
- #endif
1043
-
1044
- if (path_x -> pacing_bucket_nanosec > path_x -> pacing_bucket_max ) {
1045
- path_x -> pacing_bucket_nanosec = path_x -> pacing_bucket_max ;
1046
- }
1047
-
1048
- if (cnx -> is_pacing_update_requested && path_x == cnx -> path [0 ] &&
1049
- cnx -> callback_fn != NULL ) {
1050
- if ((path_x -> pacing_rate > cnx -> pacing_rate_signalled &&
1051
- (path_x -> pacing_rate - cnx -> pacing_rate_signalled >= cnx -> pacing_increase_threshold )) ||
1052
- (path_x -> pacing_rate < cnx -> pacing_rate_signalled &&
1053
- (cnx -> pacing_rate_signalled - path_x -> pacing_rate > cnx -> pacing_decrease_threshold ))){
1054
- (void )cnx -> callback_fn (cnx , path_x -> pacing_rate , NULL , 0 , picoquic_callback_pacing_changed , cnx -> callback_ctx , NULL );
1055
- cnx -> pacing_rate_signalled = path_x -> pacing_rate ;
1056
- }
1057
- }
1058
- if (cnx -> is_path_quality_update_requested &&
1059
- cnx -> callback_fn != NULL ) {
1060
- /* TODO: add a function "export path quality" */
1061
- /* TODO: remember previous signalled value for change tests */
1062
- if (path_x -> smoothed_rtt < path_x -> rtt_threshold_low ||
1063
- path_x -> smoothed_rtt > path_x -> rtt_threshold_high ||
1064
- path_x -> pacing_rate < path_x -> pacing_rate_threshold_low ||
1065
- path_x -> pacing_rate > path_x -> pacing_rate_threshold_high ) {
1066
- (void )cnx -> callback_fn (cnx , path_x -> unique_path_id , NULL , 0 , picoquic_callback_path_quality_changed , cnx -> callback_ctx , path_x -> app_path_ctx );
1067
- picoquic_refresh_path_quality_thresholds (path_x );
1068
- }
1069
- }
1070
- }
1071
-
1072
- /*
1073
- * Reset the pacing data after CWIN is updated.
1074
- * The max bucket is set to contain at least 2 packets more than 1/8th of the congestion window.
1075
- */
1076
-
1077
- void picoquic_update_pacing_data (picoquic_cnx_t * cnx , picoquic_path_t * path_x , int slow_start )
1078
- {
1079
- uint64_t rtt_nanosec = path_x -> smoothed_rtt * 1000 ;
1080
-
1081
- if ((path_x -> cwin < ((uint64_t )path_x -> send_mtu ) * 8 ) || rtt_nanosec <= 1000 ) {
1082
- /* Small windows, should only relie on ACK clocking */
1083
- path_x -> pacing_bucket_max = rtt_nanosec ;
1084
- path_x -> pacing_packet_time_nanosec = 1 ;
1085
- path_x -> pacing_packet_time_microsec = 1 ;
1086
-
1087
- if (path_x -> pacing_bucket_nanosec > path_x -> pacing_bucket_max ) {
1088
- path_x -> pacing_bucket_nanosec = path_x -> pacing_bucket_max ;
1089
- }
1090
- }
1091
- else {
1092
- double pacing_rate = ((double )path_x -> cwin / (double )rtt_nanosec ) * 1000000000.0 ;
1093
- uint64_t quantum = path_x -> cwin / 4 ;
1094
-
1095
- if (quantum < 2ull * path_x -> send_mtu ) {
1096
- quantum = 2ull * path_x -> send_mtu ;
1097
- }
1098
- else {
1099
- if (slow_start && path_x -> smoothed_rtt > 4 * PICOQUIC_MAX_BANDWIDTH_TIME_INTERVAL_MAX ) {
1100
- const uint64_t quantum_min = 0x8000 ;
1101
- if (quantum < quantum_min ){
1102
- quantum = quantum_min ;
1103
- }
1104
- else {
1105
- uint64_t quantum2 = (uint64_t )((pacing_rate * PICOQUIC_MAX_BANDWIDTH_TIME_INTERVAL_MAX ) / 1000000.0 );
1106
- if (quantum2 > quantum ) {
1107
- quantum = quantum2 ;
1108
- }
1109
- }
1110
- }
1111
- else if (quantum > 16ull * path_x -> send_mtu ) {
1112
- quantum = 16ull * path_x -> send_mtu ;
1113
- }
1114
-
1115
- }
1116
-
1117
- if (slow_start ) {
1118
- pacing_rate *= 1.25 ;
1119
- }
1120
-
1121
- picoquic_update_pacing_rate (cnx , path_x , pacing_rate , quantum );
1122
- }
1123
- }
1124
-
1125
- /*
1126
- * Update the pacing data after sending a packet.
1127
- */
1128
- void picoquic_update_pacing_after_send (picoquic_path_t * path_x , size_t length , uint64_t current_time )
1129
- {
1130
- uint64_t packet_time_nanosec ;
1131
-
1132
- picoquic_update_pacing_bucket (path_x , current_time );
1133
-
1134
- packet_time_nanosec = ((path_x -> pacing_packet_time_nanosec * (uint64_t )length ) + (path_x -> send_mtu - 1 )) / path_x -> send_mtu ;
1135
- path_x -> pacing_bucket_nanosec -= packet_time_nanosec ;
1136
- }
1137
- #endif
1138
916
/*
1139
917
* Final steps in packet transmission: queue for retransmission, etc
1140
918
*/
@@ -4678,7 +4456,7 @@ int picoquic_prepare_packet_ex(picoquic_cnx_t* cnx,
4678
4456
if (cnx -> path [path_id ]-> cwin <= cnx -> path [path_id ]-> bytes_in_transit ) {
4679
4457
cnx -> nb_trains_blocked_cwin ++ ;
4680
4458
}
4681
- else if (cnx -> path [path_id ]-> pacing . bucket_nanosec < cnx -> path [ path_id ] -> pacing . packet_time_nanosec ) {
4459
+ else if (picoquic_is_pacing_blocked ( & cnx -> path [path_id ]-> pacing )) {
4682
4460
cnx -> nb_trains_blocked_pacing ++ ;
4683
4461
}
4684
4462
else {
0 commit comments