/* * Copyright (c) 2003 Sean Chittenden . * All rights reserved. * * $Id$ */ #include #include #include #include #include #include #include #include #include #include #ifdef notdef #define DEBUG 1 #endif #ifdef notdef # define DO_MMAP 1 #endif #ifdef notdef # define DO_MMAP_ONCE 1 #endif #ifdef notdef # define DO_SHOW_FILENAMES 1 #endif #ifdef DEFAULT_READSIZE # ifndef READ_SIZE # define READ_SIZE MAXBSIZE # endif #else # define READ_SIZE 0 #endif struct bs { off_t size; int fd; struct stat fs; struct timeval t_start; struct timeval t_final; void *addr; char *filename; }; struct timeval t_teststart, t_testfinal; int npages, psize, ret, wret; inline void setup_fd(struct bs *s) { s->fd = open(s->filename, O_RDWR); if (s->fd < 0) err(1, "Unable to open: %s", s->filename); #ifdef DEBUG fprintf(stderr, "open():\t\t%s\n", s->filename); #endif ret = fstat(s->fd, &s->fs); if (ret < 0) err(1, "Unable to fstat: %s", s->filename); #ifdef DEBUG fprintf(stderr, "fstat():\t%d (st_size: %d)\n", s->fd, (int)s->fs.st_size); #endif if (READ_SIZE != 0) s->size = READ_SIZE; else s->size = s->fs.st_size; npages = s->size / psize; if ((s->size % psize) != 0) npages++; #ifdef DEBUG fprintf(stderr, "pages:\t\t%d\n", npages); #endif s->size = npages * psize; #ifdef DEBUG fprintf(stderr, "size:\t\t%d\n", (int)s->size); #endif #ifdef DO_MMAP s->addr = mmap(0, s->size, PROT_READ|PROT_WRITE, MAP_NOSYNC|MAP_SHARED, s->fd, 0); if (s->addr == MAP_FAILED) err(1, "Unable to mmap() file %s\n", s->filename); #ifdef DEBUG fprintf(stderr, "mmap():\t\t%d\n", s->fd); #endif ret = madvise(s->addr, s->size, MADV_SEQUENTIAL); if (ret < 0) err(1, "Unable to madvise() region %p\n", s->addr); #ifdef DEBUG fprintf(stderr, "madvise():\t%p\n", s->addr); #endif #endif return; } inline void close_fd(struct bs *s) { #ifdef DO_MMAP ret = munmap(s->addr, s->size); if (ret < 0) err(1, "Unable to munmap() file %p\n", s->addr); #ifdef DEBUG fprintf(stderr, "munmap():\t%p\n", s->addr); #endif #endif ret = close(s->fd); if (ret < 0) err(1, "Unable to close: %s\n", s->filename); #ifdef DEBUG fprintf(stderr, "close():\t%d\n", s->fd); #endif } inline int bench(struct bs *s) { ret = gettimeofday(&s->t_start, NULL); if (ret < 0) err(1, "Unable to get the time of day"); #ifndef DO_MMAP_ONCE setup_fd(s); #endif /* Do some tests */ #ifdef DO_MMAP write(STDOUT_FILENO, s->addr, s->size); #else s->addr = malloc(s->size); if (s->addr == NULL) err(1, "Unable to malloc %d bytes", s->size); do { ret = read(s->fd, s->addr, s->size); if (ret < 0) err(1, "Unable to read from fd %d", s->fd); wret = write(STDOUT_FILENO, s->addr, ret); } while (ret > 0); free(s->addr); #endif /* End tests */ #ifndef DO_MMAP_ONCE close_fd(s); #endif ret = gettimeofday(&s->t_final, NULL); if (ret < 0) err(1, "Unable to get the time of day"); return(0); } int main(int argc, char *argv[]) { int i, j, numfiles, numiterations; struct bs *s; numiterations = 100000; if (argc == 0) { fprintf(stderr, "Please specify one or more files as arguments\n"); exit(1); } numfiles = argc - 1; s = (struct bs *)malloc(sizeof(struct bs) * numfiles); if (s == NULL) err(1, "Unable to malloc enough data for benchmark struct array"); for (i = 0; i < numfiles; i++) { s[i].addr = NULL; s[i].size = -1; s[i].fd = -1; s[i].addr = NULL; s[i].filename = argv[i + 1]; } #ifdef DO_SHOW_FILENAMES fprintf(stderr, "Beginning tests with file(s):\t\t"); for (i = 0; i < numfiles; i++) fprintf(stderr, "%s, ", s[i].filename); fprintf(stderr, "\n"); #endif psize = getpagesize(); fprintf(stderr, "Page size:\t\t\t\t%d\n", psize); #ifndef DO_MMAP #ifdef DEFAULT_READSIZE if (READ_SIZE != 0) fprintf(stderr, "File read size is default read size:\t%d\n", READ_SIZE); else fprintf(stderr, "File read size is the same as the file size\n"); #else fprintf(stderr, "File read size is the same as the file size\n"); #endif #else fprintf(stderr, "File read size is the same as the file size\n"); #endif fprintf(stderr, "Number of iterations:\t\t\t%d\n", numiterations); ret = gettimeofday(&t_teststart, NULL); if (ret < 0) err(1, "Unable to get the time of day"); #ifdef DO_MMAP_ONCE for (i = 0; i < numfiles; i++) setup_fd(&s[i]); #endif /* some kind of benchmarking */ for (i = 0, j = 0; j < numiterations; i++, j++) { if (i == numfiles) i = 0; bench(&s[i]); #ifdef DEBUG fprintf(stderr, "Time:\t\t%lu.%lu\n", (s[i]->t_final.tv_sec - s[i]->t_start.tv_sec), (s[i]->t_final.tv_usec - s[i]->t_start.tv_usec)); #endif } #ifdef DO_MMAP_ONCE for (i = 0; i < numfiles; i++) close_fd(&s[i]); #endif ret = gettimeofday(&t_testfinal, NULL); if (ret < 0) err(1, "Unable to get the time of day"); fprintf(stderr, "Start time:\t\t\t\t%lu.%lu\n", t_teststart.tv_sec, t_teststart.tv_usec); fprintf(stderr, "Time:\t\t\t\t\t%lu.%lu\n", (t_testfinal.tv_sec - t_teststart.tv_sec), (t_testfinal.tv_usec - t_teststart.tv_usec)); fprintf(stderr, "\nCompleted tests\n"); return(0); }