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

all: public procPin and procUnpin to internal/runtime/proc #66941

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/go/build/deps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ var depsRules = `
unicode/utf8, unicode/utf16, unicode,
unsafe;

unsafe < internal/runtime/proc;

# These packages depend only on internal/goarch and unsafe.
internal/goarch, unsafe
< internal/abi, internal/chacha8rand;
Expand All @@ -64,7 +66,8 @@ var depsRules = `
internal/goarch,
internal/godebugs,
internal/goexperiment,
internal/goos
internal/goos,
internal/runtime/proc
< internal/bytealg
< internal/itoa
< internal/unsafeheader
Expand Down
15 changes: 15 additions & 0 deletions src/internal/runtime/proc/proc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package proc

import _ "unsafe"

//go:linkname Pin runtime.procPin
//go:nosplit
func Pin() int

//go:linkname Unpin runtime.procUnpin
//go:nosplit
func Unpin()
36 changes: 0 additions & 36 deletions src/runtime/proc.go
Original file line number Diff line number Diff line change
Expand Up @@ -6921,42 +6921,6 @@ func procUnpin() {
gp.m.locks--
}

//go:linkname sync_runtime_procPin sync.runtime_procPin
//go:nosplit
func sync_runtime_procPin() int {
return procPin()
}

//go:linkname sync_runtime_procUnpin sync.runtime_procUnpin
//go:nosplit
func sync_runtime_procUnpin() {
procUnpin()
}

//go:linkname sync_atomic_runtime_procPin sync/atomic.runtime_procPin
//go:nosplit
func sync_atomic_runtime_procPin() int {
return procPin()
}

//go:linkname sync_atomic_runtime_procUnpin sync/atomic.runtime_procUnpin
//go:nosplit
func sync_atomic_runtime_procUnpin() {
procUnpin()
}

//go:linkname internal_weak_runtime_procPin internal/weak.runtime_procPin
//go:nosplit
func internal_weak_runtime_procPin() int {
return procPin()
}

//go:linkname internal_weak_runtime_procUnpin internal/weak.runtime_procUnpin
//go:nosplit
func internal_weak_runtime_procUnpin() {
procUnpin()
}

// Active spinning for sync.Mutex.
//
//go:linkname sync_runtime_canSpin sync.runtime_canSpin
Expand Down
23 changes: 10 additions & 13 deletions src/sync/atomic/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package atomic

import (
"internal/runtime/proc"
"unsafe"
)

Expand Down Expand Up @@ -56,15 +57,15 @@ func (v *Value) Store(val any) {
// Attempt to start first store.
// Disable preemption so that other goroutines can use
// active spin wait to wait for completion.
runtime_procPin()
proc.Pin()
if !CompareAndSwapPointer(&vp.typ, nil, unsafe.Pointer(&firstStoreInProgress)) {
runtime_procUnpin()
proc.Unpin()
continue
}
// Complete first store.
StorePointer(&vp.data, vlp.data)
StorePointer(&vp.typ, vlp.typ)
runtime_procUnpin()
proc.Unpin()
return
}
if typ == unsafe.Pointer(&firstStoreInProgress) {
Expand Down Expand Up @@ -100,15 +101,15 @@ func (v *Value) Swap(new any) (old any) {
// Disable preemption so that other goroutines can use
// active spin wait to wait for completion; and so that
// GC does not see the fake type accidentally.
runtime_procPin()
proc.Pin()
if !CompareAndSwapPointer(&vp.typ, nil, unsafe.Pointer(&firstStoreInProgress)) {
runtime_procUnpin()
proc.Unpin()
continue
}
// Complete first store.
StorePointer(&vp.data, np.data)
StorePointer(&vp.typ, np.typ)
runtime_procUnpin()
proc.Unpin()
return nil
}
if typ == unsafe.Pointer(&firstStoreInProgress) {
Expand Down Expand Up @@ -152,15 +153,15 @@ func (v *Value) CompareAndSwap(old, new any) (swapped bool) {
// Disable preemption so that other goroutines can use
// active spin wait to wait for completion; and so that
// GC does not see the fake type accidentally.
runtime_procPin()
proc.Pin()
if !CompareAndSwapPointer(&vp.typ, nil, unsafe.Pointer(&firstStoreInProgress)) {
runtime_procUnpin()
proc.Unpin()
continue
}
// Complete first store.
StorePointer(&vp.data, np.data)
StorePointer(&vp.typ, np.typ)
runtime_procUnpin()
proc.Unpin()
return true
}
if typ == unsafe.Pointer(&firstStoreInProgress) {
Expand Down Expand Up @@ -188,7 +189,3 @@ func (v *Value) CompareAndSwap(old, new any) (swapped bool) {
return CompareAndSwapPointer(&vp.data, data, np.data)
}
}

// Disable/enable preemption, implemented in runtime.
func runtime_procPin() int
func runtime_procUnpin()
6 changes: 4 additions & 2 deletions src/sync/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@

package sync

import "internal/runtime/proc"

// Export for testing.
var Runtime_Semacquire = runtime_Semacquire
var Runtime_Semrelease = runtime_Semrelease
var Runtime_procPin = runtime_procPin
var Runtime_procUnpin = runtime_procUnpin
var Runtime_procPin = proc.Pin
var Runtime_procUnpin = proc.Unpin

// poolDequeue testing.
type PoolDequeue interface {
Expand Down
13 changes: 6 additions & 7 deletions src/sync/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package sync

import (
"internal/race"
"internal/runtime/proc"
"runtime"
"sync/atomic"
"unsafe"
Expand Down Expand Up @@ -112,7 +113,7 @@ func (p *Pool) Put(x any) {
} else {
l.shared.pushHead(x)
}
runtime_procUnpin()
proc.Unpin()
if race.Enabled {
race.Enable()
}
Expand Down Expand Up @@ -142,7 +143,7 @@ func (p *Pool) Get() any {
x = p.getSlow(pid)
}
}
runtime_procUnpin()
proc.Unpin()
if race.Enabled {
race.Enable()
if x != nil {
Expand Down Expand Up @@ -205,7 +206,7 @@ func (p *Pool) pin() (*poolLocal, int) {
panic("nil Pool")
}

pid := runtime_procPin()
pid := proc.Pin()
// In pinSlow we store to local and then to localSize, here we load in opposite order.
// Since we've disabled preemption, GC cannot happen in between.
// Thus here we must observe local at least as large localSize.
Expand All @@ -221,10 +222,10 @@ func (p *Pool) pin() (*poolLocal, int) {
func (p *Pool) pinSlow() (*poolLocal, int) {
// Retry under the mutex.
// Can not lock the mutex while pinned.
runtime_procUnpin()
proc.Unpin()
allPoolsMu.Lock()
defer allPoolsMu.Unlock()
pid := runtime_procPin()
pid := proc.Pin()
// poolCleanup won't be called while we are pinned.
s := p.localSize
l := p.local
Expand Down Expand Up @@ -292,8 +293,6 @@ func indexLocal(l unsafe.Pointer, i int) *poolLocal {

// Implemented in runtime.
func runtime_registerPoolCleanup(cleanup func())
func runtime_procPin() int
func runtime_procUnpin()

// The below are implemented in internal/runtime/atomic and the
// compiler also knows to intrinsify the symbol we linkname into this
Expand Down