libfio.c revision 36d80bc7c7f7fbc2612941b7dd7ceaf645798c7f
1/* 2 * fio - the flexible io tester 3 * 4 * Copyright (C) 2005 Jens Axboe <axboe@suse.de> 5 * Copyright (C) 2006-2012 Jens Axboe <axboe@kernel.dk> 6 * 7 * The license below covers all files distributed with fio unless otherwise 8 * noted in the file itself. 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * 23 */ 24 25#include <string.h> 26#include <sys/types.h> 27#include <signal.h> 28#include "fio.h" 29 30/* 31 * Just expose an empty list, if the OS does not support disk util stats 32 */ 33#ifndef FIO_HAVE_DISK_UTIL 34FLIST_HEAD(disk_list); 35#endif 36 37unsigned long arch_flags = 0; 38 39static const char *fio_os_strings[os_nr] = { 40 "Invalid", 41 "Linux", 42 "AIX", 43 "FreeBSD", 44 "HP-UX", 45 "OSX", 46 "NetBSD", 47 "Solaris", 48 "Windows" 49}; 50 51static const char *fio_arch_strings[arch_nr] = { 52 "Invalid", 53 "x86-64", 54 "x86", 55 "ppc", 56 "ia64", 57 "s390", 58 "alpha", 59 "sparc", 60 "sparc64", 61 "arm", 62 "sh", 63 "hppa", 64 "generic" 65}; 66 67static void reset_io_counters(struct thread_data *td) 68{ 69 int ddir; 70 for (ddir = 0; ddir < DDIR_RWDIR_CNT; ddir++) { 71 td->stat_io_bytes[ddir] = 0; 72 td->this_io_bytes[ddir] = 0; 73 td->stat_io_blocks[ddir] = 0; 74 td->this_io_blocks[ddir] = 0; 75 td->rate_bytes[ddir] = 0; 76 td->rate_blocks[ddir] = 0; 77 } 78 td->zone_bytes = 0; 79 80 td->last_was_sync = 0; 81 82 /* 83 * reset file done count if we are to start over 84 */ 85 if (td->o.time_based || td->o.loops) 86 td->nr_done_files = 0; 87} 88 89void clear_io_state(struct thread_data *td) 90{ 91 struct fio_file *f; 92 unsigned int i; 93 94 reset_io_counters(td); 95 96 close_files(td); 97 for_each_file(td, f, i) 98 fio_file_clear_done(f); 99 100 /* 101 * Set the same seed to get repeatable runs 102 */ 103 td_fill_rand_seeds(td); 104} 105 106void reset_all_stats(struct thread_data *td) 107{ 108 struct timeval tv; 109 int i; 110 111 reset_io_counters(td); 112 113 for (i = 0; i < DDIR_RWDIR_CNT; i++) { 114 td->io_bytes[i] = 0; 115 td->io_blocks[i] = 0; 116 td->io_issues[i] = 0; 117 td->ts.total_io_u[i] = 0; 118 td->ts.runtime[i] = 0; 119 } 120 121 fio_gettime(&tv, NULL); 122 memcpy(&td->epoch, &tv, sizeof(tv)); 123 memcpy(&td->start, &tv, sizeof(tv)); 124} 125 126void reset_fio_state(void) 127{ 128 groupid = 0; 129 thread_number = 0; 130 stat_number = 0; 131 nr_process = 0; 132 nr_thread = 0; 133 done_secs = 0; 134} 135 136const char *fio_get_os_string(int nr) 137{ 138 if (nr < os_nr) 139 return fio_os_strings[nr]; 140 141 return NULL; 142} 143 144const char *fio_get_arch_string(int nr) 145{ 146 if (nr < arch_nr) 147 return fio_arch_strings[nr]; 148 149 return NULL; 150} 151 152void td_set_runstate(struct thread_data *td, int runstate) 153{ 154 if (td->runstate == runstate) 155 return; 156 157 dprint(FD_PROCESS, "pid=%d: runstate %d -> %d\n", (int) td->pid, 158 td->runstate, runstate); 159 td->runstate = runstate; 160} 161 162void fio_terminate_threads(int group_id) 163{ 164 struct thread_data *td; 165 pid_t pid = getpid(); 166 int i; 167 168 dprint(FD_PROCESS, "terminate group_id=%d\n", group_id); 169 170 for_each_td(td, i) { 171 if (group_id == TERMINATE_ALL || groupid == td->groupid) { 172 dprint(FD_PROCESS, "setting terminate on %s/%d\n", 173 td->o.name, (int) td->pid); 174 td->terminate = 1; 175 td->o.start_delay = 0; 176 177 /* 178 * if the thread is running, just let it exit 179 */ 180 if (!td->pid || pid == td->pid) 181 continue; 182 else if (td->runstate < TD_RAMP) 183 kill(td->pid, SIGTERM); 184 else { 185 struct ioengine_ops *ops = td->io_ops; 186 187 if (ops && ops->terminate) 188 ops->terminate(td); 189 } 190 } 191 } 192} 193 194 195