Skip to content

Instantly share code, notes, and snippets.

@tobert
Last active August 29, 2015 14:00
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tobert/e3b9a44e5de35be06dad to your computer and use it in GitHub Desktop.
Save tobert/e3b9a44e5de35be06dad to your computer and use it in GitHub Desktop.
mincore in Go
package main
import (
"flag"
"log"
"os"
"syscall"
"unsafe"
)
func main() {
flag.Parse()
for _, fname := range flag.Args() {
Mincore(fname)
}
}
func Mincore(fname string) {
f, err := os.Open(fname)
if err != nil {
log.Fatalf("Could not open file '%s' for read: %s\n", fname, err)
}
defer f.Close()
fi, err := f.Stat()
if err != nil {
log.Fatalf("Could not stat file %s: %s\n", fname, err)
}
if fi.Size() == 0 {
log.Fatalf("%s appears to be 0 bytes in length\n", fname)
}
mmap, err := syscall.Mmap(int(f.Fd()), 0, int(fi.Size()), syscall.PROT_NONE, syscall.MAP_SHARED)
if err != nil {
log.Fatalf("Could not mmap file '%s': %s\n", fname, err)
}
defer syscall.Munmap(mmap)
// TODO: check for MAP_FAILED which is ((void *) -1)
// but maybe unnecessary since it looks like errno is always set when MAP_FAILED
// one byte per page, only LSB is used, remainder is reserved and clear
vecsz := (fi.Size() + int64(os.Getpagesize()) - 1) / int64(os.Getpagesize())
vec := make([]byte, vecsz)
mmap_ptr := uintptr(unsafe.Pointer(&mmap[0]))
size_ptr := uintptr(fi.Size())
vec_ptr := uintptr(unsafe.Pointer(&vec[0]))
ret, _, err := syscall.RawSyscall(syscall.SYS_MINCORE, mmap_ptr, size_ptr, vec_ptr)
if ret != 0 {
log.Fatalf("mincore() failed: %s", err)
}
for i, b := range vec {
if b % 2 == 1 {
log.Printf("%d -> cached", i)
} else {
log.Printf("%d -> NOT", i)
}
}
}
open("main.go", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=1605, ...}) = 0
mmap(NULL, 1605, PROT_NONE, MAP_SHARED, 3, 0) = 0x7fd82e704000
mincore(0x7fd82e704000, 1605, [10000000000000000000000000000000...]) = 0
munmap(0x7fd82e704000, 1605) = 0
close(3) = 0
atobey@brak ~/src/mincore $ ./mincore main.go
2014/04/30 17:14:30 Cached pages: 1, Uncached: 0
atobey@brak ~/src/mincore $ echo 1 |sudo tee /proc/sys/vm/drop_caches
1
atobey@brak ~/src/mincore $ ./mincore main.go
2014/04/30 17:14:40 Cached pages: 0, Uncached: 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment