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 58 struct ffsb_thread; 59 struct ffsb_config; 60 61 typedef 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 */ 108 void init_ffsb_tg(ffsb_tg_t *tg, unsigned num_threads, unsigned tg_num); 109 void 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 */ 117 typedef 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 */ 133 void *tg_run(void *); 134 135 void tg_print_config(ffsb_tg_t *tg); 136 void tg_print_config_aging(ffsb_tg_t *tg, char *fsname); 137 138 /* Adds all of this tg's results to res */ 139 void tg_collect_results(ffsb_tg_t *tg, ffsb_op_results_t *res); 140 141 /* Adds up all this tg's stats to totals */ 142 void 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 146 void tg_set_statsc(ffsb_tg_t *tg, ffsb_statsc_t *fsc); 147 148 void tg_set_bindfs(ffsb_tg_t *tg, int fsnum); 149 int tg_get_bindfs(ffsb_tg_t *tg); 150 151 unsigned tg_get_numthreads(ffsb_tg_t *tg); 152 153 void tg_set_op_weight(ffsb_tg_t *tg, char *opname, unsigned weight); 154 unsigned tg_get_op_weight(ffsb_tg_t *tg, char *opname); 155 156 void tg_set_read_random(ffsb_tg_t *tg, int rr); 157 void tg_set_write_random(ffsb_tg_t *tg, int wr); 158 void tg_set_fsync_file(ffsb_tg_t *tg, int fsync); 159 160 int tg_get_read_random(ffsb_tg_t *tg); 161 int tg_get_write_random(ffsb_tg_t *tg); 162 int tg_get_fsync_file(ffsb_tg_t *tg); 163 164 void tg_set_read_size(ffsb_tg_t *tg, uint64_t rs); 165 void tg_set_read_blocksize(ffsb_tg_t *tg, uint32_t rs); 166 167 void tg_set_read_skipsize(ffsb_tg_t *tg, uint32_t rs); 168 void tg_set_read_skip(ffsb_tg_t *tg, int rs); 169 170 void tg_set_write_size(ffsb_tg_t *tg, uint64_t ws); 171 void tg_set_write_blocksize(ffsb_tg_t *tg, uint32_t ws); 172 173 uint64_t tg_get_read_size(ffsb_tg_t *tg); 174 uint32_t tg_get_read_blocksize(ffsb_tg_t *tg); 175 176 int tg_get_read_skip(ffsb_tg_t *tg); 177 uint32_t tg_get_read_skipsize(ffsb_tg_t *tg); 178 179 uint64_t tg_get_write_size(ffsb_tg_t *tg); 180 uint32_t tg_get_write_blocksize(ffsb_tg_t *tg); 181 182 void tg_set_waittime(ffsb_tg_t *tg, unsigned time); 183 unsigned 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 */ 188 ffsb_barrier_t *tg_get_start_barrier(ffsb_tg_t *tg); 189 int tg_get_stopval(ffsb_tg_t *tg); 190 int 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 */ 195 typedef 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 */ 201 void tg_get_op(ffsb_tg_t *tg, randdata_t *rd, tg_op_params_t *params); 202 203 /* want stats for this tg ? */ 204 int tg_needs_stats(ffsb_tg_t *tg); 205 206 #endif /* _FFSB_TG_H_ */ 207