Source file
src/runtime/vdso_freebsd_x86.go
1
2
3
4
5
6
7 package runtime
8
9 import (
10 "runtime/internal/atomic"
11 "unsafe"
12 )
13
14 const (
15 _VDSO_TH_ALGO_X86_TSC = 1
16 _VDSO_TH_ALGO_X86_HPET = 2
17 )
18
19 const (
20 _HPET_DEV_MAP_MAX = 10
21 _HPET_MAIN_COUNTER = 0xf0
22
23 hpetDevPath = "/dev/hpetX\x00"
24 )
25
26 var hpetDevMap [_HPET_DEV_MAP_MAX]uintptr
27
28
29 func (th *vdsoTimehands) getTSCTimecounter() uint32 {
30 tsc := cputicks()
31 if th.x86_shift > 0 {
32 tsc >>= th.x86_shift
33 }
34 return uint32(tsc)
35 }
36
37
38 func (th *vdsoTimehands) getHPETTimecounter() (uint32, bool) {
39 const digits = "0123456789"
40
41 idx := int(th.x86_hpet_idx)
42 if idx >= len(hpetDevMap) {
43 return 0, false
44 }
45
46 p := atomic.Loaduintptr(&hpetDevMap[idx])
47 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 , 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 }
67 p = atomic.Loaduintptr(&hpetDevMap[idx])
68 }
69 if p == ^uintptr(0) {
70 return 0, false
71 }
72 return *(*uint32)(unsafe.Pointer(p + _HPET_MAIN_COUNTER)), true
73 }
74
75
76 func (th *vdsoTimehands) getTimecounter() (uint32, bool) {
77 switch th.algo {
78 case _VDSO_TH_ALGO_X86_TSC:
79 return th.getTSCTimecounter(), true
80 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
89 default:
90 return 0, false
91 }
92 }
93
View as plain text