/* * A test program to reveal a system has virtual cache aliasing problem. * * It does mmap() a file and write some stuff to the file * Immediately it will read the file through read() and try to verify * the written data. * * Normally it should succeed. But on a badly implemented system * (such as MIPS as of 2003/10/14), it shows up on quite a few boards. */ #include #include #include #include #include #include #define TEST_FNAME "test.data" #define TEST_SIZE 1000000 #if 0 #define WRITE_START 0xcf375 /* 848757 */ #define WRITE_SIZE 4536 #endif #define PATTERN "shittystuff" #define PATTERN_SIZE (sizeof(PATTERN) -1 ) void create_file() { int ret; int fd = open(TEST_FNAME, O_RDWR | O_CREAT, S_IRWXU); // printf("fd = %d\n",fd ); assert(fd > 0); lseek(fd, TEST_SIZE-1, SEEK_SET); ret=write(fd, "c", 1); assert(ret == 1); close(fd); } char buf[102400]; void check_write(int WRITE_START, int WRITE_SIZE) { int fd, ret; int size; char * dst; fd = open(TEST_FNAME, O_RDONLY); assert(fd > 0); lseek(fd, WRITE_START, SEEK_SET); ret = read(fd, buf, WRITE_SIZE); assert(ret == WRITE_SIZE); for(size=0, dst = buf; size < WRITE_SIZE; ) { int s = PATTERN_SIZE; if (size + s > WRITE_SIZE) s = WRITE_SIZE - size; if (strncmp(dst, PATTERN, s) != 0) { printf("differ!\n"); } size += s; dst += s; } close(fd); } void do_mmap_write(int WRITE_START, int WRITE_SIZE) { int fd; char * addr; char *dst; int size; int ret; fd = open(TEST_FNAME, O_RDWR); // printf("fd = %d\n", fd); assert(fd > 0); addr = mmap(NULL, TEST_SIZE, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0); // printf("file mapped at %p\n", addr); for (size=0, dst = addr + WRITE_START; size < WRITE_SIZE; ) { int s = PATTERN_SIZE; if (size + s > WRITE_SIZE) s = WRITE_SIZE - size; memcpy(dst, PATTERN, s); size += s; dst += s; } // check // msync(addr, TEST_SIZE, MS_SYNC); check_write(WRITE_START, WRITE_SIZE); // clean up ret = munmap(addr, TEST_SIZE); close(fd); assert(ret == 0); } void gen_params(int *start, int *size) { /* size is between 4096 and 8192 */ *size = random() % 4096 + 4096; *start = random() % (TEST_SIZE - *size - 1); // printf("start = %d, size = %d\n", *start, *size); assert(*size >= 4096); assert(*size <= 8192); assert(*start > 0); assert(*start + *size < TEST_SIZE); } main() { create_file(); for(;;) { int write_start, write_size; gen_params(&write_start, &write_size); do_mmap_write(write_start, write_size); // check_write(write_start, write_size); } }