mirror of
https://github.com/golang/go
synced 2024-10-02 02:08:33 -06:00
runtime: fast clock_gettime on FreeBSD, always call getHPETTimecounter on systemstack
CL 108095 goes to some length inorder to keep the stack usage of getHPETTimecounter code paths bellow a limit being checked by the linker analysis. That limit is spurious, when running on the system or signal stack. In a similar scenario, cgocallback_gofunc performs an indirect call through AX to hide the call from the linker analysis. Here instead, mark getHPETTimecounter //go:systemstack and call it appropriately. Change-Id: I80bec5e4974eee3c564d94f6e1142f322df88b2f Reviewed-on: https://go-review.googlesource.com/111495 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
88d677be96
commit
a9fc375258
@ -20,23 +20,11 @@ const (
|
|||||||
const (
|
const (
|
||||||
_HPET_DEV_MAP_MAX = 10
|
_HPET_DEV_MAP_MAX = 10
|
||||||
_HPET_MAIN_COUNTER = 0xf0 /* Main counter register */
|
_HPET_MAIN_COUNTER = 0xf0 /* Main counter register */
|
||||||
|
|
||||||
|
hpetDevPath = "/dev/hpetX\x00"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var hpetDevMap [_HPET_DEV_MAP_MAX]uintptr
|
||||||
hpetDevMap [_HPET_DEV_MAP_MAX]uintptr
|
|
||||||
hpetDevPath = [_HPET_DEV_MAP_MAX][11]byte{
|
|
||||||
{'/', 'd', 'e', 'v', '/', 'h', 'p', 'e', 't', '0', 0},
|
|
||||||
{'/', 'd', 'e', 'v', '/', 'h', 'p', 'e', 't', '1', 0},
|
|
||||||
{'/', 'd', 'e', 'v', '/', 'h', 'p', 'e', 't', '2', 0},
|
|
||||||
{'/', 'd', 'e', 'v', '/', 'h', 'p', 'e', 't', '3', 0},
|
|
||||||
{'/', 'd', 'e', 'v', '/', 'h', 'p', 'e', 't', '4', 0},
|
|
||||||
{'/', 'd', 'e', 'v', '/', 'h', 'p', 'e', 't', '5', 0},
|
|
||||||
{'/', 'd', 'e', 'v', '/', 'h', 'p', 'e', 't', '6', 0},
|
|
||||||
{'/', 'd', 'e', 'v', '/', 'h', 'p', 'e', 't', '7', 0},
|
|
||||||
{'/', 'd', 'e', 'v', '/', 'h', 'p', 'e', 't', '8', 0},
|
|
||||||
{'/', 'd', 'e', 'v', '/', 'h', 'p', 'e', 't', '9', 0},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
//go:nosplit
|
//go:nosplit
|
||||||
func (th *vdsoTimehands) getTSCTimecounter() uint32 {
|
func (th *vdsoTimehands) getTSCTimecounter() uint32 {
|
||||||
@ -47,8 +35,10 @@ func (th *vdsoTimehands) getTSCTimecounter() uint32 {
|
|||||||
return uint32(tsc)
|
return uint32(tsc)
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:nosplit
|
//go:systemstack
|
||||||
func (th *vdsoTimehands) getHPETTimecounter() (uint32, bool) {
|
func (th *vdsoTimehands) getHPETTimecounter() (uint32, bool) {
|
||||||
|
const digits = "0123456789"
|
||||||
|
|
||||||
idx := int(th.x86_hpet_idx)
|
idx := int(th.x86_hpet_idx)
|
||||||
if idx >= len(hpetDevMap) {
|
if idx >= len(hpetDevMap) {
|
||||||
return 0, false
|
return 0, false
|
||||||
@ -56,7 +46,11 @@ func (th *vdsoTimehands) getHPETTimecounter() (uint32, bool) {
|
|||||||
|
|
||||||
p := atomic.Loaduintptr(&hpetDevMap[idx])
|
p := atomic.Loaduintptr(&hpetDevMap[idx])
|
||||||
if p == 0 {
|
if p == 0 {
|
||||||
fd := open(&hpetDevPath[idx][0], 0 /* O_RDONLY */, 0)
|
var devPath [len(hpetDevPath)]byte
|
||||||
|
copy(devPath[:], hpetDevPath)
|
||||||
|
devPath[9] = digits[idx]
|
||||||
|
|
||||||
|
fd := open(&devPath[0], 0 /* O_RDONLY */, 0)
|
||||||
if fd < 0 {
|
if fd < 0 {
|
||||||
atomic.Casuintptr(&hpetDevMap[idx], 0, ^uintptr(0))
|
atomic.Casuintptr(&hpetDevMap[idx], 0, ^uintptr(0))
|
||||||
return 0, false
|
return 0, false
|
||||||
@ -85,7 +79,14 @@ func (th *vdsoTimehands) getTimecounter() (uint32, bool) {
|
|||||||
case _VDSO_TH_ALGO_X86_TSC:
|
case _VDSO_TH_ALGO_X86_TSC:
|
||||||
return th.getTSCTimecounter(), true
|
return th.getTSCTimecounter(), true
|
||||||
case _VDSO_TH_ALGO_X86_HPET:
|
case _VDSO_TH_ALGO_X86_HPET:
|
||||||
return th.getHPETTimecounter()
|
var (
|
||||||
|
tc uint32
|
||||||
|
ok bool
|
||||||
|
)
|
||||||
|
systemstack(func() {
|
||||||
|
tc, ok = th.getHPETTimecounter()
|
||||||
|
})
|
||||||
|
return tc, ok
|
||||||
default:
|
default:
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user