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
init_ffsb_op_results(ffsb_op_results_t * results)58 void init_ffsb_op_results(ffsb_op_results_t * results)
59 {
60 memset(results, 0, sizeof(ffsb_op_results_t));
61 }
62
exclusive_op(ffsb_op_results_t * results,unsigned int op_num)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
generic_op_print(char * name,unsigned num,double op_pcnt,double weigth_pcnt,double runtime,char * tput)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
print_op_results(unsigned int op_num,ffsb_op_results_t * results,double runtime,unsigned total_ops,unsigned total_weight)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
print_results(struct ffsb_op_results * results,double runtime)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
op_get_name(int opnum)147 char *op_get_name(int opnum)
148 {
149 return ffsb_op_list[opnum].op_name;
150 }
151
ops_setup_bench(ffsb_fs_t * fs)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
ops_setup_age(ffsb_fs_t * fs)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
ops_find_op(char * opname)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
add_results(struct ffsb_op_results * target,struct ffsb_op_results * src)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
do_op(struct ffsb_thread * ft,struct ffsb_fs * fs,unsigned op_num)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