Files
wireguard-go/device/pools.go
T

122 lines
3.1 KiB
Go
Raw Normal View History

2019-01-02 01:55:51 +01:00
/* SPDX-License-Identifier: MIT
2018-09-22 06:29:02 +02:00
*
2025-05-04 17:48:53 +02:00
* Copyright (C) 2017-2025 WireGuard LLC. All Rights Reserved.
2018-09-22 06:29:02 +02:00
*/
2019-03-03 04:04:41 +01:00
package device
2018-09-22 06:29:02 +02:00
import (
"sync"
)
type WaitPool struct {
pool sync.Pool
cond sync.Cond
lock sync.Mutex
2024-06-27 08:43:41 -07:00
count uint32 // Get calls not yet Put back
max uint32
}
2022-03-16 16:40:24 -07:00
func NewWaitPool(max uint32, new func() any) *WaitPool {
p := &WaitPool{pool: sync.Pool{New: new}, max: max}
p.cond = sync.Cond{L: &p.lock}
return p
}
2022-03-16 16:40:24 -07:00
func (p *WaitPool) Get() any {
if p.max != 0 {
p.lock.Lock()
2024-06-27 08:43:41 -07:00
for p.count >= p.max {
p.cond.Wait()
}
2024-06-27 08:43:41 -07:00
p.count++
p.lock.Unlock()
}
return p.pool.Get()
}
2022-03-16 16:40:24 -07:00
func (p *WaitPool) Put(x any) {
p.pool.Put(x)
if p.max == 0 {
return
}
2024-06-27 08:43:41 -07:00
p.lock.Lock()
defer p.lock.Unlock()
p.count--
p.cond.Signal()
}
2018-09-22 06:29:02 +02:00
func (device *Device) PopulatePools() {
device.pool.inboundElementsContainer = NewWaitPool(PreallocatedBuffersPerPool, func() any {
s := make([]*QueueInboundElement, 0, device.BatchSize())
return &QueueInboundElementsContainer{elems: s}
})
device.pool.outboundElementsContainer = NewWaitPool(PreallocatedBuffersPerPool, func() any {
s := make([]*QueueOutboundElement, 0, device.BatchSize())
return &QueueOutboundElementsContainer{elems: s}
})
2022-03-16 16:40:24 -07:00
device.pool.messageBuffers = NewWaitPool(PreallocatedBuffersPerPool, func() any {
return new([MaxMessageSize]byte)
})
2022-03-16 16:40:24 -07:00
device.pool.inboundElements = NewWaitPool(PreallocatedBuffersPerPool, func() any {
return new(QueueInboundElement)
})
2022-03-16 16:40:24 -07:00
device.pool.outboundElements = NewWaitPool(PreallocatedBuffersPerPool, func() any {
return new(QueueOutboundElement)
})
2018-09-22 06:29:02 +02:00
}
func (device *Device) GetInboundElementsContainer() *QueueInboundElementsContainer {
c := device.pool.inboundElementsContainer.Get().(*QueueInboundElementsContainer)
c.Mutex = sync.Mutex{}
return c
}
func (device *Device) PutInboundElementsContainer(c *QueueInboundElementsContainer) {
for i := range c.elems {
c.elems[i] = nil
}
c.elems = c.elems[:0]
device.pool.inboundElementsContainer.Put(c)
}
func (device *Device) GetOutboundElementsContainer() *QueueOutboundElementsContainer {
c := device.pool.outboundElementsContainer.Get().(*QueueOutboundElementsContainer)
c.Mutex = sync.Mutex{}
return c
}
func (device *Device) PutOutboundElementsContainer(c *QueueOutboundElementsContainer) {
for i := range c.elems {
c.elems[i] = nil
}
c.elems = c.elems[:0]
device.pool.outboundElementsContainer.Put(c)
}
2018-09-22 06:29:02 +02:00
func (device *Device) GetMessageBuffer() *[MaxMessageSize]byte {
return device.pool.messageBuffers.Get().(*[MaxMessageSize]byte)
2018-09-22 06:29:02 +02:00
}
func (device *Device) PutMessageBuffer(msg *[MaxMessageSize]byte) {
device.pool.messageBuffers.Put(msg)
2018-09-22 06:29:02 +02:00
}
func (device *Device) GetInboundElement() *QueueInboundElement {
return device.pool.inboundElements.Get().(*QueueInboundElement)
2018-09-22 06:29:02 +02:00
}
func (device *Device) PutInboundElement(elem *QueueInboundElement) {
elem.clearPointers()
device.pool.inboundElements.Put(elem)
2018-09-22 06:29:02 +02:00
}
func (device *Device) GetOutboundElement() *QueueOutboundElement {
return device.pool.outboundElements.Get().(*QueueOutboundElement)
2018-09-22 06:29:02 +02:00
}
func (device *Device) PutOutboundElement(elem *QueueOutboundElement) {
elem.clearPointers()
device.pool.outboundElements.Put(elem)
2018-09-22 06:29:02 +02:00
}