shardvalue.go 1.1 KB

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