struct timeval has usec resolution whereas struct timespec has nsec resolution.
This commit changes several dozen instances of struct timeval to struct timespec.
All of the output is unchanged.
The ticks to nsec conversion in this patch is broken but fixed in a later patch.
/*
* Check if we are above the minimum rate given.
*/
-static bool __check_min_rate(struct thread_data *td, struct timeval *now,
+static bool __check_min_rate(struct thread_data *td, struct timespec *now,
enum fio_ddir ddir)
{
unsigned long long bytes = 0;
return false;
}
-static bool check_min_rate(struct thread_data *td, struct timeval *now)
+static bool check_min_rate(struct thread_data *td, struct timespec *now)
{
bool ret = false;
return ret;
}
-static inline void __update_tv_cache(struct thread_data *td)
+static inline void __update_ts_cache(struct thread_data *td)
{
- fio_gettime(&td->tv_cache, NULL);
+ fio_gettime(&td->ts_cache, NULL);
}
-static inline void update_tv_cache(struct thread_data *td)
+static inline void update_ts_cache(struct thread_data *td)
{
- if ((++td->tv_cache_nr & td->tv_cache_mask) == td->tv_cache_mask)
- __update_tv_cache(td);
+ if ((++td->ts_cache_nr & td->ts_cache_mask) == td->ts_cache_mask)
+ __update_ts_cache(td);
}
-static inline bool runtime_exceeded(struct thread_data *td, struct timeval *t)
+static inline bool runtime_exceeded(struct thread_data *td, struct timespec *t)
{
if (in_ramp_time(td))
return false;
}
}
-static int wait_for_completions(struct thread_data *td, struct timeval *time)
+static int wait_for_completions(struct thread_data *td, struct timespec *time)
{
const int full = queue_full(td);
int min_evts = 0;
int io_queue_event(struct thread_data *td, struct io_u *io_u, int *ret,
enum fio_ddir ddir, uint64_t *bytes_issued, int from_verify,
- struct timeval *comp_time)
+ struct timespec *comp_time)
{
int ret2;
enum fio_ddir ddir;
int full;
- update_tv_cache(td);
+ update_ts_cache(td);
check_update_rusage(td);
- if (runtime_exceeded(td, &td->tv_cache)) {
- __update_tv_cache(td);
- if (runtime_exceeded(td, &td->tv_cache)) {
+ if (runtime_exceeded(td, &td->ts_cache)) {
+ __update_ts_cache(td);
+ if (runtime_exceeded(td, &td->ts_cache)) {
fio_mark_td_terminate(td);
break;
}
while ((td->o.read_iolog_file && !flist_empty(&td->io_log_list)) ||
(!flist_empty(&td->trim_list)) || !io_issue_bytes_exceeded(td) ||
td->o.time_based) {
- struct timeval comp_time;
+ struct timespec comp_time;
struct io_u *io_u;
int full;
enum fio_ddir ddir;
if (td->terminate || td->done)
break;
- update_tv_cache(td);
+ update_ts_cache(td);
- if (runtime_exceeded(td, &td->tv_cache)) {
- __update_tv_cache(td);
- if (runtime_exceeded(td, &td->tv_cache)) {
+ if (runtime_exceeded(td, &td->ts_cache)) {
+ __update_ts_cache(td);
+ if (runtime_exceeded(td, &td->ts_cache)) {
fio_mark_td_terminate(td);
break;
}
uint64_t verify_bytes;
fio_gettime(&td->start, NULL);
- memcpy(&td->tv_cache, &td->start, sizeof(td->start));
+ memcpy(&td->ts_cache, &td->start, sizeof(td->start));
if (clear_state) {
clear_io_state(td, 0);
while (todo) {
struct thread_data *map[REAL_MAX_JOBS];
- struct timeval this_start;
+ struct timespec this_start;
int this_jobs = 0, left;
struct fork_data *fd;
.client_type = FIO_CLIENT_TYPE_CLI,
};
-static struct timeval eta_tv;
+static struct timespec eta_ts;
static FLIST_HEAD(client_list);
static FLIST_HEAD(eta_list);
}
static int client_check_cmd_timeout(struct fio_client *client,
- struct timeval *now)
+ struct timespec *now)
{
struct fio_net_cmd_reply *reply;
struct flist_head *entry, *tmp;
flist_for_each_safe(entry, tmp, &client->cmd_list) {
reply = flist_entry(entry, struct fio_net_cmd_reply, list);
- if (mtime_since(&reply->tv, now) < FIO_NET_CLIENT_TIMEOUT)
+ if (mtime_since(&reply->ts, now) < FIO_NET_CLIENT_TIMEOUT)
continue;
if (!handle_cmd_timeout(client, reply))
{
struct fio_client *client;
struct flist_head *entry, *tmp;
- struct timeval tv;
+ struct timespec ts;
int ret = 0;
- fio_gettime(&tv, NULL);
+ fio_gettime(&ts, NULL);
flist_for_each_safe(entry, tmp, &client_list) {
client = flist_entry(entry, struct fio_client, list);
if (flist_empty(&client->cmd_list))
continue;
- if (!client_check_cmd_timeout(client, &tv))
+ if (!client_check_cmd_timeout(client, &ts))
continue;
if (client->ops->timed_out)
struct pollfd *pfds;
int i, ret = 0, retval = 0;
- fio_gettime(&eta_tv, NULL);
+ fio_gettime(&eta_ts, NULL);
pfds = malloc(nr_clients * sizeof(struct pollfd));
assert(i == nr_clients);
do {
- struct timeval tv;
+ struct timespec ts;
int timeout;
- fio_gettime(&tv, NULL);
- if (mtime_since(&eta_tv, &tv) >= 900) {
+ fio_gettime(&ts, NULL);
+ if (mtime_since(&eta_ts, &ts) >= 900) {
request_client_etas(ops);
- memcpy(&eta_tv, &tv, sizeof(tv));
+ memcpy(&eta_ts, &ts, sizeof(ts));
if (fio_check_clients_timed_out())
break;
fill_random_buf(&state, buf, CHUNK);
for (i = 0; t[i].name; i++) {
- struct timeval tv;
+ struct timespec ts;
double mb_sec;
uint64_t usec;
char pre[3];
t[i].fn(&t[i], buf, CHUNK);
}
- fio_gettime(&tv, NULL);
+ fio_gettime(&ts, NULL);
t[i].fn(&t[i], buf, CHUNK);
- usec = utime_since_now(&tv);
+ usec = utime_since_now(&ts);
if (usec) {
mb_sec = (double) mb / (double) usec;
static void update_io_tick_disk(struct disk_util *du)
{
struct disk_util_stat __dus, *dus, *ldus;
- struct timeval t;
+ struct timespec t;
if (!du->users)
return;
*/
struct flist_head slaves;
- struct timeval time;
+ struct timespec time;
struct fio_mutex *lock;
unsigned long users;
{
int i;
struct io_u *io_u;
- struct timeval now;
+ struct timespec now;
if (!fio_fill_issue_time(td))
return;
static void fio_libaio_queued(struct thread_data *td, struct io_u **io_us,
unsigned int nr)
{
- struct timeval now;
+ struct timespec now;
unsigned int i;
if (!fio_fill_issue_time(td))
struct libaio_data *ld = td->io_ops_data;
struct iocb **iocbs;
struct io_u **io_us;
- struct timeval tv;
+ struct timespec ts;
int ret, wait_start = 0;
if (!ld->queued)
break;
}
if (!wait_start) {
- fio_gettime(&tv, NULL);
+ fio_gettime(&ts, NULL);
wait_start = 1;
- } else if (mtime_since_now(&tv) > 30000) {
+ } else if (mtime_since_now(&ts) > 30000) {
log_err("fio: aio appears to be stalled, giving up\n");
break;
}
unsigned int nr)
{
struct rdmaio_data *rd = td->io_ops_data;
- struct timeval now;
+ struct timespec now;
unsigned int i;
if (!fio_fill_issue_time(td))
uint64_t rate_time, disp_time, bw_avg_time, *eta_secs;
unsigned long long io_bytes[DDIR_RWDIR_CNT];
unsigned long long io_iops[DDIR_RWDIR_CNT];
- struct timeval now;
+ struct timespec now;
static unsigned long long rate_io_bytes[DDIR_RWDIR_CNT];
static unsigned long long disp_io_bytes[DDIR_RWDIR_CNT];
static unsigned long long disp_io_iops[DDIR_RWDIR_CNT];
- static struct timeval rate_prev_time, disp_prev_time;
+ static struct timespec rate_prev_time, disp_prev_time;
if (!force) {
if (!(output_format & FIO_OUTPUT_NORMAL) &&
void display_thread_status(struct jobs_eta *je)
{
- static struct timeval disp_eta_new_line;
+ static struct timespec disp_eta_new_line;
static int eta_new_line_init, eta_new_line_pending;
static int linelen_last;
static int eta_good;
struct thread_data *parent;
uint64_t stat_io_bytes[DDIR_RWDIR_CNT];
- struct timeval bw_sample_time;
+ struct timespec bw_sample_time;
uint64_t stat_io_blocks[DDIR_RWDIR_CNT];
- struct timeval iops_sample_time;
+ struct timespec iops_sample_time;
volatile int update_rusage;
struct fio_mutex *rusage_sem;
unsigned long rate_bytes[DDIR_RWDIR_CNT];
unsigned long rate_blocks[DDIR_RWDIR_CNT];
unsigned long long rate_io_issue_bytes[DDIR_RWDIR_CNT];
- struct timeval lastrate[DDIR_RWDIR_CNT];
+ struct timespec lastrate[DDIR_RWDIR_CNT];
int64_t last_usec[DDIR_RWDIR_CNT];
struct frand_state poisson_state[DDIR_RWDIR_CNT];
*/
struct frand_state random_state;
- struct timeval start; /* start of this loop */
- struct timeval epoch; /* time job was started */
+ struct timespec start; /* start of this loop */
+ struct timespec epoch; /* time job was started */
unsigned long long unix_epoch; /* Time job was started, unix epoch based. */
- struct timeval last_issue;
+ struct timespec last_issue;
long time_offset;
- struct timeval tv_cache;
- struct timeval terminate_time;
- unsigned int tv_cache_nr;
- unsigned int tv_cache_mask;
+ struct timespec ts_cache;
+ struct timespec terminate_time;
+ unsigned int ts_cache_nr;
+ unsigned int ts_cache_mask;
unsigned int ramp_time_over;
/*
* Time since last latency_window was started
*/
- struct timeval latency_ts;
+ struct timespec latency_ts;
unsigned int latency_qd;
unsigned int latency_qd_high;
unsigned int latency_qd_low;
extern int io_queue_event(struct thread_data *td, struct io_u *io_u, int *ret,
enum fio_ddir ddir, uint64_t *bytes_issued, int from_verify,
- struct timeval *comp_time);
+ struct timespec *comp_time);
/*
* Latency target helpers
#include "lib/types.h"
struct thread_data;
-extern uint64_t utime_since(const struct timeval *,const struct timeval *);
-extern uint64_t utime_since_now(const struct timeval *);
-extern uint64_t mtime_since(const struct timeval *, const struct timeval *);
-extern uint64_t mtime_since_now(const struct timeval *);
-extern uint64_t time_since_now(const struct timeval *);
+extern uint64_t utime_since(const struct timespec *,const struct timespec *);
+extern uint64_t utime_since_now(const struct timespec *);
+extern uint64_t mtime_since(const struct timespec *, const struct timespec *);
+extern uint64_t mtime_since_now(const struct timespec *);
+extern uint64_t mtime_since_tv(const struct timeval *, const struct timeval *);
+extern uint64_t time_since_now(const struct timespec *);
extern uint64_t time_since_genesis(void);
extern uint64_t mtime_since_genesis(void);
extern uint64_t utime_since_genesis(void);
extern uint64_t usec_spin(unsigned int);
extern uint64_t usec_sleep(struct thread_data *, unsigned long);
-extern void fill_start_time(struct timeval *);
+extern void fill_start_time(struct timespec *);
extern void set_genesis_time(void);
extern bool ramp_time_over(struct thread_data *);
extern bool in_ramp_time(struct thread_data *);
extern void fio_time_init(void);
-extern void timeval_add_msec(struct timeval *, unsigned int);
+extern void timespec_add_msec(struct timespec *, unsigned int);
extern void set_epoch_time(struct thread_data *, int);
#endif
#include "fio.h"
#include "smalloc.h"
-struct timeval *fio_tv = NULL;
+struct timespec *fio_ts = NULL;
int fio_gtod_offload = 0;
static pthread_t gtod_thread;
static os_cpu_mask_t fio_gtod_cpumask;
void fio_gtod_init(void)
{
- if (fio_tv)
+ if (fio_ts)
return;
- fio_tv = smalloc(sizeof(struct timeval));
- if (!fio_tv)
+ fio_ts = smalloc(sizeof(*fio_ts));
+ if (!fio_ts)
log_err("fio: smalloc pool exhausted\n");
}
static void fio_gtod_update(void)
{
- if (fio_tv) {
+ if (fio_ts) {
struct timeval __tv;
gettimeofday(&__tv, NULL);
- fio_tv->tv_sec = __tv.tv_sec;
+ fio_ts->tv_sec = __tv.tv_sec;
write_barrier();
- fio_tv->tv_usec = __tv.tv_usec;
+ fio_ts->tv_nsec = __tv.tv_usec * 1000;
write_barrier();
}
}
#if defined(ARCH_HAVE_CPU_CLOCK)
#ifndef ARCH_CPU_CLOCK_CYCLES_PER_USEC
static unsigned long cycles_per_usec;
-static unsigned long inv_cycles_per_usec;
+static unsigned long inv_cycles_per_nsec;
static uint64_t max_cycles_for_mult;
+#define NSEC_INV_FACTOR 4096
#endif
#ifdef ARCH_CPU_CLOCK_WRAPS
static unsigned long long cycles_start, cycles_wrap;
}
#endif
-static void __fio_gettime(struct timeval *tp)
+static void __fio_gettime(struct timespec *tp)
{
switch (fio_clock_source) {
#ifdef CONFIG_GETTIMEOFDAY
- case CS_GTOD:
- gettimeofday(tp, NULL);
+ case CS_GTOD: {
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+
+ tp->tv_sec = tv.tv_sec;
+ tp->tv_nsec = tv.tv_usec * 1000;
break;
+ }
#endif
#ifdef CONFIG_CLOCK_GETTIME
case CS_CGETTIME: {
- struct timespec ts;
-
- if (fill_clock_gettime(&ts) < 0) {
+ if (fill_clock_gettime(tp) < 0) {
log_err("fio: clock_gettime fails\n");
assert(0);
}
-
- tp->tv_sec = ts.tv_sec;
- tp->tv_usec = ts.tv_nsec / 1000;
break;
}
#endif
#ifdef ARCH_HAVE_CPU_CLOCK
case CS_CPUCLOCK: {
- uint64_t usecs, t;
+ uint64_t nsecs, t;
struct tv_valid *tv;
#ifdef CONFIG_TLS_THREAD
tv->last_cycles = t;
tv->last_tv_valid = 1;
#ifdef ARCH_CPU_CLOCK_CYCLES_PER_USEC
- usecs = t / ARCH_CPU_CLOCK_CYCLES_PER_USEC;
+ nsecs = t * 1000 / ARCH_CPU_CLOCK_CYCLES_PER_USEC;
#else
if (t < max_cycles_for_mult)
- usecs = (t * inv_cycles_per_usec) / 16777216UL;
+ nsecs = (t * inv_cycles_per_nsec) / NSEC_INV_FACTOR;
else
- usecs = t / cycles_per_usec;
+ nsecs = (t / NSEC_INV_FACTOR) * inv_cycles_per_nsec;
#endif
- tp->tv_sec = usecs / 1000000;
- tp->tv_usec = usecs % 1000000;
+ tp->tv_sec = nsecs / 1000000000ULL;
+ tp->tv_nsec = nsecs % 1000000000ULL;
break;
}
#endif
}
#ifdef FIO_DEBUG_TIME
-void fio_gettime(struct timeval *tp, void *caller)
+void fio_gettime(struct timespec *tp, void *caller)
#else
-void fio_gettime(struct timeval *tp, void fio_unused *caller)
+void fio_gettime(struct timespec *tp, void fio_unused *caller)
#endif
{
#ifdef FIO_DEBUG_TIME
#if defined(ARCH_HAVE_CPU_CLOCK) && !defined(ARCH_CPU_CLOCK_CYCLES_PER_USEC)
static unsigned long get_cycles_per_usec(void)
{
- struct timeval s, e;
+ struct timespec s, e;
uint64_t c_s, c_e;
enum fio_cs old_cs = fio_clock_source;
uint64_t elapsed;
(unsigned long long) maxc, mean, S);
cycles_per_usec = avg;
- inv_cycles_per_usec = 16777216UL / cycles_per_usec;
- max_cycles_for_mult = ~0ULL / inv_cycles_per_usec;
- dprint(FD_TIME, "inv_cycles_per_usec=%lu\n", inv_cycles_per_usec);
+ inv_cycles_per_nsec = NSEC_INV_FACTOR * 1000 / cycles_per_usec;
+ max_cycles_for_mult = ~0ULL / inv_cycles_per_nsec;
+ dprint(FD_TIME, "inv_cycles_per_nsec=%lu\n", inv_cycles_per_nsec);
#ifdef ARCH_CPU_CLOCK_WRAPS
cycles_start = get_cpu_clock();
dprint(FD_TIME, "cycles_start=%llu\n", cycles_start);
log_info("fio: clocksource=cpu may not be reliable\n");
}
-uint64_t utime_since(const struct timeval *s, const struct timeval *e)
+uint64_t utime_since(const struct timespec *s, const struct timespec *e)
{
int64_t sec, usec;
sec = e->tv_sec - s->tv_sec;
- usec = e->tv_usec - s->tv_usec;
+ usec = (e->tv_nsec - s->tv_nsec) / 1000;
if (sec > 0 && usec < 0) {
sec--;
usec += 1000000;
return usec + (sec * 1000000);
}
-uint64_t utime_since_now(const struct timeval *s)
+uint64_t utime_since_now(const struct timespec *s)
{
- struct timeval t;
+ struct timespec t;
#ifdef FIO_DEBUG_TIME
void *p = __builtin_return_address(0);
return utime_since(s, &t);
}
-uint64_t mtime_since(const struct timeval *s, const struct timeval *e)
+uint64_t mtime_since_tv(const struct timeval *s, const struct timeval *e)
{
- long sec, usec;
+ int64_t sec, usec;
sec = e->tv_sec - s->tv_sec;
- usec = e->tv_usec - s->tv_usec;
+ usec = (e->tv_usec - s->tv_usec);
if (sec > 0 && usec < 0) {
sec--;
usec += 1000000;
return sec + usec;
}
-uint64_t mtime_since_now(const struct timeval *s)
+uint64_t mtime_since_now(const struct timespec *s)
{
- struct timeval t;
+ struct timespec t;
#ifdef FIO_DEBUG_TIME
void *p = __builtin_return_address(0);
return mtime_since(s, &t);
}
-uint64_t time_since_now(const struct timeval *s)
+uint64_t mtime_since(const struct timespec *s, const struct timespec *e)
+{
+ int64_t sec, usec;
+
+ sec = e->tv_sec - s->tv_sec;
+ usec = (e->tv_nsec - s->tv_nsec) / 1000;
+ if (sec > 0 && usec < 0) {
+ sec--;
+ usec += 1000000;
+ }
+
+ if (sec < 0 || (sec == 0 && usec < 0))
+ return 0;
+
+ sec *= 1000;
+ usec /= 1000;
+ return sec + usec;
+}
+
+uint64_t time_since_now(const struct timespec *s)
{
return mtime_since_now(s) / 1000;
}
CS_INVAL,
};
-extern void fio_gettime(struct timeval *, void *);
+extern void fio_gettime(struct timespec *, void *);
extern void fio_gtod_init(void);
extern void fio_clock_init(void);
extern int fio_start_gtod_thread(void);
extern int fio_monotonic_clocktest(int debug);
extern void fio_local_clock_init(int);
-extern struct timeval *fio_tv;
+extern struct timespec *fio_ts;
-static inline int fio_gettime_offload(struct timeval *tv)
+static inline int fio_gettime_offload(struct timespec *ts)
{
time_t last_sec;
- if (!fio_tv)
+ if (!fio_ts)
return 0;
do {
read_barrier();
- last_sec = tv->tv_sec = fio_tv->tv_sec;
- tv->tv_usec = fio_tv->tv_usec;
- } while (fio_tv->tv_sec != last_sec);
+ last_sec = ts->tv_sec = fio_ts->tv_sec;
+ ts->tv_nsec = fio_ts->tv_nsec;
+ } while (fio_ts->tv_sec != last_sec);
return 1;
}
{
struct helper_data *hd = data;
unsigned int msec_to_next_event, next_log, next_ss = STEADYSTATE_MSEC;
- struct timeval tv, last_du, last_ss;
+ struct timeval tv;
+ struct timespec ts, last_du, last_ss;
int ret = 0;
sk_out_assign(hd->sk_out);
gettimeofday(&tv, NULL);
- memcpy(&last_du, &tv, sizeof(tv));
- memcpy(&last_ss, &tv, sizeof(tv));
+ ts.tv_sec = tv.tv_sec;
+ ts.tv_nsec = tv.tv_usec * 1000;
+ memcpy(&last_du, &ts, sizeof(ts));
+ memcpy(&last_ss, &ts, sizeof(ts));
fio_mutex_up(hd->startup_mutex);
msec_to_next_event = DISK_UTIL_MSEC;
while (!ret && !hd->exit) {
- struct timespec ts;
- struct timeval now;
uint64_t since_du, since_ss = 0;
- timeval_add_msec(&tv, msec_to_next_event);
- ts.tv_sec = tv.tv_sec;
- ts.tv_nsec = tv.tv_usec * 1000;
+ timespec_add_msec(&ts, msec_to_next_event);
pthread_mutex_lock(&hd->lock);
pthread_cond_timedwait(&hd->cond, &hd->lock, &ts);
- gettimeofday(&now, NULL);
+ gettimeofday(&tv, NULL);
+ ts.tv_sec = tv.tv_sec;
+ ts.tv_nsec = tv.tv_usec * 1000;
if (hd->reset) {
- memcpy(&tv, &now, sizeof(tv));
- memcpy(&last_du, &now, sizeof(last_du));
- memcpy(&last_ss, &now, sizeof(last_ss));
+ memcpy(&last_du, &ts, sizeof(ts));
+ memcpy(&last_ss, &ts, sizeof(ts));
hd->reset = 0;
}
pthread_mutex_unlock(&hd->lock);
- since_du = mtime_since(&last_du, &now);
+ since_du = mtime_since(&last_du, &ts);
if (since_du >= DISK_UTIL_MSEC || DISK_UTIL_MSEC - since_du < 10) {
ret = update_io_ticks();
- timeval_add_msec(&last_du, DISK_UTIL_MSEC);
+ timespec_add_msec(&last_du, DISK_UTIL_MSEC);
msec_to_next_event = DISK_UTIL_MSEC;
if (since_du >= DISK_UTIL_MSEC)
msec_to_next_event -= (since_du - DISK_UTIL_MSEC);
next_log = DISK_UTIL_MSEC;
if (steadystate_enabled) {
- since_ss = mtime_since(&last_ss, &now);
+ since_ss = mtime_since(&last_ss, &ts);
if (since_ss >= STEADYSTATE_MSEC || STEADYSTATE_MSEC - since_ss < 10) {
steadystate_check();
- timeval_add_msec(&last_ss, since_ss);
+ timespec_add_msec(&last_ss, since_ss);
if (since_ss > STEADYSTATE_MSEC)
next_ss = STEADYSTATE_MSEC - (since_ss - STEADYSTATE_MSEC);
else
static double calibrate_unit(unsigned char *data)
{
unsigned long t, i, j, k;
- struct timeval tps;
+ struct timespec tps;
double tunit = 0.0;
for (i = 0; i < CALIBRATE_RUNS; i++) {
void fio_idle_prof_init(void)
{
int i, ret;
- struct timeval tp;
struct timespec ts;
pthread_attr_t tattr;
struct idle_prof_thread *ipt;
pthread_mutex_lock(&ipt->init_lock);
while ((ipt->state != TD_EXITED) &&
(ipt->state!=TD_INITIALIZED)) {
- fio_gettime(&tp, NULL);
- ts.tv_sec = tp.tv_sec + 1;
- ts.tv_nsec = tp.tv_usec * 1000;
+ fio_gettime(&ts, NULL);
+ ts.tv_sec += 1;
pthread_cond_timedwait(&ipt->cond, &ipt->init_lock, &ts);
}
pthread_mutex_unlock(&ipt->init_lock);
{
int i;
uint64_t runt;
- struct timeval tp;
struct timespec ts;
struct idle_prof_thread *ipt;
pthread_mutex_lock(&ipt->start_lock);
while ((ipt->state != TD_EXITED) &&
(ipt->state!=TD_NOT_CREATED)) {
- fio_gettime(&tp, NULL);
- ts.tv_sec = tp.tv_sec + 1;
- ts.tv_nsec = tp.tv_usec * 1000;
+ fio_gettime(&ts, NULL);
+ ts.tv_sec += 1;
/* timed wait in case a signal is not received */
pthread_cond_timedwait(&ipt->cond, &ipt->start_lock, &ts);
}
pthread_t thread;
int cpu;
int state;
- struct timeval tps;
- struct timeval tpe;
+ struct timespec tps;
+ struct timespec tpe;
double cali_time; /* microseconds to finish a unit work */
double loops;
double idleness;
int error; /* output */
uint64_t bytes_done[DDIR_RWDIR_CNT]; /* output */
- struct timeval time; /* output */
+ struct timespec time; /* output */
};
/*
* the buffer, given by the product of the usec time
* and the actual offset.
*/
- offset = (io_u->start_time.tv_usec ^ boffset) & 511;
+ offset = ((io_u->start_time.tv_nsec/1000) ^ boffset) & 511;
offset &= ~(sizeof(uint64_t) - 1);
if (offset >= 512 - sizeof(uint64_t))
offset -= sizeof(uint64_t);
* The io unit
*/
struct io_u {
- struct timeval start_time;
- struct timeval issue_time;
+ struct timespec start_time;
+ struct timespec issue_time;
struct fio_file *file;
unsigned int flags;
*/
if (td->o.read_iolog_file)
memcpy(&td->last_issue, &io_u->issue_time,
- sizeof(struct timeval));
+ sizeof(io_u->issue_time));
}
if (ddir_rw(ddir)) {
*/
if (td->o.read_iolog_file)
memcpy(&td->last_issue, &io_u->issue_time,
- sizeof(struct timeval));
+ sizeof(io_u->issue_time));
}
return ret;
{
uint64_t usec = utime_since_now(&td->last_issue);
uint64_t this_delay;
- struct timeval tv;
+ struct timespec ts;
if (delay < td->time_offset) {
td->time_offset = 0;
delay -= usec;
- fio_gettime(&tv, NULL);
+ fio_gettime(&ts, NULL);
while (delay && !td->terminate) {
this_delay = delay;
if (this_delay > 500000)
delay -= this_delay;
}
- usec = utime_since_now(&tv);
+ usec = utime_since_now(&ts);
if (usec > delay)
td->time_offset = usec - delay;
else
}
set_epoch_time(td, td->o.log_unix_epoch);
- memcpy(&td->start, &td->epoch, sizeof(struct timeval));
- memcpy(&td->iops_sample_time, &td->epoch, sizeof(struct timeval));
- memcpy(&td->bw_sample_time, &td->epoch, sizeof(struct timeval));
- memcpy(&td->ss.prev_time, &td->epoch, sizeof(struct timeval));
+ memcpy(&td->start, &td->epoch, sizeof(td->epoch));
+ memcpy(&td->iops_sample_time, &td->epoch, sizeof(td->epoch));
+ memcpy(&td->bw_sample_time, &td->epoch, sizeof(td->epoch));
+ memcpy(&td->ss.prev_time, &td->epoch, sizeof(td->epoch));
lat_target_reset(td);
clear_rusage_stat(td);
return NULL;
}
-static bool mutex_timed_out(struct timeval *t, unsigned int msecs)
+static bool mutex_timed_out(struct timespec *t, unsigned int msecs)
{
- struct timeval now;
+ struct timeval tv;
+ struct timespec now;
+
+ gettimeofday(&tv, NULL);
+ now.tv_sec = tv.tv_sec;
+ now.tv_nsec = tv.tv_usec * 1000;
- gettimeofday(&now, NULL);
return mtime_since(t, &now) >= msecs;
}
* way too early, double check.
*/
ret = pthread_cond_timedwait(&mutex->cond, &mutex->lock, &t);
- if (ret == ETIMEDOUT && !mutex_timed_out(&tv_s, msecs))
+ if (ret == ETIMEDOUT && !mutex_timed_out(&t, msecs))
ret = 0;
}
mutex->waiters--;
td->o.disable_bw = !!val;
td->o.clat_percentiles = !val;
if (val)
- td->tv_cache_mask = 63;
+ td->ts_cache_mask = 63;
return 0;
}
#include "../os-windows.h"
#include "../../lib/hweight.h"
-extern unsigned long mtime_since_now(struct timeval *);
-extern void fio_gettime(struct timeval *, void *);
+extern unsigned long mtime_since_now(struct timespec *);
+extern void fio_gettime(struct timespec *, void *);
/* These aren't defined in the MinGW headers */
HRESULT WINAPI StringCchCopyA(
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
{
- struct timeval tv;
+ struct timespec tv;
DWORD ms_remaining;
DWORD ms_total = (rqtp->tv_sec * 1000) + (rqtp->tv_nsec / 1000000.0);
static struct act_run_data *act_run_data;
struct act_prof_data {
- struct timeval sample_tv;
+ struct timespec sample_tv;
struct act_slice *slices;
unsigned int cur_slice;
unsigned int nr_slices;
reply = calloc(1, sizeof(*reply));
INIT_FLIST_HEAD(&reply->list);
- fio_gettime(&reply->tv, NULL);
+ fio_gettime(&reply->ts, NULL);
reply->saved_tag = tag;
reply->opcode = opcode;
struct fio_net_cmd_reply {
struct flist_head list;
- struct timeval tv;
+ struct timespec ts;
uint64_t saved_tag;
uint16_t opcode;
};
struct thread_stat *ts = &td->ts;
fio_getrusage(&td->ru_end);
- ts->usr_time += mtime_since(&td->ru_start.ru_utime,
+ ts->usr_time += mtime_since_tv(&td->ru_start.ru_utime,
&td->ru_end.ru_utime);
- ts->sys_time += mtime_since(&td->ru_start.ru_stime,
+ ts->sys_time += mtime_since_tv(&td->ru_start.ru_stime,
&td->ru_end.ru_stime);
ts->ctx += td->ru_end.ru_nvcsw + td->ru_end.ru_nivcsw
- (td->ru_start.ru_nvcsw + td->ru_start.ru_nivcsw);
{
struct thread_data *td;
unsigned long long *rt;
- struct timeval tv;
+ struct timespec ts;
int i;
fio_mutex_down(stat_mutex);
rt = malloc(thread_number * sizeof(unsigned long long));
- fio_gettime(&tv, NULL);
+ fio_gettime(&ts, NULL);
for_each_td(td, i) {
td->update_rusage = 1;
td->ts.io_bytes[DDIR_READ] = td->io_bytes[DDIR_READ];
td->ts.io_bytes[DDIR_WRITE] = td->io_bytes[DDIR_WRITE];
td->ts.io_bytes[DDIR_TRIM] = td->io_bytes[DDIR_TRIM];
- td->ts.total_run_time = mtime_since(&td->epoch, &tv);
+ td->ts.total_run_time = mtime_since(&td->epoch, &ts);
- rt[i] = mtime_since(&td->start, &tv);
+ rt[i] = mtime_since(&td->start, &ts);
if (td_read(td) && td->ts.io_bytes[DDIR_READ])
td->ts.runtime[DDIR_READ] += rt[i];
if (td_write(td) && td->ts.io_bytes[DDIR_WRITE])
}
static int status_interval_init;
-static struct timeval status_time;
+static struct timespec status_time;
static int status_file_disabled;
#define FIO_STATUS_FILE "fio-dump-status"
td_io_u_unlock(td);
}
-static int __add_samples(struct thread_data *td, struct timeval *parent_tv,
- struct timeval *t, unsigned int avg_time,
+static int __add_samples(struct thread_data *td, struct timespec *parent_tv,
+ struct timespec *t, unsigned int avg_time,
uint64_t *this_io_bytes, uint64_t *stat_io_bytes,
struct io_stat *stat, struct io_log *log,
bool is_kb)
stat_io_bytes[ddir] = this_io_bytes[ddir];
}
- timeval_add_msec(parent_tv, avg_time);
+ timespec_add_msec(parent_tv, avg_time);
td_io_u_unlock(td);
return min(next, next_log);
}
-static int add_bw_samples(struct thread_data *td, struct timeval *t)
+static int add_bw_samples(struct thread_data *td, struct timespec *t)
{
return __add_samples(td, &td->bw_sample_time, t, td->o.bw_avg_time,
td->this_io_bytes, td->stat_io_bytes,
td_io_u_unlock(td);
}
-static int add_iops_samples(struct thread_data *td, struct timeval *t)
+static int add_iops_samples(struct thread_data *td, struct timespec *t)
{
return __add_samples(td, &td->iops_sample_time, t, td->o.iops_avg_time,
td->this_io_blocks, td->stat_io_blocks,
{
struct thread_data *td;
unsigned int next = ~0U, tmp;
- struct timeval now;
+ struct timespec now;
int i;
fio_gettime(&now, NULL);
int i, j, ddir, prev_groupid, group_ramp_time_over = 0;
unsigned long rate_time;
struct thread_data *td, *td2;
- struct timeval now;
+ struct timespec now;
uint64_t group_bw = 0, group_iops = 0;
uint64_t td_iops, td_bytes;
bool ret;
uint64_t sum_xy;
uint64_t oldest_y;
- struct timeval prev_time;
+ struct timespec prev_time;
uint64_t prev_iops;
uint64_t prev_bytes;
};
#include <stdio.h>
FILE *f_err;
-struct timeval *fio_tv = NULL;
+struct timespec *fio_ts = NULL;
unsigned long fio_debug = 0;
void __dprint(int type, const char *str, ...)
static void show_progress(struct worker_thread *threads, unsigned long total)
{
unsigned long last_nitems = 0;
- struct timeval last_tv;
+ struct timespec last_tv;
fio_gettime(&last_tv, NULL);
int main(int argc, char *argv[])
{
int r;
- struct timeval start, end;
+ struct timespec start, end;
struct fio_lfsr *fl;
int verify = 0;
unsigned int spin = 0;
#include "fio.h"
-static struct timeval genesis;
+static struct timespec genesis;
static unsigned long ns_granularity;
-void timeval_add_msec(struct timeval *tv, unsigned int msec)
+void timespec_add_msec(struct timespec *ts, unsigned int msec)
{
- unsigned long adj_usec = 1000 * msec;
+ unsigned long adj_nsec = 1000000 * msec;
- tv->tv_usec += adj_usec;
- if (adj_usec >= 1000000) {
- unsigned long adj_sec = adj_usec / 1000000;
+ ts->tv_nsec += adj_nsec;
+ if (adj_nsec >= 1000000000) {
+ unsigned long adj_sec = adj_nsec / 1000000000UL;
- tv->tv_usec -= adj_sec * 1000000;
- tv->tv_sec += adj_sec;
+ ts->tv_nsec -= adj_sec * 1000000000UL;
+ ts->tv_sec += adj_sec;
}
- if (tv->tv_usec >= 1000000){
- tv->tv_usec -= 1000000;
- tv->tv_sec++;
+ if (ts->tv_nsec >= 1000000000UL){
+ ts->tv_nsec -= 1000000000UL;
+ ts->tv_sec++;
}
}
*/
uint64_t usec_spin(unsigned int usec)
{
- struct timeval start;
+ struct timespec start;
uint64_t t;
fio_gettime(&start, NULL);
uint64_t usec_sleep(struct thread_data *td, unsigned long usec)
{
struct timespec req;
- struct timeval tv;
+ struct timespec tv;
uint64_t t = 0;
do {
bool ramp_time_over(struct thread_data *td)
{
- struct timeval tv;
-
if (!td->o.ramp_time || td->ramp_time_over)
return true;
- fio_gettime(&tv, NULL);
- if (utime_since(&td->epoch, &tv) >= td->o.ramp_time) {
+ if (utime_since_now(&td->epoch) >= td->o.ramp_time) {
td->ramp_time_over = 1;
reset_all_stats(td);
td_set_runstate(td, TD_RAMP);
* Check the granularity of the nanosleep function
*/
for (i = 0; i < 10; i++) {
- struct timeval tv;
- struct timespec ts;
+ struct timespec tv, ts;
unsigned long elapsed;
fio_gettime(&tv, NULL);
}
}
-void fill_start_time(struct timeval *t)
+void fill_start_time(struct timespec *t)
{
memcpy(t, &genesis, sizeof(genesis));
}
hdr->rand_seed = rand_seed;
hdr->offset = io_u->offset + header_num * td->o.verify_interval;
hdr->time_sec = io_u->start_time.tv_sec;
- hdr->time_usec = io_u->start_time.tv_usec;
+ hdr->time_usec = io_u->start_time.tv_nsec / 1000;
hdr->thread = td->thread_number;
hdr->numberio = io_u->numberio;
hdr->crc32 = fio_crc32c(p, offsetof(struct verify_header, crc32));