mutex: add open init function and down_trylock() variant

Signed-off-by: Jens Axboe <axboe@fb.com>
diff --git a/mutex.c b/mutex.c
index e1fbb60..466e20e 100644
--- a/mutex.c
+++ b/mutex.c
@@ -25,29 +25,19 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 *);