package platform
import (
"math/bits"
"os"
"sort"
"strconv"
"strings"
"syscall"
)
const (
__MAP_HUGE_SHIFT = 26
__MAP_HUGETLB = 0x40000
)
var hugePagesConfigs []hugePagesConfig
type hugePagesConfig struct {
size int
flag int
}
func (hpc *hugePagesConfig ) match (size int ) bool {
return (size & (hpc .size - 1 )) == 0
}
func init() {
dirents , err := os .ReadDir ("/sys/kernel/mm/hugepages/" )
if err != nil {
return
}
for _ , dirent := range dirents {
name := dirent .Name ()
if !strings .HasPrefix (name , "hugepages-" ) {
continue
}
if !strings .HasSuffix (name , "kB" ) {
continue
}
n , err := strconv .ParseUint (name [10 :len (name )-2 ], 10 , 64 )
if err != nil {
continue
}
if bits .OnesCount64 (n ) != 1 {
continue
}
n *= 1024
hugePagesConfigs = append (hugePagesConfigs , hugePagesConfig {
size : int (n ),
flag : int (bits .TrailingZeros64 (n )<<__MAP_HUGE_SHIFT ) | __MAP_HUGETLB ,
})
}
sort .Slice (hugePagesConfigs , func (i , j int ) bool {
return hugePagesConfigs [i ].size > hugePagesConfigs [j ].size
})
}
func mmapCodeSegment(size , prot int ) ([]byte , error ) {
flags := syscall .MAP_ANON | syscall .MAP_PRIVATE
for _ , hugePagesConfig := range hugePagesConfigs {
if hugePagesConfig .match (size ) {
b , err := syscall .Mmap (-1 , 0 , size , prot , flags |hugePagesConfig .flag )
if err != nil {
continue
}
return b , nil
}
}
return syscall .Mmap (-1 , 0 , size , prot , flags )
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .