1 /* 2 * CPU engine 3 * 4 * Doesn't transfer any data, merely burns CPU cycles according to 5 * the settings. 6 * 7 */ 8 #include "../fio.h" 9 #include "../optgroup.h" 10 11 struct cpu_options { 12 void *pad; 13 unsigned int cpuload; 14 unsigned int cpucycle; 15 unsigned int exit_io_done; 16 }; 17 18 static struct fio_option options[] = { 19 { 20 .name = "cpuload", 21 .lname = "CPU load", 22 .type = FIO_OPT_INT, 23 .off1 = offsetof(struct cpu_options, cpuload), 24 .help = "Use this percentage of CPU", 25 .category = FIO_OPT_C_ENGINE, 26 .group = FIO_OPT_G_INVALID, 27 }, 28 { 29 .name = "cpuchunks", 30 .lname = "CPU chunk", 31 .type = FIO_OPT_INT, 32 .off1 = offsetof(struct cpu_options, cpucycle), 33 .help = "Length of the CPU burn cycles (usecs)", 34 .def = "50000", 35 .parent = "cpuload", 36 .hide = 1, 37 .category = FIO_OPT_C_ENGINE, 38 .group = FIO_OPT_G_INVALID, 39 }, 40 { 41 .name = "exit_on_io_done", 42 .lname = "Exit when IO threads are done", 43 .type = FIO_OPT_BOOL, 44 .off1 = offsetof(struct cpu_options, exit_io_done), 45 .help = "Exit when IO threads finish", 46 .def = "0", 47 .category = FIO_OPT_C_ENGINE, 48 .group = FIO_OPT_G_INVALID, 49 }, 50 { 51 .name = NULL, 52 }, 53 }; 54 55 56 static int fio_cpuio_queue(struct thread_data *td, struct io_u fio_unused *io_u) 57 { 58 struct cpu_options *co = td->eo; 59 60 if (co->exit_io_done && !fio_running_or_pending_io_threads()) { 61 td->done = 1; 62 return FIO_Q_BUSY; 63 } 64 65 usec_spin(co->cpucycle); 66 return FIO_Q_COMPLETED; 67 } 68 69 static int fio_cpuio_init(struct thread_data *td) 70 { 71 struct thread_options *o = &td->o; 72 struct cpu_options *co = td->eo; 73 74 if (!co->cpuload) { 75 td_vmsg(td, EINVAL, "cpu thread needs rate (cpuload=)","cpuio"); 76 return 1; 77 } 78 79 if (co->cpuload > 100) 80 co->cpuload = 100; 81 82 /* 83 * set thinktime_sleep and thinktime_spin appropriately 84 */ 85 o->thinktime_blocks = 1; 86 o->thinktime_spin = 0; 87 o->thinktime = (co->cpucycle * (100 - co->cpuload)) / co->cpuload; 88 89 o->nr_files = o->open_files = 1; 90 91 log_info("%s: ioengine=%s, cpuload=%u, cpucycle=%u\n", 92 td->o.name, td->io_ops->name, co->cpuload, co->cpucycle); 93 94 return 0; 95 } 96 97 static int fio_cpuio_open(struct thread_data fio_unused *td, 98 struct fio_file fio_unused *f) 99 { 100 return 0; 101 } 102 103 static struct ioengine_ops ioengine = { 104 .name = "cpuio", 105 .version = FIO_IOOPS_VERSION, 106 .queue = fio_cpuio_queue, 107 .init = fio_cpuio_init, 108 .open_file = fio_cpuio_open, 109 .flags = FIO_SYNCIO | FIO_DISKLESSIO | FIO_NOIO, 110 .options = options, 111 .option_struct_size = sizeof(struct cpu_options), 112 }; 113 114 static void fio_init fio_cpuio_register(void) 115 { 116 register_ioengine(&ioengine); 117 } 118 119 static void fio_exit fio_cpuio_unregister(void) 120 { 121 unregister_ioengine(&ioengine); 122 } 123