mirror of
https://github.com/golang/go
synced 2024-09-29 19:34:38 -06:00
runtime: fast clock_gettime on FreeBSD, split getHPETTimecounter
Call only initHPETTimecounter on the system stack. Use O_CLOEXEC flag when opening the HPET device. FreeBSD 12.3-RELEASE-p2, AMD FX-8300 paulzhol@relic:~/go/src/time % ~/gocode/bin/benchcmp old_hpet.txt new_hpet.txt benchcmp is deprecated in favor of benchstat: https://pkg.go.dev/golang.org/x/perf/cmd/benchstat benchmark old ns/op new ns/op delta BenchmarkNow-8 1420 1397 -1.62% BenchmarkNowUnixNano-8 1421 1404 -1.20% BenchmarkNowUnixMilli-8 1423 1405 -1.26% BenchmarkNowUnixMicro-8 1423 1404 -1.34% Update #50947 Change-Id: I553b5427fb0b86d7e070af4516b36326bc0aaf00 Reviewed-on: https://go-review.googlesource.com/c/go/+/391856 Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Michael Pratt <mpratt@google.com>
This commit is contained in:
parent
a719a78c1b
commit
e51b3ae0ee
@ -34,10 +34,8 @@ func (th *vdsoTimehands) getTSCTimecounter() uint32 {
|
|||||||
return uint32(tsc)
|
return uint32(tsc)
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:systemstack
|
//go:nosplit
|
||||||
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
|
||||||
@ -45,25 +43,7 @@ func (th *vdsoTimehands) getHPETTimecounter() (uint32, bool) {
|
|||||||
|
|
||||||
p := atomic.Loaduintptr(&hpetDevMap[idx])
|
p := atomic.Loaduintptr(&hpetDevMap[idx])
|
||||||
if p == 0 {
|
if p == 0 {
|
||||||
var devPath [len(hpetDevPath)]byte
|
systemstack(func() { initHPETTimecounter(idx) })
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
addr, mmapErr := mmap(nil, physPageSize, _PROT_READ, _MAP_SHARED, fd, 0)
|
|
||||||
closefd(fd)
|
|
||||||
newP := uintptr(addr)
|
|
||||||
if mmapErr != 0 {
|
|
||||||
newP = ^uintptr(0)
|
|
||||||
}
|
|
||||||
if !atomic.Casuintptr(&hpetDevMap[idx], 0, newP) && mmapErr == 0 {
|
|
||||||
munmap(addr, physPageSize)
|
|
||||||
}
|
|
||||||
p = atomic.Loaduintptr(&hpetDevMap[idx])
|
p = atomic.Loaduintptr(&hpetDevMap[idx])
|
||||||
}
|
}
|
||||||
if p == ^uintptr(0) {
|
if p == ^uintptr(0) {
|
||||||
@ -72,20 +52,38 @@ func (th *vdsoTimehands) getHPETTimecounter() (uint32, bool) {
|
|||||||
return *(*uint32)(unsafe.Pointer(p + _HPET_MAIN_COUNTER)), true
|
return *(*uint32)(unsafe.Pointer(p + _HPET_MAIN_COUNTER)), true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//go:systemstack
|
||||||
|
func initHPETTimecounter(idx int) {
|
||||||
|
const digits = "0123456789"
|
||||||
|
|
||||||
|
var devPath [len(hpetDevPath)]byte
|
||||||
|
copy(devPath[:], hpetDevPath)
|
||||||
|
devPath[9] = digits[idx]
|
||||||
|
|
||||||
|
fd := open(&devPath[0], 0 /* O_RDONLY */ |_O_CLOEXEC, 0)
|
||||||
|
if fd < 0 {
|
||||||
|
atomic.Casuintptr(&hpetDevMap[idx], 0, ^uintptr(0))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
addr, mmapErr := mmap(nil, physPageSize, _PROT_READ, _MAP_SHARED, fd, 0)
|
||||||
|
closefd(fd)
|
||||||
|
newP := uintptr(addr)
|
||||||
|
if mmapErr != 0 {
|
||||||
|
newP = ^uintptr(0)
|
||||||
|
}
|
||||||
|
if !atomic.Casuintptr(&hpetDevMap[idx], 0, newP) && mmapErr == 0 {
|
||||||
|
munmap(addr, physPageSize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//go:nosplit
|
//go:nosplit
|
||||||
func (th *vdsoTimehands) getTimecounter() (uint32, bool) {
|
func (th *vdsoTimehands) getTimecounter() (uint32, bool) {
|
||||||
switch th.algo {
|
switch th.algo {
|
||||||
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:
|
||||||
var (
|
return th.getHPETTimecounter()
|
||||||
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