/* * Copyright (c) International Business Machines Corp., 2001-2004 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "ffsb_op.h" #include "fileops.h" #include "metaops.h" ffsb_op_t ffsb_op_list[] = { {0, "read", ffsb_readfile, READ, fop_bench, NULL} , {1, "readall", ffsb_readall, READ, fop_bench, NULL} , {2, "write", ffsb_writefile, WRITE, fop_bench, NULL} , {3, "create", ffsb_createfile, WRITE, fop_bench, fop_age} , {4, "append", ffsb_appendfile, WRITE, fop_bench, fop_age} , {5, "delete", ffsb_deletefile, NA, fop_bench, fop_age} , {6, "metaop", ffsb_metaops, NA, metaops_metadir, NULL} , {7, "createdir", ffsb_createdir, NA, fop_bench, NULL} , {8, "stat", ffsb_stat, NA, fop_bench, NULL} , {9, "writeall", ffsb_writeall, WRITE, fop_bench, NULL} , {10, "writeall_fsync", ffsb_writeall_fsync, WRITE, fop_bench, NULL} , {11, "open_close", ffsb_open_close, NA, fop_bench, NULL} , {12, "write_fsync", ffsb_writefile_fsync, WRITE, fop_bench, NULL} , {13, "create_fsync", ffsb_createfile_fsync, WRITE, fop_bench, fop_age} , {14, "append_fsync", ffsb_appendfile_fsync, WRITE, fop_bench, fop_age} , }; void init_ffsb_op_results(ffsb_op_results_t * results) { memset(results, 0, sizeof(ffsb_op_results_t)); } static int exclusive_op(ffsb_op_results_t * results, unsigned int op_num) { int i; int ret = 0; for (i = 0; i < FFSB_NUMOPS; i++) { if (i == op_num) continue; ret += results->ops[i]; } if (ret) return 0; return 1; } static void generic_op_print(char *name, unsigned num, double op_pcnt, double weigth_pcnt, double runtime, char *tput) { printf("%20s : %12u\t%10.2lf\t%6.3lf%%\t\t%6.3lf%%\t %11s\n", name, num, num / runtime, op_pcnt, weigth_pcnt, tput); } static void print_op_results(unsigned int op_num, ffsb_op_results_t * results, double runtime, unsigned total_ops, unsigned total_weight) { char buf[256]; double op_pcnt = 100 * (double)results->ops[op_num] / (double)total_ops; double weight_pcnt = 100 * (double)results->op_weight[op_num] / (double)total_weight; if (ffsb_op_list[op_num].throughput) { ffsb_printsize(buf, results->bytes[op_num] / runtime, 256); sprintf(buf, "%s/sec\0", buf); } else sprintf(buf, "NA\0"); generic_op_print(ffsb_op_list[op_num].op_name, results->ops[op_num], op_pcnt, weight_pcnt, runtime, buf); } #if 0 static void print_op_throughput(unsigned int op_num, ffsb_op_results_t * results, double runtime) { if (ffsb_op_list[op_num].op_exl_print_fn != NULL) ffsb_op_list[op_num].op_exl_print_fn(results, runtime, op_num); } #endif void print_results(struct ffsb_op_results *results, double runtime) { int i; uint64_t total_ops = 0; uint64_t total_weight = 0; char buf[256]; for (i = 0; i < FFSB_NUMOPS; i++) { total_ops += results->ops[i]; total_weight += results->op_weight[i]; } printf (" Op Name Transactions\t Trans/sec\t% Trans\t % Op Weight\t Throughput\n"); printf (" ======= ============\t =========\t=======\t ===========\t ==========\n"); for (i = 0; i < FFSB_NUMOPS; i++) if (results->ops[i] != 0) print_op_results(i, results, runtime, total_ops, total_weight); printf("-\n%.2lf Transactions per Second\n\n", (double)total_ops / runtime); if (results->write_bytes || results->read_bytes) printf("Throughput Results\n===================\n"); if (results->read_bytes) { ffsb_printsize(buf, results->read_bytes / runtime, 256); printf("Read Throughput: %s/sec\n", buf); } if (results->write_bytes) { ffsb_printsize(buf, results->write_bytes / runtime, 256); printf("Write Throughput: %s/sec\n", buf); } } char *op_get_name(int opnum) { return ffsb_op_list[opnum].op_name; } void ops_setup_bench(ffsb_fs_t * fs) { int i; for (i = 0; i < FFSB_NUMOPS; i++) ffsb_op_list[i].op_bench(fs, i); } void ops_setup_age(ffsb_fs_t * fs) { int i; for (i = 0; i < FFSB_NUMOPS; i++) if (ffsb_op_list[i].op_age) ffsb_op_list[i].op_age(fs, i); } int ops_find_op(char *opname) { int i; for (i = 0; i < FFSB_NUMOPS; i++) if (!strcmp(opname, ffsb_op_list[i].op_name)) return i; return -1; } void add_results(struct ffsb_op_results *target, struct ffsb_op_results *src) { int i; target->read_bytes += src->read_bytes; target->write_bytes += src->write_bytes; for (i = 0; i < FFSB_NUMOPS; i++) { target->ops[i] += src->ops[i]; target->op_weight[i] += src->op_weight[i]; target->bytes[i] += src->bytes[i]; } } void do_op(struct ffsb_thread *ft, struct ffsb_fs *fs, unsigned op_num) { ffsb_op_list[op_num].op_fn(ft, fs, op_num); }