Update dependencies

This commit is contained in:
bluepython508
2025-04-09 01:00:12 +01:00
parent f0641ffd6e
commit 5a9cfc022c
882 changed files with 68930 additions and 24201 deletions

69
vendor/tailscale.com/syncs/shardedint.go generated vendored Normal file
View File

@@ -0,0 +1,69 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
package syncs
import (
"encoding/json"
"strconv"
"sync/atomic"
"golang.org/x/sys/cpu"
)
// ShardedInt provides a sharded atomic int64 value that optimizes high
// frequency (Mhz range and above) writes in highly parallel workloads.
// The zero value is not safe for use; use [NewShardedInt].
// ShardedInt implements the expvar.Var interface.
type ShardedInt struct {
sv *ShardValue[intShard]
}
// NewShardedInt returns a new [ShardedInt].
func NewShardedInt() *ShardedInt {
return &ShardedInt{
sv: NewShardValue[intShard](),
}
}
// Add adds delta to the value.
func (m *ShardedInt) Add(delta int64) {
m.sv.One(func(v *intShard) {
v.Add(delta)
})
}
type intShard struct {
atomic.Int64
_ cpu.CacheLinePad // avoid false sharing of neighboring shards
}
// Value returns the current value.
func (m *ShardedInt) Value() int64 {
var v int64
for s := range m.sv.All {
v += s.Load()
}
return v
}
// GetDistribution returns the current value in each shard.
// This is intended for observability/debugging only.
func (m *ShardedInt) GetDistribution() []int64 {
v := make([]int64, 0, m.sv.Len())
for s := range m.sv.All {
v = append(v, s.Load())
}
return v
}
// String implements the expvar.Var interface
func (m *ShardedInt) String() string {
v, _ := json.Marshal(m.Value())
return string(v)
}
// AppendText implements the encoding.TextAppender interface
func (m *ShardedInt) AppendText(b []byte) ([]byte, error) {
return strconv.AppendInt(b, m.Value(), 10), nil
}

36
vendor/tailscale.com/syncs/shardvalue.go generated vendored Normal file
View File

@@ -0,0 +1,36 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
package syncs
// TODO(raggi): this implementation is still imperfect as it will still result
// in cross CPU sharing periodically, we instead really want a per-CPU shard
// key, but the limitations of calling platform code make reaching for even the
// getcpu vdso very painful. See https://github.com/golang/go/issues/18802, and
// hopefully one day we can replace with a primitive that falls out of that
// work.
// ShardValue contains a value sharded over a set of shards.
// In order to be useful, T should be aligned to cache lines.
// Users must organize that usage in One and All is concurrency safe.
// The zero value is not safe for use; use [NewShardValue].
type ShardValue[T any] struct {
shards []T
//lint:ignore U1000 unused under tailscale_go builds.
pool shardValuePool
}
// Len returns the number of shards.
func (sp *ShardValue[T]) Len() int {
return len(sp.shards)
}
// All yields a pointer to the value in each shard.
func (sp *ShardValue[T]) All(yield func(*T) bool) {
for i := range sp.shards {
if !yield(&sp.shards[i]) {
return
}
}
}

36
vendor/tailscale.com/syncs/shardvalue_go.go generated vendored Normal file
View File

@@ -0,0 +1,36 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
//go:build !tailscale_go
package syncs
import (
"runtime"
"sync"
"sync/atomic"
)
type shardValuePool struct {
atomic.Int64
sync.Pool
}
// NewShardValue constructs a new ShardValue[T] with a shard per CPU.
func NewShardValue[T any]() *ShardValue[T] {
sp := &ShardValue[T]{
shards: make([]T, runtime.NumCPU()),
}
sp.pool.New = func() any {
i := sp.pool.Add(1) - 1
return &sp.shards[i%int64(len(sp.shards))]
}
return sp
}
// One yields a pointer to a single shard value with best-effort P-locality.
func (sp *ShardValue[T]) One(yield func(*T)) {
v := sp.pool.Get().(*T)
yield(v)
sp.pool.Put(v)
}

24
vendor/tailscale.com/syncs/shardvalue_tailscale.go generated vendored Normal file
View File

@@ -0,0 +1,24 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// TODO(raggi): update build tag after toolchain update
//go:build tailscale_go
package syncs
import (
"runtime"
)
//lint:ignore U1000 unused under tailscale_go builds.
type shardValuePool struct{}
// NewShardValue constructs a new ShardValue[T] with a shard per CPU.
func NewShardValue[T any]() *ShardValue[T] {
return &ShardValue[T]{shards: make([]T, runtime.NumCPU())}
}
// One yields a pointer to a single shard value with best-effort P-locality.
func (sp *ShardValue[T]) One(f func(*T)) {
f(&sp.shards[runtime.TailscaleCurrentP()%len(sp.shards)])
}

62
vendor/tailscale.com/syncs/syncs.go generated vendored
View File

@@ -25,6 +25,7 @@ func initClosedChan() <-chan struct{} {
}
// AtomicValue is the generic version of [atomic.Value].
// See [MutexValue] for guidance on whether to use this type.
type AtomicValue[T any] struct {
v atomic.Value
}
@@ -74,6 +75,67 @@ func (v *AtomicValue[T]) CompareAndSwap(oldV, newV T) (swapped bool) {
return v.v.CompareAndSwap(wrappedValue[T]{oldV}, wrappedValue[T]{newV})
}
// MutexValue is a value protected by a mutex.
//
// AtomicValue, [MutexValue], [atomic.Pointer] are similar and
// overlap in their use cases.
//
// - Use [atomic.Pointer] if the value being stored is a pointer and
// you only ever need load and store operations.
// An atomic pointer only occupies 1 word of memory.
//
// - Use [MutexValue] if the value being stored is not a pointer or
// you need the ability for a mutex to protect a set of operations
// performed on the value.
// A mutex-guarded value occupies 1 word of memory plus
// the memory representation of T.
//
// - AtomicValue is useful for non-pointer types that happen to
// have the memory layout of a single pointer.
// Examples include a map, channel, func, or a single field struct
// that contains any prior types.
// An atomic value occupies 2 words of memory.
// Consequently, Storing of non-pointer types always allocates.
//
// Note that [AtomicValue] has the ability to report whether it was set
// while [MutexValue] lacks the ability to detect if the value was set
// and it happens to be the zero value of T. If such a use case is
// necessary, then you could consider wrapping T in [opt.Value].
type MutexValue[T any] struct {
mu sync.Mutex
v T
}
// WithLock calls f with a pointer to the value while holding the lock.
// The provided pointer must not leak beyond the scope of the call.
func (m *MutexValue[T]) WithLock(f func(p *T)) {
m.mu.Lock()
defer m.mu.Unlock()
f(&m.v)
}
// Load returns a shallow copy of the underlying value.
func (m *MutexValue[T]) Load() T {
m.mu.Lock()
defer m.mu.Unlock()
return m.v
}
// Store stores a shallow copy of the provided value.
func (m *MutexValue[T]) Store(v T) {
m.mu.Lock()
defer m.mu.Unlock()
m.v = v
}
// Swap stores new into m and returns the previous value.
func (m *MutexValue[T]) Swap(new T) (old T) {
m.mu.Lock()
defer m.mu.Unlock()
old, m.v = m.v, new
return old
}
// WaitGroupChan is like a sync.WaitGroup, but has a chan that closes
// on completion that you can wait on. (This, you can only use the
// value once)