/*
* Check if we are above the minimum rate given.
*/
-static int __check_min_rate(struct thread_data *td, struct timeval *now,
- enum fio_ddir ddir)
+static bool __check_min_rate(struct thread_data *td, struct timeval *now,
+ enum fio_ddir ddir)
{
unsigned long long bytes = 0;
unsigned long iops = 0;
assert(ddir_rw(ddir));
if (!td->o.ratemin[ddir] && !td->o.rate_iops_min[ddir])
- return 0;
+ return false;
/*
* allow a 2 second settle period in the beginning
*/
if (mtime_since(&td->start, now) < 2000)
- return 0;
+ return false;
iops += td->this_io_blocks[ddir];
bytes += td->this_io_bytes[ddir];
if (td->rate_bytes[ddir] || td->rate_blocks[ddir]) {
spent = mtime_since(&td->lastrate[ddir], now);
if (spent < td->o.ratecycle)
- return 0;
+ return false;
if (td->o.rate[ddir] || td->o.ratemin[ddir]) {
/*
if (bytes < td->rate_bytes[ddir]) {
log_err("%s: min rate %u not met\n", td->o.name,
ratemin);
- return 1;
+ return true;
} else {
if (spent)
rate = ((bytes - td->rate_bytes[ddir]) * 1000) / spent;
log_err("%s: min rate %u not met, got"
" %luKB/sec\n", td->o.name,
ratemin, rate);
- return 1;
+ return true;
}
}
} else {
if (iops < rate_iops) {
log_err("%s: min iops rate %u not met\n",
td->o.name, rate_iops);
- return 1;
+ return true;
} else {
if (spent)
rate = ((iops - td->rate_blocks[ddir]) * 1000) / spent;
log_err("%s: min iops rate %u not met,"
" got %lu\n", td->o.name,
rate_iops_min, rate);
- return 1;
+ return true;
}
}
}
td->rate_bytes[ddir] = bytes;
td->rate_blocks[ddir] = iops;
memcpy(&td->lastrate[ddir], now, sizeof(*now));
- return 0;
+ return false;
}
-static int check_min_rate(struct thread_data *td, struct timeval *now)
+static bool check_min_rate(struct thread_data *td, struct timeval *now)
{
- int ret = 0;
+ bool ret = false;
if (td->bytes_done[DDIR_READ])
ret |= __check_min_rate(td, now, DDIR_READ);
* Helper to handle the final sync of a file. Works just like the normal
* io path, just does everything sync.
*/
-static int fio_io_sync(struct thread_data *td, struct fio_file *f)
+static bool fio_io_sync(struct thread_data *td, struct fio_file *f)
{
struct io_u *io_u = __get_io_u(td);
int ret;
if (!io_u)
- return 1;
+ return true;
io_u->ddir = DDIR_SYNC;
io_u->file = f;
if (td_io_prep(td, io_u)) {
put_io_u(td, io_u);
- return 1;
+ return true;
}
requeue:
if (ret < 0) {
td_verror(td, io_u->error, "td_io_queue");
put_io_u(td, io_u);
- return 1;
+ return true;
} else if (ret == FIO_Q_QUEUED) {
if (io_u_queued_complete(td, 1) < 0)
- return 1;
+ return true;
} else if (ret == FIO_Q_COMPLETED) {
if (io_u->error) {
td_verror(td, io_u->error, "td_io_queue");
- return 1;
+ return true;
}
if (io_u_sync_complete(td, io_u) < 0)
- return 1;
+ return true;
} else if (ret == FIO_Q_BUSY) {
if (td_io_commit(td))
- return 1;
+ return true;
goto requeue;
}
- return 0;
+ return false;
}
static int fio_file_fsync(struct thread_data *td, struct fio_file *f)
__update_tv_cache(td);
}
-static inline int runtime_exceeded(struct thread_data *td, struct timeval *t)
+static inline bool runtime_exceeded(struct thread_data *td, struct timeval *t)
{
if (in_ramp_time(td))
- return 0;
+ return false;
if (!td->o.timeout)
- return 0;
+ return false;
if (utime_since(&td->epoch, t) >= td->o.timeout)
- return 1;
+ return true;
- return 0;
+ return false;
}
/*
td->ts.runtime[ddir] += (elapsed_us[ddir] + 999) / 1000;
}
-static int break_on_this_error(struct thread_data *td, enum fio_ddir ddir,
- int *retptr)
+static bool break_on_this_error(struct thread_data *td, enum fio_ddir ddir,
+ int *retptr)
{
int ret = *retptr;
eb = td_error_type(ddir, err);
if (!(td->o.continue_on_error & (1 << eb)))
- return 1;
+ return true;
if (td_non_fatal_error(td, eb, err)) {
/*
update_error_count(td, err);
td_clear_error(td);
*retptr = 0;
- return 0;
+ return false;
} else if (td->o.fill_device && err == ENOSPC) {
/*
* We expect to hit this error if
*/
td_clear_error(td);
fio_mark_td_terminate(td);
- return 1;
+ return true;
} else {
/*
* Stop the I/O in case of a fatal
* error.
*/
update_error_count(td, err);
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
static void check_update_rusage(struct thread_data *td)
return 0;
}
-static inline int io_in_polling(struct thread_data *td)
+static inline bool io_in_polling(struct thread_data *td)
{
return !td->o.iodepth_batch_complete_min &&
!td->o.iodepth_batch_complete_max;
dprint(FD_VERIFY, "exiting loop\n");
}
-static unsigned int exceeds_number_ios(struct thread_data *td)
+static bool exceeds_number_ios(struct thread_data *td)
{
unsigned long long number_ios;
if (!td->o.number_ios)
- return 0;
+ return false;
number_ios = ddir_rw_sum(td->io_blocks);
number_ios += td->io_u_queued + td->io_u_in_flight;
return number_ios >= (td->o.number_ios * td->loops);
}
-static int io_issue_bytes_exceeded(struct thread_data *td)
+static bool io_issue_bytes_exceeded(struct thread_data *td)
{
unsigned long long bytes, limit;
return bytes >= limit || exceeds_number_ios(td);
}
-static int io_complete_bytes_exceeded(struct thread_data *td)
+static bool io_complete_bytes_exceeded(struct thread_data *td)
{
unsigned long long bytes, limit;
return 0;
}
-static int keep_running(struct thread_data *td)
+static bool keep_running(struct thread_data *td)
{
unsigned long long limit;
if (td->done)
- return 0;
+ return false;
if (td->o.time_based)
- return 1;
+ return true;
if (td->o.loops) {
td->o.loops--;
- return 1;
+ return true;
}
if (exceeds_number_ios(td))
- return 0;
+ return false;
if (td->o.io_limit)
limit = td->o.io_limit;
*/
diff = limit - ddir_rw_sum(td->io_bytes);
if (diff < td_max_bs(td))
- return 0;
+ return false;
if (fio_files_done(td))
- return 0;
+ return false;
- return 1;
+ return true;
}
- return 0;
+ return false;
}
static int exec_string(struct thread_options *o, const char *string, const char *mode)
fio_terminate_threads(TERMINATE_ALL);
}
-static int __check_trigger_file(void)
+static bool __check_trigger_file(void)
{
struct stat sb;
if (!trigger_file)
- return 0;
+ return false;
if (stat(trigger_file, &sb))
- return 0;
+ return false;
if (unlink(trigger_file) < 0)
log_err("fio: failed to unlink %s: %s\n", trigger_file,
strerror(errno));
- return 1;
+ return true;
}
-static int trigger_timedout(void)
+static bool trigger_timedout(void)
{
if (trigger_timeout)
return time_since_genesis() >= trigger_timeout;
- return 0;
+ return false;
}
void exec_trigger(const char *cmd)
usleep(usecs);
}
-static int check_mount_writes(struct thread_data *td)
+static bool check_mount_writes(struct thread_data *td)
{
struct fio_file *f;
unsigned int i;
if (!td_write(td) || td->o.allow_mounted_write)
- return 0;
+ return false;
for_each_file(td, f, i) {
if (f->filetype != FIO_TYPE_BD)
goto mounted;
}
- return 0;
+ return false;
mounted:
log_err("fio: %s appears mounted, and 'allow_mounted_write' isn't set. Aborting.", f->file_name);
- return 1;
+ return true;
}
/*
static_assert="yes"
fi
echo "Static Assert $static_assert"
+
+##########################################
+# Check whether we have bool / stdbool.h
+have_bool="no"
+cat > $TMPC << EOF
+#include <stdbool.h>
+int main(int argc, char **argv)
+{
+ bool var = true;
+ return var != false;
+}
+EOF
+if compile_prog "" "" "bool"; then
+ have_bool="yes"
+fi
+echo "bool $have_bool"
+
#############################################################################
if test "$wordsize" = "64" ; then
if test "$static_assert" = "yes" ; then
output_sym "CONFIG_STATIC_ASSERT"
fi
+if test "$have_bool" = "yes" ; then
+ output_sym "CONFIG_HAVE_BOOL"
+fi
if test "$zlib" = "no" ; then
echo "Consider installing zlib-dev (zlib-devel), some fio features depend on it."
* The ->io_axmap contains a map of blocks we have or have not done io
* to yet. Used to make sure we cover the entire range in a fair fashion.
*/
-static int random_map_free(struct fio_file *f, const uint64_t block)
+static bool random_map_free(struct fio_file *f, const uint64_t block)
{
return !axmap_isset(f->io_axmap, block);
}
* Sort the reads for a verify phase in batches of verifysort_nr, if
* specified.
*/
-static inline int should_sort_io(struct thread_data *td)
+static inline bool should_sort_io(struct thread_data *td)
{
if (!td->o.verifysort_nr || !td->o.do_verify)
- return 0;
+ return false;
if (!td_random(td))
- return 0;
+ return false;
if (td->runstate != TD_VERIFYING)
- return 0;
+ return false;
if (td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE ||
td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE64)
- return 0;
+ return false;
- return 1;
+ return true;
}
-static int should_do_random(struct thread_data *td, enum fio_ddir ddir)
+static bool should_do_random(struct thread_data *td, enum fio_ddir ddir)
{
uint64_t frand_max;
unsigned int v;
unsigned long r;
if (td->o.perc_rand[ddir] == 100)
- return 1;
+ return true;
frand_max = rand_max(&td->seq_rand_state[ddir]);
r = __rand(&td->seq_rand_state[ddir]);
return __get_next_offset(td, io_u, is_random);
}
-static inline int io_u_fits(struct thread_data *td, struct io_u *io_u,
- unsigned int buflen)
+static inline bool io_u_fits(struct thread_data *td, struct io_u *io_u,
+ unsigned int buflen)
{
struct fio_file *f = io_u->file;
* We had an IO outside the latency target. Reduce the queue depth. If we
* are at QD=1, then it's time to give up.
*/
-static int __lat_target_failed(struct thread_data *td)
+static bool __lat_target_failed(struct thread_data *td)
{
if (td->latency_qd == 1)
- return 1;
+ return true;
td->latency_qd_high = td->latency_qd;
*/
io_u_quiesce(td);
lat_new_cycle(td);
- return 0;
+ return false;
}
-static int lat_target_failed(struct thread_data *td)
+static bool lat_target_failed(struct thread_data *td)
{
if (td->o.latency_percentile.u.f == 100.0)
return __lat_target_failed(td);
td->latency_failed++;
- return 0;
+ return false;
}
void lat_target_init(struct thread_data *td)
* If latency target is enabled, we might be ramping up or down and not
* using the full queue depth available.
*/
-int queue_full(const struct thread_data *td)
+bool queue_full(const struct thread_data *td)
{
const int qempty = io_u_qempty(&td->io_u_freelist);
if (qempty)
- return 1;
+ return true;
if (!td->o.latency_target)
- return 0;
+ return false;
return td->cur_depth >= td->latency_qd;
}
return io_u;
}
-static int check_get_trim(struct thread_data *td, struct io_u *io_u)
+static bool check_get_trim(struct thread_data *td, struct io_u *io_u)
{
if (!(td->flags & TD_F_TRIM_BACKLOG))
- return 0;
+ return false;
if (td->trim_entries) {
int get_trim = 0;
}
if (get_trim && !get_next_trim(td, io_u))
- return 1;
+ return true;
}
- return 0;
+ return false;
}
-static int check_get_verify(struct thread_data *td, struct io_u *io_u)
+static bool check_get_verify(struct thread_data *td, struct io_u *io_u)
{
if (!(td->flags & TD_F_VER_BACKLOG))
- return 0;
+ return false;
if (td->io_hist_len) {
int get_verify = 0;
if (get_verify && !get_next_verify(td, io_u)) {
td->verify_batch--;
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
/*
__io_u_log_error(td, io_u);
}
-static inline int gtod_reduce(struct thread_data *td)
+static inline bool gtod_reduce(struct thread_data *td)
{
return td->o.disable_clat && td->o.disable_lat && td->o.disable_slat
&& td->o.disable_bw;
extern void io_u_fill_buffer(struct thread_data *td, struct io_u *, unsigned int, unsigned int);
void io_u_mark_complete(struct thread_data *, unsigned int);
void io_u_mark_submit(struct thread_data *, unsigned int);
-int queue_full(const struct thread_data *);
+bool queue_full(const struct thread_data *);
int do_io_u_sync(const struct thread_data *, struct io_u *);
int do_io_u_trim(const struct thread_data *, struct io_u *);
return NULL;
}
-static int axmap_handler(struct axmap *axmap, uint64_t bit_nr,
- int (*func)(struct axmap_level *, unsigned long, unsigned int,
+static bool axmap_handler(struct axmap *axmap, uint64_t bit_nr,
+ bool (*func)(struct axmap_level *, unsigned long, unsigned int,
void *), void *data)
{
struct axmap_level *al;
al = &axmap->levels[i];
if (func(al, offset, bit, data))
- return 1;
+ return true;
}
- return 0;
+ return false;
}
-static int axmap_handler_topdown(struct axmap *axmap, uint64_t bit_nr,
- int (*func)(struct axmap_level *, unsigned long, unsigned int, void *),
+static bool axmap_handler_topdown(struct axmap *axmap, uint64_t bit_nr,
+ bool (*func)(struct axmap_level *, unsigned long, unsigned int, void *),
void *data)
{
struct axmap_level *al;
al = &axmap->levels[i];
if (func(al, offset, bit, data))
- return 1;
+ return true;
}
- return 0;
+ return false;
}
-static int axmap_clear_fn(struct axmap_level *al, unsigned long offset,
+static bool axmap_clear_fn(struct axmap_level *al, unsigned long offset,
unsigned int bit, void *unused)
{
if (!(al->map[offset] & (1UL << bit)))
- return 1;
+ return true;
al->map[offset] &= ~(1UL << bit);
- return 0;
+ return false;
}
void axmap_clear(struct axmap *axmap, uint64_t bit_nr)
#endif
};
-static int axmap_set_fn(struct axmap_level *al, unsigned long offset,
+static bool axmap_set_fn(struct axmap_level *al, unsigned long offset,
unsigned int bit, void *__data)
{
struct axmap_set_data *data = __data;
*/
overlap = al->map[offset] & mask;
if (overlap == mask)
- return 1;
+ return true;
while (overlap) {
unsigned long clear_mask = ~(1UL << ffz(~overlap));
__axmap_set(axmap, bit_nr, &data);
}
-unsigned int axmap_set_nr(struct axmap *axmap, uint64_t bit_nr, unsigned int nr_bits)
+unsigned int axmap_set_nr(struct axmap *axmap, uint64_t bit_nr,
+ unsigned int nr_bits)
{
unsigned int set_bits = 0;
return set_bits;
}
-static int axmap_isset_fn(struct axmap_level *al, unsigned long offset,
- unsigned int bit, void *unused)
+static bool axmap_isset_fn(struct axmap_level *al, unsigned long offset,
+ unsigned int bit, void *unused)
{
return (al->map[offset] & (1UL << bit)) != 0;
}
-int axmap_isset(struct axmap *axmap, uint64_t bit_nr)
+bool axmap_isset(struct axmap *axmap, uint64_t bit_nr)
{
if (bit_nr <= axmap->nr_bits)
return axmap_handler_topdown(axmap, bit_nr, axmap_isset_fn, NULL);
- return 0;
+ return false;
}
static uint64_t axmap_find_first_free(struct axmap *axmap, unsigned int level,
uint64_t bit;
};
-static int axmap_next_free_fn(struct axmap_level *al, unsigned long offset,
+static bool axmap_next_free_fn(struct axmap_level *al, unsigned long offset,
unsigned int bit, void *__data)
{
struct axmap_next_free_data *data = __data;
uint64_t mask = ~bit_masks[(data->bit + 1) & BLOCKS_PER_UNIT_MASK];
if (!(mask & ~al->map[offset]))
- return 0;
+ return false;
if (al->map[offset] != -1UL) {
data->level = al->level;
data->offset = offset;
- return 1;
+ return true;
}
data->bit = (data->bit + BLOCKS_PER_UNIT - 1) / BLOCKS_PER_UNIT;
- return 0;
+ return false;
}
/*
#define FIO_BITMAP_H
#include <inttypes.h>
+#include "types.h"
struct axmap;
struct axmap *axmap_new(unsigned long nr_bits);
void axmap_clear(struct axmap *axmap, uint64_t bit_nr);
void axmap_set(struct axmap *axmap, uint64_t bit_nr);
unsigned int axmap_set_nr(struct axmap *axmap, uint64_t bit_nr, unsigned int nr_bits);
-int axmap_isset(struct axmap *axmap, uint64_t bit_nr);
+bool axmap_isset(struct axmap *axmap, uint64_t bit_nr);
uint64_t axmap_next_free(struct axmap *axmap, uint64_t bit_nr);
void axmap_reset(struct axmap *axmap);
--- /dev/null
+#ifndef FIO_TYPES_H
+#define FIO_TYPES_H
+
+#ifndef CONFIG_HAVE_BOOL
+typedef int bool;
+#ifndef false
+#define false 0
+#endif
+#ifndef true
+#define true 1
+#endif
+#else
+#include <stdbool.h>
+#endif
+
+#endif
#include <stdlib.h>
#include "../arch/arch.h"
+#include "../lib/types.h"
enum {
os_linux = 1,