introduce a buffer pool for large buffers (20k)

This commit is contained in:
Marten Seemann 2023-04-19 09:58:54 +02:00
parent bef0f3d31a
commit 7d8db149b6
5 changed files with 35 additions and 15 deletions

View file

@ -56,13 +56,18 @@ func (b *packetBuffer) Len() protocol.ByteCount {
}
func (b *packetBuffer) putBack() {
if cap(b.Data) != int(protocol.MaxPacketBufferSize) {
panic("putPacketBuffer called with packet of wrong size!")
if cap(b.Data) == protocol.MaxPacketBufferSize {
bufferPool.Put(b)
return
}
bufferPool.Put(b)
if cap(b.Data) == protocol.MaxLargePacketBufferSize {
largeBufferPool.Put(b)
return
}
panic("putPacketBuffer called with packet of wrong size!")
}
var bufferPool sync.Pool
var bufferPool, largeBufferPool sync.Pool
func getPacketBuffer() *packetBuffer {
buf := bufferPool.Get().(*packetBuffer)
@ -71,10 +76,18 @@ func getPacketBuffer() *packetBuffer {
return buf
}
func getLargePacketBuffer() *packetBuffer {
buf := largeBufferPool.Get().(*packetBuffer)
buf.refCount = 1
buf.Data = buf.Data[:0]
return buf
}
func init() {
bufferPool.New = func() interface{} {
return &packetBuffer{
Data: make([]byte, 0, protocol.MaxPacketBufferSize),
}
bufferPool.New = func() any {
return &packetBuffer{Data: make([]byte, 0, protocol.MaxPacketBufferSize)}
}
largeBufferPool.New = func() any {
return &packetBuffer{Data: make([]byte, 0, protocol.MaxLargePacketBufferSize)}
}
}

View file

@ -9,13 +9,17 @@ import (
var _ = Describe("Buffer Pool", func() {
It("returns buffers of cap", func() {
buf := getPacketBuffer()
Expect(buf.Data).To(HaveCap(int(protocol.MaxPacketBufferSize)))
buf1 := getPacketBuffer()
Expect(buf1.Data).To(HaveCap(protocol.MaxPacketBufferSize))
buf2 := getLargePacketBuffer()
Expect(buf2.Data).To(HaveCap(protocol.MaxLargePacketBufferSize))
})
It("releases buffers", func() {
buf := getPacketBuffer()
buf.Release()
buf1 := getPacketBuffer()
buf1.Release()
buf2 := getLargePacketBuffer()
buf2.Release()
})
It("gets the length", func() {

View file

@ -59,7 +59,10 @@ type StatelessResetToken [16]byte
// ethernet's max size, minus the IP and UDP headers. IPv6 has a 40 byte header,
// UDP adds an additional 8 bytes. This is a total overhead of 48 bytes.
// Ethernet's max packet size is 1500 bytes, 1500 - 48 = 1452.
const MaxPacketBufferSize ByteCount = 1452
const MaxPacketBufferSize = 1452
// MaxLargePacketBufferSize is used when using GSO
const MaxLargePacketBufferSize = 20 * 1024
// MinInitialPacketSize is the minimum size an Initial packet is required to have.
const MinInitialPacketSize = 1200

View file

@ -216,7 +216,7 @@ var _ = Describe("OOB Conn Test", func() {
Expect(ms).To(HaveLen(batchSize))
for i := 0; i < numMsgRead; i++ {
Expect(ms[i].Buffers).To(HaveLen(1))
Expect(ms[i].Buffers[0]).To(HaveLen(int(protocol.MaxPacketBufferSize)))
Expect(ms[i].Buffers[0]).To(HaveLen(protocol.MaxPacketBufferSize))
data := []byte(fmt.Sprintf("message %d", counter))
counter++
ms[i].Buffers[0] = data

View file

@ -18,7 +18,7 @@ var _ = Describe("Basic Conn Test", func() {
addr := &net.UDPAddr{IP: net.IPv4(1, 2, 3, 4), Port: 1234}
c.EXPECT().ReadFrom(gomock.Any()).DoAndReturn(func(b []byte) (int, net.Addr, error) {
data := []byte("foobar")
Expect(b).To(HaveLen(int(protocol.MaxPacketBufferSize)))
Expect(b).To(HaveLen(protocol.MaxPacketBufferSize))
return copy(b, data), addr, nil
})