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>
28 #include <linux/param.h>
30 typedef void *(*fpi_t)(void);
31 typedef void (*fpt_t)(int, void *);
32 typedef void (*fpd_t)(void *);
41 static void d_readdir(void *);
42 static void *i_readdir(void);
43 static void t_readdir(int, void *);
44 static void crfiles(char **, int, char *);
45 static void d_chown(void *);
46 static void d_create(void *);
47 static void d_linkun(void *);
48 static void d_open(void *);
49 static void d_rename(void *);
50 static void d_stat(void *);
51 static void delflist(char **);
52 static void dotest(tdesc_t *);
53 static void *i_chown(void);
54 static void *i_create(void);
55 static void *i_linkun(void);
56 static void *i_open(void);
57 static void *i_rename(void);
58 static void *i_stat(void);
59 static char **mkflist(int, int, char);
60 static double now(void);
61 static void prtime(char *, int, double);
62 static void rmfiles(char **);
63 static void t_chown(int, void *);
64 static void t_create(int, void *);
65 static void t_crunlink(int, void *);
66 static void t_linkun(int, void *);
67 static void t_open(int, void *);
68 static void t_rename(int, void *);
69 static void t_stat(int, void *);
70 static void usage(void);
73 { "chown", i_chown, t_chown, d_chown },
74 { "create", i_create, t_create, d_create },
75 { "crunlink", (fpi_t)0, t_crunlink, (fpd_t)0 },
76 { "readdir", i_readdir, t_readdir, d_readdir },
77 { "linkun", i_linkun, t_linkun, d_linkun },
78 { "open", i_open, t_open, d_open },
79 { "rename", i_rename, t_rename, d_rename },
80 { "stat", i_stat, t_stat, d_stat },
100 main(int argc, char **argv)
106 testdir = getenv("TMPDIR");
109 while ((c = getopt(argc, argv, "cd:i:l:L:n:N:s:t:v")) != -1) {
118 iters = atoi(optarg);
121 fnlen_op = atoi(optarg);
124 fnlen_bg = atoi(optarg);
127 files_op = atoi(optarg);
130 files_bg = atoi(optarg);
133 fsize = atoi(optarg);
136 totsec = atoi(optarg);
142 fprintf(stderr, "bad option\n");
146 if (!iters && !totsec)
148 if (chdir(testdir) < 0) {
152 if (mkdir("metaperf", 0777) < 0 || chdir("metaperf") < 0) {
156 for (; optind < argc; optind++) {
157 for (tp = tests; tp->name; tp++) {
158 if (strcmp(argv[optind], tp->name) == 0) {
170 crfiles(char **flist, int fsize, char *buf)
175 for (fnp = flist; *fnp; fnp++) {
176 fd = creat(*fnp, 0666);
178 write(fd, buf, fsize);
223 delflist((char **)v);
234 delflist(char **flist)
238 for (fnp = flist; *fnp; fnp++)
251 flist_bg = mkflist(files_bg, fnlen_bg, 'b');
252 flist_op = mkflist(files_op, fnlen_op, 'o');
254 buffer = calloc(fsize, 1);
257 crfiles(flist_bg, 0, (char *)0);
258 n = iters ? iters : 1;
270 gotsec = time_end - time_start;
271 if (!totsec || gotsec >= 0.9 * totsec)
274 prtime(tp->name, n, gotsec);
276 gotsec = 1.0 / (2 * HZ);
277 if (gotsec < 0.001 * totsec)
278 dn = n * (0.01 * totsec / gotsec);
279 else if (gotsec < 0.01 * totsec)
280 dn = n * (0.1 * totsec / gotsec);
282 dn = n * (totsec / gotsec);
288 prtime(tp->name, n, gotsec);
301 crfiles(flist_op, 0, (char *)0);
302 for (fnp = flist_op; *fnp; fnp++)
310 crfiles(flist_op, fsize, buffer);
317 crfiles(flist_op, 0, (char *)0);
324 close(creat("a", 0666));
331 crfiles(flist_op, 0, (char *)0);
338 crfiles(flist_op, 0, (char *)0);
339 return (void *)mkflist(files_op, fnlen_op, 'r');
345 crfiles(flist_op, 0, (char *)0);
350 mkflist(int files, int fnlen, char start)
355 rval = calloc(files + 1, sizeof(char *));
356 for (i = 0; i < files; i++) {
357 rval[i] = malloc(fnlen + 1);
358 sprintf(rval[i], "%0*d%c", fnlen - 1, i, start);
368 gettimeofday(&t, (void *)0);
369 return (double)t.tv_sec + 1.0e-6 * (double)t.tv_usec;
373 prtime(char *name, int n, double t)
378 ops_per_sec = (double)n * (double)files_op / t;
379 usec_per_op = t * 1.0e6 / ((double)n * (double)files_op);
381 printf("%s %d %d %d %d %d %d %f %f %f\n",
382 name, n, files_op, fnlen_op, fsize, files_bg, fnlen_bg,
383 t, ops_per_sec, usec_per_op);
385 printf("%s: %d times, %d file(s) namelen %d",
386 name, n, files_op, fnlen_op);
388 printf(" size %d", fsize);
390 printf(", bg %d file(s) namelen %d",
392 printf(", time = %f sec, ops/sec=%f, usec/op = %f\n",
393 t, ops_per_sec, usec_per_op);
398 rmfiles(char **flist)
402 for (fnp = flist; *fnp; fnp++)
408 t_chown(int n, void *v)
413 for (i = 0; i < n; i++) {
414 for (fnp = flist_op; *fnp; fnp++) {
425 t_create(int n, void *v)
429 for (i = 0; i < n; i++)
430 crfiles(flist_op, fsize, buffer);
435 t_crunlink(int n, void *v)
439 for (i = 0; i < n; i++) {
440 crfiles(flist_op, fsize, buffer);
446 t_readdir(int n, void *v)
451 for (dir = (DIR *)v, i = 0; i < n; i++) {
453 while ((readdir(dir)) != NULL);
459 t_linkun(int n, void *v)
464 for (i = 0; i < n; i++) {
465 for (fnp = flist_op; *fnp; fnp++)
473 t_open(int n, void *v)
478 for (i = 0; i < n; i++) {
479 for (fnp = flist_op; *fnp; fnp++)
480 close(open(*fnp, O_RDWR));
485 t_rename(int n, void *v)
492 for (rflist = (char **)v, i = 0; i < n; i++) {
493 for (fnp = flist_op, rfp = rflist; *fnp; fnp++, rfp++) {
504 t_stat(int n, void *v)
510 for (i = 0; i < n; i++) {
511 for (fnp = flist_op; *fnp; fnp++)
520 "Usage: metaperf [-d dname] [-i iters|-t seconds] [-s fsize]\n"
521 "\t[-l opfnamelen] [-L bgfnamelen]\n"
522 "\t[-n opfcount] [-N bgfcount] test...\n");
524 "Tests: chown create crunlink linkun open rename stat readdir\n");