X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=flow.c;h=a8dbfb9bb48e66a991953810d2c25d92eeeacb54;hp=bf5eeec59c0acf2e06d0038ff438dab459d3b2ee;hb=39281024d26b5dbd4c70ce7620aeadc8933ac8c7;hpb=8e8b225d177c8e824785a87a1116309049a27a7c diff --git a/flow.c b/flow.c index bf5eeec5..a8dbfb9b 100644 --- a/flow.c +++ b/flow.c @@ -1,5 +1,5 @@ #include "fio.h" -#include "mutex.h" +#include "fio_sem.h" #include "smalloc.h" #include "flist.h" @@ -11,20 +11,27 @@ struct fio_flow { }; static struct flist_head *flow_list; -static struct fio_mutex *flow_lock; +static struct fio_sem *flow_lock; int flow_threshold_exceeded(struct thread_data *td) { struct fio_flow *flow = td->flow; - int sign; + long long flow_counter; if (!flow) return 0; - sign = td->o.flow > 0 ? 1 : -1; - if (sign * flow->flow_counter > td->o.flow_watermark) { - if (td->o.flow_sleep) + if (td->o.flow > 0) + flow_counter = flow->flow_counter; + else + flow_counter = -flow->flow_counter; + + if (flow_counter > td->o.flow_watermark) { + if (td->o.flow_sleep) { + io_u_quiesce(td); usleep(td->o.flow_sleep); + } + return 1; } @@ -39,7 +46,10 @@ static struct fio_flow *flow_get(unsigned int id) struct fio_flow *flow = NULL; struct flist_head *n; - fio_mutex_down(flow_lock); + if (!flow_lock) + return NULL; + + fio_sem_down(flow_lock); flist_for_each(n, flow_list) { flow = flist_entry(n, struct fio_flow, list); @@ -51,6 +61,10 @@ static struct fio_flow *flow_get(unsigned int id) if (!flow) { flow = smalloc(sizeof(*flow)); + if (!flow) { + fio_sem_up(flow_lock); + return NULL; + } flow->refs = 0; INIT_FLIST_HEAD(&flow->list); flow->id = id; @@ -60,20 +74,23 @@ static struct fio_flow *flow_get(unsigned int id) } flow->refs++; - fio_mutex_up(flow_lock); + fio_sem_up(flow_lock); return flow; } static void flow_put(struct fio_flow *flow) { - fio_mutex_down(flow_lock); + if (!flow_lock) + return; + + fio_sem_down(flow_lock); if (!--flow->refs) { flist_del(&flow->list); sfree(flow); } - fio_mutex_up(flow_lock); + fio_sem_up(flow_lock); } void flow_init_job(struct thread_data *td) @@ -92,13 +109,26 @@ void flow_exit_job(struct thread_data *td) void flow_init(void) { - flow_lock = fio_mutex_init(1); flow_list = smalloc(sizeof(*flow_list)); + if (!flow_list) { + log_err("fio: smalloc pool exhausted\n"); + return; + } + + flow_lock = fio_sem_init(FIO_SEM_UNLOCKED); + if (!flow_lock) { + log_err("fio: failed to allocate flow lock\n"); + sfree(flow_list); + return; + } + INIT_FLIST_HEAD(flow_list); } void flow_exit(void) { - fio_mutex_remove(flow_lock); - sfree(flow_list); + if (flow_lock) + fio_sem_remove(flow_lock); + if (flow_list) + sfree(flow_list); }