Recent changes (master)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The following changes since commit 10aa136bddbaa7c845ab4eacb4a9a4a88d6657a3:

  Cleanup symbols that should be static (2014-04-01 21:10:36 -0600)

are available in the git repository at:

  git://git.kernel.dk/fio.git master

for you to fetch changes up to 2e80228232afc9cf90ad06b360a33a05637978f3:

  Use setvbuf() for log writing (2014-04-02 21:47:27 -0600)

----------------------------------------------------------------
Erwan Velu (3):
      iolog: Keep full path for logs files
      stat: fixing bw_agg reporting
      io_u: Using initialized local variable

Jens Axboe (12):
      Merge branch 'erwan/nobasename' of https://github.com/enovance/fio
      Merge branch 'erwan/clang' of https://github.com/enovance/fio
      Fix propagation of error value on failure to connect to fio server
      Add missing crc/test.h file
      Don't crash when using filehash lock before init
      mutex: add open init function and down_trylock() variant
      Add 'f' (Finishing) flag to status output
      iolog: don't serialize the writing of all logs
      Cleanup the parallellized log writing
      crc: add test.h header to test.c
      iolog: invert log_mask bits
      Use setvbuf() for log writing

 HOWTO      |    1 +
 Makefile   |    2 +-
 backend.c  |   44 +--------------
 configure  |   20 +++++++
 crc/test.c |    2 +
 crc/test.h |    6 ++
 eta.c      |    6 +-
 filehash.c |    6 +-
 filelock.c |  157 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 filelock.h |   11 ++++
 fio.h      |    1 +
 init.c     |    9 ++-
 io_u.c     |    4 +-
 iolog.c    |  179 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 iolog.h    |    3 +-
 libfio.c   |    6 ++
 mutex.c    |   55 +++++++++++++------
 mutex.h    |    2 +
 stat.c     |    2 +-
 19 files changed, 432 insertions(+), 84 deletions(-)
 create mode 100644 crc/test.h
 create mode 100644 filelock.c
 create mode 100644 filelock.h

---

Diff of recent changes:

diff --git a/HOWTO b/HOWTO
index 47eff96..7db7b89 100644
--- a/HOWTO
+++ b/HOWTO
@@ -1590,6 +1590,7 @@ I		Thread initialized, waiting or generating necessary data.
 	M	Running, doing mixed sequential reads/writes.
 	m	Running, doing mixed random reads/writes.
 	F	Running, currently waiting for fsync()
+	f	Running, finishing up (writing IO logs, etc)
 	V	Running, doing verification of written data.
 E		Thread exited, not reaped by main thread yet.
 _		Thread reaped, or
diff --git a/Makefile b/Makefile
index 1113c2f..231b4ab 100644
--- a/Makefile
+++ b/Makefile
@@ -35,7 +35,7 @@ SOURCE := gettime.c ioengines.c init.c stat.c log.c time.c filesetup.c \
 		cconv.c lib/prio_tree.c json.c lib/zipf.c lib/axmap.c \
 		lib/lfsr.c gettime-thread.c helpers.c lib/flist_sort.c \
 		lib/hweight.c lib/getrusage.c idletime.c td_error.c \
-		profiles/tiobench.c profiles/act.c io_u_queue.c
+		profiles/tiobench.c profiles/act.c io_u_queue.c filelock.c
 
 ifdef CONFIG_64BIT_LLP64
   CFLAGS += -DBITS_PER_LONG=32
diff --git a/backend.c b/backend.c
index 1ff8b3f..5ac3659 100644
--- a/backend.c
+++ b/backend.c
@@ -57,7 +57,6 @@
 static pthread_t disk_util_thread;
 static struct fio_mutex *disk_thread_mutex;
 static struct fio_mutex *startup_mutex;
-static struct fio_mutex *writeout_mutex;
 static struct flist_head *cgroup_list;
 static char *cgroup_mnt;
 static int exit_value;
@@ -1490,45 +1489,8 @@ static void *thread_main(void *data)
 
 	fio_unpin_memory(td);
 
-	fio_mutex_down(writeout_mutex);
-	finalize_logs(td);
-	if (td->bw_log) {
-		if (o->bw_log_file) {
-			finish_log_named(td, td->bw_log,
-						o->bw_log_file, "bw");
-		} else
-			finish_log(td, td->bw_log, "bw");
-	}
-	if (td->lat_log) {
-		if (o->lat_log_file) {
-			finish_log_named(td, td->lat_log,
-						o->lat_log_file, "lat");
-		} else
-			finish_log(td, td->lat_log, "lat");
-	}
-	if (td->slat_log) {
-		if (o->lat_log_file) {
-			finish_log_named(td, td->slat_log,
-						o->lat_log_file, "slat");
-		} else
-			finish_log(td, td->slat_log, "slat");
-	}
-	if (td->clat_log) {
-		if (o->lat_log_file) {
-			finish_log_named(td, td->clat_log,
-						o->lat_log_file, "clat");
-		} else
-			finish_log(td, td->clat_log, "clat");
-	}
-	if (td->iops_log) {
-		if (o->iops_log_file) {
-			finish_log_named(td, td->iops_log,
-						o->iops_log_file, "iops");
-		} else
-			finish_log(td, td->iops_log, "iops");
-	}
+	fio_writeout_logs(td);
 
-	fio_mutex_up(writeout_mutex);
 	if (o->exec_postrun)
 		exec_string(o, o->exec_postrun, (const char *)"postrun");
 
@@ -2033,9 +1995,6 @@ int fio_backend(void)
 	startup_mutex = fio_mutex_init(FIO_MUTEX_LOCKED);
 	if (startup_mutex == NULL)
 		return 1;
-	writeout_mutex = fio_mutex_init(FIO_MUTEX_UNLOCKED);
-	if (writeout_mutex == NULL)
-		return 1;
 
 	set_genesis_time();
 	stat_init();
@@ -2066,7 +2025,6 @@ int fio_backend(void)
 	sfree(cgroup_mnt);
 
 	fio_mutex_remove(startup_mutex);
-	fio_mutex_remove(writeout_mutex);
 	fio_mutex_remove(disk_thread_mutex);
 	stat_exit();
 	return exit_value;
diff --git a/configure b/configure
index 63aa02d..05f985b 100755
--- a/configure
+++ b/configure
@@ -1163,6 +1163,23 @@ if compile_prog "" "-lrbd -lrados" "rbd"; then
 fi
 echo "Rados Block Device engine     $rbd"
 
+##########################################
+# Check whether we have setvbuf
+setvbuf="no"
+cat > $TMPC << EOF
+#include <stdio.h>
+int main(int argc, char **argv)
+{
+  FILE *f = NULL;
+  char buf[80];
+  setvbuf(f, buf, _IOFBF, sizeof(buf));
+  return 0;
+}
+EOF
+if compile_prog "" "" "setvbuf"; then
+  setvbuf="yes"
+fi
+echo "setvbuf                       $setvbuf"
 
 #############################################################################
 
@@ -1291,6 +1308,9 @@ fi
 if test "$cpu_count" = "yes" ; then
   output_sym "CONFIG_CPU_COUNT"
 fi
+if test "$setvbuf" = "yes" ; then
+  output_sym "CONFIG_SETVBUF"
+fi
 
 echo "LIBS+=$LIBS" >> $config_host_mak
 echo "CFLAGS+=$CFLAGS" >> $config_host_mak
diff --git a/crc/test.c b/crc/test.c
index 174bea3..2cc7c0f 100644
--- a/crc/test.c
+++ b/crc/test.c
@@ -18,6 +18,8 @@
 #include "../crc/sha512.h"
 #include "../crc/xxhash.h"
 
+#include "test.h"
+
 #define CHUNK		131072U
 #define NR_CHUNKS	  2048U
 
diff --git a/crc/test.h b/crc/test.h
new file mode 100644
index 0000000..2b52d6a
--- /dev/null
+++ b/crc/test.h
@@ -0,0 +1,6 @@
+#ifndef FIO_CRC_TEST_H
+#define FIO_CRC_TEST_H
+
+int fio_crctest(const char *type);
+
+#endif
diff --git a/eta.c b/eta.c
index b050102..42066e0 100644
--- a/eta.c
+++ b/eta.c
@@ -74,6 +74,9 @@ static void check_str_update(struct thread_data *td)
 	case TD_FSYNCING:
 		c = 'F';
 		break;
+	case TD_FINISHING:
+		c = 'f';
+		break;
 	case TD_CREATED:
 		c = 'C';
 		break;
@@ -331,7 +334,8 @@ int calc_thread_status(struct jobs_eta *je, int force)
 			bw_avg_time = td->o.bw_avg_time;
 		if (td->runstate == TD_RUNNING || td->runstate == TD_VERIFYING
 		    || td->runstate == TD_FSYNCING
-		    || td->runstate == TD_PRE_READING) {
+		    || td->runstate == TD_PRE_READING
+		    || td->runstate == TD_FINISHING) {
 			je->nr_running++;
 			if (td_read(td)) {
 				je->t_rate[0] += td->o.rate[DDIR_READ];
diff --git a/filehash.c b/filehash.c
index c6ebe76..0d61f54 100644
--- a/filehash.c
+++ b/filehash.c
@@ -21,12 +21,14 @@ static unsigned short hash(const char *name)
 
 void fio_file_hash_lock(void)
 {
-	fio_mutex_down(hash_lock);
+	if (hash_lock)
+		fio_mutex_down(hash_lock);
 }
 
 void fio_file_hash_unlock(void)
 {
-	fio_mutex_up(hash_lock);
+	if (hash_lock)
+		fio_mutex_up(hash_lock);
 }
 
 void remove_file_hash(struct fio_file *f)
diff --git a/filelock.c b/filelock.c
new file mode 100644
index 0000000..b252a97
--- /dev/null
+++ b/filelock.c
@@ -0,0 +1,157 @@
+/*
+ * Really simple exclusive file locking based on filename.
+ * No hash indexing, just a list, so only works well for < 100 files or
+ * so. But that's more than what fio needs, so should be fine.
+ */
+#include <inttypes.h>
+#include <string.h>
+#include <assert.h>
+
+#include "flist.h"
+#include "filelock.h"
+#include "smalloc.h"
+#include "mutex.h"
+#include "hash.h"
+#include "log.h"
+
+struct fio_filelock {
+	uint32_t hash;
+	struct fio_mutex lock;
+	struct flist_head list;
+	unsigned int references;
+};
+	
+static struct flist_head *filelock_list;
+static struct fio_mutex *filelock_lock;
+
+int fio_filelock_init(void)
+{
+	filelock_list = smalloc(sizeof(*filelock_list));
+	if (!filelock_list)
+		return 1;
+
+	INIT_FLIST_HEAD(filelock_list);
+	filelock_lock = fio_mutex_init(FIO_MUTEX_UNLOCKED);
+	if (!filelock_lock) {
+		sfree(filelock_list);
+		return 1;
+	}
+
+	return 0;
+}
+
+void fio_filelock_exit(void)
+{
+	if (!filelock_list)
+		return;
+
+	assert(flist_empty(filelock_list));
+	sfree(filelock_list);
+	filelock_list = NULL;
+	fio_mutex_remove(filelock_lock);
+	filelock_lock = NULL;
+}
+
+static struct fio_filelock *fio_hash_find(uint32_t hash)
+{
+	struct flist_head *entry;
+	struct fio_filelock *ff;
+
+	flist_for_each(entry, filelock_list) {
+		ff = flist_entry(entry, struct fio_filelock, list);
+		if (ff->hash == hash)
+			return ff;
+	}
+
+	return NULL;
+}
+
+static struct fio_filelock *fio_hash_get(uint32_t hash)
+{
+	struct fio_filelock *ff;
+
+	ff = fio_hash_find(hash);
+	if (!ff) {
+		ff = smalloc(sizeof(*ff));
+		ff->hash = hash;
+		__fio_mutex_init(&ff->lock, FIO_MUTEX_UNLOCKED);
+		ff->references = 0;
+		flist_add(&ff->list, filelock_list);
+	}
+
+	return ff;
+}
+
+int fio_trylock_file(const char *fname)
+{
+	struct fio_filelock *ff;
+	uint32_t hash;
+
+	hash = jhash(fname, strlen(fname), 0);
+
+	fio_mutex_down(filelock_lock);
+	ff = fio_hash_get(hash);
+	ff->references++;
+	fio_mutex_up(filelock_lock);
+
+	if (!fio_mutex_down_trylock(&ff->lock))
+		return 0;
+
+	fio_mutex_down(filelock_lock);
+
+	/*
+	 * If we raced and the only reference to the lock is us, we can
+	 * grab it
+	 */
+	if (ff->references != 1) {
+		ff->references--;
+		ff = NULL;
+	}
+
+	fio_mutex_up(filelock_lock);
+
+	if (ff) {
+		fio_mutex_down(&ff->lock);
+		return 0;
+	}
+
+	return 1;
+}
+
+void fio_lock_file(const char *fname)
+{
+	struct fio_filelock *ff;
+	uint32_t hash;
+
+	hash = jhash(fname, strlen(fname), 0);
+
+	fio_mutex_down(filelock_lock);
+	ff = fio_hash_get(hash);
+	ff->references++;
+	fio_mutex_up(filelock_lock);
+
+	fio_mutex_down(&ff->lock);
+}
+
+void fio_unlock_file(const char *fname)
+{
+	struct fio_filelock *ff;
+	uint32_t hash;
+
+	hash = jhash(fname, strlen(fname), 0);
+
+	fio_mutex_down(filelock_lock);
+
+	ff = fio_hash_find(hash);
+	if (ff) {
+		ff->references--;
+		fio_mutex_up(&ff->lock);
+		if (!ff->references) {
+			flist_del(&ff->list);
+			sfree(ff);
+		}
+	} else
+		log_err("fio: file not found for unlocking\n");
+
+	fio_mutex_up(filelock_lock);
+}
diff --git a/filelock.h b/filelock.h
new file mode 100644
index 0000000..97d13b7
--- /dev/null
+++ b/filelock.h
@@ -0,0 +1,11 @@
+#ifndef FIO_LOCK_FILE_H
+#define FIO_LOCK_FILE_H
+
+extern void fio_lock_file(const char *);
+extern int fio_trylock_file(const char *);
+extern void fio_unlock_file(const char *);
+
+extern int fio_filelock_init(void);
+extern void fio_filelock_exit(void);
+
+#endif
diff --git a/fio.h b/fio.h
index befdce3..a539f21 100644
--- a/fio.h
+++ b/fio.h
@@ -471,6 +471,7 @@ enum {
 	TD_PRE_READING,
 	TD_VERIFYING,
 	TD_FSYNCING,
+	TD_FINISHING,
 	TD_EXITED,
 	TD_REAPED,
 };
diff --git a/init.c b/init.c
index c3996a7..910f2ba 100644
--- a/init.c
+++ b/init.c
@@ -24,6 +24,7 @@
 #include "profile.h"
 #include "server.h"
 #include "idletime.h"
+#include "filelock.h"
 
 #include "lib/getopt.h"
 #include "lib/strcasestr.h"
@@ -259,6 +260,7 @@ static void free_shm(void)
 	}
 
 	options_free(fio_options, &def_thread);
+	fio_filelock_exit();
 	scleanup();
 }
 
@@ -1963,11 +1965,8 @@ int parse_cmd_line(int argc, char *argv[], int client_type)
 	if (do_exit && !(is_backend || nr_clients))
 		exit(exit_val);
 
-	if (nr_clients && fio_clients_connect()) {
-		do_exit++;
-		exit_val = 1;
-		return -1;
-	}
+	if (nr_clients && fio_clients_connect())
+		exit(1);
 
 	if (is_backend && backend)
 		return fio_start_server(pid_file);
diff --git a/io_u.c b/io_u.c
index 2f6aecf..411da32 100644
--- a/io_u.c
+++ b/io_u.c
@@ -426,12 +426,10 @@ static unsigned int __get_next_buflen(struct thread_data *td, struct io_u *io_u,
 	unsigned int minbs, maxbs;
 	unsigned long r, rand_max;
 
-	assert(ddir_rw(io_u->ddir));
+	assert(ddir_rw(ddir));
 
 	if (td->o.bs_is_seq_rand)
 		ddir = is_random ? DDIR_WRITE: DDIR_READ;
-	else
-		ddir = io_u->ddir;
 
 	minbs = td->o.min_bs[ddir];
 	maxbs = td->o.max_bs[ddir];
diff --git a/iolog.c b/iolog.c
index b8ee067..e805eae 100644
--- a/iolog.c
+++ b/iolog.c
@@ -10,6 +10,7 @@
 #include "fio.h"
 #include "verify.h"
 #include "trim.h"
+#include "filelock.h"
 
 static const char iolog_ver2[] = "fio version 2 iolog";
 
@@ -515,9 +516,36 @@ void setup_log(struct io_log **log, unsigned long avg_msec, int log_type)
 	*log = l;
 }
 
+#ifdef CONFIG_SETVBUF
+static void *set_file_buffer(FILE *f)
+{
+	size_t size = 1048576;
+	void *buf;
+
+	buf = malloc(size);
+	setvbuf(f, buf, _IOFBF, size);
+	return buf;
+}
+
+static void clear_file_buffer(void *buf)
+{
+	free(buf);
+}
+#else
+static void *set_file_buffer(FILE *f)
+{
+	return NULL;
+}
+
+static void clear_file_buffer(void *buf)
+{
+}
+#endif
+
 void __finish_log(struct io_log *log, const char *name)
 {
 	unsigned int i;
+	void *buf;
 	FILE *f;
 
 	f = fopen(name, "a");
@@ -526,6 +554,8 @@ void __finish_log(struct io_log *log, const char *name)
 		return;
 	}
 
+	buf = set_file_buffer(f);
+
 	for (i = 0; i < log->nr_samples; i++) {
 		fprintf(f, "%lu, %lu, %u, %u\n",
 				(unsigned long) log->log[i].time,
@@ -534,27 +564,160 @@ void __finish_log(struct io_log *log, const char *name)
 	}
 
 	fclose(f);
+	clear_file_buffer(buf);
 	free(log->log);
 	free(log);
 }
 
-void finish_log_named(struct thread_data *td, struct io_log *log,
-		       const char *prefix, const char *postfix)
+static int finish_log_named(struct thread_data *td, struct io_log *log,
+			    const char *prefix, const char *postfix,
+			    int trylock)
 {
-	char file_name[256], *p;
+	char file_name[256];
 
 	snprintf(file_name, sizeof(file_name), "%s_%s.log", prefix, postfix);
-	p = basename(file_name);
+
+	if (trylock) {
+		if (fio_trylock_file(file_name))
+			return 1;
+	} else
+		fio_lock_file(file_name);
 
 	if (td->client_type == FIO_CLIENT_TYPE_GUI) {
-		fio_send_iolog(td, log, p);
+		fio_send_iolog(td, log, file_name);
 		free(log->log);
 		free(log);
 	} else
-		__finish_log(log, p);
+		__finish_log(log, file_name);
+
+	fio_unlock_file(file_name);
+	return 0;
+}
+
+static int finish_log(struct thread_data *td, struct io_log *log,
+		      const char *name, int trylock)
+{
+	return finish_log_named(td, log, td->o.name, name, trylock);
+}
+
+static int write_this_log(struct thread_data *td, struct io_log *log,
+			  const char *log_file, const char *name, int try)
+{
+	int ret;
+
+	if (!log)
+		return 0;
+
+	if (log_file)
+		ret = finish_log_named(td, log, log_file, name, try);
+	else
+		ret = finish_log(td, log, name, try);
+
+	return ret;
 }
 
-void finish_log(struct thread_data *td, struct io_log *log, const char *name)
+static int write_iops_log(struct thread_data *td, int try)
 {
-	finish_log_named(td, log, td->o.name, name);
+	struct thread_options *o = &td->o;
+
+	return write_this_log(td, td->iops_log, o->iops_log_file, "iops", try);
+}
+
+static int write_slat_log(struct thread_data *td, int try)
+{
+	struct thread_options *o = &td->o;
+
+	return write_this_log(td, td->slat_log, o->lat_log_file, "slat", try);
+}
+
+static int write_clat_log(struct thread_data *td, int try)
+{
+	struct thread_options *o = &td->o;
+
+	return write_this_log(td, td->clat_log, o->lat_log_file, "clat" , try);
+}
+
+static int write_lat_log(struct thread_data *td, int try)
+{
+	struct thread_options *o = &td->o;
+
+	return write_this_log(td, td->lat_log, o->lat_log_file, "lat", try);
+}
+
+static int write_bandw_log(struct thread_data *td, int try)
+{
+	struct thread_options *o = &td->o;
+
+	return write_this_log(td, td->bw_log, o->bw_log_file, "bw", try);
+}
+
+enum {
+	BW_LOG_MASK	= 1,
+	LAT_LOG_MASK	= 2,
+	SLAT_LOG_MASK	= 4,
+	CLAT_LOG_MASK	= 8,
+	IOPS_LOG_MASK	= 16,
+
+	ALL_LOG_NR	= 5,
+};
+
+struct log_type {
+	unsigned int mask;
+	int (*fn)(struct thread_data *, int);
+};
+
+static struct log_type log_types[] = {
+	{
+		.mask	= BW_LOG_MASK,
+		.fn	= write_bandw_log,
+	},
+	{
+		.mask	= LAT_LOG_MASK,
+		.fn	= write_lat_log,
+	},
+	{
+		.mask	= SLAT_LOG_MASK,
+		.fn	= write_slat_log,
+	},
+	{
+		.mask	= CLAT_LOG_MASK,
+		.fn	= write_clat_log,
+	},
+	{
+		.mask	= IOPS_LOG_MASK,
+		.fn	= write_iops_log,
+	},
+};
+
+void fio_writeout_logs(struct thread_data *td)
+{
+	unsigned int log_mask = 0;
+	unsigned int log_left = ALL_LOG_NR;
+	int old_state, i;
+
+	old_state = td_bump_runstate(td, TD_FINISHING);
+
+	finalize_logs(td);
+
+	while (log_left) {
+		int prev_log_left = log_left;
+
+		for (i = 0; i < ALL_LOG_NR && log_left; i++) {
+			struct log_type *lt = &log_types[i];
+			int ret;
+
+			if (!(log_mask & lt->mask)) {
+				ret = lt->fn(td, log_left != 1);
+				if (!ret) {
+					log_left--;
+					log_mask |= lt->mask;
+				}
+			}
+		}
+
+		if (prev_log_left == log_left)
+			usleep(5000);
+	}
+
+	td_restore_runstate(td, old_state);
 }
diff --git a/iolog.h b/iolog.h
index 0716391..50d09e2 100644
--- a/iolog.h
+++ b/iolog.h
@@ -131,12 +131,11 @@ extern void add_iops_sample(struct thread_data *, enum fio_ddir, unsigned int,
 extern void init_disk_util(struct thread_data *);
 extern void update_rusage_stat(struct thread_data *);
 extern void setup_log(struct io_log **, unsigned long, int);
-extern void finish_log(struct thread_data *, struct io_log *, const char *);
-extern void finish_log_named(struct thread_data *, struct io_log *, const char *, const char *);
 extern void __finish_log(struct io_log *, const char *);
 extern struct io_log *agg_io_log[DDIR_RWDIR_CNT];
 extern int write_bw_log;
 extern void add_agg_sample(unsigned long, enum fio_ddir, unsigned int);
+extern void fio_writeout_logs(struct thread_data *);
 
 static inline void init_ipo(struct io_piece *ipo)
 {
diff --git a/libfio.c b/libfio.c
index 8eddab8..1fd77e4 100644
--- a/libfio.c
+++ b/libfio.c
@@ -31,6 +31,7 @@
 #include "fio.h"
 #include "smalloc.h"
 #include "os/os.h"
+#include "filelock.h"
 
 /*
  * Just expose an empty list, if the OS does not support disk util stats
@@ -265,6 +266,11 @@ int initialize_fio(char *envp[])
 
 	sinit();
 
+	if (fio_filelock_init()) {
+		log_err("fio: failed initializing filelock subsys\n");
+		return 1;
+	}
+
 	/*
 	 * We need locale for number printing, if it isn't set then just
 	 * go with the US format.
diff --git a/mutex.c b/mutex.c
index e1fbb60..466e20e 100644
--- a/mutex.c
+++ b/mutex.c
@@ -25,29 +25,19 @@ void fio_mutex_remove(struct fio_mutex *mutex)
 	munmap((void *) mutex, sizeof(*mutex));
 }
 
-struct fio_mutex *fio_mutex_init(int value)
+int __fio_mutex_init(struct fio_mutex *mutex, int value)
 {
-	struct fio_mutex *mutex = NULL;
 	pthread_mutexattr_t attr;
 	pthread_condattr_t cond;
 	int ret;
 
-	mutex = (void *) mmap(NULL, sizeof(struct fio_mutex),
-				PROT_READ | PROT_WRITE,
-				OS_MAP_ANON | MAP_SHARED, -1, 0);
-	if (mutex == MAP_FAILED) {
-		perror("mmap mutex");
-		mutex = NULL;
-		goto err;
-	}
-
 	mutex->value = value;
 	mutex->magic = FIO_MUTEX_MAGIC;
 
 	ret = pthread_mutexattr_init(&attr);
 	if (ret) {
 		log_err("pthread_mutexattr_init: %s\n", strerror(ret));
-		goto err;
+		return ret;
 	}
 
 	/*
@@ -57,7 +47,7 @@ struct fio_mutex *fio_mutex_init(int value)
 	ret = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
 	if (ret) {
 		log_err("pthread_mutexattr_setpshared: %s\n", strerror(ret));
-		goto err;
+		return ret;
 	}
 #endif
 
@@ -70,17 +60,30 @@ struct fio_mutex *fio_mutex_init(int value)
 	ret = pthread_mutex_init(&mutex->lock, &attr);
 	if (ret) {
 		log_err("pthread_mutex_init: %s\n", strerror(ret));
-		goto err;
+		return ret;
 	}
 
 	pthread_condattr_destroy(&cond);
 	pthread_mutexattr_destroy(&attr);
+	return 0;
+}
 
-	return mutex;
-err:
-	if (mutex)
-		fio_mutex_remove(mutex);
+struct fio_mutex *fio_mutex_init(int value)
+{
+	struct fio_mutex *mutex = NULL;
+
+	mutex = (void *) mmap(NULL, sizeof(struct fio_mutex),
+				PROT_READ | PROT_WRITE,
+				OS_MAP_ANON | MAP_SHARED, -1, 0);
+	if (mutex == MAP_FAILED) {
+		perror("mmap mutex");
+		return NULL;
+	}
+
+	if (!__fio_mutex_init(mutex, value))
+		return mutex;
 
+	fio_mutex_remove(mutex);
 	return NULL;
 }
 
@@ -125,6 +128,22 @@ int fio_mutex_down_timeout(struct fio_mutex *mutex, unsigned int seconds)
 	return ret;
 }
 
+int fio_mutex_down_trylock(struct fio_mutex *mutex)
+{
+	int ret = 1;
+
+	assert(mutex->magic == FIO_MUTEX_MAGIC);
+
+	pthread_mutex_lock(&mutex->lock);
+	if (mutex->value) {
+		mutex->value--;
+		ret = 0;
+	}
+	pthread_mutex_unlock(&mutex->lock);
+
+	return ret;
+}
+
 void fio_mutex_down(struct fio_mutex *mutex)
 {
 	assert(mutex->magic == FIO_MUTEX_MAGIC);
diff --git a/mutex.h b/mutex.h
index 4f3486d..246afee 100644
--- a/mutex.h
+++ b/mutex.h
@@ -24,10 +24,12 @@ enum {
 	FIO_MUTEX_UNLOCKED	= 1,
 };
 
+extern int __fio_mutex_init(struct fio_mutex *, int);
 extern struct fio_mutex *fio_mutex_init(int);
 extern void fio_mutex_remove(struct fio_mutex *);
 extern void fio_mutex_up(struct fio_mutex *);
 extern void fio_mutex_down(struct fio_mutex *);
+extern int fio_mutex_down_trylock(struct fio_mutex *);
 extern int fio_mutex_down_timeout(struct fio_mutex *, unsigned int);
 
 extern void fio_rwlock_read(struct fio_rwlock *);
diff --git a/stat.c b/stat.c
index 4529f69..509c6f0 100644
--- a/stat.c
+++ b/stat.c
@@ -770,7 +770,7 @@ static void add_ddir_status_json(struct thread_stat *ts,
 	}
 	json_object_add_value_int(dir_object, "bw_min", min);
 	json_object_add_value_int(dir_object, "bw_max", max);
-	json_object_add_value_float(dir_object, "bw_agg", mean);
+	json_object_add_value_float(dir_object, "bw_agg", p_of_agg);
 	json_object_add_value_float(dir_object, "bw_mean", mean);
 	json_object_add_value_float(dir_object, "bw_dev", dev);
 }
--
To unsubscribe from this list: send the line "unsubscribe fio" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel]     [Linux SCSI]     [Linux IDE]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux