Start and stop status interval (or file) thread separately
authorJens Axboe <axboe@fb.com>
Thu, 23 Oct 2014 15:15:20 +0000 (09:15 -0600)
committerJens Axboe <axboe@fb.com>
Thu, 23 Oct 2014 15:15:20 +0000 (09:15 -0600)
This gets rid of the need to create threads on the fly for this,
and we can manage it and stop it before we do real stats at
the end.

Signed-off-by: Jens Axboe <axboe@fb.com>
backend.c
stat.c
stat.h

index 14803c3835de6c0cda1e155f07e271bafce45c81..4437d196c0d5cdf2b5a9ce34c1982d353e7ea480 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -2073,6 +2073,7 @@ int fio_backend(void)
        set_genesis_time();
        stat_init();
        create_disk_util_thread();
+       create_status_interval_thread();
 
        cgroup_list = smalloc(sizeof(*cgroup_list));
        INIT_FLIST_HEAD(cgroup_list);
@@ -2080,6 +2081,7 @@ int fio_backend(void)
        run_threads();
 
        wait_for_disk_thread_exit();
+       wait_for_status_interval_thread_exit();
 
        if (!fio_abort) {
                __show_run_stats();
diff --git a/stat.c b/stat.c
index 03dc45880ed73b9a5cb051a59be37cfc29db1e78..a5fd50b921dbad3279561bf5f471838f67cc87dd 100644 (file)
--- a/stat.c
+++ b/stat.c
@@ -1422,7 +1422,7 @@ void show_run_stats(void)
        fio_mutex_up(stat_mutex);
 }
 
-static void *__show_running_run_stats(void *arg)
+static void __show_running_run_stats(void)
 {
        struct thread_data *td;
        unsigned long long *rt;
@@ -1471,34 +1471,6 @@ static void *__show_running_run_stats(void *arg)
 
        free(rt);
        fio_mutex_up(stat_mutex);
-       free(arg);
-       return NULL;
-}
-
-/*
- * Called from signal handler. It _should_ be safe to just run this inline
- * in the sig handler, but we should be disturbing the system less by just
- * creating a thread to do it.
- */
-void show_running_run_stats(void)
-{
-       pthread_t *thread;
-
-       thread = calloc(1, sizeof(*thread));
-       if (!thread)
-               return;
-
-       if (!pthread_create(thread, NULL, __show_running_run_stats, thread)) {
-               int err;
-
-               err = pthread_detach(*thread);
-               if (err)
-                       log_err("fio: DU thread detach failed: %s\n", strerror(err));
-
-               return;
-       }
-
-       free(thread);
 }
 
 static int status_interval_init;
@@ -1917,3 +1889,53 @@ void stat_exit(void)
        fio_mutex_down(stat_mutex);
        fio_mutex_remove(stat_mutex);
 }
+
+static pthread_t si_thread;
+static pthread_cond_t si_cond;
+static pthread_mutex_t si_lock;
+static int si_thread_exit;
+
+/*
+ * Called from signal handler. Wake up status thread.
+ */
+void show_running_run_stats(void)
+{
+       pthread_cond_signal(&si_cond);
+}
+
+static void *si_thread_main(void *unused)
+{
+       while (!si_thread_exit) {
+               pthread_cond_wait(&si_cond, &si_lock);
+               if (si_thread_exit)
+                       break;
+
+               __show_running_run_stats();
+       }
+
+       return NULL;
+}
+
+void create_status_interval_thread(void)
+{
+       int ret;
+
+       pthread_cond_init(&si_cond, NULL);
+       pthread_mutex_init(&si_lock, NULL);
+
+       ret = pthread_create(&si_thread, NULL, si_thread_main, NULL);
+       if (ret) {
+               log_err("Can't create status thread: %s\n", strerror(ret));
+               return;
+       }
+}
+
+void wait_for_status_interval_thread_exit(void)
+{
+       void *ret;
+
+       si_thread_exit = 1;
+       pthread_cond_signal(&si_cond);
+       pthread_join(si_thread, &ret);
+       pthread_cond_destroy(&si_cond);
+}
diff --git a/stat.h b/stat.h
index d834cffc2ae485cd07394e4454b22d4beceac154..2c68edcc4513fc40bd7f0e9f37daa5a8dd3d6d98 100644 (file)
--- a/stat.h
+++ b/stat.h
@@ -234,6 +234,8 @@ extern void stat_calc_lat_m(struct thread_stat *ts, double *io_u_lat);
 extern void stat_calc_lat_u(struct thread_stat *ts, double *io_u_lat);
 extern void stat_calc_dist(unsigned int *map, unsigned long total, double *io_u_dist);
 extern void reset_io_stats(struct thread_data *);
+extern void create_status_interval_thread(void);
+extern void wait_for_status_interval_thread_exit(void);
 
 static inline int usec_to_msec(unsigned long *min, unsigned long *max,
                               double *mean, double *dev)