diff --git a/src/tests/system/libroot/posix/bonnie/Bonnie.c b/src/tests/system/libroot/posix/bonnie/Bonnie.c deleted file mode 100644 index 0f876d2a6b..0000000000 --- a/src/tests/system/libroot/posix/bonnie/Bonnie.c +++ /dev/null @@ -1,593 +0,0 @@ -/* - * This is a file system benchmark which attempts to study bottlenecks - - * it is named 'Bonnie' after Bonnie Raitt, who knows how to use one. - * - * Commentary on Bonnie's operations may be found at - * http://www.textuality.com/bonnie/intro.html - * - * COPYRIGHT NOTICE: - * Copyright (c) Tim Bray, 1990-1996. - * - * Everybody is hereby granted rights to use, copy, and modify this program, - * provided only that this copyright notice and the disclaimer below - * are preserved without change. - * DISCLAIMER: - * This program is provided AS IS with no warranty of any kind, and - * The author makes no representation with respect to the adequacy of this - * program for any particular purpose or with respect to its adequacy to - * produce any particular result, and - * The author shall not be liable for loss or damage arising out of - * the use of this program regardless of how sustained, and - * In no event shall the author be liable for special, direct, indirect - * or consequential damage, loss, costs or fees or expenses of any - * nature or kind. - */ - -#include -#include -#include -#include -#include -#include -#if defined(SysV) -#include -#include -#else -#include -#endif - -#define IntSize (sizeof(int)) - -/* - * N.B. in seeker_reports, CPU appears and Start/End time, but not Elapsed, - * so position 1 is re-used; icky data coupling. - */ -#define CPU (0) -#define Elapsed (1) -#define StartTime (1) -#define EndTime (2) -#define Seeks (4000) -#define UpdateSeek (10) -#define SeekProcCount (3) -#define Chunk (16384) - -/* labels for the tests, used as an array index */ -typedef enum -{ - Putc, ReWrite, FastWrite, Getc, FastRead, Lseek, TestCount -} tests_t; - -static double cpu_so_far(); -static void doseek(off_t where, int fd, int update); -static void get_delta_t(tests_t test); -static void io_error(char * message); -static void newfile(char * name, int * fd, FILE * * stream, int create); - -#if defined(SysV) -/* System V wrappers for randomizers */ -static long random(); -static void srandom(int seed); -#endif - -static void report(char * machine, off_t size); -static void write_html(char * machine, off_t size); -static double time_so_far(); -static void timestamp(); -static void usage(); - -/* - * Housekeeping variables to build up timestamps for the tests; - * global to make it easy to keep track of the progress of time. - * all of this could have been done with non-global variables, - * but the code is easier to read this way and I don't anticipate - * much software engineering down the road - */ -static int basetime; /* when we started */ -static double delta[(int) TestCount][2]; /* array of DeltaT values */ -static double last_cpustamp = 0.0; /* for computing delta-t */ -static double last_timestamp = 0.0; /* for computing delta-t */ - -main( - int argc, - char * argv[]) -{ - int buf[Chunk / IntSize]; - int bufindex; - int chars[256]; - int child; - char * dir; - int html = 0; - int fd; - double first_start; - double last_stop; - int lseek_count = 0; - char * machine; - char name[Chunk]; - int next; - int seek_control[2]; - int seek_feedback[2]; - char seek_tickets[Seeks + SeekProcCount]; - double seeker_report[3]; - off_t size; - FILE * stream; - off_t words; - - fd = -1; - basetime = (int) time((time_t *) NULL); - size = 100; - dir = "."; - machine = ""; - - /* pick apart args */ - for (next = 1; next < argc; next++) - if (strcmp(argv[next], "-d") == 0) - dir = argv[++next]; - else if (strcmp(argv[next], "-s") == 0) - size = atol(argv[++next]); - else if (strcmp(argv[next], "-m") == 0) - machine = argv[++next]; - else if (strcmp(argv[next], "-html") == 0) - html = 1; - else - usage(); - - if (size < 1) - usage(); - - /* sanity check - 32-bit machines can't handle more than 2047 Mb */ - if (sizeof(off_t) <= 4 && size > 2047) - { - fprintf(stderr, "File too large for 32-bit machine, sorry\n"); - exit(1); - } - - sprintf(name, "%s/Bonnie.%d", dir, getpid()); - - /* size is in meg, rounded down to multiple of Chunk */ - size *= (1024 * 1024); - size = Chunk * (size / Chunk); - fprintf(stderr, "File '%s', size: %ld\n", name, size); - - /* 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); - timestamp(); - for (words = 0; words < size; words++) - if (putc(words & 0x7f, stream) == EOF) - io_error("putc"); - - /* - * 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 - */ - if (fclose(stream) == -1) - io_error("fclose after putc"); - get_delta_t(Putc); - fprintf(stderr, "done\n"); - - /* Now read & rewrite it using block I/O. Dirty one word in each block */ - newfile(name, &fd, &stream, 0); - 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) - io_error("rewrite read"); - while (words == Chunk) - { /* while we can read a block */ - if (bufindex == Chunk / IntSize) - bufindex = 0; - buf[bufindex++]++; - if (lseek(fd, (off_t) -words, 1) == -1) - io_error("relative lseek(2)"); - if (write(fd, (char *) buf, words) == -1) - io_error("re write(2)"); - if ((words = read(fd, (char *) buf, Chunk)) == -1) - io_error("rwrite read"); - } /* while we can read a block */ - 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); - fprintf(stderr, "Writing intelligently..."); - for (words = 0; words < Chunk / IntSize; words++) - buf[words] = 0; - timestamp(); - for (words = bufindex = 0; words < (size / Chunk); words++) - { /* for each word */ - if (bufindex == (Chunk / IntSize)) - bufindex = 0; - buf[bufindex++]++; - if (write(fd, (char *) buf, Chunk) == -1) - io_error("write(2)"); - } /* for each word */ - 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); - for (words = 0; words < 256; words++) - chars[words] = 0; - fprintf(stderr, "Reading with getc()..."); - timestamp(); - for (words = 0; words < size; words++) - { /* for each byte */ - if ((next = getc(stream)) == EOF) - io_error("getc(3)"); - - /* just to fool optimizers */ - chars[next]++; - } /* for each byte */ - if (fclose(stream) == -1) - io_error("fclose after getc"); - get_delta_t(Getc); - fprintf(stderr, "done\n"); - - /* use the frequency count */ - for (words = 0; words < 256; words++) - sprintf((char *) buf, "%d", chars[words]); - - /* Now suck it in, Chunk at a time, as fast as we can */ - newfile(name, &fd, &stream, 0); - if (lseek(fd, (off_t) 0, 0) == -1) - io_error("lseek before read"); - fprintf(stderr, "Reading intelligently..."); - timestamp(); - do - { /* per block */ - if ((words = read(fd, (char *) buf, Chunk)) == -1) - io_error("read(2)"); - chars[buf[abs(buf[0]) % (Chunk / IntSize)] & 0x7f]++; - } /* per block */ - while (words); - if (close(fd) == -1) - io_error("close after read"); - get_delta_t(FastRead); - fprintf(stderr, "done\n"); - - /* use the frequency count */ - for (words = 0; words < 256; words++) - sprintf((char *) buf, "%d", chars[words]); - - /* - * Now test random seeks; first, set up for communicating with children. - * The object of the game is to do "Seeks" lseek() calls as quickly - * as possible. So we'll farm them out among SeekProcCount processes. - * We'll control them by writing 1-byte tickets down a pipe which - * the children all read. We write "Seeks" bytes with val 1, whichever - * child happens to get them does it and the right number of seeks get - * done. - * The idea is that since the write() of the tickets is probably - * atomic, the parent process likely won't get scheduled while the - * children are seeking away. If you draw a picture of the likely - * timelines for three children, it seems likely that the seeks will - * overlap very nicely with the process scheduling with the effect - * that there will *always* be a seek() outstanding on the file. - * Question: should the file be opened *before* the fork, so that - * all the children are lseeking on the same underlying file object? - */ - if (pipe(seek_feedback) == -1 || pipe(seek_control) == -1) - io_error("pipe"); - for (next = 0; next < Seeks; next++) - seek_tickets[next] = 1; - for ( ; next < (Seeks + SeekProcCount); next++) - seek_tickets[next] = 0; - - /* launch some parallel seek processes */ - for (next = 0; next < SeekProcCount; next++) - { /* for each seek proc */ - if ((child = fork()) == -1) - io_error("fork"); - else if (child == 0) - { /* child process */ - - /* set up and wait for the go-ahead */ - close(seek_feedback[0]); - close(seek_control[1]); - newfile(name, &fd, &stream, 0); - srandom(getpid()); - fprintf(stderr, "Seeker %d...", next + 1); - - /* wait for the go-ahead */ - if (read(seek_control[0], seek_tickets, 1) != 1) - io_error("read ticket"); - timestamp(); - seeker_report[StartTime] = time_so_far(); - - /* loop until we read a 0 ticket back from our parent */ - while(seek_tickets[0]) - { /* until Mom says stop */ - doseek((long) (random() % (size / Chunk)), fd, - ((lseek_count++ % UpdateSeek) == 0)); - if (read(seek_control[0], seek_tickets, 1) != 1) - io_error("read ticket"); - } /* until Mom says stop */ - if (close(fd) == -1) - io_error("close after seek"); - - /* report to parent */ - get_delta_t(Lseek); - seeker_report[EndTime] = time_so_far(); - seeker_report[CPU] = delta[(int) Lseek][CPU]; - if (write(seek_feedback[1], seeker_report, sizeof(seeker_report)) - != sizeof(seeker_report)) - io_error("pipe write"); - exit(0); - } /* child process */ - } /* for each seek proc */ - - /* - * Back in the parent; in an effort to ensure the children get an even - * start, wait a few seconds for them to get scheduled, open their - * files & so on. - */ - close(seek_feedback[1]); - close(seek_control[0]); - sleep(5); - fprintf(stderr, "start 'em..."); - if (write(seek_control[1], seek_tickets, sizeof(seek_tickets)) - != sizeof(seek_tickets)) - io_error("write tickets"); - - /* read back from children */ - for (next = 0; next < SeekProcCount; next++) - { /* for each child */ - if (read(seek_feedback[0], (char *) seeker_report, sizeof(seeker_report)) - != sizeof(seeker_report)) - io_error("pipe read"); - - /* - * each child writes back its CPU, start & end times. The elapsed time - * to do all the seeks is the time the first child started until the - * time the last child stopped - */ - delta[(int) Lseek][CPU] += seeker_report[CPU]; - if (next == 0) - { /* first time */ - first_start = seeker_report[StartTime]; - last_stop = seeker_report[EndTime]; - } /* first time */ - else - { /* not first time */ - first_start = (first_start < seeker_report[StartTime]) ? - first_start : seeker_report[StartTime]; - last_stop = (last_stop > seeker_report[EndTime]) ? - last_stop : seeker_report[EndTime]; - } /* not first time */ - if (wait(&child) == -1) - io_error("wait"); - fprintf(stderr, "done..."); - } /* for each child */ - fprintf(stderr, "\n"); - delta[(int) Lseek][Elapsed] = last_stop - first_start; - - if (html) - write_html(machine, size); - else - report(machine, size); - unlink(name); -} - -static void -write_html( - char * machine, - off_t size) -{ - - printf("%s%d", machine, size / (1024 * 1024)); - printf("%d%4.1f%d%4.1f%d%4.1f", - (int) (((double) size) / (delta[(int) Putc][Elapsed] * 1024.0)), - delta[(int) Putc][CPU] / delta[(int) Putc][Elapsed] * 100.0, - (int) (((double) size) / (delta[(int) FastWrite][Elapsed] * 1024.0)), - delta[(int) FastWrite][CPU] / delta[(int) FastWrite][Elapsed] * 100.0, - (int) (((double) size) / (delta[(int) ReWrite][Elapsed] * 1024.0)), - delta[(int) ReWrite][CPU] / delta[(int) ReWrite][Elapsed] * 100.0); - printf("%d%4.1f%d%4.1f", - (int) (((double) size) / (delta[(int) Getc][Elapsed] * 1024.0)), - delta[(int) Getc][CPU] / delta[(int) Getc][Elapsed] * 100.0, - (int) (((double) size) / (delta[(int) FastRead][Elapsed] * 1024.0)), - delta[(int) FastRead][CPU] / delta[(int) FastRead][Elapsed] * 100.0); - printf("%5.1f%4.1f\n", - ((double) Seeks) / delta[(int) Lseek][Elapsed], - delta[(int) Lseek][CPU] / delta[(int) Lseek][Elapsed] * 100.0); -} - -static void -report( - char * machine, - off_t size) -{ - printf(" "); - printf( - "-------Sequential Output-------- ---Sequential Input-- --Random--\n"); - printf(" "); - printf( - "-Per Char- --Block--- -Rewrite-- -Per Char- --Block--- --Seeks---\n"); - printf("Machine MB "); - printf("K/sec %%CPU K/sec %%CPU K/sec %%CPU K/sec %%CPU K/sec "); - printf("%%CPU /sec %%CPU\n"); - - printf("%-8.8s %4d ", machine, size / (1024 * 1024)); - printf("%5d %4.1f %5d %4.1f %5d %4.1f ", - (int) (((double) size) / (delta[(int) Putc][Elapsed] * 1024.0)), - delta[(int) Putc][CPU] / delta[(int) Putc][Elapsed] * 100.0, - (int) (((double) size) / (delta[(int) FastWrite][Elapsed] * 1024.0)), - delta[(int) FastWrite][CPU] / delta[(int) FastWrite][Elapsed] * 100.0, - (int) (((double) size) / (delta[(int) ReWrite][Elapsed] * 1024.0)), - delta[(int) ReWrite][CPU] / delta[(int) ReWrite][Elapsed] * 100.0); - printf("%5d %4.1f %5d %4.1f ", - (int) (((double) size) / (delta[(int) Getc][Elapsed] * 1024.0)), - delta[(int) Getc][CPU] / delta[(int) Getc][Elapsed] * 100.0, - (int) (((double) size) / (delta[(int) FastRead][Elapsed] * 1024.0)), - delta[(int) FastRead][CPU] / delta[(int) FastRead][Elapsed] * 100.0); - printf("%5.1f %4.1f\n", - ((double) Seeks) / delta[(int) Lseek][Elapsed], - delta[(int) Lseek][CPU] / delta[(int) Lseek][Elapsed] * 100.0); -} - -static void -newfile( - char * name, - int * fd, - FILE * * stream, - int create) -{ - if (create) - { /* create from scratch */ - if (unlink(name) == -1 && *fd != -1) - io_error("unlink"); - *fd = open(name, O_RDWR | O_CREAT | O_EXCL, 0777); - } /* create from scratch */ - else - *fd = open(name, O_RDWR, 0777); - - if (*fd == -1) - io_error(name); - *stream = fdopen(*fd, "r+"); - if (*stream == NULL) - io_error("fdopen"); -} - -static void -usage() -{ - fprintf(stderr, - "usage: Bonnie [-d scratch-dir] [-s size-in-Mb] [-html] [-m machine-label]\n"); - exit(1); -} - -static void -timestamp() -{ - last_timestamp = time_so_far(); - last_cpustamp = cpu_so_far(); -} - -static void -get_delta_t(test) - tests_t test; -{ - int which = (int) test; - - delta[which][Elapsed] = time_so_far() - last_timestamp; - delta[which][CPU] = cpu_so_far() - last_cpustamp; -} - -static double -cpu_so_far() -{ -#if defined(SysV) - struct tms tms; - - if (times(&tms) == -1) - io_error("times"); - return ((double) tms.tms_utime) / ((double) sysconf(_SC_CLK_TCK)) + - ((double) tms.tms_stime) / ((double) sysconf(_SC_CLK_TCK)); - -#else - struct rusage rusage; - - getrusage(RUSAGE_SELF, &rusage); - return - ((double) rusage.ru_utime.tv_sec) + - (((double) rusage.ru_utime.tv_usec) / 1000000.0) + - ((double) rusage.ru_stime.tv_sec) + - (((double) rusage.ru_stime.tv_usec) / 1000000.0); -#endif -} - -static double -time_so_far() -{ -#if defined(SysV) - int val; - struct tms tms; - - if ((val = times(&tms)) == -1) - io_error("times"); - - return ((double) val) / ((double) sysconf(_SC_CLK_TCK)); - -#else - struct timeval tp; - - if (gettimeofday(&tp, (struct timezone *) NULL) == -1) - io_error("gettimeofday"); - return ((double) (tp.tv_sec - basetime)) + - (((double) tp.tv_usec) / 1000000.0); -#endif -} - -static void -io_error(char * message) -{ - char buf[Chunk]; - - sprintf(buf, "Bonnie: drastic I/O error (%s)", message); - perror(buf); - exit(1); -} - -/* - * Do a typical-of-something random I/O. Any serious application that - * has a random I/O bottleneck is going to be smart enough to operate - * in a page mode, and not stupidly pull individual words out at - * odd offsets. - * The 'where' argument is used as a chunk number - * To keep the cache from getting too clever, some pages must be updated. - * However an application that updated each of many random pages that - * it looked at is hard to imagine. - * However, it would be wrong to put the update percentage in as a - * parameter - the effect is too nonlinear. - */ -static void -doseek( - off_t where, - int fd, - int update) -{ - int buf[Chunk / IntSize]; - off_t probe; - off_t size; - - probe = where * Chunk; - if (lseek(fd, probe, 0) != probe) - io_error("lseek in doseek"); - if ((size = read(fd, (char *) buf, Chunk)) == -1) - io_error("read in doseek"); - - /* every so often, update a block */ - if (update) - { /* update this block */ - - /* touch a word */ - buf[((int) random() % (size/IntSize - 2)) + 1]--; - if (lseek(fd, (long) probe, 0) != probe) - io_error("lseek in doseek update"); - if (write(fd, (char *) buf, size) == -1) - io_error("write in doseek"); - } /* update this block */ -} - -#if defined(SysV) -static char randseed[32]; - -static void -srandom(int seed) -{ - sprintf(randseed, "%06d", seed); -} - -static long -random() -{ - return nrand48(randseed); -} -#endif - diff --git a/src/tests/system/libroot/posix/bonnie/Jamfile b/src/tests/system/libroot/posix/bonnie/Jamfile deleted file mode 100644 index e7310aa0b8..0000000000 --- a/src/tests/system/libroot/posix/bonnie/Jamfile +++ /dev/null @@ -1,6 +0,0 @@ -SubDir HAIKU_TOP src tests system libroot posix bonnie ; - -SimpleTest bonnie : - Bonnie.c -; - diff --git a/src/tests/system/libroot/posix/bonnie/bonnie.1 b/src/tests/system/libroot/posix/bonnie/bonnie.1 deleted file mode 100644 index 9a6b98637a..0000000000 --- a/src/tests/system/libroot/posix/bonnie/bonnie.1 +++ /dev/null @@ -1,92 +0,0 @@ -.\"------- -.\" Man page portability notes -.\" -.\" These are some notes on conventions to maintain for greatest -.\" portability of this man page to various other versions of -.\" nroff. -.\" -.\" When you want a \ to appear in the output, use \e in the man page. -.\" (NOTE this comes up in the rc grammar, where to print out '\n' the -.\" man page must contain '\en'.) -.\" -.\" Evidently not all versions of nroff allow the omission of the -.\" terminal " on a macro argument. Thus what could be written -.\" -.\" .Cr "exec >[2] err.out -.\" -.\" in true nroffs must be written -.\" -.\" .Cr "exec >[2] err.out" -.\" -.\" instead. -.\" -.\" Use symbolic font names (e.g. R, I, B) instead of the standard -.\" font positions 1, 2, 3. Note that for Xf to work the standard -.\" font names must be single characters. -.\" -.\" Note that sentences should end at the end of a line. nroff and -.\" troff will supply the correct intersentence spacing, but only if -.\" the sentences end at the end of a line. Explicit spaces, if given, -.\" are apparently honored and the normal intersentence spacing is -.\" supressed. -.\" -.\" DaviD W. Sanderson -.\"------- -.\" Dd distance to space vertically before a "display" -.\" These are what n/troff use for interparagraph distance -.\"------- -.if t .nr Dd .4v -.if n .nr Dd 1v -.\"------- -.\" Sp space down the interparagraph distance -.\"------- -.de Sp -.sp \\n(Ddu -.. -.\"------- -.\" Ds begin a display, indented .5 inches from the surrounding text. -.\" -.\" Note that uses of Ds and De may NOT be nested. -.\"------- -.de Ds -.Sp -.in +0.5i -.nf -.. -.\"------- -.\" De end a display (no trailing vertical spacing) -.\"------- -.de De -.fi -.in -.. -.TH Bonnie 1 "2.0.6" Textuality -.SH NAME -Bonnie - File system benchmark -.SH "SYNOPSIS" -.B Bonnie -.RI "[-d\ scratch-dir]" -.RI "[-html]" -.RI "[-m\ machine-label]" -.RI "[-s\ size-in-Mb]" -.SH "OPTIONS" -.PP - -d scratch-dir : Write scratch file in named directory (default: ".") - -html : Generate HTML output - -m machine-label : use to label report - -s size-in-Mb : how many Mb to use for testing (default: 100) -.\"------- -.SH "DESCRIPTION" -.\"------- -.I Bonnie -measures the performance of UNIX filesystem operations. -For details, see http://www.textuality.com/bonnie/ -.\"------- -.SH "AUTHOR" -.\"------- -.I Bonnie -was written by Tim Bray, -(tbray@textuality.com), -.I Bonnie -is copyrighted 1990-1996 by Tim Bray. -For details, see http://www.textuality.com/bonnie/copyright.html