X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=fio.c;h=f183eeb5f3ea8da9667068c718a1780171498202;hp=22f0124459352e2011a0fe99ced7fb65e514b5f7;hb=c1302d44dd1720bebe5308f976b59d879d994fd3;hpb=34403fb14ba48d708fdfd2934583506bb5caac05 diff --git a/fio.c b/fio.c index 22f01244..f183eeb5 100644 --- a/fio.c +++ b/fio.c @@ -60,17 +60,20 @@ static inline void td_set_runstate(struct thread_data *td, int runstate) td->runstate = runstate; } -static void terminate_threads(int group_id, int forced_kill) +static void terminate_threads(int group_id) { struct thread_data *td; int i; for_each_td(td, i) { if (group_id == TERMINATE_ALL || groupid == td->groupid) { + /* + * if the thread is running, just let it exit + */ + if (td->runstate < TD_RUNNING) + kill(td->pid, SIGQUIT); td->terminate = 1; td->start_delay = 0; - if (forced_kill) - td_set_runstate(td, TD_EXITED); } } } @@ -86,7 +89,7 @@ static void sig_handler(int sig) default: printf("\nfio: terminating on signal %d\n", sig); fflush(stdout); - terminate_threads(TERMINATE_ALL, 0); + terminate_threads(TERMINATE_ALL); break; } } @@ -270,6 +273,8 @@ static void do_verify(struct thread_data *td) io_u = NULL; while (!td->terminate) { + int ret2; + io_u = __get_io_u(td); if (!io_u) break; @@ -290,29 +295,31 @@ static void do_verify(struct thread_data *td) } io_u->end_io = verify_io_u; -requeue: - ret = td_io_queue(td, io_u); + ret = td_io_queue(td, io_u); switch (ret) { case FIO_Q_COMPLETED: if (io_u->error) ret = -io_u->error; - if (io_u->xfer_buflen != io_u->resid && io_u->resid) { + else if (io_u->xfer_buflen != io_u->resid && io_u->resid) { int bytes = io_u->xfer_buflen - io_u->resid; io_u->xfer_buflen = io_u->resid; io_u->xfer_buf += bytes; - goto requeue; + requeue_io_u(td, &io_u); + } else { + ret = io_u_sync_complete(td, io_u); + if (ret < 0) + break; } - ret = io_u_sync_complete(td, io_u); - if (ret < 0) - break; continue; case FIO_Q_QUEUED: break; case FIO_Q_BUSY: requeue_io_u(td, &io_u); - ret = td_io_commit(td); + ret2 = td_io_commit(td); + if (ret2 < 0) + ret = ret2; break; default: assert(ret < 0); @@ -396,6 +403,7 @@ static void do_io(struct thread_data *td) long bytes_done = 0; int min_evts = 0; struct io_u *io_u; + int ret2; if (td->terminate) break; @@ -410,26 +418,24 @@ static void do_io(struct thread_data *td) put_io_u(td, io_u); break; } -requeue: - ret = td_io_queue(td, io_u); + ret = td_io_queue(td, io_u); switch (ret) { case FIO_Q_COMPLETED: - if (io_u->error) { - ret = io_u->error; - break; - } - if (io_u->xfer_buflen != io_u->resid && io_u->resid) { + if (io_u->error) + ret = -io_u->error; + else if (io_u->xfer_buflen != io_u->resid && io_u->resid) { int bytes = io_u->xfer_buflen - io_u->resid; io_u->xfer_buflen = io_u->resid; io_u->xfer_buf += bytes; - goto requeue; + requeue_io_u(td, &io_u); + } else { + fio_gettime(&comp_time, NULL); + bytes_done = io_u_sync_complete(td, io_u); + if (bytes_done < 0) + ret = bytes_done; } - fio_gettime(&comp_time, NULL); - bytes_done = io_u_sync_complete(td, io_u); - if (bytes_done < 0) - ret = bytes_done; break; case FIO_Q_QUEUED: /* @@ -442,7 +448,9 @@ requeue: break; case FIO_Q_BUSY: requeue_io_u(td, &io_u); - ret = td_io_commit(td); + ret2 = td_io_commit(td); + if (ret2 < 0) + ret = ret2; break; default: assert(ret < 0); @@ -485,7 +493,7 @@ requeue: if (check_min_rate(td, &comp_time)) { if (exitall_on_terminate) - terminate_threads(td->groupid, 0); + terminate_threads(td->groupid); td_verror(td, ENODATA, "check_min_rate"); break; } @@ -802,7 +810,7 @@ static void *thread_main(void *data) } if (exitall_on_terminate) - terminate_threads(td->groupid, 0); + terminate_threads(td->groupid); err: if (td->error) @@ -888,7 +896,8 @@ static void reap_threads(int *nr_running, int *t_rate, int *m_rate) if (WIFSIGNALED(status)) { int sig = WTERMSIG(status); - log_err("fio: pid=%d, got signal=%d\n", td->pid, sig); + if (sig != SIGQUIT) + log_err("fio: pid=%d, got signal=%d\n", td->pid, sig); td_set_runstate(td, TD_REAPED); goto reaped; } @@ -922,7 +931,7 @@ reaped: } if (*nr_running == cputhreads && !pending) - terminate_threads(TERMINATE_ALL, 0); + terminate_threads(TERMINATE_ALL); } /*