Skip to content

Commit

Permalink
remove cgo (#5)
Browse files Browse the repository at this point in the history
* remove cgo

Go can call POSIX API without using cgo.

* update glide.yaml and glide.lock

* miss

* review changes

* match the original C code.
  • Loading branch information
catatsuy authored and cubicdaiya committed Mar 28, 2017
1 parent 94afbc3 commit 275dfba
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 111 deletions.
115 changes: 48 additions & 67 deletions cachectl/activepages.go
Original file line number Diff line number Diff line change
@@ -1,74 +1,55 @@
package cachectl

/*
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
int activePages(const char *path)
{
int i, j, fd, pages, pagesize;
struct stat st;
void *m;
char *pageinfo;
fd = open(path, O_RDONLY);
if(fd == -1) {
return -1;
}
if(fstat(fd, &st) == -1) {
goto error;
}
pagesize = getpagesize();
pages = (st.st_size + pagesize - 1) / pagesize;
pageinfo = calloc(sizeof(*pageinfo), pages);
if(!pageinfo) {
goto error;
}
m = mmap(NULL, st.st_size, PROT_NONE, MAP_SHARED, fd, 0);
if(m == MAP_FAILED) {
free(pageinfo);
goto error;
}
if(mincore(m, st.st_size, pageinfo) == -1) {
free(pageinfo);
munmap(m, st.st_size);
goto error;
}
i = 0;
j = 0;
for (i = 0; i < pages; i++) {
if(pageinfo[i] & 1) {
j++;
}
}
free(pageinfo);
munmap(m, st.st_size);
return j;
error:
close(fd);
return -1;
}
*/
import "C"
import (
"os"
"unsafe"

"golang.org/x/sys/unix"
)

func activePages(path string) int {
cs := C.CString(path)
result := C.activePages(cs)
C.free(unsafe.Pointer(cs))
return int(result)
func activePages(path string) (int, error) {
f, err := os.Open(path)
if err != nil {
return 0, err
}
defer f.Close()

fi, err := f.Stat()
if err != nil {
return 0, err
}
fsize := fi.Size()

if fsize == 0 {
return 0, nil
}

mmap, err := unix.Mmap(int(f.Fd()), 0, int(fsize), unix.PROT_NONE, unix.MAP_SHARED)
if err != nil {
return 0, err
}
defer unix.Munmap(mmap)

pagesize := int64(os.Getpagesize())
pages := (fsize + pagesize - 1) / pagesize
pageinfo := make([]byte, pages)

mmapPtr := uintptr(unsafe.Pointer(&mmap[0]))
sizePtr := uintptr(fsize)
pageinfoPtr := uintptr(unsafe.Pointer(&pageinfo[0]))

ret, _, err := unix.Syscall(unix.SYS_MINCORE, mmapPtr, sizePtr, pageinfoPtr)
if ret != 0 {
return 0, err
}

result := 0

for _, p := range pageinfo {
if p&1 == 1 {
result++
}
}

return result, nil
}
58 changes: 17 additions & 41 deletions cachectl/purge.go
Original file line number Diff line number Diff line change
@@ -1,56 +1,32 @@
package cachectl

/*
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
int fadvise(const char *path, float r)
{
int fd;
struct stat st;
off_t l;
fd = open(path, O_RDONLY);
if(fd == -1) {
return -1;
}
if(fstat(fd, &st) == -1) {
goto error;
}
l = (off_t)(st.st_size * r);
if(posix_fadvise(fd, 0, l, POSIX_FADV_DONTNEED) != 0) {
goto error;
}
close(fd);
return 1;
error:
close(fd);
return -1;
}
*/
import "C"
import (
"fmt"
"log"
"unsafe"
"os"

"golang.org/x/sys/unix"
)

func purgePages(fpath string, fsize int64, rate float64) error {
if rate < 0.0 || rate > 1.0 {
return fmt.Errorf("%.1f: rate should be over 0.0 and less than 1.0\n", rate)
}

cs := C.CString(fpath)
defer C.free(unsafe.Pointer(cs))
result := C.fadvise(cs, C.float(rate))
if result == -1 {
f, err := os.Open(fpath)
if err != nil {
return err
}
defer f.Close()

fi, err := f.Stat()
if err != nil {
return err
}
size := fi.Size()

err = unix.Fadvise(int(f.Fd()), 0, int64(float64(size)*rate), unix.FADV_DONTNEED)
if err != nil {
return fmt.Errorf("failed to purge page cache for %s", fpath)
}

Expand Down
7 changes: 6 additions & 1 deletion cachectl/stat.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ func PrintPagesStat(fpath string, fsize int64) {

pages := (fsize + int64(pagesize) - 1) / int64(pagesize)

pagesActive := activePages(fpath)
pagesActive, err := activePages(fpath)
if err != nil {
log.Printf("%v\n", err)
return
}

activeRate := float64(0)
if pagesActive == -1 {
pagesActive = 0
Expand Down
8 changes: 6 additions & 2 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions glide.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@ package: github.com/cubicdaiya/cachectl
import:
- package: github.com/BurntSushi/toml
version: v0.2.0
- package: golang.org/x/sys
subpackages:
- unix

0 comments on commit 275dfba

Please sign in to comment.