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