summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/sys/mutex.h
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2013-11-06 16:20:21 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2013-11-11 10:08:08 +0100
commit66659ff1ad6831b0ea7425fa6ecd8a8687523658 (patch)
tree48e22b475fa8854128e0861a33fed6f78c8094b5 /freebsd/sys/sys/mutex.h
parentDefine __GLOBL1() and __GLOBL() (diff)
downloadrtems-libbsd-66659ff1ad6831b0ea7425fa6ecd8a8687523658.tar.bz2
Update to FreeBSD 9.2
Diffstat (limited to 'freebsd/sys/sys/mutex.h')
-rw-r--r--freebsd/sys/sys/mutex.h172
1 files changed, 77 insertions, 95 deletions
diff --git a/freebsd/sys/sys/mutex.h b/freebsd/sys/sys/mutex.h
index 447ca17f..0e356e15 100644
--- a/freebsd/sys/sys/mutex.h
+++ b/freebsd/sys/sys/mutex.h
@@ -32,7 +32,6 @@
#ifndef _SYS_MUTEX_H_
#define _SYS_MUTEX_H_
-#ifndef LOCORE
#include <sys/queue.h>
#include <sys/_lock.h>
#include <sys/_mutex.h>
@@ -43,12 +42,6 @@
#include <sys/lockstat.h>
#include <machine/atomic.h>
#include <machine/cpufunc.h>
-#endif /* _KERNEL_ */
-#endif /* !LOCORE */
-
-#include <machine/mutex.h>
-
-#ifdef _KERNEL
#ifdef __rtems__
#define MUTEX_NOINLINE 1
@@ -84,18 +77,6 @@
*/
#define MTX_DESTROYED (MTX_CONTESTED | MTX_UNOWNED)
-#endif /* _KERNEL */
-
-#ifndef LOCORE
-
-/*
- * XXX: Friendly reminder to fix things in MP code that is presently being
- * XXX: worked on.
- */
-#define mp_fixme(string)
-
-#ifdef _KERNEL
-
/*
* Prototypes
*
@@ -103,6 +84,10 @@
* of the kernel via macros, thus allowing us to use the cpp LOCK_FILE
* and LOCK_LINE. These functions should not be called directly by any
* code using the API. Their macros cover their functionality.
+ * Functions with a `_' suffix are the entrypoint for the common
+ * KPI covering both compat shims and fast path case. These can be
+ * used by consumers willing to pass options, file and line
+ * informations, in an option-independent way.
*
* [See below for descriptions]
*
@@ -136,7 +121,12 @@ void _mtx_assert(struct mtx *m, int what, const char *file, int line);
#endif
void _thread_lock_flags(struct thread *, int, const char *, int);
+#define mtx_trylock_flags_(m, opts, file, line) \
+ _mtx_trylock((m), (opts), (file), (line))
+
#ifndef __rtems__
+#define thread_lock_flags_(tdp, opts, file, line) \
+ _thread_lock_flags((tdp), (opts), (file), (line))
#define thread_lock(tdp) \
_thread_lock_flags((tdp), 0, __FILE__, __LINE__)
#define thread_lock_flags(tdp, opt) \
@@ -151,68 +141,59 @@ void _thread_lock_flags(struct thread *, int, const char *, int);
#define mtx_recurse lock_object.lo_data
-/*
- * We define our machine-independent (unoptimized) mutex micro-operations
- * here, if they are not already defined in the machine-dependent mutex.h
- */
+/* Very simple operations on mtx_lock. */
/* Try to obtain mtx_lock once. */
-#ifndef _obtain_lock
-#define _obtain_lock(mp, tid) \
+#define _mtx_obtain_lock(mp, tid) \
atomic_cmpset_acq_ptr(&(mp)->mtx_lock, MTX_UNOWNED, (tid))
-#endif
/* Try to release mtx_lock if it is unrecursed and uncontested. */
-#ifndef _release_lock
-#define _release_lock(mp, tid) \
+#define _mtx_release_lock(mp, tid) \
atomic_cmpset_rel_ptr(&(mp)->mtx_lock, (tid), MTX_UNOWNED)
-#endif
/* Release mtx_lock quickly, assuming we own it. */
-#ifndef _release_lock_quick
-#define _release_lock_quick(mp) \
+#define _mtx_release_lock_quick(mp) \
atomic_store_rel_ptr(&(mp)->mtx_lock, MTX_UNOWNED)
-#endif
/*
- * Obtain a sleep lock inline, or call the "hard" function if we can't get it
- * easy.
+ * Full lock operations that are suitable to be inlined in non-debug
+ * kernels. If the lock cannot be acquired or released trivially then
+ * the work is deferred to another function.
*/
-#ifndef _get_sleep_lock
-#define _get_sleep_lock(mp, tid, opts, file, line) do { \
+
+/* Lock a normal mutex. */
+#define __mtx_lock(mp, tid, opts, file, line) do { \
uintptr_t _tid = (uintptr_t)(tid); \
- if (!_obtain_lock((mp), _tid)) \
+ \
+ if (!_mtx_obtain_lock((mp), _tid)) \
_mtx_lock_sleep((mp), _tid, (opts), (file), (line)); \
else \
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_MTX_LOCK_ACQUIRE, \
mp, 0, 0, (file), (line)); \
} while (0)
-#endif
/*
- * Obtain a spin lock inline, or call the "hard" function if we can't get it
- * easy. For spinlocks, we handle recursion inline (it turns out that function
- * calls can be significantly expensive on some architectures).
- * Since spin locks are not _too_ common, inlining this code is not too big
- * a deal.
+ * Lock a spin mutex. For spinlocks, we handle recursion inline (it
+ * turns out that function calls can be significantly expensive on
+ * some architectures). Since spin locks are not _too_ common,
+ * inlining this code is not too big a deal.
*/
-#ifndef _get_spin_lock
#ifdef SMP
-#define _get_spin_lock(mp, tid, opts, file, line) do { \
+#define __mtx_lock_spin(mp, tid, opts, file, line) do { \
uintptr_t _tid = (uintptr_t)(tid); \
+ \
spinlock_enter(); \
- if (!_obtain_lock((mp), _tid)) { \
+ if (!_mtx_obtain_lock((mp), _tid)) { \
if ((mp)->mtx_lock == _tid) \
(mp)->mtx_recurse++; \
- else { \
+ else \
_mtx_lock_spin((mp), _tid, (opts), (file), (line)); \
- } \
} else \
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_MTX_SPIN_LOCK_ACQUIRE, \
mp, 0, 0, (file), (line)); \
} while (0)
#else /* SMP */
-#define _get_spin_lock(mp, tid, opts, file, line) do { \
+#define __mtx_lock_spin(mp, tid, opts, file, line) do { \
uintptr_t _tid = (uintptr_t)(tid); \
\
spinlock_enter(); \
@@ -220,49 +201,42 @@ void _thread_lock_flags(struct thread *, int, const char *, int);
(mp)->mtx_recurse++; \
else { \
KASSERT((mp)->mtx_lock == MTX_UNOWNED, ("corrupt spinlock")); \
- (mp)->mtx_lock = _tid; \
+ (mp)->mtx_lock = _tid; \
} \
} while (0)
#endif /* SMP */
-#endif
-/*
- * Release a sleep lock inline, or call the "hard" function if we can't do it
- * easy.
- */
-#ifndef _rel_sleep_lock
-#define _rel_sleep_lock(mp, tid, opts, file, line) do { \
+/* Unlock a normal mutex. */
+#define __mtx_unlock(mp, tid, opts, file, line) do { \
uintptr_t _tid = (uintptr_t)(tid); \
\
- if (!_release_lock((mp), _tid)) \
+ if (!_mtx_release_lock((mp), _tid)) \
_mtx_unlock_sleep((mp), (opts), (file), (line)); \
} while (0)
-#endif
/*
- * For spinlocks, we can handle everything inline, as it's pretty simple and
- * a function call would be too expensive (at least on some architectures).
- * Since spin locks are not _too_ common, inlining this code is not too big
- * a deal.
+ * Unlock a spin mutex. For spinlocks, we can handle everything
+ * inline, as it's pretty simple and a function call would be too
+ * expensive (at least on some architectures). Since spin locks are
+ * not _too_ common, inlining this code is not too big a deal.
*
* Since we always perform a spinlock_enter() when attempting to acquire a
* spin lock, we need to always perform a matching spinlock_exit() when
* releasing a spin lock. This includes the recursion cases.
*/
-#ifndef _rel_spin_lock
#ifdef SMP
-#define _rel_spin_lock(mp) do { \
+#define __mtx_unlock_spin(mp) do { \
if (mtx_recursed((mp))) \
(mp)->mtx_recurse--; \
else { \
LOCKSTAT_PROFILE_RELEASE_LOCK(LS_MTX_SPIN_UNLOCK_RELEASE, \
mp); \
- _release_lock_quick((mp)); \
+ _mtx_release_lock_quick((mp)); \
} \
spinlock_exit(); \
} while (0)
#else /* SMP */
-#define _rel_spin_lock(mp) do { \
+#define __mtx_unlock_spin(mp) do { \
if (mtx_recursed((mp))) \
(mp)->mtx_recurse--; \
else { \
@@ -273,7 +247,6 @@ void _thread_lock_flags(struct thread *, int, const char *, int);
spinlock_exit(); \
} while (0)
#endif /* SMP */
-#endif
/*
* Exported lock manipulation interface.
@@ -340,27 +313,48 @@ extern struct mtx_pool *mtxpool_sleep;
#error LOCK_DEBUG not defined, include <sys/lock.h> before <sys/mutex.h>
#endif
#if LOCK_DEBUG > 0 || defined(MUTEX_NOINLINE)
-#define mtx_lock_flags(m, opts) \
- _mtx_lock_flags((m), (opts), LOCK_FILE, LOCK_LINE)
-#define mtx_unlock_flags(m, opts) \
- _mtx_unlock_flags((m), (opts), LOCK_FILE, LOCK_LINE)
-#define mtx_lock_spin_flags(m, opts) \
- _mtx_lock_spin_flags((m), (opts), LOCK_FILE, LOCK_LINE)
-#define mtx_unlock_spin_flags(m, opts) \
- _mtx_unlock_spin_flags((m), (opts), LOCK_FILE, LOCK_LINE)
+#define mtx_lock_flags_(m, opts, file, line) \
+ _mtx_lock_flags((m), (opts), (file), (line))
+#define mtx_unlock_flags_(m, opts, file, line) \
+ _mtx_unlock_flags((m), (opts), (file), (line))
+#define mtx_lock_spin_flags_(m, opts, file, line) \
+ _mtx_lock_spin_flags((m), (opts), (file), (line))
+#define mtx_unlock_spin_flags_(m, opts, file, line) \
+ _mtx_unlock_spin_flags((m), (opts), (file), (line))
#else /* LOCK_DEBUG == 0 && !MUTEX_NOINLINE */
+#define mtx_lock_flags_(m, opts, file, line) \
+ __mtx_lock((m), curthread, (opts), (file), (line))
+#define mtx_unlock_flags_(m, opts, file, line) \
+ __mtx_unlock((m), curthread, (opts), (file), (line))
+#define mtx_lock_spin_flags_(m, opts, file, line) \
+ __mtx_lock_spin((m), curthread, (opts), (file), (line))
+#define mtx_unlock_spin_flags_(m, opts, file, line) \
+ __mtx_unlock_spin((m))
+#endif /* LOCK_DEBUG > 0 || MUTEX_NOINLINE */
+
+#ifdef INVARIANTS
+#define mtx_assert_(m, what, file, line) \
+ _mtx_assert((m), (what), (file), (line))
+
+#define GIANT_REQUIRED mtx_assert_(&Giant, MA_OWNED, __FILE__, __LINE__)
+
+#else /* INVARIANTS */
+#define mtx_assert_(m, what, file, line) (void)0
+#define GIANT_REQUIRED
+#endif /* INVARIANTS */
+
#define mtx_lock_flags(m, opts) \
- _get_sleep_lock((m), curthread, (opts), LOCK_FILE, LOCK_LINE)
+ mtx_lock_flags_((m), (opts), LOCK_FILE, LOCK_LINE)
#define mtx_unlock_flags(m, opts) \
- _rel_sleep_lock((m), curthread, (opts), LOCK_FILE, LOCK_LINE)
+ mtx_unlock_flags_((m), (opts), LOCK_FILE, LOCK_LINE)
#define mtx_lock_spin_flags(m, opts) \
- _get_spin_lock((m), curthread, (opts), LOCK_FILE, LOCK_LINE)
+ mtx_lock_spin_flags_((m), (opts), LOCK_FILE, LOCK_LINE)
#define mtx_unlock_spin_flags(m, opts) \
- _rel_spin_lock((m))
-#endif /* LOCK_DEBUG > 0 || MUTEX_NOINLINE */
-
+ mtx_unlock_spin_flags_((m), (opts), LOCK_FILE, LOCK_LINE)
#define mtx_trylock_flags(m, opts) \
- _mtx_trylock((m), (opts), LOCK_FILE, LOCK_LINE)
+ mtx_trylock_flags_((m), (opts), LOCK_FILE, LOCK_LINE)
+#define mtx_assert(m, what) \
+ mtx_assert_((m), (what), __FILE__, __LINE__)
#define mtx_sleep(chan, mtx, pri, wmesg, timo) \
_sleep((chan), &(mtx)->lock_object, (pri), (wmesg), (timo))
@@ -454,22 +448,10 @@ struct mtx_args {
#define MA_NOTRECURSED LA_NOTRECURSED
#endif
-#ifdef INVARIANTS
-#define mtx_assert(m, what) \
- _mtx_assert((m), (what), __FILE__, __LINE__)
-
-#define GIANT_REQUIRED mtx_assert(&Giant, MA_OWNED)
-
-#else /* INVARIANTS */
-#define mtx_assert(m, what) (void)0
-#define GIANT_REQUIRED
-#endif /* INVARIANTS */
-
/*
* Common lock type names.
*/
#define MTX_NETWORK_LOCK "network driver"
#endif /* _KERNEL */
-#endif /* !LOCORE */
#endif /* _SYS_MUTEX_H_ */