mirror of
https://github.com/yggdrasil-network/yggdrasil-go.git
synced 2025-04-29 06:35:07 +03:00
commit
bd3b42022b
10 changed files with 353 additions and 203 deletions
|
@ -26,27 +26,25 @@ func UnlockThread() {
|
|||
}
|
||||
|
||||
// This is used to buffer recently used slices of bytes, to prevent allocations in the hot loops.
|
||||
var byteStoreMutex sync.Mutex
|
||||
var byteStore [][]byte
|
||||
var byteStore = sync.Pool{New: func() interface{} { return []byte(nil) }}
|
||||
|
||||
// Gets an empty slice from the byte store.
|
||||
func GetBytes() []byte {
|
||||
byteStoreMutex.Lock()
|
||||
defer byteStoreMutex.Unlock()
|
||||
if len(byteStore) > 0 {
|
||||
var bs []byte
|
||||
bs, byteStore = byteStore[len(byteStore)-1][:0], byteStore[:len(byteStore)-1]
|
||||
return bs
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return byteStore.Get().([]byte)[:0]
|
||||
}
|
||||
|
||||
// Puts a slice in the store.
|
||||
func PutBytes(bs []byte) {
|
||||
byteStoreMutex.Lock()
|
||||
defer byteStoreMutex.Unlock()
|
||||
byteStore = append(byteStore, bs)
|
||||
byteStore.Put(bs)
|
||||
}
|
||||
|
||||
// Gets a slice of the appropriate length, reusing existing slice capacity when possible
|
||||
func ResizeBytes(bs []byte, length int) []byte {
|
||||
if cap(bs) >= length {
|
||||
return bs[:length]
|
||||
} else {
|
||||
return make([]byte, length)
|
||||
}
|
||||
}
|
||||
|
||||
// This is a workaround to go's broken timer implementation
|
||||
|
|
29
src/util/workerpool.go
Normal file
29
src/util/workerpool.go
Normal file
|
@ -0,0 +1,29 @@
|
|||
package util
|
||||
|
||||
import "runtime"
|
||||
|
||||
var workerPool chan func()
|
||||
|
||||
func init() {
|
||||
maxProcs := runtime.GOMAXPROCS(0)
|
||||
if maxProcs < 1 {
|
||||
maxProcs = 1
|
||||
}
|
||||
workerPool = make(chan func(), maxProcs)
|
||||
for idx := 0; idx < maxProcs; idx++ {
|
||||
go func() {
|
||||
for f := range workerPool {
|
||||
f()
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
// WorkerGo submits a job to a pool of GOMAXPROCS worker goroutines.
|
||||
// This is meant for short non-blocking functions f() where you could just go f(),
|
||||
// but you want some kind of backpressure to prevent spawning endless goroutines.
|
||||
// WorkerGo returns as soon as the function is queued to run, not when it finishes.
|
||||
// In Yggdrasil, these workers are used for certain cryptographic operations.
|
||||
func WorkerGo(f func()) {
|
||||
workerPool <- f
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue