From f4b377415b4b53722addedc10801db24ad4e6f23 Mon Sep 17 00:00:00 2001 From: behlendo Date: Sat, 1 Mar 2008 00:45:59 +0000 Subject: 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 --- include/sys/mutex.h | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 include/sys/mutex.h (limited to 'include/sys/mutex.h') 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 +#include + +/* 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 */ -- cgit v1.2.3