2 * Copyright (c) 2000-2003 Silicon Graphics, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 #include <sys/param.h>
29 typedef void *(*fpi_t)(void);
30 typedef void (*fpt_t)(int, void *);
31 typedef void (*fpd_t)(void *);
40 static void d_readdir(void *);
41 static void *i_readdir(void);
42 static void t_readdir(int, void *);
43 static void crfiles(char **, int, char *);
44 static void d_chown(void *);
45 static void d_create(void *);
46 static void d_linkun(void *);
47 static void d_open(void *);
48 static void d_rename(void *);
49 static void d_stat(void *);
50 static void delflist(char **);
51 static void dotest(tdesc_t *);
52 static void *i_chown(void);
53 static void *i_create(void);
54 static void *i_linkun(void);
55 static void *i_open(void);
56 static void *i_rename(void);
57 static void *i_stat(void);
58 static char **mkflist(int, int, char);
59 static double now(void);
60 static void prtime(char *, int, double);
61 static void rmfiles(char **);
62 static void t_chown(int, void *);
63 static void t_create(int, void *);
64 static void t_crunlink(int, void *);
65 static void t_linkun(int, void *);
66 static void t_open(int, void *);
67 static void t_rename(int, void *);
68 static void t_stat(int, void *);
69 static void usage(void);
72 { "chown", i_chown, t_chown, d_chown },
73 { "create", i_create, t_create, d_create },
74 { "crunlink", (fpi_t)0, t_crunlink, (fpd_t)0 },
75 { "readdir", i_readdir, t_readdir, d_readdir },
76 { "linkun", i_linkun, t_linkun, d_linkun },
77 { "open", i_open, t_open, d_open },
78 { "rename", i_rename, t_rename, d_rename },
79 { "stat", i_stat, t_stat, d_stat },
99 main(int argc, char **argv)
105 testdir = getenv("TMPDIR");
108 while ((c = getopt(argc, argv, "cd:i:l:L:n:N:s:t:v")) != -1) {
117 iters = atoi(optarg);
120 fnlen_op = atoi(optarg);
123 fnlen_bg = atoi(optarg);
126 files_op = atoi(optarg);
129 files_bg = atoi(optarg);
132 fsize = atoi(optarg);
135 totsec = atoi(optarg);
141 fprintf(stderr, "bad option\n");
145 if (!iters && !totsec)
147 if (chdir(testdir) < 0) {
151 if (mkdir("metaperf", 0777) < 0 || chdir("metaperf") < 0) {
155 for (; optind < argc; optind++) {
156 for (tp = tests; tp->name; tp++) {
157 if (strcmp(argv[optind], tp->name) == 0) {
169 crfiles(char **flist, int fsize, char *buf)
174 for (fnp = flist; *fnp; fnp++) {
175 fd = creat(*fnp, 0666);
177 write(fd, buf, fsize);
222 delflist((char **)v);
233 delflist(char **flist)
237 for (fnp = flist; *fnp; fnp++)
250 flist_bg = mkflist(files_bg, fnlen_bg, 'b');
251 flist_op = mkflist(files_op, fnlen_op, 'o');
253 buffer = calloc(fsize, 1);
256 crfiles(flist_bg, 0, (char *)0);
257 n = iters ? iters : 1;
269 gotsec = time_end - time_start;
270 if (!totsec || gotsec >= 0.9 * totsec)
273 prtime(tp->name, n, gotsec);
275 gotsec = 1.0 / (2 * HZ);
276 if (gotsec < 0.001 * totsec)
277 dn = n * (0.01 * totsec / gotsec);
278 else if (gotsec < 0.01 * totsec)
279 dn = n * (0.1 * totsec / gotsec);
281 dn = n * (totsec / gotsec);
287 prtime(tp->name, n, gotsec);
300 crfiles(flist_op, 0, (char *)0);
301 for (fnp = flist_op; *fnp; fnp++)
309 crfiles(flist_op, fsize, buffer);
316 crfiles(flist_op, 0, (char *)0);
323 close(creat("a", 0666));
330 crfiles(flist_op, 0, (char *)0);
337 crfiles(flist_op, 0, (char *)0);
338 return (void *)mkflist(files_op, fnlen_op, 'r');
344 crfiles(flist_op, 0, (char *)0);
349 mkflist(int files, int fnlen, char start)
354 rval = calloc(files + 1, sizeof(char *));
355 for (i = 0; i < files; i++) {
356 rval[i] = malloc(fnlen + 1);
357 sprintf(rval[i], "%0*d%c", fnlen - 1, i, start);
367 gettimeofday(&t, (void *)0);
368 return (double)t.tv_sec + 1.0e-6 * (double)t.tv_usec;
372 prtime(char *name, int n, double t)
377 ops_per_sec = (double)n * (double)files_op / t;
378 usec_per_op = t * 1.0e6 / ((double)n * (double)files_op);
380 printf("%s %d %d %d %d %d %d %f %f %f\n",
381 name, n, files_op, fnlen_op, fsize, files_bg, fnlen_bg,
382 t, ops_per_sec, usec_per_op);
384 printf("%s: %d times, %d file(s) namelen %d",
385 name, n, files_op, fnlen_op);
387 printf(" size %d", fsize);
389 printf(", bg %d file(s) namelen %d",
391 printf(", time = %f sec, ops/sec=%f, usec/op = %f\n",
392 t, ops_per_sec, usec_per_op);
397 rmfiles(char **flist)
401 for (fnp = flist; *fnp; fnp++)
407 t_chown(int n, void *v)
412 for (i = 0; i < n; i++) {
413 for (fnp = flist_op; *fnp; fnp++) {
424 t_create(int n, void *v)
428 for (i = 0; i < n; i++)
429 crfiles(flist_op, fsize, buffer);
434 t_crunlink(int n, void *v)
438 for (i = 0; i < n; i++) {
439 crfiles(flist_op, fsize, buffer);
445 t_readdir(int n, void *v)
450 for (dir = (DIR *)v, i = 0; i < n; i++) {
452 while ((readdir(dir)) != NULL);
458 t_linkun(int n, void *v)
463 for (i = 0; i < n; i++) {
464 for (fnp = flist_op; *fnp; fnp++)
472 t_open(int n, void *v)
477 for (i = 0; i < n; i++) {
478 for (fnp = flist_op; *fnp; fnp++)
479 close(open(*fnp, O_RDWR));
484 t_rename(int n, void *v)
491 for (rflist = (char **)v, i = 0; i < n; i++) {
492 for (fnp = flist_op, rfp = rflist; *fnp; fnp++, rfp++) {
503 t_stat(int n, void *v)
509 for (i = 0; i < n; i++) {
510 for (fnp = flist_op; *fnp; fnp++)
519 "Usage: metaperf [-d dname] [-i iters|-t seconds] [-s fsize]\n"
520 "\t[-l opfnamelen] [-L bgfnamelen]\n"
521 "\t[-n opfcount] [-N bgfcount] test...\n");
523 "Tests: chown create crunlink linkun open rename stat readdir\n");