1e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 2e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Blktrace replay utility - Play traces back 3e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 4e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Copyright (C) 2007 Alan D. Brunelle <Alan.Brunelle@hp.com> 5e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 6e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * This program is free software; you can redistribute it and/or modify 7e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * it under the terms of the GNU General Public License as published by 8e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * the Free Software Foundation; either version 2 of the License, or 9e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * (at your option) any later version. 10e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 11e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * This program is distributed in the hope that it will be useful, 12e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * but WITHOUT ANY WARRANTY; without even the implied warranty of 13e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * GNU General Public License for more details. 15e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 16e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * You should have received a copy of the GNU General Public License 17e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * along with this program; if not, write to the Free Software 18e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 20e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 21e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic char build_date[] = __DATE__ " at "__TIME__; 22e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 23e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <assert.h> 24e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <errno.h> 25e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <fcntl.h> 26e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <libaio.h> 27e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <pthread.h> 28e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <sched.h> 29e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <signal.h> 30e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <stdio.h> 31e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <stdlib.h> 32e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <string.h> 33e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <time.h> 34e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <unistd.h> 35e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <sys/param.h> 36e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <sys/stat.h> 37e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <sys/time.h> 38e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <sys/types.h> 39e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <dirent.h> 40e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <stdarg.h> 41e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 42e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#if !defined(_GNU_SOURCE) 43e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat# define _GNU_SOURCE 44e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#endif 45e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <getopt.h> 46e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 47e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include "list.h" 48e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include "btrecord.h" 49e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 50e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 51e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 52e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ==== STRUCTURE DEFINITIONS ============================================= 53e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 54e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 55e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 56e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 57e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Each device map has one of these: 58e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 59e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @head: Linked on to map_devs 60e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @from_dev: Device name as seen on recorded system 61e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @to_dev: Device name to be used on replay system 62e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 63e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct map_dev { 64e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct list_head head; 65e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char *from_dev, *to_dev; 66e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}; 67e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 68e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 69e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Each device name specified has one of these (until threads are created) 70e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 71e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @head: Linked onto input_devs 72e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @devnm: Device name -- 'sd*' 73e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 74e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct dev_info { 75e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct list_head head; 76e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char *devnm; 77e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}; 78e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 79e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 80e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Per input file information 81e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 82e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @head: Used to link up on input_files 83e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @free_iocbs: List of free iocb's available for use 84e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @used_iocbs: List of iocb's currently outstanding 85e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @mutex: Mutex used with condition variable to protect volatile values 86e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @cond: Condition variable used when waiting on a volatile value change 87e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @naios_out: Current number of AIOs outstanding on this context 88e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @naios_free: Number of AIOs on the free list (short cut for list_len) 89e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @send_wait: Boolean: When true, the sub thread is waiting on free IOCBs 90e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @reap_wait: Boolean: When true, the rec thread is waiting on used IOCBs 91e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @send_done: Boolean: When true, the sub thread has completed work 92e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @reap_done: Boolean: When true, the rec thread has completed work 93e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @sub_thread: Thread used to submit IOs. 94e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @rec_thread: Thread used to reclaim IOs. 95e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @ctx: IO context 96e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @devnm: Copy of the device name being managed by this thread 97e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @file_name: Full name of the input file 98e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @cpu: CPU this thread is pinned to 99e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @ifd: Input file descriptor 100e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @ofd: Output file descriptor 101e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @iterations: Remaining iterations to process 102e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @vfp: For verbose dumping of actions performed 103e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 104e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct thr_info { 105e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct list_head head, free_iocbs, used_iocbs; 106e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_mutex_t mutex; 107e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_cond_t cond; 108e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat volatile long naios_out, naios_free; 109e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat volatile int send_wait, reap_wait, send_done, reap_done; 110e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_t sub_thread, rec_thread; 111e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat io_context_t ctx; 112e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char *devnm, *file_name; 113e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int cpu, ifd, ofd, iterations; 114e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat FILE *vfp; 115e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}; 116e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 117e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 118e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Every Asynchronous IO used has one of these (naios per file/device). 119e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 120e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @iocb: IOCB sent down via io_submit 121e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @head: Linked onto file_list.free_iocbs or file_list.used_iocbs 122e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @tip: Pointer to per-thread information this IO is associated with 123e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @nbytes: Number of bytes in buffer associated with iocb 124e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 125e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct iocb_pkt { 126e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct iocb iocb; 127e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct list_head head; 128e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct thr_info *tip; 129e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int nbytes; 130e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}; 131e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 132e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 133e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 134e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ==== GLOBAL VARIABLES ================================================== 135e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 136e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 137e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 138e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic volatile int signal_done = 0; // Boolean: Signal'ed, need to quit 139e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 140e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic char *ibase = "replay"; // Input base name 141e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic char *idir = "."; // Input directory base 142e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int cpus_to_use = -1; // Number of CPUs to use 143e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int def_iterations = 1; // Default number of iterations 144e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int naios = 512; // Number of AIOs per thread 145e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int ncpus = 0; // Number of CPUs in the system 146e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int verbose = 0; // Boolean: Output some extra info 147e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int write_enabled = 0; // Boolean: Enable writing 148e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic __u64 genesis = ~0; // Earliest time seen 149e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic __u64 rgenesis; // Our start time 150e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic size_t pgsize; // System Page size 151e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int nb_sec = 512; // Number of bytes per sector 152e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic LIST_HEAD(input_devs); // List of devices to handle 153e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic LIST_HEAD(input_files); // List of input files to handle 154e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic LIST_HEAD(map_devs); // List of device maps 155e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int nfiles = 0; // Number of files to handle 156e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int no_stalls = 0; // Boolean: Disable pre-stalls 157e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic unsigned acc_factor = 1; // Int: Acceleration factor 158e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int find_records = 0; // Boolean: Find record files auto 159e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 160e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 161e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Variables managed under control of condition variables. 162e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 163e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * n_reclaims_done: Counts number of reclaim threads that have completed. 164e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * n_replays_done: Counts number of replay threads that have completed. 165e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * n_replays_ready: Counts number of replay threads ready to start. 166e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * n_iters_done: Counts number of replay threads done one iteration. 167e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * iter_start: Starts an iteration for the replay threads. 168e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 169e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic volatile int n_reclaims_done = 0; 170e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic pthread_mutex_t reclaim_done_mutex = PTHREAD_MUTEX_INITIALIZER; 171e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic pthread_cond_t reclaim_done_cond = PTHREAD_COND_INITIALIZER; 172e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 173e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic volatile int n_replays_done = 0; 174e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic pthread_mutex_t replay_done_mutex = PTHREAD_MUTEX_INITIALIZER; 175e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic pthread_cond_t replay_done_cond = PTHREAD_COND_INITIALIZER; 176e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 177e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic volatile int n_replays_ready = 0; 178e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic pthread_mutex_t replay_ready_mutex = PTHREAD_MUTEX_INITIALIZER; 179e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic pthread_cond_t replay_ready_cond = PTHREAD_COND_INITIALIZER; 180e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 181e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic volatile int n_iters_done = 0; 182e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic pthread_mutex_t iter_done_mutex = PTHREAD_MUTEX_INITIALIZER; 183e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic pthread_cond_t iter_done_cond = PTHREAD_COND_INITIALIZER; 184e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 185e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic volatile int iter_start = 0; 186e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic pthread_mutex_t iter_start_mutex = PTHREAD_MUTEX_INITIALIZER; 187e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic pthread_cond_t iter_start_cond = PTHREAD_COND_INITIALIZER; 188e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 189e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 190e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 191e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ==== FORWARD REFERENECES =============================================== 192e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 193e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 194e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 195e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void *replay_sub(void *arg); 196e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void *replay_rec(void *arg); 197e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic char usage_str[]; 198e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 199e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 200e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 201e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ==== INLINE ROUTINES =================================================== 202e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 203e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 204e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 205e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 206e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * The 'fatal' macro will output a perror message (if errstring is !NULL) 207e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * and display a string (with variable arguments) and then exit with the 208e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * specified exit value. 209e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 210e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#define ERR_ARGS 1 211e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#define ERR_SYSCALL 2 212e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void fatal(const char *errstring, const int exitval, 213e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat const char *fmt, ...) 214e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 215e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat va_list ap; 216e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 217e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (errstring) 218e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat perror(errstring); 219e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 220e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat va_start(ap, fmt); 221e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat vfprintf(stderr, fmt, ap); 222e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat va_end(ap); 223e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 224e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat exit(exitval); 225e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 226e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 227e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 228e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline long long unsigned du64_to_sec(__u64 du64) 229e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 230e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return (long long unsigned)du64 / (1000 * 1000 * 1000); 231e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 232e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 233e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline long long unsigned du64_to_nsec(__u64 du64) 234e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 235e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return llabs((long long)du64) % (1000 * 1000 * 1000); 236e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 237e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 238e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 239e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * min - Return minimum of two integers 240e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 241e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline int min(int a, int b) 242e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 243e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return a < b ? a : b; 244e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 245e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 246e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 247e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * minl - Return minimum of two longs 248e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 249e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline long minl(long a, long b) 250e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 251e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return a < b ? a : b; 252e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 253e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 254e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 255e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * usage - Display usage string and version 256e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 257e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void usage(void) 258e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 259e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr, "Usage: btreplay -- version %s\n%s", 260e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat my_btversion, usage_str); 261e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 262e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 263e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 264e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * is_send_done - Returns true if sender should quit early 265e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @tip: Per-thread information 266e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 267e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline int is_send_done(struct thr_info *tip) 268e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 269e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return signal_done || tip->send_done; 270e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 271e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 272e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 273e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * is_reap_done - Returns true if reaper should quit early 274e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @tip: Per-thread information 275e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 276e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline int is_reap_done(struct thr_info *tip) 277e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 278e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return tip->send_done && tip->naios_out == 0; 279e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 280e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 281e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 282e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ts2ns - Convert timespec values to a nanosecond value 283e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 284e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#define NS_TICKS ((__u64)1000 * (__u64)1000 * (__u64)1000) 285e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline __u64 ts2ns(struct timespec *ts) 286e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 287e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return ((__u64)(ts->tv_sec) * NS_TICKS) + (__u64)(ts->tv_nsec); 288e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 289e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 290e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 291e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ts2ns - Convert timeval values to a nanosecond value 292e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 293e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline __u64 tv2ns(struct timeval *tp) 294e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 295e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return ((__u64)(tp->tv_sec)) + ((__u64)(tp->tv_usec) * (__u64)1000); 296e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 297e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 298e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 299e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * touch_memory - Force physical memory to be allocating it 300e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 301e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * For malloc()ed memory we need to /touch/ it to make it really 302e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * exist. Otherwise, for write's (to storage) things may not work 303e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * as planned - we see Linux just use a single area to /read/ from 304e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * (as there isn't any memory that has been associated with the 305e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * allocated virtual addresses yet). 306e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 307e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void touch_memory(char *buf, size_t bsize) 308e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 309e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#if defined(PREP_BUFS) 310e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat memset(buf, 0, bsize); 311e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#else 312e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat size_t i; 313e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 314e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for (i = 0; i < bsize; i += pgsize) 315e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat buf[i] = 0; 316e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#endif 317e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 318e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 319e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 320e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * buf_alloc - Returns a page-aligned buffer of the specified size 321e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @nbytes: Number of bytes to allocate 322e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 323e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void *buf_alloc(size_t nbytes) 324e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 325e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat void *buf; 326e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 327e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (posix_memalign(&buf, pgsize, nbytes)) { 328e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal("posix_memalign", ERR_SYSCALL, "Allocation failed\n"); 329e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 330e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 331e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 332e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return buf; 333e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 334e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 335e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 336e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * gettime - Returns current time 337e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 338e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline __u64 gettime(void) 339e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 340e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat static int use_clock_gettime = -1; // Which clock to use 341e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 342e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (use_clock_gettime < 0) { 343e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat use_clock_gettime = clock_getres(CLOCK_MONOTONIC, NULL) == 0; 344e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (use_clock_gettime) { 345e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct timespec ts = { 346e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .tv_sec = 0, 347e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .tv_nsec = 0 348e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }; 349e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat clock_settime(CLOCK_MONOTONIC, &ts); 350e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 351e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 352e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 353e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (use_clock_gettime) { 354e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct timespec ts; 355e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat clock_gettime(CLOCK_MONOTONIC, &ts); 356e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return ts2ns(&ts); 357e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 358e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else { 359e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct timeval tp; 360e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat gettimeofday(&tp, NULL); 361e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return tv2ns(&tp); 362e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 363e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 364e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 365e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 366e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * setup_signal - Set up a signal handler for the specified signum 367e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 368e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void setup_signal(int signum, sighandler_t handler) 369e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 370e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (signal(signum, handler) == SIG_ERR) { 371e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal("signal", ERR_SYSCALL, "Failed to set signal %d\n", 372e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat signum); 373e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 374e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 375e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 376e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 377e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 378e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 379e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ==== CONDITION VARIABLE ROUTINES ======================================= 380e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 381e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 382e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 383e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 384e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * __set_cv - Increments a variable under condition variable control. 385e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @pmp: Pointer to the associated mutex 386e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @pcp: Pointer to the associated condition variable 387e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @vp: Pointer to the variable being incremented 388e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @mxv: Max value for variable (Used only when ASSERTS are on) 389e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 390e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void __set_cv(pthread_mutex_t *pmp, pthread_cond_t *pcp, 391e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat volatile int *vp, 392e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __attribute__((__unused__))int mxv) 393e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 394e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_mutex_lock(pmp); 395e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(*vp < mxv); 396e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *vp += 1; 397e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_cond_signal(pcp); 398e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_mutex_unlock(pmp); 399e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 400e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 401e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 402e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * __wait_cv - Waits for a variable under cond var control to hit a value 403e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @pmp: Pointer to the associated mutex 404e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @pcp: Pointer to the associated condition variable 405e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @vp: Pointer to the variable being incremented 406e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @mxv: Value to wait for 407e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 408e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void __wait_cv(pthread_mutex_t *pmp, pthread_cond_t *pcp, 409e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat volatile int *vp, int mxv) 410e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 411e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_mutex_lock(pmp); 412e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (*vp < mxv) 413e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_cond_wait(pcp, pmp); 414e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *vp = 0; 415e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_mutex_unlock(pmp); 416e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 417e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 418e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void set_reclaim_done(void) 419e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 420e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __set_cv(&reclaim_done_mutex, &reclaim_done_cond, &n_reclaims_done, 421e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat nfiles); 422e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 423e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 424e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void wait_reclaims_done(void) 425e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 426e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __wait_cv(&reclaim_done_mutex, &reclaim_done_cond, &n_reclaims_done, 427e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat nfiles); 428e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 429e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 430e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void set_replay_ready(void) 431e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 432e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __set_cv(&replay_ready_mutex, &replay_ready_cond, &n_replays_ready, 433e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat nfiles); 434e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 435e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 436e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void wait_replays_ready(void) 437e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 438e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __wait_cv(&replay_ready_mutex, &replay_ready_cond, &n_replays_ready, 439e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat nfiles); 440e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 441e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 442e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void set_replay_done(void) 443e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 444e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __set_cv(&replay_done_mutex, &replay_done_cond, &n_replays_done, 445e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat nfiles); 446e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 447e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 448e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void wait_replays_done(void) 449e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 450e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __wait_cv(&replay_done_mutex, &replay_done_cond, &n_replays_done, 451e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat nfiles); 452e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 453e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 454e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void set_iter_done(void) 455e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 456e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __set_cv(&iter_done_mutex, &iter_done_cond, &n_iters_done, 457e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat nfiles); 458e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 459e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 460e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void wait_iters_done(void) 461e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 462e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __wait_cv(&iter_done_mutex, &iter_done_cond, &n_iters_done, 463e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat nfiles); 464e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 465e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 466e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 467e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * wait_iter_start - Wait for an iteration to start 468e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 469e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * This is /slightly/ different: we are waiting for a value to become 470e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * non-zero, and then we decrement it and go on. 471e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 472e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void wait_iter_start(void) 473e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 474e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_mutex_lock(&iter_start_mutex); 475e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (iter_start == 0) 476e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_cond_wait(&iter_start_cond, &iter_start_mutex); 477e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(1 <= iter_start && iter_start <= nfiles); 478e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iter_start--; 479e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_mutex_unlock(&iter_start_mutex); 480e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 481e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 482e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 483e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * start_iter - Start an iteration at the replay thread level 484e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 485e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline void start_iter(void) 486e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 487e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_mutex_lock(&iter_start_mutex); 488e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(iter_start == 0); 489e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iter_start = nfiles; 490e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_cond_broadcast(&iter_start_cond); 491e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_mutex_unlock(&iter_start_mutex); 492e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 493e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 494e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 495e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 496e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ==== CPU RELATED ROUTINES ============================================== 497e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 498e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 499e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 500e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 501e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * get_ncpus - Sets up the global 'ncpus' value 502e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 503e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void get_ncpus(void) 504e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 505e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat cpu_set_t cpus; 506e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 507e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (sched_getaffinity(getpid(), sizeof(cpus), &cpus)) { 508e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal("sched_getaffinity", ERR_SYSCALL, "Can't get CPU info\n"); 509e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 510e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 511e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 512e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /* 513e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * XXX This assumes (perhaps wrongly) that there are no /holes/ 514e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * XXX in the mask. 515e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 516e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for (ncpus = 0; ncpus < CPU_SETSIZE && CPU_ISSET(ncpus, &cpus); ncpus++) 517e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ; 518e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (ncpus == 0) { 519e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal(NULL, ERR_SYSCALL, "Insufficient number of CPUs\n"); 520e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 521e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 522e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 523e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 524e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 525e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * pin_to_cpu - Pin this thread to a specific CPU 526e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @tip: Thread information 527e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 528e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void pin_to_cpu(struct thr_info *tip) 529e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 530e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat cpu_set_t cpus; 531e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 532e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(0 <= tip->cpu && tip->cpu < ncpus); 533e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 534e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat CPU_ZERO(&cpus); 535e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat CPU_SET(tip->cpu, &cpus); 536e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (sched_setaffinity(getpid(), sizeof(cpus), &cpus)) { 537e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal("sched_setaffinity", ERR_SYSCALL, "Failed to pin CPU\n"); 538e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 539e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 540e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 541e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (verbose > 1) { 542e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int i; 543e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat cpu_set_t now; 544e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 545e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (void)sched_getaffinity(getpid(), sizeof(now), &now); 546e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(tip->vfp, "Pinned to CPU %02d ", tip->cpu); 547e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for (i = 0; i < ncpus; i++) 548e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(tip->vfp, "%1d", CPU_ISSET(i, &now)); 549e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(tip->vfp, "\n"); 550e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 551e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 552e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 553e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 554e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 555e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ==== INPUT DEVICE HANDLERS ============================================= 556e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 557e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 558e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 559e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 560e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * add_input_dev - Add a device ('sd*') to the list of devices to handle 561e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 562e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void add_input_dev(char *devnm) 563e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 564e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct list_head *p; 565e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct dev_info *dip; 566e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 567e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __list_for_each(p, &input_devs) { 568e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat dip = list_entry(p, struct dev_info, head); 569e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (strcmp(dip->devnm, devnm) == 0) 570e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return; 571e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 572e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 573e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat dip = malloc(sizeof(*dip)); 574e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat dip->devnm = strdup(devnm); 575e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat list_add_tail(&dip->head, &input_devs); 576e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 577e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 578e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 579e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * rem_input_dev - Remove resources associated with this device 580e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 581e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void rem_input_dev(struct dev_info *dip) 582e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 583e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat list_del(&dip->head); 584e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(dip->devnm); 585e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(dip); 586e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 587e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 588e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void find_input_devs(char *idir) 589e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 590e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct dirent *ent; 591e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat DIR *dir = opendir(idir); 592e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 593e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (dir == NULL) { 594e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal(idir, ERR_ARGS, "Unable to open %s\n", idir); 595e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 596e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 597e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 598e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while ((ent = readdir(dir)) != NULL) { 599e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char *p, *dsf = malloc(256); 600e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 601e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (strstr(ent->d_name, ".replay.") == NULL) 602e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat continue; 603e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 604e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat dsf = strdup(ent->d_name); 605e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat p = index(dsf, '.'); 606e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(p != NULL); 607e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *p = '\0'; 608e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat add_input_dev(dsf); 609e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(dsf); 610e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 611e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 612e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat closedir(dir); 613e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 614e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 615e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 616e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 617e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ==== MAP DEVICE INTERFACES ============================================= 618e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 619e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 620e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 621e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 622e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * read_map_devs - Read in a set of device mapping from the provided file. 623e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @file_name: File containing device maps 624e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 625e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * We support the notion of multiple such files being specifed on the cmd line 626e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 627e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void read_map_devs(char *file_name) 628e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 629e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat FILE *fp; 630e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char *from_dev, *to_dev; 631e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 632e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fp = fopen(file_name, "r"); 633e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!fp) { 634e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal(file_name, ERR_SYSCALL, "Could not open map devs file\n"); 635e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 636e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 637e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 638e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (fscanf(fp, "%as %as", &from_dev, &to_dev) == 2) { 639e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct map_dev *mdp = malloc(sizeof(*mdp)); 640e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 641e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat mdp->from_dev = from_dev; 642e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat mdp->to_dev = to_dev; 643e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat list_add_tail(&mdp->head, &map_devs); 644e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 645e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 646e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fclose(fp); 647e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 648e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 649e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 650e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * release_map_devs - Release resources associated with device mappings. 651e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 652e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void release_map_devs(void) 653e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 654e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct list_head *p, *q; 655e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 656e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat list_for_each_safe(p, q, &map_devs) { 657e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct map_dev *mdp = list_entry(p, struct map_dev, head); 658e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 659e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat list_del(&mdp->head); 660e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 661e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(mdp->from_dev); 662e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(mdp->to_dev); 663e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(mdp); 664e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 665e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 666e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 667e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 668e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * map_dev - Return the mapped device for that specified 669e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @from_dev: Device name as seen on recorded system 670e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 671e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Note: If there is no such mapping, we return the same name. 672e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 673e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic char *map_dev(char *from_dev) 674e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 675e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct list_head *p; 676e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 677e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __list_for_each(p, &map_devs) { 678e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct map_dev *mdp = list_entry(p, struct map_dev, head); 679e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 680e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (strcmp(from_dev, mdp->from_dev) == 0) 681e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return mdp->to_dev; 682e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 683e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 684e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return from_dev; 685e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 686e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 687e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 688e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 689e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ==== IOCB MANAGEMENT ROUTINES ========================================== 690e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 691e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 692e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 693e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 694e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * iocb_init - Initialize the fields of an IOCB 695e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @tip: Per-thread information 696e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * iocbp: IOCB pointer to update 697e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 698e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void iocb_init(struct thr_info *tip, struct iocb_pkt *iocbp) 699e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 700e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iocbp->tip = tip; 701e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iocbp->nbytes = 0; 702e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iocbp->iocb.u.c.buf = NULL; 703e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 704e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 705e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 706e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * iocb_setup - Set up an iocb with this AIOs information 707e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @iocbp: IOCB pointer to update 708e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @rw: Direction (0 == write, 1 == read) 709e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @n: Number of bytes to transfer 710e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @off: Offset (in bytes) 711e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 712e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void iocb_setup(struct iocb_pkt *iocbp, int rw, int n, long long off) 713e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 714e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char *buf; 715e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct iocb *iop = &iocbp->iocb; 716e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 717e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(rw == 0 || rw == 1); 718e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(0 < n && (n % nb_sec) == 0); 719e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(0 <= off); 720e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 721e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (iocbp->nbytes) { 722e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (iocbp->nbytes >= n) { 723e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat buf = iop->u.c.buf; 724e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat goto prep; 725e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 726e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 727e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(iop->u.c.buf); 728e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(iop->u.c.buf); 729e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 730e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 731e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat buf = buf_alloc(n); 732e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iocbp->nbytes = n; 733e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 734e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatprep: 735e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (rw) 736e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat io_prep_pread(iop, iocbp->tip->ofd, buf, n, off); 737e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat else { 738e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(write_enabled); 739e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat io_prep_pwrite(iop, iocbp->tip->ofd, buf, n, off); 740e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat touch_memory(buf, n); 741e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 742e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 743e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iop->data = iocbp; 744e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 745e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 746e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 747e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 748e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ==== PER-THREAD SET UP & TEAR DOWN ===================================== 749e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 750e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 751e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 752e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 753e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * tip_init - Per thread initialization function 754e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 755e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void tip_init(struct thr_info *tip) 756e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 757e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int i; 758e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 759e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat INIT_LIST_HEAD(&tip->free_iocbs); 760e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat INIT_LIST_HEAD(&tip->used_iocbs); 761e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 762e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_mutex_init(&tip->mutex, NULL); 763e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_cond_init(&tip->cond, NULL); 764e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 765e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (io_setup(naios, &tip->ctx)) { 766e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal("io_setup", ERR_SYSCALL, "io_setup failed\n"); 767e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 768e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 769e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 770e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tip->ofd = -1; 771e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tip->naios_out = 0; 772e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tip->send_done = tip->reap_done = 0; 773e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tip->send_wait = tip->reap_wait = 0; 774e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 775e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat memset(&tip->sub_thread, 0, sizeof(tip->sub_thread)); 776e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat memset(&tip->rec_thread, 0, sizeof(tip->rec_thread)); 777e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 778e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for (i = 0; i < naios; i++) { 779e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct iocb_pkt *iocbp = buf_alloc(sizeof(*iocbp)); 780e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 781e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iocb_init(tip, iocbp); 782e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat list_add_tail(&iocbp->head, &tip->free_iocbs); 783e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 784e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tip->naios_free = naios; 785e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 786e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (verbose > 1) { 787e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char fn[MAXPATHLEN]; 788e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 789e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat sprintf(fn, "%s/%s.%s.%d.rep", idir, tip->devnm, ibase, 790e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tip->cpu); 791e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tip->vfp = fopen(fn, "w"); 792e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!tip->vfp) { 793e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal(fn, ERR_SYSCALL, "Failed to open report\n"); 794e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 795e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 796e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 797e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat setlinebuf(tip->vfp); 798e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 799e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 800e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pthread_create(&tip->sub_thread, NULL, replay_sub, tip)) { 801e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal("pthread_create", ERR_SYSCALL, 802e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "thread create failed\n"); 803e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 804e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 805e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 806e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pthread_create(&tip->rec_thread, NULL, replay_rec, tip)) { 807e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal("pthread_create", ERR_SYSCALL, 808e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "thread create failed\n"); 809e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 810e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 811e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 812e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 813e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 814e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * tip_release - Release resources associated with this thread 815e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 816e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void tip_release(struct thr_info *tip) 817e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 818e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct list_head *p, *q; 819e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 820e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(tip->send_done); 821e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(tip->reap_done); 822e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(list_len(&tip->used_iocbs) == 0); 823e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(tip->naios_free == naios); 824e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 825e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pthread_join(tip->sub_thread, NULL)) { 826e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal("pthread_join", ERR_SYSCALL, "pthread sub join failed\n"); 827e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 828e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 829e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pthread_join(tip->rec_thread, NULL)) { 830e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal("pthread_join", ERR_SYSCALL, "pthread rec join failed\n"); 831e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 832e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 833e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 834e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat io_destroy(tip->ctx); 835e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 836e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat list_splice(&tip->used_iocbs, &tip->free_iocbs); 837e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat list_for_each_safe(p, q, &tip->free_iocbs) { 838e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct iocb_pkt *iocbp = list_entry(p, struct iocb_pkt, head); 839e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 840e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat list_del(&iocbp->head); 841e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (iocbp->nbytes) 842e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(iocbp->iocb.u.c.buf); 843e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(iocbp); 844e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 845e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 846e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_cond_destroy(&tip->cond); 847e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_mutex_destroy(&tip->mutex); 848e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 849e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 850e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 851e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * add_input_file - Allocate and initialize per-input file structure 852e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @cpu: CPU for this file 853e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @devnm: Device name for this file 854e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @file_name: Fully qualifed input file name 855e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 856e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void add_input_file(int cpu, char *devnm, char *file_name) 857e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 858e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct stat buf; 859e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_file_hdr hdr; 860e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct thr_info *tip = buf_alloc(sizeof(*tip)); 861e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __u64 my_version = mk_btversion(btver_mjr, btver_mnr, btver_sub); 862e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 863e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(0 <= cpu && cpu < ncpus); 864e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 865e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat memset(&hdr, 0, sizeof(hdr)); 866e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat memset(tip, 0, sizeof(*tip)); 867e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tip->cpu = cpu % cpus_to_use; 868e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tip->iterations = def_iterations; 869e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 870e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tip->ifd = open(file_name, O_RDONLY); 871e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (tip->ifd < 0) { 872e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal(file_name, ERR_ARGS, "Unable to open\n"); 873e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 874e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 875e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (fstat(tip->ifd, &buf) < 0) { 876e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal(file_name, ERR_SYSCALL, "fstat failed\n"); 877e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 878e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 879e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (buf.st_size < (off_t)sizeof(hdr)) { 880e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (verbose) 881e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr, "\t%s empty\n", file_name); 882e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat goto empty_file; 883e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 884e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 885e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (read(tip->ifd, &hdr, sizeof(hdr)) != sizeof(hdr)) { 886e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal(file_name, ERR_ARGS, "Header read failed\n"); 887e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 888e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 889e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 890e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (hdr.version != my_version) { 891e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr, "%llx %llx %llx %llx\n", 892e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (long long unsigned)hdr.version, 893e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (long long unsigned)hdr.genesis, 894e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (long long unsigned)hdr.nbunches, 895e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (long long unsigned)hdr.total_pkts); 896e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal(NULL, ERR_ARGS, 897e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "BT version mismatch: %lx versus my %lx\n", 898e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (long)hdr.version, (long)my_version); 899e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 900e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 901e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 902e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (hdr.nbunches == 0) { 903e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatempty_file: 904e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat close(tip->ifd); 905e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(tip); 906e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return; 907e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 908e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 909e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (hdr.genesis < genesis) { 910e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (verbose > 1) 911e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr, "Setting genesis to %llu.%llu\n", 912e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat du64_to_sec(hdr.genesis), 913e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat du64_to_nsec(hdr.genesis)); 914e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat genesis = hdr.genesis; 915e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 916e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 917e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tip->devnm = strdup(devnm); 918e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tip->file_name = strdup(file_name); 919e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 920e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat list_add_tail(&tip->head, &input_files); 921e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 922e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (verbose) 923e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr, "Added %s %llu\n", file_name, 924e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (long long)hdr.genesis); 925e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 926e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 927e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 928e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * rem_input_file - Release resources associated with an input file 929e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @tip: Per-input file information 930e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 931e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void rem_input_file(struct thr_info *tip) 932e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 933e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat list_del(&tip->head); 934e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 935e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tip_release(tip); 936e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 937e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat close(tip->ofd); 938e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat close(tip->ifd); 939e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(tip->file_name); 940e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(tip->devnm); 941e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat free(tip); 942e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 943e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 944e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 945e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * rem_input_files - Remove all input files 946e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 947e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void rem_input_files(void) 948e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 949e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct list_head *p, *q; 950e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 951e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat list_for_each_safe(p, q, &input_files) { 952e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat rem_input_file(list_entry(p, struct thr_info, head)); 953e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 954e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 955e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 956e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 957e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * __find_input_files - Find input files associated with this device (per cpu) 958e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 959e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void __find_input_files(struct dev_info *dip) 960e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 961e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int cpu = 0; 962e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 963e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for (;;) { 964e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char full_name[MAXPATHLEN]; 965e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 966e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat sprintf(full_name, "%s/%s.%s.%d", idir, dip->devnm, ibase, cpu); 967e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (access(full_name, R_OK) != 0) 968e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 969e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 970e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat add_input_file(cpu, dip->devnm, full_name); 971e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat cpu++; 972e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 973e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 974e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!cpu) { 975e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal(NULL, ERR_ARGS, "No traces found for %s\n", dip->devnm); 976e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 977e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 978e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 979e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat rem_input_dev(dip); 980e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 981e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 982e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 983e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 984e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * find_input_files - Find input files for all devices 985e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 986e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void find_input_files(void) 987e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 988e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct list_head *p, *q; 989e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 990e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat list_for_each_safe(p, q, &input_devs) { 991e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __find_input_files(list_entry(p, struct dev_info, head)); 992e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 993e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 994e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 995e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 996e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 997e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ==== RECLAIM ROUTINES ================================================== 998e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 999e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1000e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1001e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 1002e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * reap_wait_aios - Wait for and return number of outstanding AIOs 1003e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 1004e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Will return 0 if we are done 1005e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1006e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int reap_wait_aios(struct thr_info *tip) 1007e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1008e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int naios = 0; 1009e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1010e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!is_reap_done(tip)) { 1011e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_mutex_lock(&tip->mutex); 1012e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (tip->naios_out == 0) { 1013e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tip->reap_wait = 1; 1014e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pthread_cond_wait(&tip->cond, &tip->mutex)) { 1015e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal("pthread_cond_wait", ERR_SYSCALL, 1016e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "nfree_current cond wait failed\n"); 1017e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 1018e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1019e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1020e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat naios = tip->naios_out; 1021e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_mutex_unlock(&tip->mutex); 1022e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1023e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(is_reap_done(tip) || naios > 0); 1024e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1025e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return is_reap_done(tip) ? 0 : naios; 1026e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1027e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1028e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 1029e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * reclaim_ios - Reclaim AIOs completed, recycle IOCBs 1030e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @tip: Per-thread information 1031e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @naios_out: Number of AIOs we have outstanding (min) 1032e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1033e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void reclaim_ios(struct thr_info *tip, long naios_out) 1034e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1035e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat long i, ndone; 1036e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_event *evp, events[naios_out]; 1037e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1038e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatagain: 1039e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(naios > 0); 1040e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for (;;) { 1041e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ndone = io_getevents(tip->ctx, 1, naios_out, events, NULL); 1042e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (ndone > 0) 1043e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1044e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1045e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (errno && errno != EINTR) { 1046e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal("io_getevents", ERR_SYSCALL, 1047e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "io_getevents failed\n"); 1048e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 1049e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1050e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1051e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(0 < ndone && ndone <= naios_out); 1052e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1053e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_mutex_lock(&tip->mutex); 1054e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for (i = 0, evp = events; i < ndone; i++, evp++) { 1055e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct iocb_pkt *iocbp = evp->data; 1056e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1057e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (evp->res != iocbp->iocb.u.c.nbytes) { 1058e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal(NULL, ERR_SYSCALL, 1059e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "Event failure %ld/%ld\t(%ld + %ld)\n", 1060e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (long)evp->res, (long)evp->res2, 1061e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (long)iocbp->iocb.u.c.offset / nb_sec, 1062e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (long)iocbp->iocb.u.c.nbytes / nb_sec); 1063e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 1064e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1065e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1066e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat list_move_tail(&iocbp->head, &tip->free_iocbs); 1067e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1068e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1069e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tip->naios_free += ndone; 1070e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tip->naios_out -= ndone; 1071e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat naios_out = minl(naios_out, tip->naios_out); 1072e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1073e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (tip->send_wait) { 1074e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tip->send_wait = 0; 1075e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_cond_signal(&tip->cond); 1076e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1077e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_mutex_unlock(&tip->mutex); 1078e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1079e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /* 1080e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Short cut: If we /know/ there are some more AIOs, go handle them 1081e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1082e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (naios_out) 1083e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat goto again; 1084e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1085e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1086e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 1087e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * replay_rec - Worker thread to reclaim AIOs 1088e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @arg: Pointer to thread information 1089e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1090e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void *replay_rec(void *arg) 1091e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1092e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat long naios_out; 1093e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct thr_info *tip = arg; 1094e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1095e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while ((naios_out = reap_wait_aios(tip)) > 0) 1096e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat reclaim_ios(tip, naios_out); 1097e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1098e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(tip->send_done); 1099e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tip->reap_done = 1; 1100e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat set_reclaim_done(); 1101e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1102e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return NULL; 1103e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1104e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1105e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 1106e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 1107e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ==== REPLAY ROUTINES =================================================== 1108e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 1109e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1110e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1111e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 1112e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * next_bunch - Retrieve next bunch of AIOs to process 1113e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @tip: Per-thread information 1114e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @bunch: Bunch information 1115e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 1116e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Returns TRUE if we recovered a bunch of IOs, else hit EOF 1117e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1118e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int next_bunch(struct thr_info *tip, struct io_bunch *bunch) 1119e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1120e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat size_t count, result; 1121e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1122e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat result = read(tip->ifd, &bunch->hdr, sizeof(bunch->hdr)); 1123e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (result != sizeof(bunch->hdr)) { 1124e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (result == 0) 1125e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 0; 1126e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1127e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal(tip->file_name, ERR_SYSCALL, "Short hdr(%ld)\n", 1128e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (long)result); 1129e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 1130e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1131e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(bunch->hdr.npkts <= BT_MAX_PKTS); 1132e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1133e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat count = bunch->hdr.npkts * sizeof(struct io_pkt); 1134e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat result = read(tip->ifd, &bunch->pkts, count); 1135e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (result != count) { 1136e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal(tip->file_name, ERR_SYSCALL, "Short pkts(%ld/%ld)\n", 1137e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (long)result, (long)count); 1138e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 1139e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1140e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1141e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 1; 1142e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1143e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1144e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 1145e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * nfree_current - Returns current number of AIOs that are free 1146e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 1147e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Will wait for available ones... 1148e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 1149e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Returns 0 if we have some condition that causes us to exit 1150e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1151e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic int nfree_current(struct thr_info *tip) 1152e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1153e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int nfree = 0; 1154e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1155e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_mutex_lock(&tip->mutex); 1156e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (!is_send_done(tip) && ((nfree = tip->naios_free) == 0)) { 1157e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tip->send_wait = 1; 1158e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (pthread_cond_wait(&tip->cond, &tip->mutex)) { 1159e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal("pthread_cond_wait", ERR_SYSCALL, 1160e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "nfree_current cond wait failed\n"); 1161e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 1162e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1163e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1164e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_mutex_unlock(&tip->mutex); 1165e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1166e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return nfree; 1167e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1168e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1169e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 1170e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * stall - Stall for the number of nanoseconds requested 1171e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 1172e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * We may be late, in which case we just return. 1173e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1174e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void stall(struct thr_info *tip, long long oclock) 1175e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1176e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct timespec req; 1177e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat long long dreal, tclock = gettime() - rgenesis; 1178e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1179e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat oclock /= acc_factor; 1180e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1181e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (verbose > 1) 1182e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(tip->vfp, " stall(%lld.%09lld, %lld.%09lld)\n", 1183e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat du64_to_sec(oclock), du64_to_nsec(oclock), 1184e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat du64_to_sec(tclock), du64_to_nsec(tclock)); 1185e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1186e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (!is_send_done(tip) && tclock < oclock) { 1187e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat dreal = oclock - tclock; 1188e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat req.tv_sec = dreal / (1000 * 1000 * 1000); 1189e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat req.tv_nsec = dreal % (1000 * 1000 * 1000); 1190e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1191e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (verbose > 1) { 1192e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(tip->vfp, "++ stall(%lld.%09lld) ++\n", 1193e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (long long)req.tv_sec, 1194e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (long long)req.tv_nsec); 1195e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1196e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1197e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (nanosleep(&req, NULL) < 0 && signal_done) 1198e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1199e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1200e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tclock = gettime() - rgenesis; 1201e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1202e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1203e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1204e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 1205e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * iocbs_map - Map a set of AIOs onto a set of IOCBs 1206e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @tip: Per-thread information 1207e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @list: List of AIOs created 1208e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @pkts: AIOs to map 1209e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @ntodo: Number of AIOs to map 1210e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1211e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void iocbs_map(struct thr_info *tip, struct iocb **list, 1212e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_pkt *pkts, int ntodo) 1213e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1214e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int i; 1215e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_pkt *pkt; 1216e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1217e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(0 < ntodo && ntodo <= naios); 1218e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1219e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_mutex_lock(&tip->mutex); 1220e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(ntodo <= list_len(&tip->free_iocbs)); 1221e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for (i = 0, pkt = pkts; i < ntodo; i++, pkt++) { 1222e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __u32 rw = pkt->rw; 1223e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct iocb_pkt *iocbp; 1224e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1225e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!pkt->rw && !write_enabled) 1226e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat rw = 1; 1227e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1228e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (verbose > 1) 1229e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(tip->vfp, "\t%10llu + %10llu %c%c\n", 1230e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (unsigned long long)pkt->sector, 1231e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (unsigned long long)pkt->nbytes / nb_sec, 1232e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat rw ? 'R' : 'W', 1233e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat (rw == 1 && pkt->rw == 0) ? '!' : ' '); 1234e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1235e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iocbp = list_entry(tip->free_iocbs.next, struct iocb_pkt, head); 1236e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iocb_setup(iocbp, rw, pkt->nbytes, pkt->sector * nb_sec); 1237e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1238e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat list_move_tail(&iocbp->head, &tip->used_iocbs); 1239e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat list[i] = &iocbp->iocb; 1240e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1241e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1242e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tip->naios_free -= ntodo; 1243e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(tip->naios_free >= 0); 1244e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_mutex_unlock(&tip->mutex); 1245e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1246e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1247e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 1248e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * process_bunch - Process a bunch of requests 1249e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @tip: Per-thread information 1250e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @bunch: Bunch to process 1251e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1252e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void process_bunch(struct thr_info *tip, struct io_bunch *bunch) 1253e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1254e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __u64 i = 0; 1255e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct iocb *list[bunch->hdr.npkts]; 1256e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1257e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(0 < bunch->hdr.npkts && bunch->hdr.npkts <= BT_MAX_PKTS); 1258e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (!is_send_done(tip) && (i < bunch->hdr.npkts)) { 1259e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat long ndone; 1260e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int ntodo = min(nfree_current(tip), bunch->hdr.npkts - i); 1261e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1262e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(0 < ntodo && ntodo <= naios); 1263e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat iocbs_map(tip, list, &bunch->pkts[i], ntodo); 1264e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (!no_stalls) 1265e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat stall(tip, bunch->hdr.time_stamp - genesis); 1266e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1267e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (ntodo) { 1268e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (verbose > 1) 1269e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(tip->vfp, "submit(%d)\n", ntodo); 1270e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ndone = io_submit(tip->ctx, ntodo, list); 1271e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (ndone != (long)ntodo) { 1272e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal("io_submit", ERR_SYSCALL, 1273e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "%d: io_submit(%d:%ld) failed (%s)\n", 1274e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tip->cpu, ntodo, ndone, 1275e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat strerror(labs(ndone))); 1276e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 1277e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1278e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1279e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_mutex_lock(&tip->mutex); 1280e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tip->naios_out += ndone; 1281e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(tip->naios_out <= naios); 1282e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (tip->reap_wait) { 1283e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tip->reap_wait = 0; 1284e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_cond_signal(&tip->cond); 1285e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1286e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pthread_mutex_unlock(&tip->mutex); 1287e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1288e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat i += ndone; 1289e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(i <= bunch->hdr.npkts); 1290e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1291e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1292e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1293e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1294e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 1295e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * reset_input_file - Reset the input file for the next iteration 1296e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @tip: Thread information 1297e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 1298e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * We also do a dummy read of the file header to get us to the first bunch. 1299e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1300e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void reset_input_file(struct thr_info *tip) 1301e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1302e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_file_hdr hdr; 1303e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1304e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat lseek(tip->ifd, 0, 0); 1305e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1306e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (read(tip->ifd, &hdr, sizeof(hdr)) != sizeof(hdr)) { 1307e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal(tip->file_name, ERR_ARGS, "Header reread failed\n"); 1308e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 1309e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1310e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1311e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1312e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 1313e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * replay_sub - Worker thread to submit AIOs that are being replayed 1314e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1315e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void *replay_sub(void *arg) 1316e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1317e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat char path[MAXPATHLEN]; 1318e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct io_bunch bunch; 1319e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct thr_info *tip = arg; 1320e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int oflags; 1321e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1322e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pin_to_cpu(tip); 1323e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1324e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat sprintf(path, "/dev/%s", map_dev(tip->devnm)); 1325e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1326e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#ifdef O_NOATIME 1327e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat oflags = O_NOATIME; 1328e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#else 1329e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat oflags = 0; 1330e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#endif 1331e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tip->ofd = open(path, O_RDWR | O_DIRECT | oflags); 1332e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (tip->ofd < 0) { 1333e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal(path, ERR_SYSCALL, "Failed device open\n"); 1334e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 1335e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1336e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1337e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat set_replay_ready(); 1338e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (!is_send_done(tip) && tip->iterations--) { 1339e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat wait_iter_start(); 1340e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (verbose > 1) 1341e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(tip->vfp, "\n=== %d ===\n", tip->iterations); 1342e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (!is_send_done(tip) && next_bunch(tip, &bunch)) 1343e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat process_bunch(tip, &bunch); 1344e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat set_iter_done(); 1345e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat reset_input_file(tip); 1346e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1347e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tip->send_done = 1; 1348e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat set_replay_done(); 1349e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1350e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return NULL; 1351e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1352e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1353e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 1354e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 1355e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ==== COMMAND LINE ARGUMENT HANDLING ==================================== 1356e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 1357e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1358e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1359e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic char usage_str[] = \ 1360e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\n" \ 1361e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t[ -c <cpus> : --cpus=<cpus> ] Default: 1\n" \ 1362e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t[ -d <dir> : --input-directory=<dir> ] Default: .\n" \ 1363e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t[ -F : --find-records ] Default: Off\n" \ 1364e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t[ -h : --help ] Default: Off\n" \ 1365e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t[ -i <base> : --input-base=<base> ] Default: replay\n" \ 1366e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t[ -I <iters>: --iterations=<iters> ] Default: 1\n" \ 1367e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t[ -M <file> : --map-devs=<file> ] Default: None\n" \ 1368e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t[ -N : --no-stalls ] Default: Off\n" \ 1369e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t[ -x : --acc-factor ] Default: 1\n" \ 1370e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t[ -v : --verbose ] Default: Off\n" \ 1371e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t[ -V : --version ] Default: Off\n" \ 1372e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t[ -W : --write-enable ] Default: Off\n" \ 1373e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\t<dev...> Default: None\n" \ 1374e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "\n"; 1375e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1376e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#define S_OPTS "c:d:Fhi:I:M:Nx:t:vVW" 1377e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic struct option l_opts[] = { 1378e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 1379e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "cpus", 1380e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = required_argument, 1381e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 1382e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'c' 1383e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 1384e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 1385e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "input-directory", 1386e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = required_argument, 1387e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 1388e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'd' 1389e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 1390e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 1391e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "find-records", 1392e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = no_argument, 1393e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 1394e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'F' 1395e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 1396e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 1397e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "help", 1398e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = no_argument, 1399e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 1400e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'h' 1401e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 1402e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 1403e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "input-base", 1404e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = required_argument, 1405e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 1406e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'i' 1407e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 1408e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 1409e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "iterations", 1410e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = required_argument, 1411e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 1412e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'I' 1413e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 1414e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 1415e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "map-devs", 1416e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = required_argument, 1417e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 1418e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'M' 1419e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 1420e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 1421e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "no-stalls", 1422e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = no_argument, 1423e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 1424e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'N' 1425e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 1426e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 1427e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "acc-factor", 1428e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = required_argument, 1429e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 1430e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'x' 1431e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 1432e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 1433e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "verbose", 1434e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = no_argument, 1435e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 1436e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'v' 1437e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 1438e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 1439e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "version", 1440e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = no_argument, 1441e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 1442e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'V' 1443e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 1444e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 1445e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = "write-enable", 1446e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .has_arg = no_argument, 1447e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .flag = NULL, 1448e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .val = 'W' 1449e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat }, 1450e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat { 1451e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat .name = NULL 1452e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1453e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}; 1454e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1455e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 1456e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * handle_args: Parse passed in argument list 1457e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @argc: Number of arguments in argv 1458e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @argv: Arguments passed in 1459e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * 1460e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Does rudimentary parameter verification as well. 1461e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1462e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void handle_args(int argc, char *argv[]) 1463e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1464e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int c; 1465e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int r; 1466e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1467e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while ((c = getopt_long(argc, argv, S_OPTS, l_opts, NULL)) != -1) { 1468e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat switch (c) { 1469e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'c': 1470e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat cpus_to_use = atoi(optarg); 1471e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (cpus_to_use <= 0 || cpus_to_use > ncpus) { 1472e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal(NULL, ERR_ARGS, 1473e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "Invalid number of cpus %d (0<x<%d)\n", 1474e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat cpus_to_use, ncpus); 1475e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 1476e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1477e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1478e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1479e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'd': 1480e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat idir = optarg; 1481e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (access(idir, R_OK | X_OK) != 0) { 1482e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal(idir, ERR_ARGS, 1483e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "Invalid input directory specified\n"); 1484e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 1485e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1486e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1487e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1488e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'F': 1489e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat find_records = 1; 1490e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1491e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1492e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'h': 1493e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat usage(); 1494e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat exit(0); 1495e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 1496e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1497e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'i': 1498e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat ibase = optarg; 1499e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1500e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1501e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'I': 1502e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat def_iterations = atoi(optarg); 1503e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (def_iterations <= 0) { 1504e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr, 1505e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "Invalid number of iterations %d\n", 1506e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat def_iterations); 1507e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat exit(ERR_ARGS); 1508e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 1509e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1510e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1511e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1512e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'M': 1513e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat read_map_devs(optarg); 1514e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1515e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1516e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'N': 1517e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat no_stalls = 1; 1518e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1519e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1520e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'x': 1521e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat r = sscanf(optarg,"%u",&acc_factor); 1522e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (r!=1) { 1523e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr, 1524e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "Invalid acceleration factor\n"); 1525e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat exit(ERR_ARGS); 1526e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 1527e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1528e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1529e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1530e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'V': 1531e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr, "btreplay -- version %s\n", 1532e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat my_btversion); 1533e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr, " Built on %s\n", 1534e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat build_date); 1535e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat exit(0); 1536e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 1537e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1538e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'v': 1539e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat verbose++; 1540e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1541e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1542e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat case 'W': 1543e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat write_enabled = 1; 1544e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat break; 1545e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1546e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat default: 1547e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat usage(); 1548e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal(NULL, ERR_ARGS, 1549e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat "Invalid command line argument %c\n", c); 1550e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 1551e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1552e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1553e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1554e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat while (optind < argc) 1555e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat add_input_dev(argv[optind++]); 1556e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1557e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (find_records) 1558e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat find_input_devs(idir); 1559e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1560e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (list_len(&input_devs) == 0) { 1561e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fatal(NULL, ERR_ARGS, "Missing required input dev name(s)\n"); 1562e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat /*NOTREACHED*/ 1563e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1564e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1565e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (cpus_to_use < 0) 1566e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat cpus_to_use = ncpus; 1567e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1568e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1569e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/* 1570e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 1571e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ==== MAIN ROUTINE ====================================================== 1572e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * ======================================================================== 1573e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1574e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1575e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 1576e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * set_signal_done - Signal handler, catches signals & sets signal_done 1577e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1578e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void set_signal_done(__attribute__((__unused__))int signum) 1579e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1580e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat signal_done = 1; 1581e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1582e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1583e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/** 1584e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * main - 1585e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @argc: Number of arguments 1586e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * @argv: Array of arguments 1587e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */ 1588e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatint main(int argc, char *argv[]) 1589e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{ 1590e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat int i; 1591e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat struct list_head *p; 1592e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1593e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat pgsize = getpagesize(); 1594e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat assert(pgsize > 0); 1595e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1596e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat setup_signal(SIGINT, set_signal_done); 1597e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat setup_signal(SIGTERM, set_signal_done); 1598e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1599e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat get_ncpus(); 1600e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat handle_args(argc, argv); 1601e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat find_input_files(); 1602e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1603e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat nfiles = list_len(&input_files); 1604e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat __list_for_each(p, &input_files) { 1605e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat tip_init(list_entry(p, struct thr_info, head)); 1606e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1607e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1608e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat wait_replays_ready(); 1609e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat for (i = 0; i < def_iterations; i++) { 1610e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat rgenesis = gettime(); 1611e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat start_iter(); 1612e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (verbose) 1613e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr, "I"); 1614e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat wait_iters_done(); 1615e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat } 1616e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1617e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat wait_replays_done(); 1618e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat wait_reclaims_done(); 1619e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1620e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat if (verbose) 1621e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat fprintf(stderr, "\n"); 1622e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1623e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat rem_input_files(); 1624e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat release_map_devs(); 1625e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat 1626e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat return 0; 1627e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} 1628