Loading prrt/proto/bbr.c +20 −17 Original line number Diff line number Diff line Loading @@ -4,11 +4,10 @@ #include "receiver.h" #include <math.h> prrtByteCount_t BBR_Inflight(BBR* bbr, double gain) { if (bbr->rtprop == Inf) return InitialCwnd; /* no valid RTT samples yet */ return bbr->initial_cwnd; /* no valid RTT samples yet */ uint32_t quanta = 0; uint32_t estimated_bdp = (uint32_t) round((((double)bbr->bw) * bbr->rtprop) / (1000 * 1000)); return (uint32_t)(gain * estimated_bdp + quanta); Loading Loading @@ -41,7 +40,7 @@ void BBR_CheckFullPipe(BBR* bbr, PrrtRateSample* rs) { if (bbr->filled_pipe || !bbr->round_start || rs->is_app_limited) return; // no need to check for a full pipe now if (bbr->bw >= bbr->full_bw * 1.25) { // BBR.BtlBw still growing? if (bbr->bw >= bbr->full_bw * PROBE_GAIN) { // BBR.BtlBw still growing? bbr->full_bw = bbr->bw; // record new baseline level bbr->full_bw_count = 0; return; Loading @@ -58,14 +57,16 @@ bool BBR_IsNextCyclePhase(BBR* bbr, prrtByteCount_t bytes_lost, prrtByteCount_t return is_full_length; if (bbr->pacing_gain > 1) return is_full_length && (bytes_lost > 0 || prior_inflight >= BBR_Inflight(bbr, bbr->pacing_gain)); return is_full_length || (prior_inflight <= BBR_Inflight(bbr, 1.0)); bool is_max_length = (PrrtClock_get_current_time_us() - bbr->cycle_stamp) > 4 * bbr->rtprop; return is_max_length || (prior_inflight <= BBR_Inflight(bbr, 1.0)); } void BBR_AdvanceCyclePhase(BBR* bbr) { bbr->cycle_stamp = PrrtClock_get_current_time_us(); bbr->cycle_index = (uint8_t )((bbr->cycle_index + 1) % BBRGainCycleLen); float pacing_gain_cycle[BBRGainCycleLen] = {1.25, 0.75, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}; float pacing_gain_cycle[BBRGainCycleLen] = {PROBE_GAIN, DRAIN_GAIN, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}; bbr->pacing_gain = pacing_gain_cycle[bbr->cycle_index]; debug(DEBUG_BBR, "Advanced cycle with gain: %f", bbr->pacing_gain); } Loading Loading @@ -135,7 +136,7 @@ void BBR_HandleProbeRTT(BBR *bbr, PrrtPacketTracking *tracking) { tracking->app_limited = (tracking->delivered + tracking->pipe) ? : 1; /* Ignore low rate samples during ProbeRTT: */ prrtTimestamp_t now = PrrtClock_get_current_time_us(); if (bbr->probe_rtt_done_stamp == 0 && tracking->pipe <= BBRMinPipeCwnd) { if (bbr->probe_rtt_done_stamp == 0 && tracking->pipe <= bbr->min_pipe_cwnd) { bbr->probe_rtt_done_stamp = now + ProbeRTTDuration; bbr->probe_rtt_round_done = false; bbr->next_round_delivered = tracking->delivered; Loading Loading @@ -183,13 +184,13 @@ void BBR_UpdateTargetCwnd(BBR* bbr) void BBR_ModulateCwndForProbeRTT(BBR* bbr) { if (bbr->state == PROBE_RTT) bbr->cwnd = MIN(bbr->cwnd, BBRMinPipeCwnd); bbr->cwnd = MIN(bbr->cwnd, bbr->min_pipe_cwnd); } void BBR_ModulateCwndForRecovery(BBR* bbr, prrtByteCount_t bytes_lost, prrtByteCount_t pipe, prrtByteCount_t delivered) { if (bytes_lost > 0) bbr->cwnd = MAX(bbr->cwnd - bytes_lost, SMSS); bbr->cwnd = MAX(bbr->cwnd - bytes_lost, bbr->mps); if (bbr->packet_conservation) bbr->cwnd = MAX(bbr->cwnd, pipe + delivered); } Loading @@ -202,9 +203,9 @@ void BBR_SetCwnd(BBR* bbr, PrrtPacketTracking* packetTracking) if (!bbr->packet_conservation) { if (bbr->filled_pipe) bbr->cwnd = MIN(bbr->cwnd + packetTracking->delivered, bbr->target_cwnd); else if (bbr->cwnd < bbr->target_cwnd || packetTracking->delivered < InitialCwnd) else if (bbr->cwnd < bbr->target_cwnd || packetTracking->delivered < bbr->initial_cwnd) bbr->cwnd = bbr->cwnd + packetTracking->delivered; bbr->cwnd = MAX(bbr->cwnd, BBRMinPipeCwnd); bbr->cwnd = MAX(bbr->cwnd, bbr->min_pipe_cwnd); } BBR_ModulateCwndForProbeRTT(bbr); debug(DEBUG_BBR, "New cwnd: %u, State: %u", bbr->cwnd, bbr->state); Loading @@ -226,9 +227,9 @@ void BBR_SetPacingRate(BBR* bbr) void BBR_SetSendQuantum(BBR* bbr) { if(bbr->pacing_rate < 150000) { // 1.2Mbps = 0.15 MBps = 150000 Bps bbr->send_quantum = 1 * SMSS; bbr->send_quantum = 1 * bbr->mps; } else if (bbr->pacing_rate < 3000000) { // 24 Mbps = 20 * 1.2Mbps = 3000000 bbr->send_quantum = 2 * SMSS; bbr->send_quantum = 2 * bbr->mps; } else { bbr->send_quantum = MIN((prrtByteCount_t) round((double) bbr->pacing_rate / 1000), 64000); } Loading Loading @@ -270,7 +271,7 @@ void BBR_OnRTOLoss(BBR *bbr) { if(!bbr->is_loss_recovery) { bbr->is_loss_recovery = true; bbr->prior_cwnd = BBR_SaveCwnd(bbr); bbr->cwnd = SMSS; bbr->cwnd = bbr->mps; } check(pthread_mutex_unlock(&bbr->lock) == 0, "Unlock failed."); return; Loading @@ -291,7 +292,7 @@ void BBR_OnLossExit(BBR *bbr) { PERROR("BBR_OnACK failed.") } BBR* BBR_Init(void) BBR* BBR_Init(prrtByteCount_t maximum_payload_size) { BBR* bbr = calloc(1, sizeof(BBR)); check_mem(bbr); Loading @@ -301,7 +302,9 @@ BBR* BBR_Init(void) check(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) == EXIT_SUCCESS, "Setting type failed."); check(pthread_mutex_init(&bbr->lock, &attr) == 0, "lock init failed."); bbr->mps = maximum_payload_size; bbr->min_pipe_cwnd = 4 * maximum_payload_size; bbr->initial_cwnd = 4 * maximum_payload_size; bbr->has_seen_rtt = false; bbr->btlBwFilter = WindowedFilter_Init(true); bbr->rtprop = Inf; Loading @@ -310,7 +313,7 @@ BBR* BBR_Init(void) bbr->probe_rtt_round_done = false; bbr->packet_conservation = false; bbr->prior_cwnd = 0; bbr->cwnd = InitialCwnd; bbr->cwnd = bbr->initial_cwnd; bbr->idle_restart = false; bbr->is_loss_recovery = false; Loading @@ -325,7 +328,7 @@ BBR* BBR_Init(void) bbr->full_bw_count = 0; //Init pacing rate double nominal_bandwidth = InitialCwnd / (bbr->has_seen_rtt ? bbr->rtprop : 1000); double nominal_bandwidth = bbr->initial_cwnd / (bbr->has_seen_rtt ? bbr->rtprop : 1000); bbr->pacing_rate = bbr->pacing_gain * nominal_bandwidth; BBR_EnterStartup(bbr); Loading prrt/proto/bbr.h +6 −4 Original line number Diff line number Diff line Loading @@ -10,12 +10,11 @@ #include "types/rateSample.h" #include "../util/windowedFilter.h" #define SMSS 1500 #define PROBE_GAIN 1.25 #define DRAIN_GAIN 0.75 #define RTpropFilterLen 10000000 //10s #define BBRHighGain ((((float)2885) / 1000) + 1) #define InitialCwnd (10 * SMSS) #define BBRGainCycleLen 8 #define BBRMinPipeCwnd (4 * SMSS) #define ProbeRTTDuration 200000 //200ms #define Inf UINT32_MAX Loading @@ -29,6 +28,9 @@ enum bbr_state { typedef struct bbr { pthread_mutex_t lock; prrtByteCount_t mps; prrtByteCount_t min_pipe_cwnd; prrtByteCount_t initial_cwnd; prrtTimedelta_t rtprop; prrtTimestamp_t rtprop_stamp; prrtTimestamp_t probe_rtt_done_stamp; Loading Loading @@ -73,7 +75,7 @@ typedef struct bbr { WindowedFilter* btlBwFilter; } BBR; BBR* BBR_Init(void); BBR* BBR_Init(prrtByteCount_t maximum_payload_size); void BBR_OnACK(BBR* bbr, PrrtChannelStateInformation* csi, PrrtRateSample* rs, PrrtPacketTracking* packetTracking, prrtTimedelta_t rtt); void BBR_OnSpuriousLoss(BBR *bbr, PrrtPacketTracking *tracking); void BBR_OnRTOLoss(BBR *bbr); Loading prrt/proto/receiver.c +2 −2 Original line number Diff line number Diff line Loading @@ -98,7 +98,7 @@ bool update_and_generate_rate_sample(PrrtReceiver *recv, prrtSequenceNumber_t se return result; } PrrtReceiver *PrrtReceiver_create(const char *host, uint16_t port, prrtByteCount_t mss) { PrrtReceiver *PrrtReceiver_create(const char *host, uint16_t port, prrtByteCount_t maximum_payload_size) { PrrtReceiver *recv = calloc(1, sizeof(PrrtReceiver)); check_mem(recv); recv->host_name = strdup(host); Loading Loading @@ -130,7 +130,7 @@ PrrtReceiver *PrrtReceiver_create(const char *host, uint16_t port, prrtByteCount check(0 == getaddrinfo(host, portstr, &hints, &info), "getaddrinfo"); recv->ai = info; recv->bbr = BBR_Init(); recv->bbr = BBR_Init(maximum_payload_size); pthread_mutexattr_t attr; check(pthread_mutexattr_init(&attr) == EXIT_SUCCESS, "Mutex attr init failed."); Loading prrt/proto/receiver.h +1 −1 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ typedef struct prrtReceiver { PrrtPacketTracking *packetTracking; } PrrtReceiver; PrrtReceiver *PrrtReceiver_create(const char *host, uint16_t port, prrtByteCount_t mss); PrrtReceiver *PrrtReceiver_create(const char *host, uint16_t port, prrtByteCount_t maximum_payload_size); void PrrtReceiver_add_outstanding_packet_state(PrrtReceiver *recv, PrrtPacket *packet, prrtTimestamp_t sentTime); prrtByteCount_t PrrtReceiver_get_pipe(PrrtReceiver *recv); Loading Loading
prrt/proto/bbr.c +20 −17 Original line number Diff line number Diff line Loading @@ -4,11 +4,10 @@ #include "receiver.h" #include <math.h> prrtByteCount_t BBR_Inflight(BBR* bbr, double gain) { if (bbr->rtprop == Inf) return InitialCwnd; /* no valid RTT samples yet */ return bbr->initial_cwnd; /* no valid RTT samples yet */ uint32_t quanta = 0; uint32_t estimated_bdp = (uint32_t) round((((double)bbr->bw) * bbr->rtprop) / (1000 * 1000)); return (uint32_t)(gain * estimated_bdp + quanta); Loading Loading @@ -41,7 +40,7 @@ void BBR_CheckFullPipe(BBR* bbr, PrrtRateSample* rs) { if (bbr->filled_pipe || !bbr->round_start || rs->is_app_limited) return; // no need to check for a full pipe now if (bbr->bw >= bbr->full_bw * 1.25) { // BBR.BtlBw still growing? if (bbr->bw >= bbr->full_bw * PROBE_GAIN) { // BBR.BtlBw still growing? bbr->full_bw = bbr->bw; // record new baseline level bbr->full_bw_count = 0; return; Loading @@ -58,14 +57,16 @@ bool BBR_IsNextCyclePhase(BBR* bbr, prrtByteCount_t bytes_lost, prrtByteCount_t return is_full_length; if (bbr->pacing_gain > 1) return is_full_length && (bytes_lost > 0 || prior_inflight >= BBR_Inflight(bbr, bbr->pacing_gain)); return is_full_length || (prior_inflight <= BBR_Inflight(bbr, 1.0)); bool is_max_length = (PrrtClock_get_current_time_us() - bbr->cycle_stamp) > 4 * bbr->rtprop; return is_max_length || (prior_inflight <= BBR_Inflight(bbr, 1.0)); } void BBR_AdvanceCyclePhase(BBR* bbr) { bbr->cycle_stamp = PrrtClock_get_current_time_us(); bbr->cycle_index = (uint8_t )((bbr->cycle_index + 1) % BBRGainCycleLen); float pacing_gain_cycle[BBRGainCycleLen] = {1.25, 0.75, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}; float pacing_gain_cycle[BBRGainCycleLen] = {PROBE_GAIN, DRAIN_GAIN, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}; bbr->pacing_gain = pacing_gain_cycle[bbr->cycle_index]; debug(DEBUG_BBR, "Advanced cycle with gain: %f", bbr->pacing_gain); } Loading Loading @@ -135,7 +136,7 @@ void BBR_HandleProbeRTT(BBR *bbr, PrrtPacketTracking *tracking) { tracking->app_limited = (tracking->delivered + tracking->pipe) ? : 1; /* Ignore low rate samples during ProbeRTT: */ prrtTimestamp_t now = PrrtClock_get_current_time_us(); if (bbr->probe_rtt_done_stamp == 0 && tracking->pipe <= BBRMinPipeCwnd) { if (bbr->probe_rtt_done_stamp == 0 && tracking->pipe <= bbr->min_pipe_cwnd) { bbr->probe_rtt_done_stamp = now + ProbeRTTDuration; bbr->probe_rtt_round_done = false; bbr->next_round_delivered = tracking->delivered; Loading Loading @@ -183,13 +184,13 @@ void BBR_UpdateTargetCwnd(BBR* bbr) void BBR_ModulateCwndForProbeRTT(BBR* bbr) { if (bbr->state == PROBE_RTT) bbr->cwnd = MIN(bbr->cwnd, BBRMinPipeCwnd); bbr->cwnd = MIN(bbr->cwnd, bbr->min_pipe_cwnd); } void BBR_ModulateCwndForRecovery(BBR* bbr, prrtByteCount_t bytes_lost, prrtByteCount_t pipe, prrtByteCount_t delivered) { if (bytes_lost > 0) bbr->cwnd = MAX(bbr->cwnd - bytes_lost, SMSS); bbr->cwnd = MAX(bbr->cwnd - bytes_lost, bbr->mps); if (bbr->packet_conservation) bbr->cwnd = MAX(bbr->cwnd, pipe + delivered); } Loading @@ -202,9 +203,9 @@ void BBR_SetCwnd(BBR* bbr, PrrtPacketTracking* packetTracking) if (!bbr->packet_conservation) { if (bbr->filled_pipe) bbr->cwnd = MIN(bbr->cwnd + packetTracking->delivered, bbr->target_cwnd); else if (bbr->cwnd < bbr->target_cwnd || packetTracking->delivered < InitialCwnd) else if (bbr->cwnd < bbr->target_cwnd || packetTracking->delivered < bbr->initial_cwnd) bbr->cwnd = bbr->cwnd + packetTracking->delivered; bbr->cwnd = MAX(bbr->cwnd, BBRMinPipeCwnd); bbr->cwnd = MAX(bbr->cwnd, bbr->min_pipe_cwnd); } BBR_ModulateCwndForProbeRTT(bbr); debug(DEBUG_BBR, "New cwnd: %u, State: %u", bbr->cwnd, bbr->state); Loading @@ -226,9 +227,9 @@ void BBR_SetPacingRate(BBR* bbr) void BBR_SetSendQuantum(BBR* bbr) { if(bbr->pacing_rate < 150000) { // 1.2Mbps = 0.15 MBps = 150000 Bps bbr->send_quantum = 1 * SMSS; bbr->send_quantum = 1 * bbr->mps; } else if (bbr->pacing_rate < 3000000) { // 24 Mbps = 20 * 1.2Mbps = 3000000 bbr->send_quantum = 2 * SMSS; bbr->send_quantum = 2 * bbr->mps; } else { bbr->send_quantum = MIN((prrtByteCount_t) round((double) bbr->pacing_rate / 1000), 64000); } Loading Loading @@ -270,7 +271,7 @@ void BBR_OnRTOLoss(BBR *bbr) { if(!bbr->is_loss_recovery) { bbr->is_loss_recovery = true; bbr->prior_cwnd = BBR_SaveCwnd(bbr); bbr->cwnd = SMSS; bbr->cwnd = bbr->mps; } check(pthread_mutex_unlock(&bbr->lock) == 0, "Unlock failed."); return; Loading @@ -291,7 +292,7 @@ void BBR_OnLossExit(BBR *bbr) { PERROR("BBR_OnACK failed.") } BBR* BBR_Init(void) BBR* BBR_Init(prrtByteCount_t maximum_payload_size) { BBR* bbr = calloc(1, sizeof(BBR)); check_mem(bbr); Loading @@ -301,7 +302,9 @@ BBR* BBR_Init(void) check(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) == EXIT_SUCCESS, "Setting type failed."); check(pthread_mutex_init(&bbr->lock, &attr) == 0, "lock init failed."); bbr->mps = maximum_payload_size; bbr->min_pipe_cwnd = 4 * maximum_payload_size; bbr->initial_cwnd = 4 * maximum_payload_size; bbr->has_seen_rtt = false; bbr->btlBwFilter = WindowedFilter_Init(true); bbr->rtprop = Inf; Loading @@ -310,7 +313,7 @@ BBR* BBR_Init(void) bbr->probe_rtt_round_done = false; bbr->packet_conservation = false; bbr->prior_cwnd = 0; bbr->cwnd = InitialCwnd; bbr->cwnd = bbr->initial_cwnd; bbr->idle_restart = false; bbr->is_loss_recovery = false; Loading @@ -325,7 +328,7 @@ BBR* BBR_Init(void) bbr->full_bw_count = 0; //Init pacing rate double nominal_bandwidth = InitialCwnd / (bbr->has_seen_rtt ? bbr->rtprop : 1000); double nominal_bandwidth = bbr->initial_cwnd / (bbr->has_seen_rtt ? bbr->rtprop : 1000); bbr->pacing_rate = bbr->pacing_gain * nominal_bandwidth; BBR_EnterStartup(bbr); Loading
prrt/proto/bbr.h +6 −4 Original line number Diff line number Diff line Loading @@ -10,12 +10,11 @@ #include "types/rateSample.h" #include "../util/windowedFilter.h" #define SMSS 1500 #define PROBE_GAIN 1.25 #define DRAIN_GAIN 0.75 #define RTpropFilterLen 10000000 //10s #define BBRHighGain ((((float)2885) / 1000) + 1) #define InitialCwnd (10 * SMSS) #define BBRGainCycleLen 8 #define BBRMinPipeCwnd (4 * SMSS) #define ProbeRTTDuration 200000 //200ms #define Inf UINT32_MAX Loading @@ -29,6 +28,9 @@ enum bbr_state { typedef struct bbr { pthread_mutex_t lock; prrtByteCount_t mps; prrtByteCount_t min_pipe_cwnd; prrtByteCount_t initial_cwnd; prrtTimedelta_t rtprop; prrtTimestamp_t rtprop_stamp; prrtTimestamp_t probe_rtt_done_stamp; Loading Loading @@ -73,7 +75,7 @@ typedef struct bbr { WindowedFilter* btlBwFilter; } BBR; BBR* BBR_Init(void); BBR* BBR_Init(prrtByteCount_t maximum_payload_size); void BBR_OnACK(BBR* bbr, PrrtChannelStateInformation* csi, PrrtRateSample* rs, PrrtPacketTracking* packetTracking, prrtTimedelta_t rtt); void BBR_OnSpuriousLoss(BBR *bbr, PrrtPacketTracking *tracking); void BBR_OnRTOLoss(BBR *bbr); Loading
prrt/proto/receiver.c +2 −2 Original line number Diff line number Diff line Loading @@ -98,7 +98,7 @@ bool update_and_generate_rate_sample(PrrtReceiver *recv, prrtSequenceNumber_t se return result; } PrrtReceiver *PrrtReceiver_create(const char *host, uint16_t port, prrtByteCount_t mss) { PrrtReceiver *PrrtReceiver_create(const char *host, uint16_t port, prrtByteCount_t maximum_payload_size) { PrrtReceiver *recv = calloc(1, sizeof(PrrtReceiver)); check_mem(recv); recv->host_name = strdup(host); Loading Loading @@ -130,7 +130,7 @@ PrrtReceiver *PrrtReceiver_create(const char *host, uint16_t port, prrtByteCount check(0 == getaddrinfo(host, portstr, &hints, &info), "getaddrinfo"); recv->ai = info; recv->bbr = BBR_Init(); recv->bbr = BBR_Init(maximum_payload_size); pthread_mutexattr_t attr; check(pthread_mutexattr_init(&attr) == EXIT_SUCCESS, "Mutex attr init failed."); Loading
prrt/proto/receiver.h +1 −1 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ typedef struct prrtReceiver { PrrtPacketTracking *packetTracking; } PrrtReceiver; PrrtReceiver *PrrtReceiver_create(const char *host, uint16_t port, prrtByteCount_t mss); PrrtReceiver *PrrtReceiver_create(const char *host, uint16_t port, prrtByteCount_t maximum_payload_size); void PrrtReceiver_add_outstanding_packet_state(PrrtReceiver *recv, PrrtPacket *packet, prrtTimestamp_t sentTime); prrtByteCount_t PrrtReceiver_get_pipe(PrrtReceiver *recv); Loading