Merge pull request #3 from lxbsz/wip-52438
[ffsb.git] / ffsb_tg.h
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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_ */