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#include "ffsb_tg.h"
19#include "ffsb_thread.h"
20#include "ffsb_op.h"
21#include "util.h"
22
23void init_ffsb_thread(ffsb_thread_t * ft, struct ffsb_tg *tg, unsigned bufsize,
24		      unsigned tg_num, unsigned thread_num)
25{
26	memset(ft, 0, sizeof(ffsb_thread_t));
27
28	ft->tg = tg;
29	ft->tg_num = tg_num;
30	ft->thread_num = thread_num;
31
32	if (bufsize)
33		ft_alter_bufsize(ft, bufsize);
34
35	init_random(&ft->rd, MAX_RANDBUF_SIZE);
36}
37
38void destroy_ffsb_thread(ffsb_thread_t * ft)
39{
40	free(ft->mallocbuf);
41	destroy_random(&ft->rd);
42	if (ft->fsd.config)
43		ffsb_statsd_destroy(&ft->fsd);
44}
45
46void ft_set_statsc(ffsb_thread_t * ft, ffsb_statsc_t * fsc)
47{
48	ffsb_statsd_init(&ft->fsd, fsc);
49}
50
51void *ft_run(void *data)
52{
53	ffsb_thread_t *ft = (ffsb_thread_t *) data;
54	tg_op_params_t params;
55	unsigned wait_time = tg_get_waittime(ft->tg);
56	int stopval = tg_get_stopval(ft->tg);
57
58	ffsb_barrier_wait(tg_get_start_barrier(ft->tg));
59
60	while (tg_get_flagval(ft->tg) != stopval) {
61		tg_get_op(ft->tg, &ft->rd, &params);
62		do_op(ft, params.fs, params.opnum);
63		ffsb_milli_sleep(wait_time);
64	}
65	return NULL;
66}
67
68void ft_alter_bufsize(ffsb_thread_t * ft, unsigned bufsize)
69{
70	if (ft->mallocbuf != NULL)
71		free(ft->mallocbuf);
72	ft->mallocbuf = ffsb_malloc(bufsize + 4096);
73	ft->alignedbuf = ffsb_align_4k(ft->mallocbuf + (4096 - 1));
74}
75
76char *ft_getbuf(ffsb_thread_t * ft)
77{
78	return ft->alignedbuf;
79}
80
81int ft_get_read_random(ffsb_thread_t * ft)
82{
83	return tg_get_read_random(ft->tg);
84}
85
86uint32_t ft_get_read_size(ffsb_thread_t * ft)
87{
88	return tg_get_read_size(ft->tg);
89}
90
91uint32_t ft_get_read_blocksize(ffsb_thread_t * ft)
92{
93	return tg_get_read_blocksize(ft->tg);
94}
95
96int ft_get_write_random(ffsb_thread_t * ft)
97{
98	return tg_get_write_random(ft->tg);
99}
100
101uint32_t ft_get_write_size(ffsb_thread_t * ft)
102{
103	return tg_get_write_size(ft->tg);
104}
105
106uint32_t ft_get_write_blocksize(ffsb_thread_t * ft)
107{
108	return tg_get_write_blocksize(ft->tg);
109}
110
111int ft_get_fsync_file(ffsb_thread_t * ft)
112{
113	return tg_get_fsync_file(ft->tg);
114}
115
116randdata_t *ft_get_randdata(ffsb_thread_t * ft)
117{
118	return &ft->rd;
119}
120
121void ft_incr_op(ffsb_thread_t * ft, unsigned opnum, unsigned increment,
122		uint64_t bytes)
123{
124	ft->results.ops[opnum] += increment;
125	ft->results.op_weight[opnum]++;
126	ft->results.bytes[opnum] += bytes;
127}
128
129void ft_add_readbytes(ffsb_thread_t * ft, uint32_t bytes)
130{
131	ft->results.read_bytes += bytes;
132}
133
134void ft_add_writebytes(ffsb_thread_t * ft, uint32_t bytes)
135{
136	ft->results.write_bytes += bytes;
137}
138
139ffsb_op_results_t *ft_get_results(ffsb_thread_t * ft)
140{
141	return &ft->results;
142}
143
144int ft_get_read_skip(ffsb_thread_t * ft)
145{
146	return tg_get_read_skip(ft->tg);
147}
148
149uint32_t ft_get_read_skipsize(ffsb_thread_t * ft)
150{
151	return tg_get_read_skipsize(ft->tg);
152}
153
154int ft_needs_stats(ffsb_thread_t * ft, syscall_t sys)
155{
156	int ret = 0;
157	if (ft && ft->fsd.config && !fsc_ignore_sys(ft->fsd.config, sys))
158		ret = 1;
159	return ret;
160}
161
162void ft_add_stat(ffsb_thread_t * ft, syscall_t sys, uint32_t val)
163{
164	if (ft)
165		ffsb_add_data(&ft->fsd, sys, val);
166}
167
168ffsb_statsd_t *ft_get_stats_data(ffsb_thread_t * ft)
169{
170	return &ft->fsd;
171}
172