}
}
-/*
- * We need to rearm on BSD/solaris. Switch this to sigaction in the future...
- */
+static void sig_ill(int sig)
+{
+ if (!threads)
+ return;
+
+ log_err("fio: illegal instruction. your cpu does not support "
+ "the sse4.2 instruction for crc32c\n");
+ terminate_threads(TERMINATE_ALL);
+ exit(4);
+}
+
static void set_sig_handlers(void)
{
struct sigaction act;
act.sa_handler = sig_int;
act.sa_flags = SA_RESTART;
sigaction(SIGINT, &act, NULL);
+
+ memset(&act, 0, sizeof(act));
+ act.sa_handler = sig_ill;
+ act.sa_flags = SA_RESTART;
+ sigaction(SIGILL, &act, NULL);
}
/*
io_u = NULL;
while (!td->terminate) {
- int ret2;
+ int ret2, full;
io_u = __get_io_u(td);
if (!io_u)
* zero read, fail
*/
if (!bytes) {
- td_verror(td, ENODATA, "full resid");
+ td_verror(td, EIO, "full resid");
put_io_u(td, io_u);
break;
}
* if we can queue more, do so. but check if there are
* completed io_u's first.
*/
- min_events = 0;
- if (queue_full(td) || ret == FIO_Q_BUSY) {
- if (td->cur_depth >= td->o.iodepth_low)
- min_events = td->cur_depth - td->o.iodepth_low;
- if (!min_events)
+ full = queue_full(td) || ret == FIO_Q_BUSY;
+ if (full || !td->o.iodepth_batch_complete) {
+ min_events = td->o.iodepth_batch_complete;
+ if (full && !min_events)
min_events = 1;
- }
- /*
- * Reap required number of io units, if any, and do the
- * verification on them through the callback handler
- */
- if (io_u_queued_complete(td, min_events) < 0)
+ do {
+ /*
+ * Reap required number of io units, if any,
+ * and do the verification on them through
+ * the callback handler
+ */
+ if (io_u_queued_complete(td, min_events) < 0) {
+ ret = -1;
+ break;
+ }
+ } while (full && (td->cur_depth > td->o.iodepth_low));
+ }
+ if (ret < 0)
break;
}
long bytes_done = 0;
int min_evts = 0;
struct io_u *io_u;
- int ret2;
+ int ret2, full;
if (td->terminate)
break;
* zero read, fail
*/
if (!bytes) {
- td_verror(td, ENODATA, "full resid");
+ td_verror(td, EIO, "full resid");
put_io_u(td, io_u);
break;
}
/*
* See if we need to complete some commands
*/
- if (queue_full(td) || ret == FIO_Q_BUSY) {
- min_evts = 0;
- if (td->cur_depth >= td->o.iodepth_low)
- min_evts = td->cur_depth - td->o.iodepth_low;
- if (!min_evts)
+ full = queue_full(td) || ret == FIO_Q_BUSY;
+ if (full || !td->o.iodepth_batch_complete) {
+ min_evts = td->o.iodepth_batch_complete;
+ if (full && !min_evts)
min_evts = 1;
+
fio_gettime(&comp_time, NULL);
- bytes_done = io_u_queued_complete(td, min_evts);
- if (bytes_done < 0)
- break;
+
+ do {
+ ret = io_u_queued_complete(td, min_evts);
+ if (ret <= 0)
+ break;
+
+ bytes_done += ret;
+ } while (full && (td->cur_depth > td->o.iodepth_low));
}
+ if (ret < 0)
+ break;
if (!bytes_done)
continue;
* of completions except the very first one which may look
* a little bursty
*/
- usec = utime_since(&s, &comp_time);
+ if (ramp_time_over(td)) {
+ usec = utime_since(&s, &comp_time);
- rate_throttle(td, usec, bytes_done);
+ rate_throttle(td, usec, bytes_done);
- if (check_min_rate(td, &comp_time)) {
- if (exitall_on_terminate)
- terminate_threads(td->groupid);
- td_verror(td, ENODATA, "check_min_rate");
- break;
+ if (check_min_rate(td, &comp_time)) {
+ if (exitall_on_terminate)
+ terminate_threads(td->groupid);
+ td_verror(td, EIO, "check_min_rate");
+ break;
+ }
}
if (td->o.thinktime) {