From: Dave Chinner <dchinner@xxxxxxxxxx> 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@xxxxxxxxxx> --- 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