]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: fast clock_gettime on FreeBSD, always call getHPETTimecounter on systemstack
authorYuval Pavel Zholkover <paulzhol@gmail.com>
Fri, 4 May 2018 12:01:44 +0000 (15:01 +0300)
committerIan Lance Taylor <iant@golang.org>
Fri, 4 May 2018 17:34:20 +0000 (17:34 +0000)
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>
src/runtime/vdso_freebsd_x86.go

index 1b1be5f9256b4c3714f285d5c79eebfc0b069a3b..1fa5d80dcc00e82e4d3bca8bfdf8bfcf64cb07de 100644 (file)
@@ -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
        }