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