--- bonnie-1.orig/bonnie.c Tue Sep 3 00:59:11 1996 +++ bonnie/bonnie-o_direct.c Thu Apr 12 20:26:14 2001 @@ -95,6 +95,7 @@ #else #include #endif +#include #define IntSize (4) @@ -109,7 +110,11 @@ #define Seeks (4000) #define UpdateSeek (10) #define SeekProcCount (3) -#define Chunk (8192) +#define Chunk (1<<20) + +#if defined(__alpha__) || defined(__i386__) +#define O_DIRECT 040000 /* direct disk access - should check with OSF/1 */ +#endif static double cpu_so_far(); static void doseek(); @@ -146,7 +151,8 @@ int argc; char * argv[]; { - int buf[Chunk / IntSize]; + char __buf[Chunk+~PAGE_MASK]; + int *buf = (int *) ((unsigned long) (__buf + ~PAGE_MASK) & PAGE_MASK); int bufindex; int chars[256]; int child; @@ -164,24 +170,28 @@ int size; FILE * stream; int words; + int o_direct = 0, fast = 0; fd = -1; basetime = (int) time((time_t *) NULL); size = 100; dir = "."; - for (next = 1; next < argc - 1; next++) + for (next = 1; next < argc; next++) if (argv[next][0] == '-') { /* option? */ if (strcmp(argv[next] + 1, "d") == 0) - dir = argv[next + 1]; + dir = argv[next + 1], next++; else if (strcmp(argv[next] + 1, "s") == 0) - size = atoi(argv[next + 1]); + size = atoi(argv[next + 1]), next++; else if (strcmp(argv[next] + 1, "m") == 0) - machine = argv[next + 1]; + machine = argv[next + 1], next++; + else if (strcmp(argv[next] + 1, "o_direct") == 0) + o_direct = 1, printf("Using O_DIRECT for block based I/O\n"); + else if (strcmp(argv[next] + 1, "fast") == 0) + fast = 1, printf("Will skip the seek test\n"); else usage(); - next++; } /* option? */ else usage(); @@ -194,12 +204,13 @@ /* Fill up a file, writing it a char at a time with the stdio putc() call */ fprintf(stderr, "Writing with putc()..."); - newfile(name, &fd, &stream, 1); + newfile(name, &fd, &stream, 1, 0); timestamp(); for (words = 0; words < size; words++) if (putc(words & 0x7f, stream) == EOF) io_error("putc"); + fsync(fd); /* * note that we always close the file before measuring time, in an * effort to force as much of the I/O out as we can @@ -210,13 +221,13 @@ fprintf(stderr, "done\n"); /* Now read & rewrite it using block I/O. Dirty one word in each block */ - newfile(name, &fd, &stream, 0); + newfile(name, &fd, &stream, 0, o_direct); if (lseek(fd, (off_t) 0, 0) == (off_t) -1) io_error("lseek(2) before rewrite"); fprintf(stderr, "Rewriting..."); timestamp(); bufindex = 0; - if ((words = read(fd, (char *) buf, Chunk)) == -1) + if ((words = read(fd, buf, Chunk)) == -1) io_error("rewrite read"); while (words == Chunk) { /* while we can read a block */ @@ -230,13 +241,14 @@ if ((words = read(fd, (char *) buf, Chunk)) == -1) io_error("rwrite read"); } /* while we can read a block */ + fsync(fd); if (close(fd) == -1) io_error("close after rewrite"); get_delta_t(ReWrite); fprintf(stderr, "done\n"); /* Write the whole file from scratch, again, with block I/O */ - newfile(name, &fd, &stream, 1); + newfile(name, &fd, &stream, 1, o_direct); fprintf(stderr, "Writing intelligently..."); for (words = 0; words < Chunk / IntSize; words++) buf[words] = 0; @@ -249,13 +261,14 @@ if (write(fd, (char *) buf, Chunk) == -1) io_error("write(2)"); } /* for each word */ + fsync(fd); if (close(fd) == -1) io_error("close after fast write"); get_delta_t(FastWrite); fprintf(stderr, "done\n"); /* read them all back with getc() */ - newfile(name, &fd, &stream, 0); + newfile(name, &fd, &stream, 0, 0); for (words = 0; words < 256; words++) chars[words] = 0; fprintf(stderr, "Reading with getc()..."); @@ -278,7 +291,7 @@ sprintf((char *) buf, "%d", chars[words]); /* Now suck it in, Chunk at a time, as fast as we can */ - newfile(name, &fd, &stream, 0); + newfile(name, &fd, &stream, 0, o_direct); if (lseek(fd, (off_t) 0, 0) == -1) io_error("lseek before read"); fprintf(stderr, "Reading intelligently..."); @@ -295,6 +308,11 @@ get_delta_t(FastRead); fprintf(stderr, "done\n"); + if (fast) { + delta[Lseek][Elapsed] = 1; + delta[Lseek][CPU] = 0; + goto finish; + } /* use the frequency count */ for (words = 0; words < 256; words++) sprintf((char *) buf, "%d", chars[words]); @@ -334,8 +352,8 @@ /* set up and wait for the go-ahead */ close(seek_feedback[0]); close(seek_control[1]); - newfile(name, &fd, &stream, 0); - srandom(getpid()); + newfile(name, &fd, &stream, 0, 0); + srandom(next); /* must always generate the same sequence or you'll compare orange to apples */ fprintf(stderr, "Seeker %d...", next + 1); /* wait for the go-ahead */ @@ -411,6 +429,7 @@ fprintf(stderr, "\n"); delta[(int) Lseek][Elapsed] = last_stop - first_start; + finish: report(size); unlink(name); } @@ -448,20 +467,21 @@ } static void -newfile(name, fd, stream, create) +newfile(name, fd, stream, create, o_direct) char * name; int * fd; FILE * * stream; int create; + int o_direct; { if (create) { /* create from scratch */ if (unlink(name) == -1 && *fd != -1) io_error("unlink"); - *fd = open(name, O_RDWR | O_CREAT | O_EXCL, 0777); + *fd = open(name, O_RDWR | O_CREAT | O_EXCL | (o_direct ? O_DIRECT : 0), 0777); } /* create from scratch */ else - *fd = open(name, O_RDWR, 0777); + *fd = open(name, O_RDWR | (o_direct ? O_DIRECT : 0), 0777); if (*fd == -1) io_error(name); @@ -474,7 +494,7 @@ usage() { fprintf(stderr, - "usage: Bonnie [-d scratch-dir] [-s size-in-Mb] [-m machine-label]\n"); + "usage: Bonnie [-d scratch-dir] [-s size-in-Mb] [-m machine-label] [-o_direct]\n"); exit(1); } @@ -544,8 +564,7 @@ io_error(message) char * message; { - char buf[Chunk]; - + char buf[8192]; sprintf(buf, "Bonnie: drastic I/O error (%s)", message); perror(buf); exit(1);