2019-01-02 01:55:51 +01:00
|
|
|
/* SPDX-License-Identifier: MIT
|
2018-09-22 06:29:02 +02:00
|
|
|
*
|
2022-09-20 17:21:32 +02:00
|
|
|
* Copyright (C) 2017-2022 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
|
|
|
|
2021-02-02 18:37:49 +01:00
|
|
|
import (
|
|
|
|
"sync"
|
|
|
|
"sync/atomic"
|
|
|
|
)
|
2018-09-22 06:29:02 +02:00
|
|
|
|
2021-02-02 18:37:49 +01:00
|
|
|
type WaitPool struct {
|
|
|
|
pool sync.Pool
|
|
|
|
cond sync.Cond
|
|
|
|
lock sync.Mutex
|
2022-08-30 16:43:11 +02:00
|
|
|
count atomic.Uint32
|
2021-02-02 18:37:49 +01:00
|
|
|
max uint32
|
|
|
|
}
|
|
|
|
|
2022-03-17 00:40:24 +01:00
|
|
|
func NewWaitPool(max uint32, new func() any) *WaitPool {
|
2021-02-02 18:37:49 +01:00
|
|
|
p := &WaitPool{pool: sync.Pool{New: new}, max: max}
|
|
|
|
p.cond = sync.Cond{L: &p.lock}
|
|
|
|
return p
|
|
|
|
}
|
|
|
|
|
2022-03-17 00:40:24 +01:00
|
|
|
func (p *WaitPool) Get() any {
|
2021-02-02 18:37:49 +01:00
|
|
|
if p.max != 0 {
|
|
|
|
p.lock.Lock()
|
2022-08-30 16:43:11 +02:00
|
|
|
for p.count.Load() >= p.max {
|
2021-02-02 18:37:49 +01:00
|
|
|
p.cond.Wait()
|
2018-09-22 06:29:02 +02:00
|
|
|
}
|
2022-08-30 16:43:11 +02:00
|
|
|
p.count.Add(1)
|
2021-02-02 18:37:49 +01:00
|
|
|
p.lock.Unlock()
|
2018-09-22 06:29:02 +02:00
|
|
|
}
|
2021-02-02 18:37:49 +01:00
|
|
|
return p.pool.Get()
|
2018-09-22 06:29:02 +02:00
|
|
|
}
|
|
|
|
|
2022-03-17 00:40:24 +01:00
|
|
|
func (p *WaitPool) Put(x any) {
|
2021-02-02 18:37:49 +01:00
|
|
|
p.pool.Put(x)
|
|
|
|
if p.max == 0 {
|
|
|
|
return
|
2018-09-22 06:29:02 +02:00
|
|
|
}
|
2022-08-30 16:43:11 +02:00
|
|
|
p.count.Add(^uint32(0))
|
2021-02-02 18:37:49 +01:00
|
|
|
p.cond.Signal()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (device *Device) PopulatePools() {
|
2022-03-17 00:40:24 +01:00
|
|
|
device.pool.messageBuffers = NewWaitPool(PreallocatedBuffersPerPool, func() any {
|
2021-02-02 18:37:49 +01:00
|
|
|
return new([MaxMessageSize]byte)
|
|
|
|
})
|
2022-03-17 00:40:24 +01:00
|
|
|
device.pool.inboundElements = NewWaitPool(PreallocatedBuffersPerPool, func() any {
|
2021-02-02 18:37:49 +01:00
|
|
|
return new(QueueInboundElement)
|
|
|
|
})
|
2022-03-17 00:40:24 +01:00
|
|
|
device.pool.outboundElements = NewWaitPool(PreallocatedBuffersPerPool, func() any {
|
2021-02-02 18:37:49 +01:00
|
|
|
return new(QueueOutboundElement)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
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) {
|
2021-02-02 18:37:49 +01:00
|
|
|
device.pool.messageBuffers.Put(msg)
|
2018-09-22 06:29:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (device *Device) GetInboundElement() *QueueInboundElement {
|
2021-02-02 18:37:49 +01:00
|
|
|
return device.pool.inboundElements.Get().(*QueueInboundElement)
|
2018-09-22 06:29:02 +02:00
|
|
|
}
|
|
|
|
|
2020-12-16 01:00:52 +01:00
|
|
|
func (device *Device) PutInboundElement(elem *QueueInboundElement) {
|
|
|
|
elem.clearPointers()
|
2021-02-02 18:37:49 +01:00
|
|
|
device.pool.inboundElements.Put(elem)
|
2018-09-22 06:29:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (device *Device) GetOutboundElement() *QueueOutboundElement {
|
2021-02-02 18:37:49 +01:00
|
|
|
return device.pool.outboundElements.Get().(*QueueOutboundElement)
|
2018-09-22 06:29:02 +02:00
|
|
|
}
|
|
|
|
|
2020-12-16 01:00:52 +01:00
|
|
|
func (device *Device) PutOutboundElement(elem *QueueOutboundElement) {
|
|
|
|
elem.clearPointers()
|
2021-02-02 18:37:49 +01:00
|
|
|
device.pool.outboundElements.Put(elem)
|
2018-09-22 06:29:02 +02:00
|
|
|
}
|