1 /* 2 * Copyright (c) International Business Machines Corp., 2001-2004 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 12 * the GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 #include <string.h> 19 #include <stdlib.h> 20 #include <stdio.h> 21 22 #include "ffsb_op.h" 23 #include "fileops.h" 24 #include "metaops.h" 25 26 ffsb_op_t ffsb_op_list[] = { {0, "read", ffsb_readfile, READ, fop_bench, NULL} 27 , 28 {1, "readall", ffsb_readall, READ, fop_bench, NULL} 29 , 30 {2, "write", ffsb_writefile, WRITE, fop_bench, NULL} 31 , 32 {3, "create", ffsb_createfile, WRITE, fop_bench, fop_age} 33 , 34 {4, "append", ffsb_appendfile, WRITE, fop_bench, fop_age} 35 , 36 {5, "delete", ffsb_deletefile, NA, fop_bench, fop_age} 37 , 38 {6, "metaop", ffsb_metaops, NA, metaops_metadir, NULL} 39 , 40 {7, "createdir", ffsb_createdir, NA, fop_bench, NULL} 41 , 42 {8, "stat", ffsb_stat, NA, fop_bench, NULL} 43 , 44 {9, "writeall", ffsb_writeall, WRITE, fop_bench, NULL} 45 , 46 {10, "writeall_fsync", ffsb_writeall_fsync, WRITE, fop_bench, NULL} 47 , 48 {11, "open_close", ffsb_open_close, NA, fop_bench, NULL} 49 , 50 {12, "write_fsync", ffsb_writefile_fsync, WRITE, fop_bench, NULL} 51 , 52 {13, "create_fsync", ffsb_createfile_fsync, WRITE, fop_bench, fop_age} 53 , 54 {14, "append_fsync", ffsb_appendfile_fsync, WRITE, fop_bench, fop_age} 55 , 56 }; 57 58 void init_ffsb_op_results(ffsb_op_results_t * results) 59 { 60 memset(results, 0, sizeof(ffsb_op_results_t)); 61 } 62 63 static int exclusive_op(ffsb_op_results_t * results, unsigned int op_num) 64 { 65 int i; 66 int ret = 0; 67 for (i = 0; i < FFSB_NUMOPS; i++) { 68 if (i == op_num) 69 continue; 70 ret += results->ops[i]; 71 } 72 73 if (ret) 74 return 0; 75 return 1; 76 } 77 78 static void generic_op_print(char *name, unsigned num, double op_pcnt, 79 double weigth_pcnt, double runtime, char *tput) 80 { 81 printf("%20s : %12u\t%10.2lf\t%6.3lf%%\t\t%6.3lf%%\t %11s\n", 82 name, num, num / runtime, op_pcnt, weigth_pcnt, tput); 83 } 84 85 static void print_op_results(unsigned int op_num, ffsb_op_results_t * results, 86 double runtime, unsigned total_ops, 87 unsigned total_weight) 88 { 89 char buf[256]; 90 91 double op_pcnt = 100 * (double)results->ops[op_num] / (double)total_ops; 92 double weight_pcnt = 100 * (double)results->op_weight[op_num] / 93 (double)total_weight; 94 if (ffsb_op_list[op_num].throughput) { 95 ffsb_printsize(buf, results->bytes[op_num] / runtime, 256); 96 sprintf(buf, "%s/sec\0", buf); 97 } else 98 sprintf(buf, "NA\0"); 99 generic_op_print(ffsb_op_list[op_num].op_name, results->ops[op_num], 100 op_pcnt, weight_pcnt, runtime, buf); 101 } 102 103 #if 0 104 static void print_op_throughput(unsigned int op_num, 105 ffsb_op_results_t * results, double runtime) 106 { 107 if (ffsb_op_list[op_num].op_exl_print_fn != NULL) 108 ffsb_op_list[op_num].op_exl_print_fn(results, runtime, op_num); 109 } 110 #endif 111 112 void print_results(struct ffsb_op_results *results, double runtime) 113 { 114 int i; 115 uint64_t total_ops = 0; 116 uint64_t total_weight = 0; 117 char buf[256]; 118 119 for (i = 0; i < FFSB_NUMOPS; i++) { 120 total_ops += results->ops[i]; 121 total_weight += results->op_weight[i]; 122 } 123 124 printf 125 (" Op Name Transactions\t Trans/sec\t% Trans\t % Op Weight\t Throughput\n"); 126 printf 127 (" ======= ============\t =========\t=======\t ===========\t ==========\n"); 128 for (i = 0; i < FFSB_NUMOPS; i++) 129 if (results->ops[i] != 0) 130 print_op_results(i, results, runtime, total_ops, 131 total_weight); 132 printf("-\n%.2lf Transactions per Second\n\n", 133 (double)total_ops / runtime); 134 135 if (results->write_bytes || results->read_bytes) 136 printf("Throughput Results\n===================\n"); 137 if (results->read_bytes) { 138 ffsb_printsize(buf, results->read_bytes / runtime, 256); 139 printf("Read Throughput: %s/sec\n", buf); 140 } 141 if (results->write_bytes) { 142 ffsb_printsize(buf, results->write_bytes / runtime, 256); 143 printf("Write Throughput: %s/sec\n", buf); 144 } 145 } 146 147 char *op_get_name(int opnum) 148 { 149 return ffsb_op_list[opnum].op_name; 150 } 151 152 void ops_setup_bench(ffsb_fs_t * fs) 153 { 154 int i; 155 for (i = 0; i < FFSB_NUMOPS; i++) 156 ffsb_op_list[i].op_bench(fs, i); 157 } 158 159 void ops_setup_age(ffsb_fs_t * fs) 160 { 161 int i; 162 for (i = 0; i < FFSB_NUMOPS; i++) 163 if (ffsb_op_list[i].op_age) 164 ffsb_op_list[i].op_age(fs, i); 165 } 166 167 int ops_find_op(char *opname) 168 { 169 int i; 170 for (i = 0; i < FFSB_NUMOPS; i++) 171 if (!strcmp(opname, ffsb_op_list[i].op_name)) 172 return i; 173 return -1; 174 } 175 176 void add_results(struct ffsb_op_results *target, struct ffsb_op_results *src) 177 { 178 int i; 179 target->read_bytes += src->read_bytes; 180 target->write_bytes += src->write_bytes; 181 182 for (i = 0; i < FFSB_NUMOPS; i++) { 183 target->ops[i] += src->ops[i]; 184 target->op_weight[i] += src->op_weight[i]; 185 target->bytes[i] += src->bytes[i]; 186 } 187 } 188 189 void do_op(struct ffsb_thread *ft, struct ffsb_fs *fs, unsigned op_num) 190 { 191 ffsb_op_list[op_num].op_fn(ft, fs, op_num); 192 } 193