Commit a9fc3752 authored by Yuval Pavel Zholkover's avatar Yuval Pavel Zholkover Committed by Ian Lance Taylor

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: 's avatarIan Lance Taylor <iant@golang.org>
parent 88d677be
......@@ -20,24 +20,12 @@ const (
const (
_HPET_DEV_MAP_MAX = 10
_HPET_MAIN_COUNTER = 0xf0 /* Main counter register */
)
var (
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},
}
hpetDevPath = "/dev/hpetX\x00"
)
var hpetDevMap [_HPET_DEV_MAP_MAX]uintptr
//go:nosplit
func (th *vdsoTimehands) getTSCTimecounter() uint32 {
tsc := cputicks()
......@@ -47,8 +35,10 @@ func (th *vdsoTimehands) getTSCTimecounter() uint32 {
return uint32(tsc)
}
//go:nosplit
//go:systemstack
func (th *vdsoTimehands) getHPETTimecounter() (uint32, bool) {
const digits = "0123456789"
idx := int(th.x86_hpet_idx)
if idx >= len(hpetDevMap) {
return 0, false
......@@ -56,7 +46,11 @@ func (th *vdsoTimehands) getHPETTimecounter() (uint32, bool) {
p := atomic.Loaduintptr(&hpetDevMap[idx])
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 {
atomic.Casuintptr(&hpetDevMap[idx], 0, ^uintptr(0))
return 0, false
......@@ -85,7 +79,14 @@ func (th *vdsoTimehands) getTimecounter() (uint32, bool) {
case _VDSO_TH_ALGO_X86_TSC:
return th.getTSCTimecounter(), true
case _VDSO_TH_ALGO_X86_HPET:
return th.getHPETTimecounter()
var (
tc uint32
ok bool
)
systemstack(func() {
tc, ok = th.getHPETTimecounter()
})
return tc, ok
default:
return 0, false
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment