Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: runtime/local: new package to provide transparent access to Per-P Local Storage #68952

Open
lemon-mint opened this issue Aug 19, 2024 · 2 comments
Labels
Milestone

Comments

@lemon-mint
Copy link

Proposal Details

This proposal introduces a new package, runtime/local, providing an API for per-P local storage in Go. This enables efficient and race-free access to shared yet locally scoped data, like random number generator states or per-P Logger, without the overhead of locks or cas loop.

Several packages within the standard library, including runtime.fastrand and sync.Pool, already utilize per-P or per-M storage internally for performance optimization. This proposal aims to expose a similar mechanism through a public API, enables developers to leverage this approach for their own concurrency needs.

This proposal introduces the runtime/local package with the following API:

package local

// Key represents a unique identifier for accessing local storage.
type Key uint32

// AllocateKey reserves a new Key for local storage access.
func AllocateKey() Key

// ReleaseKey releases a previously allocated Key.
func ReleaseKey(k Key)

// Storage provides access to the per-P local storage.
type Storage struct {
	// pid represents the logical processor ID associated with this Storage.
	pid int

	// values holds the actual stored data, indexed by Key.
	values []any
}

// ID returns the logical processor ID associated with this Storage.
func (s *Storage) ID() int

// Load retrieves the value associated with the given Key.
// The second return value indicates whether a value was found.
func (s *Storage) Load(k Key) (any, bool)

// Store associates the given value with the specified Key.
// It returns true if the operation was successful, false otherwise.
func (s *Storage) Store(k Key, v any) bool

// OpenFunc executes the provided function f with the Storage
// instance associated with the calling goroutine's current P.
// It returns the logical processor ID associated with the Storage.
func OpenFunc(f func(*Storage)) (id int)

The proposed package name candidates are following:

  • runtime/local
  • runtime/threadlocal
  • runtime/plocal
  • runtime/tls

Open Issues:

  • Released Key Reuse and Storage Reclamation: The proposal should consider how to handle storage associated with released keys.
  • Finalizers to flush locally collected data to global storage.
@gopherbot gopherbot added this to the Proposal milestone Aug 19, 2024
@ianlancetaylor ianlancetaylor moved this to Incoming in Proposals Aug 19, 2024
@ianlancetaylor
Copy link
Member

CC @golang/runtime

@thediveo
Copy link
Contributor

I'm confused: what use case does this proposal address? Is handling thread-local storage on a locked Go routine in order to interface with non-Go code using thread-local storage? Or does it try to tackle Go routine local storage, then it appears to be wrongly using PIDs (it's probably using PIDs wrongly anyway)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Incoming
Development

No branches or pull requests

4 participants