summaryrefslogtreecommitdiffstats
path: root/include/sys/mutex.h
diff options
context:
space:
mode:
authorbehlendo <behlendo@7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c>2008-03-01 00:45:59 +0000
committerbehlendo <behlendo@7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c>2008-03-01 00:45:59 +0000
commitf4b377415b4b53722addedc10801db24ad4e6f23 (patch)
treebe8f09aeabfeaf2361d8d84e975c49ec68d96483 /include/sys/mutex.h
parent09b414e880b0c2e4ae08d82354bbae034dafdd9e (diff)
Reorganize /include/ to add a /sys/, this way we don't need to
muck with #includes in existing Solaris style source to get it to find the right stuff. git-svn-id: https://outreach.scidac.gov/svn/spl/trunk@18 7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c
Diffstat (limited to 'include/sys/mutex.h')
-rw-r--r--include/sys/mutex.h121
1 files changed, 121 insertions, 0 deletions
diff --git a/include/sys/mutex.h b/include/sys/mutex.h
new file mode 100644
index 000000000..2db4a7f96
--- /dev/null
+++ b/include/sys/mutex.h
@@ -0,0 +1,121 @@
+#ifndef _SPL_MUTEX_H
+#define _SPL_MUTEX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <linux/module.h>
+#include <sys/types.h>
+
+/* 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 /* _SPL_MUTEX_H */