#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/ipc.h>
-#ifndef FIO_NO_HAVE_SHM_H
-#include <sys/shm.h>
-#endif
#include <sys/mman.h>
#include "fio.h"
+#ifndef FIO_NO_HAVE_SHM_H
+#include <sys/shm.h>
+#endif
#include "hash.h"
#include "smalloc.h"
#include "verify.h"
#include "lib/rand.h"
#include "memalign.h"
#include "server.h"
+#include "lib/getrusage.h"
+#include "idletime.h"
static pthread_t disk_util_thread;
static struct fio_mutex *disk_thread_mutex;
return 0;
}
+static int fio_file_fsync(struct thread_data *td, struct fio_file *f)
+{
+ int ret;
+
+ if (fio_file_open(f))
+ return fio_io_sync(td, f);
+
+ if (td_io_open_file(td, f))
+ return 1;
+
+ ret = fio_io_sync(td, f);
+ td_io_close_file(td, f);
+ return ret;
+}
+
static inline void __update_tv_cache(struct thread_data *td)
{
fio_gettime(&td->tv_cache, NULL);
return 0;
}
+static void check_update_rusage(struct thread_data *td)
+{
+ if (td->update_rusage) {
+ td->update_rusage = 0;
+ update_rusage_stat(td);
+ fio_mutex_up(td->rusage_sem);
+ }
+}
+
/*
* The main verify engine. Runs over the writes we previously submitted,
* reads the blocks back in, and checks the crc/md5 of the data.
break;
}
+ check_update_rusage(td);
+
if (td->error)
return;
int ret2, full;
update_tv_cache(td);
+ check_update_rusage(td);
if (runtime_exceeded(td, &td->tv_cache)) {
__update_tv_cache(td);
break;
}
+ check_update_rusage(td);
+
if (!td->error) {
min_events = td->cur_depth;
int ret2, full;
enum fio_ddir ddir;
+ check_update_rusage(td);
+
if (td->terminate || td->done)
break;
}
}
+ check_update_rusage(td);
+
if (td->trim_entries)
log_err("fio: %d trim entries leaked?\n", td->trim_entries);
i = td->cur_depth;
if (i) {
- ret = io_u_queued_complete(td, i, NULL);
+ ret = io_u_queued_complete(td, i, bytes_done);
if (td->o.fill_device && td->error == ENOSPC)
td->error = 0;
}
td_set_runstate(td, TD_FSYNCING);
for_each_file(td, f, i) {
- if (!fio_file_open(f))
+ if (!fio_file_fsync(td, f))
continue;
- fio_io_sync(td, f);
+
+ log_err("fio: end_fsync failed for file %s\n",
+ f->file_name);
}
}
} else
char *p;
max_units = td->o.iodepth;
- max_bs = max(td->o.max_bs[DDIR_READ], td->o.max_bs[DDIR_WRITE]);
- max_bs = max(td->o.max_bs[DDIR_TRIM], max_bs);
+ max_bs = td_max_bs(td);
min_write = td->o.min_bs[DDIR_WRITE];
td->orig_buffer_size = (unsigned long long) max_bs
* (unsigned long long) max_units;
return 1;
}
- if (ddir_rw_sum(td->io_bytes) < td->o.size)
+ if (td->o.size != -1ULL && ddir_rw_sum(td->io_bytes) < td->o.size) {
+ uint64_t diff;
+
+ /*
+ * If the difference is less than the minimum IO size, we
+ * are done.
+ */
+ diff = td->o.size - ddir_rw_sum(td->io_bytes);
+ if (diff < td_max_bs(td))
+ return 0;
+
return 1;
+ }
return 0;
}
}
fio_gettime(&td->epoch, NULL);
- getrusage(RUSAGE_SELF, &td->ru_start);
-
+ fio_getrusage(&td->ru_start);
clear_state = 0;
while (keep_running(td)) {
uint64_t verify_bytes;
if (td->o.write_iolog_file)
write_iolog_close(td);
+ fio_mutex_remove(td->rusage_sem);
+ td->rusage_sem = NULL;
+
td_set_runstate(td, TD_EXITED);
return (void *) (uintptr_t) td->error;
}
if (fio_gtod_offload && fio_start_gtod_thread())
return;
+
+ fio_idle_prof_init();
set_sig_handlers();
}
}
+ /* start idle threads before io threads start to run */
+ fio_idle_prof_start();
+
set_genesis_time();
while (todo) {
init_disk_util(td);
+ td->rusage_sem = fio_mutex_init(FIO_MUTEX_LOCKED);
+ td->update_rusage = 0;
+
/*
* Set state to created. Thread will transition
* to TD_INITIALIZED when it's done setting up.
usleep(10000);
}
+ fio_idle_prof_stop();
+
update_io_ticks();
fio_unpin_memory();
}