mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: use newm for profileloop
This replaces the externalthreadhandler-based implementation of profileloop with one that uses newm to start a new thread. This is a step toward eliminating externalthreadhandler. For #45530. Change-Id: Id8e5540423fe2d2004024b649afec6998f77b092 Reviewed-on: https://go-review.googlesource.com/c/go/+/309633 Trust: Austin Clements <austin@google.com> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Michael Pratt <mpratt@google.com> Reviewed-by: Michael Knyszek <mknyszek@google.com>
This commit is contained in:
parent
e512bc2cf0
commit
e69f02265c
5 changed files with 9 additions and 32 deletions
|
|
@ -1198,9 +1198,6 @@ func ctrlHandler(_type uint32) uintptr {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// in sys_windows_386.s and sys_windows_amd64.s
|
|
||||||
func profileloop()
|
|
||||||
|
|
||||||
// called from zcallback_windows_*.s to sys_windows_*.s
|
// called from zcallback_windows_*.s to sys_windows_*.s
|
||||||
func callbackasm1()
|
func callbackasm1()
|
||||||
|
|
||||||
|
|
@ -1233,13 +1230,18 @@ func gFromSP(mp *m, sp uintptr) *g {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func profileloop1(param uintptr) uint32 {
|
func profileLoop() {
|
||||||
stdcall2(_SetThreadPriority, currentThread, _THREAD_PRIORITY_HIGHEST)
|
stdcall2(_SetThreadPriority, currentThread, _THREAD_PRIORITY_HIGHEST)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
stdcall2(_WaitForSingleObject, profiletimer, _INFINITE)
|
stdcall2(_WaitForSingleObject, profiletimer, _INFINITE)
|
||||||
first := (*m)(atomic.Loadp(unsafe.Pointer(&allm)))
|
first := (*m)(atomic.Loadp(unsafe.Pointer(&allm)))
|
||||||
for mp := first; mp != nil; mp = mp.alllink {
|
for mp := first; mp != nil; mp = mp.alllink {
|
||||||
|
if mp == getg().m {
|
||||||
|
// Don't profile ourselves.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
lock(&mp.threadLock)
|
lock(&mp.threadLock)
|
||||||
// Do not profile threads blocked on Notes,
|
// Do not profile threads blocked on Notes,
|
||||||
// this includes idle worker threads,
|
// this includes idle worker threads,
|
||||||
|
|
@ -1251,8 +1253,8 @@ func profileloop1(param uintptr) uint32 {
|
||||||
// Acquire our own handle to the thread.
|
// Acquire our own handle to the thread.
|
||||||
var thread uintptr
|
var thread uintptr
|
||||||
if stdcall7(_DuplicateHandle, currentProcess, mp.thread, currentProcess, uintptr(unsafe.Pointer(&thread)), 0, 0, _DUPLICATE_SAME_ACCESS) == 0 {
|
if stdcall7(_DuplicateHandle, currentProcess, mp.thread, currentProcess, uintptr(unsafe.Pointer(&thread)), 0, 0, _DUPLICATE_SAME_ACCESS) == 0 {
|
||||||
print("runtime.profileloop1: duplicatehandle failed; errno=", getlasterror(), "\n")
|
print("runtime: duplicatehandle failed; errno=", getlasterror(), "\n")
|
||||||
throw("runtime.profileloop1: duplicatehandle failed")
|
throw("duplicatehandle failed")
|
||||||
}
|
}
|
||||||
unlock(&mp.threadLock)
|
unlock(&mp.threadLock)
|
||||||
|
|
||||||
|
|
@ -1280,9 +1282,7 @@ func setProcessCPUProfiler(hz int32) {
|
||||||
if profiletimer == 0 {
|
if profiletimer == 0 {
|
||||||
timer := stdcall3(_CreateWaitableTimerA, 0, 0, 0)
|
timer := stdcall3(_CreateWaitableTimerA, 0, 0, 0)
|
||||||
atomic.Storeuintptr(&profiletimer, timer)
|
atomic.Storeuintptr(&profiletimer, timer)
|
||||||
thread := stdcall6(_CreateThread, 0, 0, funcPC(profileloop), 0, 0, 0)
|
newm(profileLoop, nil, -1)
|
||||||
stdcall2(_SetThreadPriority, thread, _THREAD_PRIORITY_HIGHEST)
|
|
||||||
stdcall1(_CloseHandle, thread)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -156,15 +156,6 @@ TEXT runtime·lastcontinuetramp<ABIInternal>(SB),NOSPLIT,$0-0
|
||||||
MOVL $runtime·lastcontinuehandler(SB), AX
|
MOVL $runtime·lastcontinuehandler(SB), AX
|
||||||
JMP sigtramp<>(SB)
|
JMP sigtramp<>(SB)
|
||||||
|
|
||||||
// Called by OS using stdcall ABI: uint32 profileloop(void*).
|
|
||||||
TEXT runtime·profileloop<ABIInternal>(SB),NOSPLIT,$0
|
|
||||||
PUSHL $runtime·profileloop1(SB)
|
|
||||||
NOP SP // tell vet SP changed - stop checking offsets
|
|
||||||
CALL runtime·externalthreadhandler(SB)
|
|
||||||
MOVL 4(SP), CX
|
|
||||||
ADDL $12, SP
|
|
||||||
JMP CX
|
|
||||||
|
|
||||||
TEXT runtime·externalthreadhandler<ABIInternal>(SB),NOSPLIT|TOPFRAME,$0
|
TEXT runtime·externalthreadhandler<ABIInternal>(SB),NOSPLIT|TOPFRAME,$0
|
||||||
PUSHL BP
|
PUSHL BP
|
||||||
MOVL SP, BP
|
MOVL SP, BP
|
||||||
|
|
|
||||||
|
|
@ -202,12 +202,6 @@ TEXT runtime·lastcontinuetramp<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-0
|
||||||
MOVQ $runtime·lastcontinuehandler(SB), AX
|
MOVQ $runtime·lastcontinuehandler(SB), AX
|
||||||
JMP sigtramp<>(SB)
|
JMP sigtramp<>(SB)
|
||||||
|
|
||||||
TEXT runtime·profileloop<ABIInternal>(SB),NOSPLIT|NOFRAME,$8
|
|
||||||
MOVQ $runtime·profileloop1(SB), CX
|
|
||||||
MOVQ CX, 0(SP)
|
|
||||||
CALL runtime·externalthreadhandler<ABIInternal>(SB)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT runtime·externalthreadhandler<ABIInternal>(SB),NOSPLIT|NOFRAME|TOPFRAME,$0
|
TEXT runtime·externalthreadhandler<ABIInternal>(SB),NOSPLIT|NOFRAME|TOPFRAME,$0
|
||||||
PUSHQ BP
|
PUSHQ BP
|
||||||
MOVQ SP, BP
|
MOVQ SP, BP
|
||||||
|
|
|
||||||
|
|
@ -233,10 +233,6 @@ TEXT runtime·lastcontinuetramp<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
|
||||||
MOVW $runtime·lastcontinuehandler(SB), R1
|
MOVW $runtime·lastcontinuehandler(SB), R1
|
||||||
B sigtramp<>(SB)
|
B sigtramp<>(SB)
|
||||||
|
|
||||||
TEXT runtime·profileloop<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
|
|
||||||
MOVW $runtime·profileloop1(SB), R1
|
|
||||||
B runtime·externalthreadhandler<ABIInternal>(SB)
|
|
||||||
|
|
||||||
// int32 externalthreadhandler(uint32 arg, int (*func)(uint32))
|
// int32 externalthreadhandler(uint32 arg, int (*func)(uint32))
|
||||||
// stack layout:
|
// stack layout:
|
||||||
// +----------------+
|
// +----------------+
|
||||||
|
|
|
||||||
|
|
@ -299,10 +299,6 @@ TEXT runtime·lastcontinuetramp(SB),NOSPLIT|NOFRAME,$0
|
||||||
MOVD $runtime·lastcontinuehandler<ABIInternal>(SB), R1
|
MOVD $runtime·lastcontinuehandler<ABIInternal>(SB), R1
|
||||||
B sigtramp<>(SB)
|
B sigtramp<>(SB)
|
||||||
|
|
||||||
TEXT runtime·profileloop<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
|
|
||||||
MOVD $runtime·profileloop1(SB), R1
|
|
||||||
B runtime·externalthreadhandler<ABIInternal>(SB)
|
|
||||||
|
|
||||||
// externalthreadhander called with R0 = uint32 arg, R1 = Go function f.
|
// externalthreadhander called with R0 = uint32 arg, R1 = Go function f.
|
||||||
// Need to call f(arg), which returns a uint32, and return it in R0.
|
// Need to call f(arg), which returns a uint32, and return it in R0.
|
||||||
TEXT runtime·externalthreadhandler<ABIInternal>(SB),NOSPLIT|TOPFRAME,$96-0
|
TEXT runtime·externalthreadhandler<ABIInternal>(SB),NOSPLIT|TOPFRAME,$96-0
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue