Revamp file locking

Get rid of the semaphore implementation, no need to carry both.
Add different locking modes (exclusive and readwrite) to enable
a wider range of testing. Also combine lockfile and lockfile_batch,
the latter is now a postfix option to the former.

So to enable readers-excluding-writers locking mode with a lock batch
count of 4, you would write:

lockfile=readwrite:4

instead.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
diff --git a/fio.h b/fio.h
index ffd3d7d..b22009b 100644
--- a/fio.h
+++ b/fio.h
@@ -22,7 +22,6 @@
 #include "arch/arch.h"
 #include "os/os.h"
 #include "mutex.h"
-#include "sem.h"
 #include "log.h"
 #include "debug.h"
 
@@ -47,6 +46,12 @@
 	TD_DDIR_RANDRW		= TD_DDIR_RW | TD_DDIR_RAND,
 };
 
+enum file_lock_mode {
+	FILE_LOCK_NONE,
+	FILE_LOCK_EXCLUSIVE,
+	FILE_LOCK_READWRITE,
+};
+
 /*
  * Use for maintaining statistics
  */
@@ -313,9 +318,10 @@
 	/*
 	 * if io is protected by a semaphore, this is set
 	 */
-	struct fio_sem *sem;
-	void *sem_owner;
-	unsigned int sem_batch;
+	struct fio_mutex *lock;
+	void *lock_owner;
+	unsigned int lock_batch;
+	enum fio_ddir lock_ddir;
 
 	/*
 	 * block map for random io
@@ -415,7 +421,7 @@
 
 	unsigned int nr_files;
 	unsigned int open_files;
-	unsigned int lockfile;
+	enum file_lock_mode file_lock_mode;
 	unsigned int lockfile_batch;
 
 	unsigned int odirect;
@@ -820,8 +826,9 @@
 extern int add_file(struct thread_data *, const char *);
 extern void get_file(struct fio_file *);
 extern int __must_check put_file(struct thread_data *, struct fio_file *);
-extern void lock_file(struct thread_data *, struct fio_file *);
-extern void unlock_file(struct fio_file *);
+extern void lock_file(struct thread_data *, struct fio_file *, enum fio_ddir);
+extern void unlock_file(struct thread_data *, struct fio_file *);
+extern void unlock_file_all(struct thread_data *, struct fio_file *);
 extern int add_dir_files(struct thread_data *, const char *);
 extern int init_random_map(struct thread_data *);
 extern void dup_files(struct thread_data *, struct thread_data *);