Skip to content

Instantly share code, notes, and snippets.

@mattyoho
Forked from piki/mmap.c
Created May 23, 2013 16:13
Show Gist options
  • Save mattyoho/5637281 to your computer and use it in GitHub Desktop.
Save mattyoho/5637281 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#define CHECK(thing) if (!(thing)) { perror(#thing); exit(1); }
#define MAX_PAGE_IN 104857600
#define MIN(a,b) ((a)<(b)?(a):(b))
static void get_rss(const char *tag) {
char buf[128];
snprintf(buf, sizeof(buf), "ps hu %d | cut -c-80", getpid());
printf("%-25s ==> ", tag); fflush(stdout);
system(buf);
}
int main(int argc, const char **argv) {
if (argc != 2) {
fprintf(stderr, "Usage:\n %s filename\n", argv[0]);
return 1;
}
// open it
int fd = open(argv[1], O_RDONLY);
CHECK(fd != -1);
struct stat st;
CHECK(fstat(fd, &st) != -1);
// map it
get_rss("before mmap");
void *map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
get_rss("after mmap");
CHECK(map != (void*)-1);
// does WILLNEED do anything? seems like no.
unsigned int sum = 0;
madvise(map, st.st_size, MADV_WILLNEED);
sum += ((unsigned char*)map)[0];
sleep(1);
get_rss("after WILLNEED");
// walk it. add it to sum and print at the end so the optimizer doesn't get clever.
int i;
int limit = MIN(st.st_size, MAX_PAGE_IN);
madvise(map, st.st_size, MADV_SEQUENTIAL);
for (i=0; i<limit; i++) {
sum += ((unsigned char*)map)[i];
}
get_rss("after touching");
// give it back!
// here are other flags you can pass to madvise:
// MADV_NORMAL, MADV_RANDOM, MADV_SEQUENTIAL, MADV_WILLNEED, MADV_DONTNEED
madvise(map, st.st_size, MADV_DONTNEED);
get_rss("after DONTNEED");
printf("%d\n", sum);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment