shardvalue_go.go 705 B

123456789101112131415161718192021222324252627282930313233343536
  1. // Copyright (c) Tailscale Inc & contributors
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. //go:build !tailscale_go
  4. package syncs
  5. import (
  6. "runtime"
  7. "sync"
  8. "sync/atomic"
  9. )
  10. type shardValuePool struct {
  11. atomic.Int64
  12. sync.Pool
  13. }
  14. // NewShardValue constructs a new ShardValue[T] with a shard per CPU.
  15. func NewShardValue[T any]() *ShardValue[T] {
  16. sp := &ShardValue[T]{
  17. shards: make([]T, runtime.NumCPU()),
  18. }
  19. sp.pool.New = func() any {
  20. i := sp.pool.Add(1) - 1
  21. return &sp.shards[i%int64(len(sp.shards))]
  22. }
  23. return sp
  24. }
  25. // One yields a pointer to a single shard value with best-effort P-locality.
  26. func (sp *ShardValue[T]) One(yield func(*T)) {
  27. v := sp.pool.Get().(*T)
  28. yield(v)
  29. sp.pool.Put(v)
  30. }