aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux-mutex.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux-mutex.h')
-rw-r--r--include/linux-mutex.h118
1 files changed, 118 insertions, 0 deletions
diff --git a/include/linux-mutex.h b/include/linux-mutex.h
new file mode 100644
index 000000000..42056617f
--- /dev/null
+++ b/include/linux-mutex.h
@@ -0,0 +1,118 @@
+#ifndef _SYS_LINUX_MUTEX_H
+#define _SYS_LINUX_MUTEX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* See the "Big Theory Statement" in solaris mutex.c.
+ *
+ * Spin mutexes apparently aren't needed by zfs so we assert
+ * if ibc is non-zero.
+ *
+ * Our impementation of adaptive mutexes aren't really adaptive.
+ * They go to sleep every time.
+ */
+
+#define MUTEX_DEFAULT 0
+#define MUTEX_HELD(x) (mutex_owned(x))
+
+#define KM_MAGIC 0x42424242
+#define KM_POISON 0x84
+
+typedef struct {
+ int km_magic;
+ char *km_name;
+ struct task_struct *km_owner;
+ struct semaphore km_sem;
+} kmutex_t;
+
+#undef mutex_init
+static __inline__ void
+mutex_init(kmutex_t *mp, char *name, int type, void *ibc)
+{
+ BUG_ON(ibc != NULL); /* XXX - Spin mutexes not needed? */
+ BUG_ON(type != MUTEX_DEFAULT); /* XXX - Only default type supported? */
+
+ mp->km_magic = KM_MAGIC;
+ sema_init(&mp->km_sem, 1);
+ mp->km_owner = NULL;
+ mp->km_name = NULL;
+
+ if (name) {
+ mp->km_name = kmalloc(strlen(name) + 1, GFP_KERNEL);
+ if (mp->km_name)
+ strcpy(mp->km_name, name);
+ }
+}
+
+#undef mutex_destroy
+static __inline__ void
+mutex_destroy(kmutex_t *mp)
+{
+ BUG_ON(mp->km_magic != KM_MAGIC);
+
+ if (mp->km_name)
+ kfree(mp->km_name);
+
+ memset(mp, KM_POISON, sizeof(*mp));
+}
+
+static __inline__ void
+mutex_enter(kmutex_t *mp)
+{
+ BUG_ON(mp->km_magic != KM_MAGIC);
+ down(&mp->km_sem); /* Will check in_atomic() for us */
+ BUG_ON(mp->km_owner != NULL);
+ mp->km_owner = current;
+}
+
+/* Return 1 if we acquired the mutex, else zero.
+ */
+static __inline__ int
+mutex_tryenter(kmutex_t *mp)
+{
+ int result;
+
+ BUG_ON(mp->km_magic != KM_MAGIC);
+ result = down_trylock(&mp->km_sem); /* returns 0 if acquired */
+ if (result == 0) {
+ BUG_ON(mp->km_owner != NULL);
+ mp->km_owner = current;
+ return 1;
+ }
+ return 0;
+}
+
+static __inline__ void
+mutex_exit(kmutex_t *mp)
+{
+ BUG_ON(mp->km_magic != KM_MAGIC);
+ BUG_ON(mp->km_owner != current);
+ mp->km_owner = NULL;
+ up(&mp->km_sem);
+}
+
+/* Return 1 if mutex is held by current process, else zero.
+ */
+static __inline__ int
+mutex_owned(kmutex_t *mp)
+{
+ BUG_ON(mp->km_magic != KM_MAGIC);
+ return (mp->km_owner == current);
+}
+
+/* Return owner if mutex is owned, else NULL.
+ */
+static __inline__ kthread_t *
+mutex_owner(kmutex_t *mp)
+{
+ BUG_ON(mp->km_magic != KM_MAGIC);
+ return mp->km_owner;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_LINUX_MUTEX_H */