[PATCH 11/27] libxfs: add wrappers for kernel semaphores

Dave Chinner
2020-10-15T07:22:10Z

Implemented vi pthread mutexes.

On Linux, fast pthread mutexes don't actaully check which thread
owns the lock on unlock, so can be used in situations where the
unlock occurs in a different thread to the lock. This is
non-portable behaviour, so if other platforms are supported, this
may need to be converted to posix semaphores.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
include/Makefile | 1 +
include/libxfs.h | 1 +
include/sema.h | 35 +++++++++++++++++++++++++++++++++++
libxfs/libxfs_priv.h | 1 +
4 files changed, 38 insertions(+)
create mode 100644 include/sema.h

diff --git a/include/Makefile b/include/Makefile
index 98031e70fa0d..ce89d0237c19 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -17,6 +17,7 @@ LIBHFILES = libxfs.h \
kmem.h \
list.h \
parent.h \
+ sema.h \
spinlock.h \
xfs_inode.h \
xfs_log_recover.h \
diff --git a/include/libxfs.h b/include/libxfs.h
index d03ec8aeaf5c..923a376bd71a 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -20,6 +20,7 @@
#include "atomic.h"
#include "spinlock.h"
#include "completion.h"
+#include "sema.h"

#include "xfs_types.h"
#include "xfs_fs.h"
diff --git a/include/sema.h b/include/sema.h
new file mode 100644
index 000000000000..bcccb156b0ea
--- /dev/null
+++ b/include/sema.h
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019-20 RedHat, Inc.
+ * All Rights Reserved.
+ */
+#ifndef __LIBXFS_SEMA_H__
+#define __LIBXFS_SEMA_H__
+
+/*
+ * This implements kernel compatible semaphore _exclusion_ semantics. It does
+ * not implement counting semaphore behaviour.
+ *
+ * This makes use of the fact that fast pthread mutexes on Linux don't check
+ * that the unlocker is the same thread that locked the mutex, and hence can be
+ * unlocked in a different thread safely.
+ *
+ * If this needs to be portable or we require counting semaphore behaviour in
+ * libxfs code, this requires re-implementation based on posix semaphores.
+ */
+struct semaphore {
+ pthread_mutex_t lock;
+};
+
+#define sema_init(l, nolock) \
+do { \
+ pthread_mutex_init(&(l)->lock, NULL); \
+ if (!nolock) \
+ pthread_mutex_lock(&(l)->lock); \
+} while (0)
+
+#define down(l) pthread_mutex_lock(&(l)->lock)
+#define down_trylock(l) pthread_mutex_trylock(&(l)->lock)
+#define up(l) pthread_mutex_unlock(&(l)->lock)
+
+#endif /* __LIBXFS_SEMA_H__ */
diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h
index 5cbc4fe69732..7be3f7615fdd 100644
--- a/libxfs/libxfs_priv.h
+++ b/libxfs/libxfs_priv.h
@@ -50,6 +50,7 @@
#include "atomic.h"
#include "spinlock.h"
#include "completion.h"
+#include "sema.h"

#include "xfs_types.h"
#include "xfs_arch.h"
--
2.28.0