/* * Copyright (C) Ingo Molnar, 2002 */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #define PAGE_SIZE 4096 #define PAGE_WORDS (PAGE_SIZE/sizeof(int)) #define CACHE_PAGES 1024 #define CACHE_SIZE (CACHE_PAGES*PAGE_SIZE) #define WINDOW_PAGES 16 #define WINDOW_SIZE (WINDOW_PAGES*PAGE_SIZE) #define WINDOW_START 0x48000000 static char cache_contents [CACHE_SIZE]; static void test_nonlinear(int fd) { char *data = NULL; int i, j, repeat = 2; for (i = 0; i < CACHE_PAGES; i++) { int *page = (int *) (cache_contents + i*PAGE_SIZE); for (j = 0; j < PAGE_WORDS; j++) page[j] = i; } if (write(fd, cache_contents, CACHE_SIZE) != CACHE_SIZE) perror("write"), exit(1); data = mmap((void *)WINDOW_START, WINDOW_SIZE, PROT_READ|PROT_WRITE, MAP_FIXED | MAP_SHARED , fd, 0); if (data == MAP_FAILED) perror("mmap"), exit(1); again: for (i = 0; i < WINDOW_PAGES; i += 2) { char *page = data + i*PAGE_SIZE; if (remap_file_pages(page, PAGE_SIZE * 2, 0, (WINDOW_PAGES-i-2), 0) == -1) perror("remap_file_pages"), exit(1); } for (i = 0; i < WINDOW_PAGES; i++) { /* * Double-check the correctness of the mapping: */ if (i & 1) { if (data[i*PAGE_SIZE] != WINDOW_PAGES-i) { printf("hm, mapped incorrect data!\n"); exit(1); } } else { if (data[i*PAGE_SIZE] != WINDOW_PAGES-i-2) { printf("hm, mapped incorrect data!\n"); exit(1); } } } if (--repeat) goto again; } int main(int argc, char **argv) { int fd; fd = open("/dev/shm/cache", O_RDWR|O_CREAT|O_TRUNC,S_IRWXU); if (fd < 0) perror("open"), exit(1); test_nonlinear(fd); if (close(fd) == -1) perror("close"), exit(1); printf("nonlinear shm file OK\n"); fd = open("/tmp/cache", O_RDWR|O_CREAT|O_TRUNC,S_IRWXU); if (fd < 0) perror("open"), exit(1); test_nonlinear(fd); if (close(fd) == -1) perror("close"), exit(1); printf("nonlinear /tmp/ file OK\n"); exit(0); }