Skip to content

Instantly share code, notes, and snippets.

@arunlakshman
Created February 9, 2018 11:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arunlakshman/d11c69c79005c901f8835a9023874c6b to your computer and use it in GitHub Desktop.
Save arunlakshman/d11c69c79005c901f8835a9023874c6b to your computer and use it in GitHub Desktop.
File Occupancy in Buffer Cache
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <grp.h>
#include <pwd.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#define VEC_SIZE 1024
#define PG_SIZE 4096
#define RANGE_PER_MAP VEC_SIZE*PG_SIZE
#define MIN(x,y) (((x)<(y))?(x):(y))
int main(int argc, char const *argv[]) {
struct stat s;
off_t my_offset;
int size, i, nbits, j;
long offset = 0, count = 0;
unsigned char* addr;
unsigned char vec[VEC_SIZE];
int fd = open(argv[1], O_RDONLY);
int status = fstat(fd, &s);
size = s.st_size;
off_t sz = (off_t) size;
int npages = (sz + PG_SIZE - 1) / PG_SIZE;
int nloops = (npages + VEC_SIZE - 1) / VEC_SIZE;
my_offset = (off_t) (offset / RANGE_PER_MAP) * RANGE_PER_MAP;
for(i = 0; i < nloops; ++i) {
addr = (char*) mmap(0, RANGE_PER_MAP, PROT_READ, MAP_PRIVATE, fd, my_offset);
memset(vec, 0, sizeof(unsigned char) * VEC_SIZE);
nbits = MIN(sz - my_offset, RANGE_PER_MAP);
mincore(addr, nbits, vec);
for (j = offset > my_offset ? (offset/PG_SIZE) % VEC_SIZE : 0; j < (nbits + PG_SIZE - 1) / PG_SIZE; j++) {
if (vec[j] & 0x1) {
count++;
}
}
my_offset += RANGE_PER_MAP;
munmap(addr, RANGE_PER_MAP);
}
long sz_pages = (sz + (unsigned long long) PG_SIZE - 1) / (unsigned long long) PG_SIZE;
printf("%s - %f\n", argv[1], (count * 100.0) / sz_pages);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment