Skip to content

Commit e51b3ae

Browse files
paulzholmengzhuo
authored andcommitted
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 <[email protected]> Reviewed-by: Michael Pratt <[email protected]>
1 parent a719a78 commit e51b3ae

File tree

1 file changed

+28
-30
lines changed

1 file changed

+28
-30
lines changed

src/runtime/vdso_freebsd_x86.go

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -34,36 +34,16 @@ func (th *vdsoTimehands) getTSCTimecounter() uint32 {
3434
return uint32(tsc)
3535
}
3636

37-
//go:systemstack
37+
//go:nosplit
3838
func (th *vdsoTimehands) getHPETTimecounter() (uint32, bool) {
39-
const digits = "0123456789"
40-
4139
idx := int(th.x86_hpet_idx)
4240
if idx >= len(hpetDevMap) {
4341
return 0, false
4442
}
4543

4644
p := atomic.Loaduintptr(&hpetDevMap[idx])
4745
if p == 0 {
48-
var devPath [len(hpetDevPath)]byte
49-
copy(devPath[:], hpetDevPath)
50-
devPath[9] = digits[idx]
51-
52-
fd := open(&devPath[0], 0 /* O_RDONLY */, 0)
53-
if fd < 0 {
54-
atomic.Casuintptr(&hpetDevMap[idx], 0, ^uintptr(0))
55-
return 0, false
56-
}
57-
58-
addr, mmapErr := mmap(nil, physPageSize, _PROT_READ, _MAP_SHARED, fd, 0)
59-
closefd(fd)
60-
newP := uintptr(addr)
61-
if mmapErr != 0 {
62-
newP = ^uintptr(0)
63-
}
64-
if !atomic.Casuintptr(&hpetDevMap[idx], 0, newP) && mmapErr == 0 {
65-
munmap(addr, physPageSize)
66-
}
46+
systemstack(func() { initHPETTimecounter(idx) })
6747
p = atomic.Loaduintptr(&hpetDevMap[idx])
6848
}
6949
if p == ^uintptr(0) {
@@ -72,20 +52,38 @@ func (th *vdsoTimehands) getHPETTimecounter() (uint32, bool) {
7252
return *(*uint32)(unsafe.Pointer(p + _HPET_MAIN_COUNTER)), true
7353
}
7454

55+
//go:systemstack
56+
func initHPETTimecounter(idx int) {
57+
const digits = "0123456789"
58+
59+
var devPath [len(hpetDevPath)]byte
60+
copy(devPath[:], hpetDevPath)
61+
devPath[9] = digits[idx]
62+
63+
fd := open(&devPath[0], 0 /* O_RDONLY */ |_O_CLOEXEC, 0)
64+
if fd < 0 {
65+
atomic.Casuintptr(&hpetDevMap[idx], 0, ^uintptr(0))
66+
return
67+
}
68+
69+
addr, mmapErr := mmap(nil, physPageSize, _PROT_READ, _MAP_SHARED, fd, 0)
70+
closefd(fd)
71+
newP := uintptr(addr)
72+
if mmapErr != 0 {
73+
newP = ^uintptr(0)
74+
}
75+
if !atomic.Casuintptr(&hpetDevMap[idx], 0, newP) && mmapErr == 0 {
76+
munmap(addr, physPageSize)
77+
}
78+
}
79+
7580
//go:nosplit
7681
func (th *vdsoTimehands) getTimecounter() (uint32, bool) {
7782
switch th.algo {
7883
case _VDSO_TH_ALGO_X86_TSC:
7984
return th.getTSCTimecounter(), true
8085
case _VDSO_TH_ALGO_X86_HPET:
81-
var (
82-
tc uint32
83-
ok bool
84-
)
85-
systemstack(func() {
86-
tc, ok = th.getHPETTimecounter()
87-
})
88-
return tc, ok
86+
return th.getHPETTimecounter()
8987
default:
9088
return 0, false
9189
}

0 commit comments

Comments
 (0)