2 #include "../profile.h"
5 #define OBJ_SIZE 1536 /* each object */
6 #define W_BUF_SIZE 128 * 1024 /* write coalescing */
11 #define SAMPLE_SEC 3600 /* 1h checks */
13 struct act_pass_criteria {
14 unsigned int max_usec;
15 unsigned int max_perm;
17 #define ACT_MAX_CRIT 3
19 static struct act_pass_criteria act_pass[ACT_MAX_CRIT] = {
34 struct act_prof_data {
35 struct timeval sample_tv;
36 uint64_t lat_buckets[ACT_MAX_CRIT];
40 static char *device_names;
41 static unsigned int load = 1;
43 static const char *act_opts[128] = {
46 "random_generator=lfsr",
51 static unsigned int opt_idx = 5;
52 static unsigned int org_idx;
54 static void act_add_opt(const char *format, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
56 static struct fio_option options[] = {
58 .name = "device-names",
59 .lname = "device-names",
60 .type = FIO_OPT_STR_STORE,
61 .roff1 = &device_names,
62 .help = "Devices to use",
63 .category = FIO_OPT_C_PROFILE,
64 .group = FIO_OPT_G_ACT,
68 .lname = "Load multiplier",
71 .help = "ACT load multipler (default 1x)",
72 .category = FIO_OPT_C_PROFILE,
73 .group = FIO_OPT_G_ACT,
80 static void act_add_opt(const char *str, ...)
87 len = vsnprintf(buffer, sizeof(buffer), str, args);
91 act_opts[opt_idx++] = strdup(buffer);
94 static void act_add_dev(const char *dev)
96 act_add_opt("name=act-read-%s", dev);
97 act_add_opt("filename=%s", dev);
98 act_add_opt("rw=randread");
99 act_add_opt("rate_iops=%u", load * R_LOAD);
101 act_add_opt("name=act-write-%s", dev);
102 act_add_opt("filename=%s", dev);
103 act_add_opt("rw=randwrite");
104 act_add_opt("rate_iops=%u", load * W_LOAD);
108 * Fill our private options into the command line
110 static int act_prep_cmdline(void)
113 log_err("act: need device-names\n");
118 act_add_opt("bs=%u", OBJ_SIZE);
123 dev = strsep(&device_names, ",");
133 static int act_io_u_lat(struct thread_data *td, uint64_t usec)
135 struct act_prof_data *apd = td->prof_data;
141 for (i = 0; i < ACT_MAX_CRIT; i++) {
142 if (usec <= act_pass[i].max_usec) {
143 apd->lat_buckets[i]++;
148 if (i == ACT_MAX_CRIT) {
149 log_err("act: max latency exceeded!\n");
153 if (time_since_now(&apd->sample_tv) < SAMPLE_SEC)
156 /* SAMPLE_SEC has passed, check criteria for pass */
157 for (i = 0; i < ACT_MAX_CRIT; i++) {
158 perm = (1000.0 * apd->lat_buckets[i]) / apd->total_ios;
159 if (perm <= act_pass[i].max_perm)
162 log_err("act: %f%% exceeds pass criteria of %f%%\n", perm / 10.0, (double) act_pass[i].max_perm / 10.0);
167 fio_gettime(&apd->sample_tv, NULL);
171 static int act_td_init(struct thread_data *td)
173 struct act_prof_data *apd;
175 apd = calloc(sizeof(*apd), 1);
176 fio_gettime(&apd->sample_tv, NULL);
181 static void act_td_exit(struct thread_data *td)
184 td->prof_data = NULL;
187 static struct prof_io_ops act_io_ops = {
188 .td_init = act_td_init,
189 .td_exit = act_td_exit,
190 .io_u_lat = act_io_u_lat,
193 static struct profile_ops act_profile = {
195 .desc = "ACT Aerospike like benchmark",
197 .prep_cmd = act_prep_cmdline,
199 .io_ops = &act_io_ops,
202 static void fio_init act_register(void)
204 if (register_profile(&act_profile))
205 log_err("fio: failed to register profile 'act'\n");
208 static void fio_exit act_unregister(void)
210 while (org_idx && org_idx < opt_idx)
211 free((void *) act_opts[++org_idx]);
213 unregister_profile(&act_profile);