README: add git:// for github as well
[fio.git] / idletime.c
index 244723f051791ab13881398f0eab470f2b1ce62d..db272fe4331e5783b7c755c846e9b4a3f58d9c3d 100644 (file)
@@ -43,6 +43,36 @@ static double calibrate_unit(unsigned char *data)
        return tunit / CALIBRATE_SCALE;
 }
 
+static void free_cpu_affinity(struct idle_prof_thread *ipt)
+{
+#if defined(FIO_HAVE_CPU_AFFINITY)
+       fio_cpuset_exit(&ipt->cpu_mask);
+#endif
+}
+
+static int set_cpu_affinity(struct idle_prof_thread *ipt)
+{
+#if defined(FIO_HAVE_CPU_AFFINITY)
+       if (fio_cpuset_init(&ipt->cpu_mask)) {
+               log_err("fio: cpuset init failed\n");
+               return -1;
+       }
+
+       fio_cpu_set(&ipt->cpu_mask, ipt->cpu);
+
+       if (fio_setaffinity(gettid(), ipt->cpu_mask)) {
+               log_err("fio: fio_setaffinity failed\n");
+               fio_cpuset_exit(&ipt->cpu_mask);
+               return -1;
+       }
+
+       return 0;
+#else
+       log_err("fio: fio_setaffinity not supported\n");
+       return -1;
+#endif
+}
+
 static void *idle_prof_thread_fn(void *data)
 {
        int retval;
@@ -53,20 +83,12 @@ static void *idle_prof_thread_fn(void *data)
        pthread_mutex_lock(&ipt->init_lock);
 
        /* exit if any other thread failed to start */
-       if (ipc.status == IDLE_PROF_STATUS_ABORT)
+       if (ipc.status == IDLE_PROF_STATUS_ABORT) {
+               pthread_mutex_unlock(&ipt->init_lock);
                return NULL;
+       }
 
-#if defined(FIO_HAVE_CPU_AFFINITY)
-       os_cpu_mask_t cpu_mask;
-       memset(&cpu_mask, 0, sizeof(cpu_mask));
-       fio_cpu_set(&cpu_mask, ipt->cpu);
-
-       if ((retval=fio_setaffinity(gettid(), cpu_mask)) == -1)
-               log_err("fio: fio_setaffinity failed\n");
-#else
-       retval = -1;
-       log_err("fio: fio_setaffinity not supported\n");
-#endif
+       retval = set_cpu_affinity(ipt);
        if (retval == -1) {
                ipt->state = TD_EXITED;
                pthread_mutex_unlock(&ipt->init_lock);
@@ -86,7 +108,7 @@ static void *idle_prof_thread_fn(void *data)
        if (retval == -1) {
                ipt->state = TD_EXITED;
                pthread_mutex_unlock(&ipt->init_lock);
-               return NULL;
+               goto do_exit;
        }
 
        ipt->state = TD_INITIALIZED;
@@ -99,12 +121,16 @@ static void *idle_prof_thread_fn(void *data)
        pthread_mutex_lock(&ipt->start_lock);
 
        /* exit if other threads failed to initialize */
-       if (ipc.status == IDLE_PROF_STATUS_ABORT)
-               return NULL;
+       if (ipc.status == IDLE_PROF_STATUS_ABORT) {
+               pthread_mutex_unlock(&ipt->start_lock);
+               goto do_exit;
+       }
 
        /* exit if we are doing calibration only */
-       if (ipc.status == IDLE_PROF_STATUS_CALI_STOP)
-               return NULL;
+       if (ipc.status == IDLE_PROF_STATUS_CALI_STOP) {
+               pthread_mutex_unlock(&ipt->start_lock);
+               goto do_exit;
+       }
 
        fio_gettime(&ipt->tps, NULL);
        ipt->state = TD_RUNNING;
@@ -127,6 +153,8 @@ idle_prof_done:
        ipt->state = TD_EXITED;
        pthread_mutex_unlock(&ipt->start_lock);
 
+do_exit:
+       free_cpu_affinity(ipt);
        return NULL;
 }
 
@@ -326,7 +354,10 @@ void fio_idle_prof_stop(void)
                /* calculate idleness */
                if (ipc.cali_mean != 0.0) {
                        runt = utime_since(&ipt->tps, &ipt->tpe);
-                       ipt->idleness = ipt->loops * ipc.cali_mean / runt;
+                       if (runt)
+                               ipt->idleness = ipt->loops * ipc.cali_mean / runt;
+                       else
+                               ipt->idleness = 0.0;
                } else
                        ipt->idleness = 0.0;
        }
@@ -369,7 +400,7 @@ static double fio_idle_prof_cpu_stat(int cpu)
        return p * 100.0;
 }
 
-void fio_idle_prof_cleanup(void)
+static void fio_idle_prof_cleanup(void)
 {
        if (ipc.ipts) {
                free(ipc.ipts);
@@ -406,7 +437,7 @@ int fio_idle_prof_parse_opt(const char *args)
                ipc.opt = IDLE_PROF_OPT_PERCPU;
                return 0;
        } else {
-               log_err("fio: incorrect idle-prof option\n", args);
+               log_err("fio: incorrect idle-prof option: %s\n", args);
                return -1;
        }       
 #else