aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/proc.go
diff options
context:
space:
mode:
authorCherry Mui <cherryyz@google.com>2023-03-31 19:16:12 +0000
committerCherry Mui <cherryyz@google.com>2023-03-31 19:26:35 +0000
commitbfe3c678ab70d9a033b219276636c3f4669c1dc9 (patch)
tree26b80494f04e11f926350aaf9d19eff0bc0d6fae /src/runtime/proc.go
parent99276aeb5e8b40ff9cd3cafd47ce11c58ba0130c (diff)
downloadgo-bfe3c678ab70d9a033b219276636c3f4669c1dc9.tar.xz
Revert "runtime/cgo: store M for C-created thread in pthread key"
This reverts CL 392854. Reason for revert: caused #59294, which was derived from google internal tests. The attempted fix of #59294 caused more breakage. Change-Id: I5a061561ac2740856b7ecc09725ac28bd30f8bba Reviewed-on: https://go-review.googlesource.com/c/go/+/481060 Reviewed-by: Heschi Kreinick <heschi@google.com> Run-TryBot: Cherry Mui <cherryyz@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src/runtime/proc.go')
-rw-r--r--src/runtime/proc.go92
1 files changed, 12 insertions, 80 deletions
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index fd7760a571..0c6595f92f 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -210,10 +210,6 @@ func main() {
main_init_done = make(chan bool)
if iscgo {
- if _cgo_pthread_key_created == nil {
- throw("_cgo_pthread_key_created missing")
- }
-
if _cgo_thread_start == nil {
throw("_cgo_thread_start missing")
}
@@ -228,13 +224,6 @@ func main() {
if _cgo_notify_runtime_init_done == nil {
throw("_cgo_notify_runtime_init_done missing")
}
-
- // Set the x_crosscall2_ptr C function pointer variable point to crosscall2.
- if set_crosscall2 == nil {
- throw("set_crosscall2 missing")
- }
- set_crosscall2()
-
// Start the template thread in case we enter Go from
// a C-created thread and need to create a new thread.
startTemplateThread()
@@ -1885,9 +1874,8 @@ func allocm(pp *p, fn func(), id int64) *m {
// pressed into service as the scheduling stack and current
// goroutine for the duration of the cgo callback.
//
-// It calls dropm to put the m back on the list,
-// 1. when the callback is done with the m in non-pthread platforms,
-// 2. or when the C thread exiting on pthread platforms.
+// When the callback is done with the m, it calls dropm to
+// put the m back on the list.
//
//go:nosplit
func needm() {
@@ -1949,11 +1937,6 @@ func needm() {
gp.stack.lo = getcallersp() - 32*1024
gp.stackguard0 = gp.stack.lo + _StackGuard
- // Should mark we are already in Go now.
- // Otherwise, we may call needm again when we get a signal, before cgocallbackg1,
- // which means the extram list may be empty, that will cause a deadlock.
- mp.isExtraInC = false
-
// Initialize this thread to use the m.
asminit()
minit()
@@ -1963,17 +1946,6 @@ func needm() {
sched.ngsys.Add(-1)
}
-// Acquire an extra m and bind it to the C thread when a pthread key has been created.
-//
-//go:nosplit
-func needAndBindM() {
- needm()
-
- if _cgo_pthread_key_created != nil && *(*uintptr)(_cgo_pthread_key_created) != 0 {
- cgoBindM()
- }
-}
-
// newextram allocates m's and puts them on the extra list.
// It is called with a working local m, so that it can do things
// like call schedlock and allocate.
@@ -2018,8 +1990,6 @@ func oneNewExtraM() {
gp.m = mp
mp.curg = gp
mp.isextra = true
- // mark we are in C by default.
- mp.isExtraInC = true
mp.lockedInt++
mp.lockedg.set(gp)
gp.lockedm.set(mp)
@@ -2052,11 +2022,9 @@ func oneNewExtraM() {
unlockextra(mp)
}
-// dropm puts the current m back onto the extra list.
-//
-// 1. On systems without pthreads, like Windows
// dropm is called when a cgo callback has called needm but is now
// done with the callback and returning back into the non-Go thread.
+// It puts the current m back onto the extra list.
//
// The main expense here is the call to signalstack to release the
// m's signal stack, and then the call to needm on the next callback
@@ -2068,18 +2036,15 @@ func oneNewExtraM() {
// call. These should typically not be scheduling operations, just a few
// atomics, so the cost should be small.
//
-// 2. On systems with pthreads
-// dropm is called while a non-Go thread is exiting.
-// We allocate a pthread per-thread variable using pthread_key_create,
-// to register a thread-exit-time destructor.
-// And store the g into a thread-specific value associated with the pthread key,
-// when first return back to C.
-// So that the destructor would invoke dropm while the non-Go thread is exiting.
-// This is much faster since it avoids expensive signal-related syscalls.
-//
-// NOTE: this always runs without a P, so, nowritebarrierrec required.
-//
-//go:nowritebarrierrec
+// TODO(rsc): An alternative would be to allocate a dummy pthread per-thread
+// variable using pthread_key_create. Unlike the pthread keys we already use
+// on OS X, this dummy key would never be read by Go code. It would exist
+// only so that we could register at thread-exit-time destructor.
+// That destructor would put the m back onto the extra list.
+// This is purely a performance optimization. The current version,
+// in which dropm happens on each cgo call, is still correct too.
+// We may have to keep the current version on systems with cgo
+// but without pthreads, like Windows.
func dropm() {
// Clear m and g, and return m to the extra list.
// After the call to setg we can only call nosplit functions
@@ -2111,39 +2076,6 @@ func dropm() {
msigrestore(sigmask)
}
-// bindm store the g0 of the current m into a thread-specific value.
-//
-// We allocate a pthread per-thread variable using pthread_key_create,
-// to register a thread-exit-time destructor.
-// We are here setting the thread-specific value of the pthread key, to enable the destructor.
-// So that the pthread_key_destructor would dropm while the C thread is exiting.
-//
-// And the saved g will be used in pthread_key_destructor,
-// since the g stored in the TLS by Go might be cleared in some platforms,
-// before the destructor invoked, so, we restore g by the stored g, before dropm.
-//
-// We store g0 instead of m, to make the assembly code simpler,
-// since we need to restore g0 in runtime.cgocallback.
-//
-// On systems without pthreads, like Windows, bindm shouldn't be used.
-//
-// NOTE: this always runs without a P, so, nowritebarrierrec required.
-//
-//go:nosplit
-//go:nowritebarrierrec
-func cgoBindM() {
- if GOOS == "windows" || GOOS == "plan9" {
- fatal("bindm in unexpected GOOS")
- }
- g := getg()
- if g.m.g0 != g {
- fatal("the current g is not g0")
- }
- if _cgo_bindm != nil {
- asmcgocall(_cgo_bindm, unsafe.Pointer(g))
- }
-}
-
// A helper function for EnsureDropM.
func getm() uintptr {
return uintptr(unsafe.Pointer(getg().m))