examples/libpmem.fio: clean up example
[fio.git] / flow.c
diff --git a/flow.c b/flow.c
index 2993f4e8f8c48dbdc86ad25afc0653fcef31a481..384187ef0a59095d7754c6435132afe00ef9fd09 100644 (file)
--- a/flow.c
+++ b/flow.c
@@ -16,15 +16,22 @@ static struct fio_mutex *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,6 +46,9 @@ static struct fio_flow *flow_get(unsigned int id)
        struct fio_flow *flow = NULL;
        struct flist_head *n;
 
+       if (!flow_lock)
+               return NULL;
+
        fio_mutex_down(flow_lock);
 
        flist_for_each(n, flow_list) {
@@ -51,6 +61,10 @@ static struct fio_flow *flow_get(unsigned int id)
 
        if (!flow) {
                flow = smalloc(sizeof(*flow));
+               if (!flow) {
+                       fio_mutex_up(flow_lock);
+                       return NULL;
+               }
                flow->refs = 0;
                INIT_FLIST_HEAD(&flow->list);
                flow->id = id;
@@ -66,6 +80,9 @@ static struct fio_flow *flow_get(unsigned int id)
 
 static void flow_put(struct fio_flow *flow)
 {
+       if (!flow_lock)
+               return;
+
        fio_mutex_down(flow_lock);
 
        if (!--flow->refs) {
@@ -92,13 +109,26 @@ void flow_exit_job(struct thread_data *td)
 
 void flow_init(void)
 {
-       flow_lock = fio_mutex_init(FIO_MUTEX_UNLOCKED);
        flow_list = smalloc(sizeof(*flow_list));
+       if (!flow_list) {
+               log_err("fio: smalloc pool exhausted\n");
+               return;
+       }
+
+       flow_lock = fio_mutex_init(FIO_MUTEX_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_mutex_remove(flow_lock);
+       if (flow_list)
+               sfree(flow_list);
 }