1/* 2 * Copyright (c) International Business Machines Corp., 2001-2004 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 12 * the GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18#ifndef _FFSB_TG_H_ 19#define _FFSB_TG_H_ 20#include <inttypes.h> 21#include <stdlib.h> 22#include <sys/types.h> 23 24#include <pthread.h> 25 26#include "ffsb.h" 27#include "ffsb_op.h" 28#include "ffsb_thread.h" 29#include "ffsb_fs.h" 30#include "ffsb_stats.h" 31 32#include "util.h" /* for barrier obj */ 33 34/* "Thread Group" object defs. 35 * 36 * A thread group contains configuration information and can run its 37 * "gang" of threads performing a particular mix of operations. 38 * 39 * The thread group is responsible for creating the ffsb_thread 40 * objects which must ask the thread group object to select an 41 * operation and a filesystem to run that operation on. The thread 42 * objects don't contain any of the configuration information. 43 * 44 * Thread groups are also abstracted so they can be "run" arbitrarily 45 * which is useful because we can reuse them for aging. The running 46 * is a bit complex, the thread group has to have a callback function 47 * which is runs at a specified interval to determine when to 48 * terminate. 49 * 50 * To synchronize starting across many thread groups there are two 51 * barriers used, the first one "tg_barrier" in the run_params is to 52 * synchronize multiple thread-groups being ready to start, meaning 53 * that all their threads have been spawned The second one 54 * "thread_barrier" synchronizes all threads across multiple thread 55 * groups, so that they all start at once. 56*/ 57 58struct ffsb_thread; 59struct ffsb_config; 60 61typedef struct ffsb_tg { 62 unsigned tg_num; 63 unsigned num_threads; 64 unsigned op_weights[FFSB_NUMOPS]; 65 struct ffsb_thread *threads; 66 67 /* A threadgroup can be bound to just one filesystem. 68 * A value * < 0 , means we aren't bound to any. 69 */ 70 int bindfs; 71 72 int read_random; /* boolean */ 73 uint64_t read_size; 74 uint32_t read_blocksize; 75 76 int read_skip; /* boolean */ 77 uint32_t read_skipsize; 78 79 int write_random; /* boolean */ 80 uint64_t write_size; 81 uint32_t write_blocksize; 82 83 int fsync_file; /* boolean */ 84 85 /* Should be max(write_blocksize, read_blocksize) */ 86 uint32_t thread_bufsize; 87 88 /* these fields are calculated/set by tg_run() */ 89 unsigned sum_weights; 90 struct ffsb_config *fc; 91 ffsb_barrier_t *start_barrier; 92 93 /* Used for stopping the threads */ 94 int flagval; 95 int stopval; 96 97 /* Delay between every operation, in milliseconds*/ 98 unsigned wait_time; 99 100 /* stats configuration */ 101 int need_stats; 102 ffsb_statsc_t fsc; 103} ffsb_tg_t; 104 105/* Init should be the very first thing called on the tg. After that, 106 * the user can call the set methods and finally run. 107 */ 108void init_ffsb_tg(ffsb_tg_t *tg, unsigned num_threads, unsigned tg_num); 109void destroy_ffsb_tg(ffsb_tg_t *tg); 110 111/* Parameters needed to fire off a thread group. The main thread will 112 * evaluate poll_fn(poll_data) until it gets a nonzero return value. 113 * It will sleep for wait_time secs between calls The ffsb_config 114 * struct is needed for fs selection. Barriers are to synchronize 115 * multiple tgs and all threads pt is for pthread_create() 116 */ 117typedef struct tg_run_params { 118 ffsb_tg_t *tg; 119 int (*poll_fn)(void *); 120 void *poll_data; 121 unsigned wait_time; /* in sec */ 122 struct ffsb_config *fc; 123 ffsb_barrier_t *tg_barrier; 124 125 /* Should be initialized by caller to tg_run() */ 126 ffsb_barrier_t *thread_barrier; 127 pthread_t pt; 128} tg_run_params_t; 129 130/* This function is meant to be called as a parameter to 131 * pthread_create() 132 */ 133void *tg_run(void *); 134 135void tg_print_config(ffsb_tg_t *tg); 136void tg_print_config_aging(ffsb_tg_t *tg, char *fsname); 137 138/* Adds all of this tg's results to res */ 139void tg_collect_results(ffsb_tg_t *tg, ffsb_op_results_t *res); 140 141/* Adds up all this tg's stats to totals */ 142void tg_collect_stats(ffsb_tg_t *tg, ffsb_statsd_t *totals); 143 144/* getters/setters, setters should not be called after a run has begun */ 145 146void tg_set_statsc(ffsb_tg_t *tg, ffsb_statsc_t *fsc); 147 148void tg_set_bindfs(ffsb_tg_t *tg, int fsnum); 149int tg_get_bindfs(ffsb_tg_t *tg); 150 151unsigned tg_get_numthreads(ffsb_tg_t *tg); 152 153void tg_set_op_weight(ffsb_tg_t *tg, char *opname, unsigned weight); 154unsigned tg_get_op_weight(ffsb_tg_t *tg, char *opname); 155 156void tg_set_read_random(ffsb_tg_t *tg, int rr); 157void tg_set_write_random(ffsb_tg_t *tg, int wr); 158void tg_set_fsync_file(ffsb_tg_t *tg, int fsync); 159 160int tg_get_read_random(ffsb_tg_t *tg); 161int tg_get_write_random(ffsb_tg_t *tg); 162int tg_get_fsync_file(ffsb_tg_t *tg); 163 164void tg_set_read_size(ffsb_tg_t *tg, uint64_t rs); 165void tg_set_read_blocksize(ffsb_tg_t *tg, uint32_t rs); 166 167void tg_set_read_skipsize(ffsb_tg_t *tg, uint32_t rs); 168void tg_set_read_skip(ffsb_tg_t *tg, int rs); 169 170void tg_set_write_size(ffsb_tg_t *tg, uint64_t ws); 171void tg_set_write_blocksize(ffsb_tg_t *tg, uint32_t ws); 172 173uint64_t tg_get_read_size(ffsb_tg_t *tg); 174uint32_t tg_get_read_blocksize(ffsb_tg_t *tg); 175 176int tg_get_read_skip(ffsb_tg_t *tg); 177uint32_t tg_get_read_skipsize(ffsb_tg_t *tg); 178 179uint64_t tg_get_write_size(ffsb_tg_t *tg); 180uint32_t tg_get_write_blocksize(ffsb_tg_t *tg); 181 182void tg_set_waittime(ffsb_tg_t *tg, unsigned time); 183unsigned tg_get_waittime(ffsb_tg_t *tg); 184 185/* The threads in the tg should be the only ones using these (below) 186 * funcs. 187 */ 188ffsb_barrier_t *tg_get_start_barrier(ffsb_tg_t *tg); 189int tg_get_stopval(ffsb_tg_t *tg); 190int tg_get_flagval(ffsb_tg_t *tg); 191 192/* The threads in this tg will use this function to get an op to run, 193 * so all configuration specific information is kept in this object. 194 */ 195typedef struct tg_op_params { 196 struct ffsb_fs *fs; /* out parameter */ 197 unsigned opnum; /* out parameter */ 198} tg_op_params_t; 199 200/* tg and rd and in parameters, everything in params is out */ 201void tg_get_op(ffsb_tg_t *tg, randdata_t *rd, tg_op_params_t *params); 202 203/* want stats for this tg ? */ 204int tg_needs_stats(ffsb_tg_t *tg); 205 206#endif /* _FFSB_TG_H_ */ 207