Calling pthread_cond_signal() or pthread_cond_broadcast() without
holding the associated mutex can lead to missed wakeups. Hence ensure
that td->io_u_lock is held around pthread_cond_signal(&td->free_cond)
calls. A quote from the POSIX spec
(http://pubs.opengroup.org/onlinepubs/
9699919799/functions/pthread_cond_broadcast.html):
"The pthread_cond_broadcast() or pthread_cond_signal() functions may be
called by a thread whether or not it currently owns the mutex that
threads calling pthread_cond_wait() or pthread_cond_timedwait() have
associated with the condition variable during their waits; however, if
predictable scheduling behavior is required, then that mutex shall be
locked by the thread calling pthread_cond_broadcast() or
pthread_cond_signal()."
Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
assert(!(td->flags & TD_F_CHILD));
}
io_u_qpush(&td->io_u_freelist, io_u);
assert(!(td->flags & TD_F_CHILD));
}
io_u_qpush(&td->io_u_freelist, io_u);
}
void clear_io_u(struct thread_data *td, struct io_u *io_u)
}
void clear_io_u(struct thread_data *td, struct io_u *io_u)
}
io_u_rpush(&td->io_u_requeues, __io_u);
}
io_u_rpush(&td->io_u_requeues, __io_u);
done:
pthread_mutex_lock(&td->io_u_lock);
td->nr_verify_threads--;
done:
pthread_mutex_lock(&td->io_u_lock);
td->nr_verify_threads--;
+ pthread_cond_signal(&td->free_cond);
pthread_mutex_unlock(&td->io_u_lock);
pthread_mutex_unlock(&td->io_u_lock);
- pthread_cond_signal(&td->free_cond);
if (i != td->o.verify_async) {
log_err("fio: only %d verify threads started, exiting\n", i);
if (i != td->o.verify_async) {
log_err("fio: only %d verify threads started, exiting\n", i);
+
+ pthread_mutex_lock(&td->io_u_lock);
td->verify_thread_exit = 1;
td->verify_thread_exit = 1;
pthread_cond_broadcast(&td->verify_cond);
pthread_cond_broadcast(&td->verify_cond);
+ pthread_mutex_unlock(&td->io_u_lock);
+
void verify_async_exit(struct thread_data *td)
{
void verify_async_exit(struct thread_data *td)
{
+ pthread_mutex_lock(&td->io_u_lock);
td->verify_thread_exit = 1;
td->verify_thread_exit = 1;
pthread_cond_broadcast(&td->verify_cond);
pthread_cond_broadcast(&td->verify_cond);
- pthread_mutex_lock(&td->io_u_lock);
-
while (td->nr_verify_threads)
pthread_cond_wait(&td->free_cond, &td->io_u_lock);
while (td->nr_verify_threads)
pthread_cond_wait(&td->free_cond, &td->io_u_lock);