#include #include #include #include #include #include #define PAGE_SIZE 4096 #define PAGE_MASK (~(PAGE_SIZE-1)) static void do_lock(void *addr, size_t len) { void *laddr = (void *)((unsigned long)addr & PAGE_MASK); size_t llen = (len + ((unsigned long)addr - (unsigned long)laddr) + PAGE_SIZE - 1) & PAGE_MASK; int e = mlock(laddr, llen); printf("locking %p-%p -> %p-%p -> %d\n", addr, addr+len, laddr, laddr+llen, e); if (e < 0) exit(1); } static void do_test(int lock_it) __attribute__((noinline)); static void do_test(int lock_it) { struct rusage rbefore, rafter; struct { char pad1[2*PAGE_SIZE]; unsigned long lock_me; char pad2[2*PAGE_SIZE]; } s; unsigned long esp; s.pad1[0] = 1; s.pad2[2*PAGE_SIZE-1] = 1; //memset(&s.pad1, 0, sizeof(s.pad1)); //memset(&s.pad2, 0, sizeof(s.pad2)); printf("pad1 at %p-%p\n", &s.pad1[0], &s.pad1[sizeof(s.pad1)-1]); printf("LCK at %p-%p\n", &s.lock_me, &s.lock_me + 1); printf("pad2 at %p-%p\n", &s.pad2[0], &s.pad2[sizeof(s.pad2)-1]); asm volatile("mov %%esp, %0\n" : "=r" (esp)); printf("esp: %#lx\n", esp); if (lock_it) { do_lock(&s.lock_me, sizeof(s.lock_me)); } getrusage(RUSAGE_SELF, &rbefore); s.lock_me = 0xdeadbeef; getrusage(RUSAGE_SELF, &rafter); printf("minor faults: %ld -> %ld\n", rbefore.ru_minflt, rafter.ru_minflt); printf("major faults: %ld -> %ld\n", rbefore.ru_majflt, rafter.ru_majflt); if (lock_it && (rbefore.ru_minflt != rafter.ru_minflt || rbefore.ru_majflt != rafter.ru_majflt)) printf("ERROR -- Should not have faulted\n"); } int main(int argc, char **argv) { do_test(argc > 1 && strcmp(argv[1], "lock") == 0); return 0; }