github.com/tetratelabs/wazero@v1.7.3-0.20240513003603-48f702e154b5/internal/platform/mmap_linux.go (about) 1 package platform 2 3 import ( 4 "math/bits" 5 "os" 6 "sort" 7 "strconv" 8 "strings" 9 "syscall" 10 ) 11 12 const ( 13 // https://man7.org/linux/man-pages/man2/mmap.2.html 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 }