...
1 package platform
2
3 import (
4 "math/bits"
5 "os"
6 "sort"
7 "strconv"
8 "strings"
9 "syscall"
10 )
11
12 const (
13
14 __MAP_HUGE_SHIFT = 26
15 __MAP_HUGETLB = 0x40000
16 )
17
18 var hugePagesConfigs []hugePagesConfig
19
20 type hugePagesConfig struct {
21 size int
22 flag int
23 }
24
25 func (hpc *hugePagesConfig) match(size int) bool {
26 return (size & (hpc.size - 1)) == 0
27 }
28
29 func init() {
30 dirents, err := os.ReadDir("/sys/kernel/mm/hugepages/")
31 if err != nil {
32 return
33 }
34
35 for _, dirent := range dirents {
36 name := dirent.Name()
37 if !strings.HasPrefix(name, "hugepages-") {
38 continue
39 }
40 if !strings.HasSuffix(name, "kB") {
41 continue
42 }
43 n, err := strconv.ParseUint(name[10:len(name)-2], 10, 64)
44 if err != nil {
45 continue
46 }
47 if bits.OnesCount64(n) != 1 {
48 continue
49 }
50 n *= 1024
51 hugePagesConfigs = append(hugePagesConfigs, hugePagesConfig{
52 size: int(n),
53 flag: int(bits.TrailingZeros64(n)<<__MAP_HUGE_SHIFT) | __MAP_HUGETLB,
54 })
55 }
56
57 sort.Slice(hugePagesConfigs, func(i, j int) bool {
58 return hugePagesConfigs[i].size > hugePagesConfigs[j].size
59 })
60 }
61
62 func mmapCodeSegment(size, prot int) ([]byte, error) {
63 flags := syscall.MAP_ANON | syscall.MAP_PRIVATE
64
65 for _, hugePagesConfig := range hugePagesConfigs {
66 if hugePagesConfig.match(size) {
67 b, err := syscall.Mmap(-1, 0, size, prot, flags|hugePagesConfig.flag)
68 if err != nil {
69 continue
70 }
71 return b, nil
72 }
73 }
74
75 return syscall.Mmap(-1, 0, size, prot, flags)
76 }
77
View as plain text