Skip to content

Commit

Permalink
Merge pull request #1038 from apernet/wip-pacer
Browse files Browse the repository at this point in the history
feat: pacer code improvements
  • Loading branch information
tobyxdd authored Apr 15, 2024
2 parents 234dc45 + 2408301 commit 2fcbde0
Showing 1 changed file with 15 additions and 31 deletions.
46 changes: 15 additions & 31 deletions core/internal/congestion/common/pacer.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package common

import (
"math"
"time"

"github.com/apernet/quic-go/congestion"
)

const (
maxBurstPackets = 10
maxBurstPackets = 10
maxBurstPacingDelayMultiplier = 4
)

// Pacer implements a token bucket pacing algorithm.
Expand Down Expand Up @@ -46,12 +46,12 @@ func (p *Pacer) Budget(now time.Time) congestion.ByteCount {
if budget < 0 { // protect against overflows
budget = congestion.ByteCount(1<<62 - 1)
}
return minByteCount(p.maxBurstSize(), budget)
return min(p.maxBurstSize(), budget)
}

func (p *Pacer) maxBurstSize() congestion.ByteCount {
return maxByteCount(
congestion.ByteCount((congestion.MinPacingDelay+time.Millisecond).Nanoseconds())*p.getBandwidth()/1e9,
return max(
congestion.ByteCount((maxBurstPacingDelayMultiplier*congestion.MinPacingDelay).Nanoseconds())*p.getBandwidth()/1e9,
maxBurstPackets*p.maxDatagramSize,
)
}
Expand All @@ -62,34 +62,18 @@ func (p *Pacer) TimeUntilSend() time.Time {
if p.budgetAtLastSent >= p.maxDatagramSize {
return time.Time{}
}
return p.lastSentTime.Add(maxDuration(
congestion.MinPacingDelay,
time.Duration(math.Ceil(float64(p.maxDatagramSize-p.budgetAtLastSent)*1e9/
float64(p.getBandwidth())))*time.Nanosecond,
))
diff := 1e9 * uint64(p.maxDatagramSize-p.budgetAtLastSent)
bw := uint64(p.getBandwidth())
// We might need to round up this value.
// Otherwise, we might have a budget (slightly) smaller than the datagram size when the timer expires.
d := diff / bw
// this is effectively a math.Ceil, but using only integer math
if diff%bw > 0 {
d++
}
return p.lastSentTime.Add(max(congestion.MinPacingDelay, time.Duration(d)*time.Nanosecond))
}

func (p *Pacer) SetMaxDatagramSize(s congestion.ByteCount) {
p.maxDatagramSize = s
}

func maxByteCount(a, b congestion.ByteCount) congestion.ByteCount {
if a < b {
return b
}
return a
}

func minByteCount(a, b congestion.ByteCount) congestion.ByteCount {
if a < b {
return a
}
return b
}

func maxDuration(a, b time.Duration) time.Duration {
if a > b {
return a
}
return b
}

0 comments on commit 2fcbde0

Please sign in to comment.